diff --git a/.github/workflows/autochangelog.yml b/.github/workflows/autochangelog.yml
index 77324267187..7953929ce55 100644
--- a/.github/workflows/autochangelog.yml
+++ b/.github/workflows/autochangelog.yml
@@ -1,6 +1,6 @@
name: Autochangelog
on:
- pull_request:
+ pull_request_target:
types: closed
branches:
- master
@@ -15,6 +15,10 @@ jobs:
if: github.event.pull_request.merged == true
steps:
- uses: /actions/checkout@v2
+ with:
+ ref: master
+ - name: Update repository to master
+ run: git pull "origin" master
- name: Ensure +x on CI directory
run: |
chmod -R +x ./tools/ci
diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm
index c87b9942dfc..db1a71c77a6 100644
--- a/code/__defines/damage_organs.dm
+++ b/code/__defines/damage_organs.dm
@@ -61,4 +61,8 @@
#define INFECTION_LEVEL_ONE 100
#define INFECTION_LEVEL_TWO 500
#define INFECTION_LEVEL_THREE 1000
-#define INFECTION_LEVEL_MAX 1500
\ No newline at end of file
+#define INFECTION_LEVEL_MAX 1500
+
+#define MODULAR_BODYPART_INVALID 0 // Cannot be detached or reattached.
+#define MODULAR_BODYPART_PROSTHETIC 1 // Can be detached or reattached freely.
+#define MODULAR_BODYPART_CYBERNETIC 2 // Can be detached or reattached to compatible parent organs.
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index a7b3bd86f8f..f9ce5a1b7f3 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -159,6 +159,14 @@
#define MAT_CHITIN "chitin"
#define MAT_CLOTH "cloth"
#define MAT_SYNCLOTH "syncloth"
+#define MAT_COPPER "copper"
+#define MAT_QUARTZ "quartz"
+#define MAT_TIN "tin"
+#define MAT_VOPAL "void opal"
+#define MAT_ALUMINIUM "aluminium"
+#define MAT_BRONZE "bronze"
+#define MAT_PAINITE "painite"
+#define MAT_BOROSILICATE "borosilicate glass"
#define SHARD_SHARD "shard"
#define SHARD_SHRAPNEL "shrapnel"
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index f6ca0ea5655..4c80db6450b 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -24,6 +24,29 @@
#define EMP_TOX_DMG 0x80 // EMPs inflict toxin damage
#define EMP_OXY_DMG 0x100 // EMPs inflict oxy damage
+// Species allergens
+#define MEAT 0x1 // Skrell won't like this.
+#define FISH 0x2 // Seperate for completion's sake. Still bad for skrell.
+#define FRUIT 0x4 // An apple a day only keeps the doctor away if they're allergic.
+#define VEGETABLE 0x8 // Taters 'n' carrots. Potato allergy is a thing, apparently.
+#define GRAINS 0x10 // Wheat, oats, etc.
+#define BEANS 0x20 // The musical fruit! Includes soy.
+#define SEEDS 0x40 // Hope you don't have a nut allergy.
+#define DAIRY 0x80 // Lactose intolerance, ho! Also bad for skrell.
+#define FUNGI 0x100 // Delicious shrooms.
+#define COFFEE 0x200 // Mostly here for tajara.
+#define GENERIC 0x400 // Catchall for stuff that doesn't fall into the groups above. You shouldn't be allergic to this type, ever.
+#define SUGARS 0x800 // For unathi-like reactions
+
+// Allergen reactions
+#define AG_TOX_DMG 0x1 // the classic
+#define AG_OXY_DMG 0x2 // intense airway reactions
+#define AG_EMOTE 0x4 // general emote reactions based on affect type
+#define AG_PAIN 0x8 // short-lived hurt
+#define AG_WEAKEN 0x10 // too weak to move, oof
+#define AG_BLURRY 0x20 // blurred vision!
+#define AG_SLEEPY 0x40 // fatigue/exhaustion
+
// Species spawn flags
#define SPECIES_IS_WHITELISTED 0x1 // Must be whitelisted to play.
#define SPECIES_IS_RESTRICTED 0x2 // Is not a core/normally playable species. (castes, mutantraces)
diff --git a/code/_helpers/_global_objects.dm b/code/_helpers/_global_objects.dm
index 4cbbcf33147..adbd2785e85 100644
--- a/code/_helpers/_global_objects.dm
+++ b/code/_helpers/_global_objects.dm
@@ -1 +1,2 @@
-var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
\ No newline at end of file
+var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
+var/datum/gear_tweak/implant_location/gear_tweak_implant_location = new()
\ No newline at end of file
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index 855decff39a..0d10e33b492 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -94,13 +94,13 @@ var/global/list/string_slot_flags = list(
"holster" = SLOT_HOLSTER
)
-/proc/get_mannequin(var/ckey)
- if(!mannequins_)
- mannequins_ = new()
- . = mannequins_[ckey]
- if(!.)
- . = new/mob/living/carbon/human/dummy/mannequin()
- mannequins_[ckey] = .
+GLOBAL_LIST_EMPTY(mannequins)
+/proc/get_mannequin(var/ckey = "NULL")
+ var/mob/living/carbon/human/dummy/mannequin/M = GLOB.mannequins[ckey]
+ if(!istype(M))
+ GLOB.mannequins[ckey] = new /mob/living/carbon/human/dummy/mannequin(null)
+ M = GLOB.mannequins[ckey]
+ return M
//////////////////////////
/////Initial Building/////
diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm
index f0787cec292..d45406225c1 100644
--- a/code/_helpers/global_lists_vr.dm
+++ b/code/_helpers/global_lists_vr.dm
@@ -537,4 +537,22 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
for(var/species_name in whitelisted_icons)
custom_species_bases += species_name
+ // Weaver recipe stuff
+ paths = typesof(/datum/weaver_recipe/structure) - /datum/weaver_recipe/structure
+ for(var/path in paths)
+ var/datum/weaver_recipe/instance = new path()
+ if(!instance.title)
+ continue //A prototype or something
+ weavable_structures[instance.title] = instance
+
+ paths = typesof(/datum/weaver_recipe/item) - /datum/weaver_recipe/item
+ for(var/path in paths)
+ var/datum/weaver_recipe/instance = new path()
+ if(!instance.title)
+ continue //A prototype or something
+ weavable_items[instance.title] = instance
+
return 1 // Hooks must return 1
+
+var/global/list/weavable_structures = list()
+var/global/list/weavable_items = list()
\ No newline at end of file
diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm
index 10fcc662f14..6a8e6482ec8 100644
--- a/code/_helpers/unsorted.dm
+++ b/code/_helpers/unsorted.dm
@@ -1284,6 +1284,10 @@ var/list/WALLITEMS = list(
colour += temp_col
return colour
+/proc/color_square(red, green, blue, hex)
+ var/color = hex ? hex : "#[num2hex(red, 2)][num2hex(green, 2)][num2hex(blue, 2)]"
+ return "___"
+
var/mob/dview/dview_mob = new
//Version of view() which ignores darkness, because BYOND doesn't have it.
diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index d63d49e8d76..213fe57b90e 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -60,6 +60,8 @@
// Cyborgs have no range-checking unless there is item use
if(!W)
+ if(bolt && !bolt.malfunction && A.loc != module)
+ return
A.add_hiddenprint(src)
A.attack_robot(src)
return
@@ -120,35 +122,56 @@
/atom/proc/BorgCtrlShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
CtrlShiftClick(user)
-/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/user)
+/obj/machinery/door/airlock/BorgCtrlShiftClick(var/mob/living/silicon/robot/user)
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlShiftClick(user)
/atom/proc/BorgShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
ShiftClick(user)
-/obj/machinery/door/airlock/BorgShiftClick(mob/user) // Opens and closes doors! Forwards to AI code.
+/obj/machinery/door/airlock/BorgShiftClick(var/mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AIShiftClick(user)
/atom/proc/BorgCtrlClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
CtrlClick(user)
-/obj/machinery/door/airlock/BorgCtrlClick(mob/user) // Bolts doors. Forwards to AI code.
+/obj/machinery/door/airlock/BorgCtrlClick(var/mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlClick(user)
-/obj/machinery/power/apc/BorgCtrlClick(mob/user) // turns off/on APCs. Forwards to AI code.
+/obj/machinery/power/apc/BorgCtrlClick(var/mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlClick(user)
-/obj/machinery/turretid/BorgCtrlClick(mob/user) //turret control on/off. Forwards to AI code.
+/obj/machinery/turretid/BorgCtrlClick(var/mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AICtrlClick(user)
/atom/proc/BorgAltClick(var/mob/living/silicon/robot/user)
AltClick(user)
return
-/obj/machinery/door/airlock/BorgAltClick(mob/user) // Eletrifies doors. Forwards to AI code.
+/obj/machinery/door/airlock/BorgAltClick(var/mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AIAltClick(user)
-/obj/machinery/turretid/BorgAltClick(mob/user) //turret lethal on/off. Forwards to AI code.
+/obj/machinery/turretid/BorgAltClick(var/mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
+ if(user.bolt && !user.bolt.malfunction)
+ return
+
AIAltClick(user)
/*
diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm
index 60b08c71d2c..77c9d3ab94a 100644
--- a/code/controllers/subsystems/overlays.dm
+++ b/code/controllers/subsystems/overlays.dm
@@ -5,7 +5,6 @@ SUBSYSTEM_DEF(overlays)
priority = FIRE_PRIORITY_OVERLAYS
init_order = INIT_ORDER_OVERLAY
- var/initialized = FALSE
var/list/queue // Queue of atoms needing overlay compiling (TODO-VERIFY!)
var/list/stats
var/list/overlay_icon_state_caches // Cache thing
@@ -22,7 +21,6 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
stats = list()
/datum/controller/subsystem/overlays/Initialize()
- initialized = TRUE
fire(mc_check = FALSE)
..()
diff --git a/code/controllers/subsystems/processing/chemistry.dm b/code/controllers/subsystems/processing/chemistry.dm
index 7f4fd9c42b6..b4641ba7e00 100644
--- a/code/controllers/subsystems/processing/chemistry.dm
+++ b/code/controllers/subsystems/processing/chemistry.dm
@@ -22,6 +22,7 @@ PROCESSING_SUBSYSTEM_DEF(chemistry)
/datum/controller/subsystem/processing/chemistry/Initialize()
initialize_chemical_reactions()
initialize_chemical_reagents()
+ ..()
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
// It is filtered into multiple lists within a list.
diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm
index 169232d8451..b2bb0c98b7d 100644
--- a/code/datums/autolathe/arms.dm
+++ b/code/datums/autolathe/arms.dm
@@ -326,6 +326,15 @@
category = list("Arms and Ammunition")
hidden = 1*/
+/*
+ * High Caliber
+ */
+
+/datum/category_item/autolathe/arms/rifle_145
+ name = "14.5mm round (sabot)"
+ path = /obj/item/ammo_casing/a145/highvel
+ hidden = 1
+
///////////////////////////////
/*Ammo clips and Speedloaders*/
///////////////////////////////
diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm
index 4af1abfccdb..03d1ca0fddb 100644
--- a/code/datums/autolathe/autolathe.dm
+++ b/code/datums/autolathe/autolathe.dm
@@ -1,6 +1,13 @@
/datum/category_item/autolathe/New()
..()
- var/obj/item/I = new path()
+ var/obj/item/I
+ if(path)
+ I = new path()
+
+ if(!I) // Something has gone horribly wrong, or right.
+ log_debug("[name] created an Autolathe design without an assigned path. This is expected for only the Material Sheet generation.")
+ return
+
if(I.matter && !resources)
resources = list()
for(var/material in I.matter)
@@ -57,6 +64,42 @@
name = "Tools"
category_item_type = /datum/category_item/autolathe/tools
+/datum/category_group/autolathe/materials
+ name = "Materials"
+ category_item_type = /datum/category_item/autolathe/materials
+
+/datum/category_group/autolathe/materials/New()
+ ..()
+
+ for(var/Name in name_to_material)
+ var/datum/material/M = name_to_material[Name]
+
+ if(!M.stack_type) // Shouldn't happen, but might. Never know.
+ continue
+
+ if(istype(M, /datum/material/alienalloy))
+ continue
+
+ var/obj/item/stack/material/Mat = new M.stack_type()
+
+ if(Mat.name in items_by_name)
+ qdel(Mat)
+ continue
+
+ var/datum/category_item/autolathe/materials/WorkDat = new(src)
+
+ WorkDat.name = "[Mat.name]"
+ WorkDat.resources = Mat.matter.Copy()
+ WorkDat.is_stack = TRUE
+ WorkDat.no_scale = TRUE
+ WorkDat.max_stack = Mat.max_amount
+ WorkDat.path = M.stack_type
+
+ qdel(Mat)
+
+ items |= WorkDat
+ items_by_name[WorkDat.name] = WorkDat
+
/*******************
* Category entries *
*******************/
diff --git a/code/datums/autolathe/engineering_vr.dm b/code/datums/autolathe/engineering_vr.dm
index 08e1cf986bf..90970c6e481 100644
--- a/code/datums/autolathe/engineering_vr.dm
+++ b/code/datums/autolathe/engineering_vr.dm
@@ -4,4 +4,24 @@
/datum/category_item/autolathe/engineering/id_restorer
name = "ID restoration console electronics"
- path =/obj/item/weapon/circuitboard/id_restorer
\ No newline at end of file
+ path =/obj/item/weapon/circuitboard/id_restorer
+
+/datum/category_item/autolathe/engineering/oven
+ name = "oven electronics"
+ path =/obj/item/weapon/circuitboard/oven
+
+/datum/category_item/autolathe/engineering/fryer
+ name = "fryer electronics"
+ path =/obj/item/weapon/circuitboard/fryer
+
+/datum/category_item/autolathe/engineering/grill
+ name = "grill electronics"
+ path =/obj/item/weapon/circuitboard/grill
+
+/datum/category_item/autolathe/engineering/cerealmaker
+ name = "cereal maker electronics"
+ path =/obj/item/weapon/circuitboard/cerealmaker
+
+/datum/category_item/autolathe/engineering/candymachine
+ name = "candy machine electronics"
+ path =/obj/item/weapon/circuitboard/candymachine
\ No newline at end of file
diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm
index 8ee77ce6564..00151d6e757 100644
--- a/code/datums/autolathe/general.dm
+++ b/code/datums/autolathe/general.dm
@@ -85,44 +85,6 @@
name = "welding mask"
path =/obj/item/clothing/head/welding
-/datum/category_item/autolathe/general/metal
- name = "steel sheets"
- path =/obj/item/stack/material/steel
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/glass
- name = "glass sheets"
- path =/obj/item/stack/material/glass
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/rglass
- name = "reinforced glass sheets"
- path =/obj/item/stack/material/glass/reinforced
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/rods
- name = "metal rods"
- path =/obj/item/stack/rods
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
-
-/datum/category_item/autolathe/general/plasteel
- name = "plasteel sheets"
- path =/obj/item/stack/material/plasteel
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
- resources = list(MAT_PLASTEEL = 2000)
-
-/datum/category_item/autolathe/general/plastic
- name = "plastic sheets"
- path =/obj/item/stack/material/plastic
- is_stack = TRUE
- no_scale = TRUE //prevents material duplication exploits
- resources = list(MAT_PLASTIC = 2000)
-
//TFF 24/12/19 - Let people print more spray bottles if needed.
/datum/category_item/autolathe/general/spraybottle
name = "spray bottle"
diff --git a/code/datums/autolathe/materials.dm b/code/datums/autolathe/materials.dm
new file mode 100644
index 00000000000..653fca8222e
--- /dev/null
+++ b/code/datums/autolathe/materials.dm
@@ -0,0 +1,38 @@
+
+/datum/category_item/autolathe/materials/metal
+ name = "steel sheets"
+ path =/obj/item/stack/material/steel
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/glass
+ name = "glass sheets"
+ path =/obj/item/stack/material/glass
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/rglass
+ name = "reinforced glass sheets"
+ path =/obj/item/stack/material/glass/reinforced
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/rods
+ name = "metal rods"
+ path =/obj/item/stack/rods
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+
+/datum/category_item/autolathe/materials/plasteel
+ name = "plasteel sheets"
+ path =/obj/item/stack/material/plasteel
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+ resources = list(MAT_PLASTEEL = 2000)
+
+/datum/category_item/autolathe/materials/plastic
+ name = "plastic sheets"
+ path =/obj/item/stack/material/plastic
+ is_stack = TRUE
+ no_scale = TRUE //prevents material duplication exploits
+ resources = list(MAT_PLASTIC = 2000)
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 157a3f113ff..82e5f1f78bd 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -513,8 +513,9 @@
//HUMAN
/mob/living/carbon/human/mind_initialize()
- ..()
- if(!mind.assigned_role) mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
+ . = ..()
+ if(!mind.assigned_role)
+ mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
//slime
/mob/living/simple_mob/slime/mind_initialize()
diff --git a/code/datums/roundstats/departmentgoal.dm b/code/datums/roundstats/departmentgoal.dm
index b0aa69784c6..333e6c03963 100644
--- a/code/datums/roundstats/departmentgoal.dm
+++ b/code/datums/roundstats/departmentgoal.dm
@@ -35,6 +35,7 @@ GLOBAL_LIST(active_department_goals)
cat_goals -= G
GLOB.active_department_goals[category] |= G
+ return 1
/hook/roundend/proc/checkDepartmentGoals()
for(var/category in GLOB.active_department_goals)
@@ -50,6 +51,7 @@ GLOBAL_LIST(active_department_goals)
var/success = G.check_completion()
to_world("[success ? "[G.name]" : "[G.name]"]")
to_world("[G.goal_text]")
+ return 1
/datum/goal
var/name = "goal"
diff --git a/code/datums/roundstats/roundstats.dm b/code/datums/roundstats/roundstats.dm
index c5ceb686a75..c1453b18aff 100644
--- a/code/datums/roundstats/roundstats.dm
+++ b/code/datums/roundstats/roundstats.dm
@@ -32,7 +32,7 @@ GLOBAL_VAR_INIT(mech_destroyed_roundstat, 0)
else if(GLOB.mech_destroyed_roundstat > 1)
valid_stats_list.Add("[GLOB.mech_destroyed_roundstat] mechs were destroyed this shift. What did you do?")
else if(GLOB.seed_planted_shift_roundstat > 20)
- valid_stats_list.Add("[GLOB.seed_planted_shift_roundstat] were planted according to our sensors this shift.")
+ valid_stats_list.Add("[GLOB.seed_planted_shift_roundstat] seeds were planted according to our sensors this shift.")
if(GLOB.rocks_drilled_roundstat > 80)
valid_stats_list.Add("Our strong miners pulverized a whole [GLOB.rocks_drilled_roundstat] piles of pathetic rubble.")
diff --git a/code/datums/supplypacks/materials.dm b/code/datums/supplypacks/materials.dm
index 95f15caa6d1..87780766d96 100644
--- a/code/datums/supplypacks/materials.dm
+++ b/code/datums/supplypacks/materials.dm
@@ -35,6 +35,13 @@
containertype = /obj/structure/closet/crate/grayson
containername = "Plastic sheets crate"
+/datum/supply_pack/materials/copper50
+ name = "50 copper ingots"
+ contains = list(/obj/fiftyspawner/copper)
+ cost = 60
+ containertype = /obj/structure/closet/crate/grayson
+ containername = "Copper ingots crate"
+
/datum/supply_pack/materials/cardboard_sheets
contains = list(/obj/fiftyspawner/cardboard)
name = "50 cardboard sheets"
diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm
index 5f8cf6337c8..1928ee7db68 100644
--- a/code/datums/supplypacks/robotics.dm
+++ b/code/datums/supplypacks/robotics.dm
@@ -189,6 +189,17 @@
containername = "Jumper kit crate"
access = access_robotics
+/datum/supply_pack/robotics/restrainingbolt
+ name = "Restraining bolt crate"
+ contains = list(
+ /obj/item/weapon/implanter = 1,
+ /obj/item/weapon/implantcase/restrainingbolt = 2
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate/secure/cybersolutions
+ containername = "Restraining bolt crate"
+ access = access_robotics
+
/datum/supply_pack/robotics/bike
name = "Spacebike Crate"
contains = list()
diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm
index 5fd24a473fe..32c847ece2e 100644
--- a/code/datums/supplypacks/security.dm
+++ b/code/datums/supplypacks/security.dm
@@ -281,10 +281,7 @@
name = "Armor - Riot plates"
contains = list(
/obj/item/clothing/head/helmet/riot,
- /obj/item/clothing/suit/armor/pcarrier,
- /obj/item/clothing/accessory/armor/armorplate/riot,
- /obj/item/clothing/accessory/armor/armguards/riot,
- /obj/item/clothing/accessory/armor/legguards/riot
+ /obj/item/clothing/suit/armor/pcarrier/riot/full
)
cost = 40
containertype = /obj/structure/closet/crate/secure/lawson
@@ -308,10 +305,7 @@
name = "Armor - Ablative plates"
contains = list(
/obj/item/clothing/head/helmet/laserproof,
- /obj/item/clothing/suit/armor/pcarrier,
- /obj/item/clothing/accessory/armor/armorplate/laserproof,
- /obj/item/clothing/accessory/armor/armguards/laserproof,
- /obj/item/clothing/accessory/armor/legguards/laserproof
+ /obj/item/clothing/suit/armor/pcarrier/laserproof/full
)
cost = 50
containertype = /obj/structure/closet/crate/secure/lawson
@@ -336,10 +330,7 @@
name = "Armor - Ballistic plates"
contains = list(
/obj/item/clothing/head/helmet/bulletproof,
- /obj/item/clothing/suit/armor/pcarrier,
- /obj/item/clothing/accessory/armor/armorplate/bulletproof,
- /obj/item/clothing/accessory/armor/armguards/bulletproof,
- /obj/item/clothing/accessory/armor/legguards/bulletproof
+ /obj/item/clothing/suit/armor/pcarrier/bulletproof/full
)
cost = 50
containertype = /obj/structure/closet/crate/secure/heph
diff --git a/code/datums/underwear/undershirts.dm b/code/datums/underwear/undershirts.dm
index 7da82fa5801..6b2cc3d10f6 100644
--- a/code/datums/underwear/undershirts.dm
+++ b/code/datums/underwear/undershirts.dm
@@ -186,4 +186,14 @@
/datum/category_item/underwear/undershirt/pinkblack_tshirt
name = "Pink and Black T-Shirt"
- icon_state = "pinkblack_tshirt"
\ No newline at end of file
+ icon_state = "pinkblack_tshirt"
+
+/datum/category_item/underwear/undershirt/turtle
+ name = "Turtleneck"
+ icon_state = "turtleneck"
+ has_color = TRUE
+
+/datum/category_item/underwear/undershirt/sleevelessturtle
+ name = "Turtleneck, Sleeveless"
+ icon_state = "sleevelessturtle"
+ has_color = TRUE
\ No newline at end of file
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index b5f9ac3a2fb..9c8bbccc798 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -54,10 +54,8 @@
/area/Initialize()
. = ..()
-
luminosity = !(dynamic_lighting)
icon_state = ""
-
return INITIALIZE_HINT_LATELOAD // Areas tradiationally are initialized AFTER other atoms.
/area/LateInitialize()
@@ -68,7 +66,6 @@
power_change() // all machines set to current power level, also updates lighting icon
if(no_spoilers)
set_spoiler_obfuscation(TRUE)
- return INITIALIZE_HINT_LATELOAD
// Changes the area of T to A. Do not do this manually.
// Area is expected to be a non-null instance.
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 5ec5af0e6b0..c20c29be7b9 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -627,7 +627,7 @@
speech_bubble_hearers += M.client
if(length(speech_bubble_hearers))
- var/image/I = image('icons/mob/talk.dmi', src, "[bubble_icon][say_test(message)]", FLY_LAYER)
+ var/image/I = generate_speech_bubble(src, "[bubble_icon][say_test(message)]", FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index bf5fc0ab18c..4bc8892273f 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -134,7 +134,7 @@
for(var/i in loc)
var/atom/movable/thing = i
// We don't call parent so we are calling this for byond
- thing.Crossed(src)
+ thing.Crossed(src, oldloc)
// We're a multi-tile object (multiple locs)
else if(. && newloc)
@@ -303,6 +303,8 @@
if(AM == src)
continue
AM.Uncrossed(src)
+ if(loc != destination) // Uncrossed() triggered a separate movement
+ return
// Information about turf and z-levels for source and dest collected
var/turf/oldturf = get_turf(oldloc)
@@ -327,6 +329,8 @@
if(AM == src)
continue
AM.Crossed(src, oldloc)
+ if(loc != destination) // Crossed triggered a separate movement
+ return
// Call our thingy to inform everyone we moved
Moved(oldloc, NONE, TRUE)
@@ -462,6 +466,8 @@
minor_dir = dx
minor_dist = dist_x
+ range = min(dist_x + dist_y, range)
+
while(src && target && src.throwing && istype(src.loc, /turf) \
&& ((abs(target.x - src.x)+abs(target.y - src.y) > 0 && dist_travelled < range) \
|| (a && a.has_gravity == 0) \
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index fccf178af9c..ef0af0fab79 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -118,6 +118,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
var/base_species = "Human"
var/list/species_traits = list()
var/blood_color = "#A10808"
+ var/custom_say
+ var/custom_ask
+ var/custom_whisper
+ var/custom_exclaim
// VOREStation
// New stuff
@@ -139,6 +143,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
new_dna.custom_species=custom_species //VOREStaton Edit
new_dna.species_traits=species_traits.Copy() //VOREStation Edit
new_dna.blood_color=blood_color //VOREStation Edit
+ new_dna.custom_say=custom_say //VOREStaton Edit
+ new_dna.custom_ask=custom_ask //VOREStaton Edit
+ new_dna.custom_whisper=custom_whisper //VOREStaton Edit
+ new_dna.custom_exclaim=custom_exclaim //VOREStaton Edit
for(var/b=1;b<=DNA_SE_LENGTH;b++)
new_dna.SE[b]=SE[b]
if(b<=DNA_UI_LENGTH)
@@ -205,6 +213,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
src.base_species = character.species.base_species
src.blood_color = character.species.blood_color
src.species_traits = character.species.traits.Copy()
+ src.custom_say = character.custom_say
+ src.custom_ask = character.custom_ask
+ src.custom_whisper = character.custom_whisper
+ src.custom_exclaim = character.custom_exclaim
// +1 to account for the none-of-the-above possibility
SetUIValueRange(DNA_UI_EAR_STYLE, ear_style + 1, ear_styles_list.len + 1, 1)
diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm
index 758f74d8737..d250c441ad4 100644
--- a/code/game/dna/dna2_helpers.dm
+++ b/code/game/dna/dna2_helpers.dm
@@ -237,6 +237,10 @@
// Technically custom_species is not part of the UI, but this place avoids merge problems.
H.custom_species = dna.custom_species
+ H.custom_say = dna.custom_say
+ H.custom_ask = dna.custom_ask
+ H.custom_whisper = dna.custom_whisper
+ H.custom_exclaim = dna.custom_exclaim
H.species.blood_color = dna.blood_color
var/datum/species/S = H.species
S.produceCopy(dna.base_species,dna.species_traits,src)
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index bbf4bfb3437..241d6132756 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -34,7 +34,7 @@
var/last_activation = 0
/obj/structure/cult/pylon/Initialize()
- ..()
+ . = ..()
START_PROCESSING(SSobj, src)
/obj/structure/cult/pylon/attack_hand(mob/M as mob)
diff --git a/code/game/jobs/job/captain_vr.dm b/code/game/jobs/job/captain_vr.dm
index 4062775846d..dd057fff7bf 100644
--- a/code/game/jobs/job/captain_vr.dm
+++ b/code/game/jobs/job/captain_vr.dm
@@ -26,13 +26,13 @@
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth)
+ access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth, access_gateway)
minimal_access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers,
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
- access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth)
+ access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth, access_gateway)
/datum/alt_title/deputy_manager
title = "Deputy Manager"
diff --git a/code/game/jobs/job/engineering_vr.dm b/code/game/jobs/job/engineering_vr.dm
index 8799aa39058..39905f0bc85 100644
--- a/code/game/jobs/job/engineering_vr.dm
+++ b/code/game/jobs/job/engineering_vr.dm
@@ -6,12 +6,12 @@
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
access_heads, access_construction,
- access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
+ access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload, access_gateway)
minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
access_heads, access_construction,
- access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
+ access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload, access_gateway)
alt_titles = list("Head Engineer" = /datum/alt_title/head_engineer, "Foreman" = /datum/alt_title/foreman, "Maintenance Manager" = /datum/alt_title/maintenance_manager)
/datum/alt_title/head_engineer
diff --git a/code/game/jobs/job/exploration_vr.dm b/code/game/jobs/job/exploration_vr.dm
index 0e6e003f7db..5189ca39b0c 100644
--- a/code/game/jobs/job/exploration_vr.dm
+++ b/code/game/jobs/job/exploration_vr.dm
@@ -1,8 +1,3 @@
-var/const/PATHFINDER =(1<<11)
-var/const/EXPLORER =(1<<12)
-var/const/PILOT =(1<<13)
-var/const/SAR =(1<<14)
-
/obj/item/weapon/card/id/medical/sar
assignment = "Field Medic"
rank = "Field Medic"
@@ -64,13 +59,13 @@ var/const/SAR =(1<<14)
/datum/job/pilot
title = "Pilot"
flag = PILOT
- departments = list(DEPARTMENT_PLANET)
- department_flag = MEDSCI
+ departments = list(DEPARTMENT_CIVILIAN)
+ department_flag = CIVILIAN
faction = "Station"
- total_positions = 4
- spawn_positions = 4
- supervisors = "the Pathfinder and the Head of Personnel"
- selection_color = "#999440"
+ total_positions = 5
+ spawn_positions = 5
+ supervisors = "the Head of Personnel"
+ selection_color = "#515151"
economic_modifier = 5
minimal_player_age = 3
pto_type = PTO_EXPLORATION
diff --git a/code/game/jobs/job/medical_vr.dm b/code/game/jobs/job/medical_vr.dm
index 2679137cf0f..6d5ee57c4e4 100644
--- a/code/game/jobs/job/medical_vr.dm
+++ b/code/game/jobs/job/medical_vr.dm
@@ -5,11 +5,11 @@
access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads,
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
- access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
+ access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels, access_gateway)
minimal_access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads,
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce,
- access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
+ access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels, access_gateway)
alt_titles = list("Chief Physician" = /datum/alt_title/chief_physician, "Medical Director" = /datum/alt_title/medical_director, "Healthcare Manager" = /datum/alt_title/healthcare_manager)
/datum/alt_title/chief_physician
diff --git a/code/game/jobs/job/science_vr.dm b/code/game/jobs/job/science_vr.dm
index 0356656446b..52647422b4f 100644
--- a/code/game/jobs/job/science_vr.dm
+++ b/code/game/jobs/job/science_vr.dm
@@ -10,7 +10,7 @@
minimal_access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
access_tox_storage, access_teleporter,
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
- access_RC_announce, access_keycard_auth, access_tcomsat, access_xenoarch, access_eva, access_network, access_xenobotany)
+ access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network, access_xenobotany)
alt_titles = list("Research Supervisor" = /datum/alt_title/research_supervisor, "Research Manager" = /datum/alt_title/research_manager,
"Head of Development" = /datum/alt_title/head_of_development,"Head Scientist" = /datum/alt_title/head_scientist)
diff --git a/code/game/jobs/job/security_vr.dm b/code/game/jobs/job/security_vr.dm
index e9b9017d9af..082531d944e 100644
--- a/code/game/jobs/job/security_vr.dm
+++ b/code/game/jobs/job/security_vr.dm
@@ -6,11 +6,11 @@
access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_construction,
- access_heads, access_hos, access_RC_announce, access_keycard_auth, access_external_airlocks)
+ access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks)
minimal_access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
access_construction,
- access_heads, access_hos, access_RC_announce, access_keycard_auth, access_external_airlocks)
+ access_heads, access_hos, access_RC_announce, access_keycard_auth, access_gateway, access_external_airlocks)
alt_titles = list("Security Commander" = /datum/alt_title/sec_commander, "Chief of Security" = /datum/alt_title/sec_chief, "Security Manager" = /datum/alt_title/security_manager)
/datum/alt_title/security_manager
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index 4e53589c2ff..96dfbd31834 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -415,7 +415,7 @@ var/global/datum/controller/occupations/job_master
// Implants get special treatment
if(G.slot == "implant")
- var/obj/item/weapon/implant/I = G.spawn_item(H)
+ var/obj/item/weapon/implant/I = G.spawn_item(H, H.client.prefs.gear[G.display_name])
I.invisibility = 100
I.implant_loadout(H)
continue
@@ -514,11 +514,12 @@ var/global/datum/controller/occupations/job_master
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
var/obj/item/weapon/storage/S = locate() in H.contents
- var/obj/item/wheelchair/R = null
+ var/obj/item/wheelchair/R
if(S)
R = locate() in S.contents
if(!l_foot || !r_foot || R)
- var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc)
+ var/wheelchair_type = R?.unfolded_type || /obj/structure/bed/chair/wheelchair
+ var/obj/structure/bed/chair/wheelchair/W = new wheelchair_type(H.loc)
W.buckle_mob(H)
H.update_canmove()
W.set_dir(H.dir)
diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm
index 40f0fdb4a41..9312c84571d 100644
--- a/code/game/jobs/jobs.dm
+++ b/code/game/jobs/jobs.dm
@@ -26,7 +26,10 @@ var/const/PSYCHIATRIST =(1<<7)
var/const/ROBOTICIST =(1<<8)
var/const/XENOBIOLOGIST =(1<<9)
var/const/PARAMEDIC =(1<<10)
-var/const/XENOBOTANIST =(1<<15) //VOREStation Add
+var/const/PATHFINDER =(1<<11) //VOREStation Add
+var/const/EXPLORER =(1<<12) //VOREStation Add
+var/const/SAR =(1<<13) //VOREStation Add
+var/const/XENOBOTANIST =(1<<14) //VOREStation Add
var/const/CIVILIAN =(1<<2)
@@ -43,9 +46,10 @@ var/const/LAWYER =(1<<9)
var/const/CHAPLAIN =(1<<10)
var/const/ASSISTANT =(1<<11)
var/const/BRIDGE =(1<<12)
-var/const/CLOWN =(1<<13) //VOREStation Add
-var/const/MIME =(1<<14) //VOREStation Add
-var/const/ENTERTAINER =(1<<15) //VOREStation Add
+var/const/PILOT =(1<<13) //VOREStation Add
+var/const/CLOWN =(1<<14) //VOREStation Add
+var/const/MIME =(1<<15) //VOREStation Add
+var/const/ENTERTAINER =(1<<16) //VOREStation Add
//VOREStation Add
var/const/TALON =(1<<3)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index a97fbf986f7..e0ff3a6086c 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -529,5 +529,5 @@
stasis_level = 100 //Just one setting
/obj/machinery/sleeper/survival_pod/Initialize()
- ..()
+ . = ..()
RefreshParts(1)
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 3cde4792387..80ff6aee29a 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -36,6 +36,14 @@
if(!autolathe_recipes)
autolathe_recipes = new()
wires = new(src)
+
+ for(var/Name in name_to_material)
+ if(Name in stored_material)
+ continue
+
+ stored_material[Name] = 0
+ storage_capacity[Name] = 0
+
default_apply_parts()
RefreshParts()
@@ -270,6 +278,15 @@
//Create the desired item.
var/obj/item/I = new making.path(src.loc)
+
+ if(LAZYLEN(I.matter)) // Sadly we must obey the laws of equivalent exchange.
+ I.matter.Cut()
+ else
+ I.matter = list()
+
+ for(var/material in making.resources) // Handle the datum's autoscaling for waste, so we're properly wasting material, but not so much if we have efficiency.
+ I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
+
flick("[initial(icon_state)]_finish", src)
if(multiplier > 1)
if(istype(I, /obj/item/stack))
@@ -277,7 +294,16 @@
S.amount = multiplier
else
for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack.
- new making.path(src.loc)
+ I = new making.path(src.loc)
+ // We've already deducted the cost of multiple items. Process the matter the same.
+ if(LAZYLEN(I.matter))
+ I.matter.Cut()
+
+ else
+ I.matter = list()
+
+ for(var/material in making.resources)
+ I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
return TRUE
return FALSE
@@ -303,10 +329,9 @@
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
man_rating += M.rating
- storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000
- storage_capacity[MAT_PLASTIC] = mb_rating * 20000
- storage_capacity[MAT_PLASTEEL] = mb_rating * 16250
- storage_capacity["glass"] = mb_rating * 12500
+ for(var/mat_name in storage_capacity)
+ storage_capacity[mat_name] = mb_rating * 25000
+
build_time = 50 / man_rating
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5
update_tgui_static_data(usr)
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 7ff97c83e85..2c12343c883 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -1,9 +1,8 @@
-/obj/machinery/computer/arcade/
+/obj/machinery/computer/arcade
name = "random arcade"
desc = "random arcade machine"
- icon_state = "arcade"
+ icon_state = "arcade1"
icon_keyboard = null
- icon_screen = "invaders"
clicksound = null //Gets too spammy and makes no sense for arcade to have the console keyboard noise anyway
var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2,
/obj/item/toy/blink = 2,
@@ -25,15 +24,15 @@
/obj/item/toy/stickhorse = 2
)
-/obj/machinery/computer/arcade/New()
- ..()
+/obj/machinery/computer/arcade/Initialize()
+ . = ..()
// If it's a generic arcade machine, pick a random arcade
// circuit board for it and make the new machine
if(!circuit)
var/choice = pick(subtypesof(/obj/item/weapon/circuitboard/arcade) - /obj/item/weapon/circuitboard/arcade/clawmachine)
var/obj/item/weapon/circuitboard/CB = new choice()
new CB.build_path(loc, CB)
- qdel(src)
+ return INITIALIZE_HINT_QDEL
/obj/machinery/computer/arcade/proc/prizevend()
if(!(contents-circuit).len)
@@ -77,9 +76,10 @@
///////////////////
/obj/machinery/computer/arcade/battle
- name = "arcade machine"
- desc = "Does not support Pinball."
- icon_state = "arcade"
+ name = "Battler"
+ desc = "Fight through what space has to offer!"
+ icon_state = "arcade2"
+ icon_screen = "battler"
circuit = /obj/item/weapon/circuitboard/arcade/battle
var/enemy_name = "Space Villian"
var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc
@@ -310,7 +310,8 @@
/obj/machinery/computer/arcade/orion_trail
name = "The Orion Trail"
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
- icon_state = "arcade"
+ icon_state = "arcade1"
+ icon_screen = "orion"
circuit = /obj/item/weapon/circuitboard/arcade/orion_trail
var/busy = 0 //prevent clickspam that allowed people to ~speedrun~ the game.
var/engine = 0
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index cc05d632176..8d4202d4213 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -26,7 +26,7 @@
light_color = "#315ab4"
/obj/machinery/computer/cloning/Initialize()
- ..()
+ . = ..()
pods = list()
records = list()
set_scan_temp("Scanner ready.", "good")
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index adf53c80a8e..680ce44345f 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -29,7 +29,7 @@
/obj/machinery/computer/med_data/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"sex" = "Please select new sex:",
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 1caa7b61a4d..430b42591cf 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -335,7 +335,7 @@
name = "Monitor Decryption Key"
/obj/item/weapon/paper/monitorkey/Initialize()
- ..() //Late init
+ ..()
return INITIALIZE_HINT_LATELOAD
/obj/item/weapon/paper/monitorkey/LateInitialize()
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index dbd5ba8383f..5eae5e82d08 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -13,7 +13,7 @@
var/title = "Mass Driver Controls"
/obj/machinery/computer/pod/Initialize()
- ..() //Not returning parent because lateload
+ ..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/pod/LateInitialize()
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 9932934a83d..c26d2c5365b 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -15,6 +15,9 @@
var/stop = 0.0
var/screen = 0 // 0 - No Access Denied, 1 - Access allowed
+/obj/machinery/computer/prisoner/attack_ai(var/mob/user as mob)
+ return src.attack_hand(user)
+
/obj/machinery/computer/prisoner/attack_hand(mob/user)
if(..())
return
@@ -28,7 +31,7 @@
/obj/machinery/computer/prisoner/tgui_data(mob/user)
var/list/data = list()
-
+
data["locked"] = !screen
data["chemImplants"] = list()
data["trackImplants"] = list()
@@ -65,24 +68,22 @@
return data
+
/obj/machinery/computer/prisoner/tgui_act(action, list/params)
if(..())
return TRUE
-
switch(action)
if("inject")
var/obj/item/weapon/implant/I = locate(params["imp"])
if(I)
I.activate(clamp(params["val"], 0, 10))
. = TRUE
-
if("lock")
if(allowed(usr))
screen = !screen
else
to_chat(usr, "Unauthorized Access.")
. = TRUE
-
if("warn")
var/warning = sanitize(input(usr, "Message:", "Enter your message here!", ""))
if(!warning)
@@ -91,5 +92,4 @@
if(I && I.imp_in)
to_chat(I.imp_in, "You hear a voice in your head saying: '[warning]'")
. = TRUE
-
add_fingerprint(usr)
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 1fbd897113d..4222e1264cd 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -25,7 +25,7 @@
var/static/list/field_edit_choices
/obj/machinery/computer/secure_data/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"name" = "Please enter new name:",
@@ -389,11 +389,11 @@
if(field == "age")
answer = text2num(answer)
-
+
if(field == "rank")
if(answer in joblist)
active1.fields["real_rank"] = answer
-
+
if(field == "criminal")
for(var/mob/living/carbon/human/H in player_list)
BITSET(H.hud_updateflag, WANTED_HUD)
diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm
index 47b9e8ce256..e11f404b165 100644
--- a/code/game/machinery/computer/skills.dm
+++ b/code/game/machinery/computer/skills.dm
@@ -30,7 +30,7 @@
var/static/list/field_edit_choices
/obj/machinery/computer/skills/Initialize()
- ..()
+ . = ..()
field_edit_questions = list(
// General
"name" = "Please input new name:",
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 014efcb5813..39d54ef96d5 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -862,14 +862,14 @@ About the new airlock wires panel:
/obj/machinery/door/airlock/tgui_data(mob/user)
var/list/data = list()
-
+
var/list/power = list()
power["main"] = main_power_lost_until > 0 ? 0 : 2
power["main_timeleft"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1)
power["backup"] = backup_power_lost_until > 0 ? 0 : 2
power["backup_timeleft"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1)
data["power"] = power
-
+
data["shock"] = (electrified_until == 0) ? 2 : 0
data["shock_timeleft"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1)
data["id_scanner"] = !aiDisabledIdScanner
diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index f4d9c900ed3..e3098507f21 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -8,8 +8,6 @@
#define PRESET_MEDIUM 5 MINUTES
#define PRESET_LONG 10 MINUTES
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
///////////////////////////////////////////////////////////////////////////////////////////////
// Brig Door control displays.
// Description: This is a controls the timer for the brig doors, displays the timer on itself and
@@ -25,22 +23,21 @@
layer = ABOVE_WINDOW_LAYER
desc = "A remote control for a door."
req_access = list(access_brig)
- anchored = 1.0 // can't pick it up
- density = 0 // can walk through it.
- var/id = null // id of door it controls.
-
+ anchored = 1.0 // can't pick it up
+ density = 0 // can walk through it.
+ var/id = null // id of door it controls.
var/activation_time = 0
var/timer_duration = 0
var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing
var/list/obj/machinery/targets = list()
+
maptext_height = 26
maptext_width = 32
/obj/machinery/door_timer/Initialize()
..()
- //Doors need to go first, and can't rely on init order, so come back to me.
return INITIALIZE_HINT_LATELOAD
/obj/machinery/door_timer/LateInitialize()
@@ -72,12 +69,12 @@
/obj/machinery/door_timer/process()
if(stat & (NOPOWER|BROKEN))
return
-
if(timing)
if(world.time - activation_time >= timer_duration)
timer_end() // open doors, reset timer, clear status screen
update_icon()
+
// has the door power situation changed, if so update icon.
/obj/machinery/door_timer/power_change()
..()
@@ -108,7 +105,7 @@
C.icon_state = "closed_locked"
return 1
-// Opens and unlocks doors, power check
+/// Opens and unlocks doors, power check
/obj/machinery/door_timer/proc/timer_end(forced = FALSE)
if(stat & (NOPOWER|BROKEN))
return 0
@@ -145,6 +142,9 @@
if(timer_duration && activation_time && timing) // Setting it while active will reset the activation time
activation_time = world.time
+/obj/machinery/door_timer/attack_ai(mob/user)
+ return src.attack_hand(user)
+
/obj/machinery/door_timer/attack_hand(mob/user)
if(..())
return TRUE
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index c23d02f4d01..af506f4fe95 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -4,6 +4,7 @@
/datum/feed_message
var/author =""
+ var/title
var/body =""
var/message_type ="Story"
var/datum/feed_channel/parent_channel
@@ -58,9 +59,6 @@
var/list/datum/feed_channel/network_channels = list()
var/datum/feed_message/wanted_issue
-/datum/feed_network/New()
- CreateFeedChannel("Station Announcements", "SS13", 1, 1, "New Station Announcement Available")
-
/datum/feed_network/proc/CreateFeedChannel(var/channel_name, var/author, var/locked, var/adminChannel = 0, var/announcement_message)
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = channel_name
@@ -73,12 +71,16 @@
newChannel.announcement = "Breaking news from [channel_name]!"
network_channels += newChannel
-/datum/feed_network/proc/SubmitArticle(var/msg, var/author, var/channel_name, var/obj/item/weapon/photo/photo, var/adminMessage = 0, var/message_type = "")
+/datum/feed_network/proc/SubmitArticle(var/msg, var/author, var/channel_name, var/obj/item/weapon/photo/photo, var/adminMessage = 0, var/message_type = "", var/title)
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = author
newMsg.body = msg
newMsg.time_stamp = "[stationtime2text()]"
newMsg.is_admin_message = adminMessage
+ if(title)
+ newMsg.title = title
+ else
+ newMsg.title = "News Update"
newMsg.post_time = round_duration_in_ds // Should be almost universally unique
if(message_type)
newMsg.message_type = message_type
@@ -147,6 +149,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
// 1 = there has
var/scanned_user = "Unknown" //Will contain the name of the person who currently uses the newscaster
var/msg = ""; //Feed message
+ var/title = ""; // Feed title
var/datum/news_photo/photo_data = null
var/channel_name = ""; //the feed channel which will be receiving the feed, or being created
var/c_locked=0; //Will our new channel be locked to public submissions?
@@ -164,7 +167,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
securityCaster = 1
/obj/machinery/newscaster/Initialize()
- ..() //Not returning . because lateload below
+ ..()
allCasters += src
unit_no = ++unit_no_cur
paper_remaining = 15
@@ -371,7 +374,6 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
/obj/machinery/newscaster/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
-
switch(action)
if("cleartemp")
temp = null
@@ -434,6 +436,10 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
msg = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", "") as message|null)
return TRUE
+ if("set_new_title")
+ title = sanitize(input(usr, "Enter your Feed title", "Network Channel Handler", "") as message|null)
+ return TRUE
+
if("set_attachment")
AttachPhoto(usr)
return TRUE
@@ -449,10 +455,13 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
if(channel_name == "")
set_temp("Error: Could not submit feed message to network: No feed channel selected.", "danger", FALSE)
return TRUE
+ if(title == "")
+ set_temp("Error: Invalid Title.", "danger", FALSE)
+ return TRUE
var/image = photo_data ? photo_data.photo : null
feedback_inc("newscaster_stories",1)
- news_network.SubmitArticle(msg, our_user, channel_name, image, 0)
+ news_network.SubmitArticle(msg, our_user, channel_name, image, 0, "", title)
set_temp("Feed message created successfully.", "success", FALSE)
return TRUE
@@ -629,153 +638,6 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
photo_data = new(selection, 1)
-//########################################################################################################################
-//###################################### NEWSPAPER! ######################################################################
-//########################################################################################################################
-
-/obj/item/weapon/newspaper
- name = "newspaper"
- desc = "An issue of The Griffon, the newspaper circulating aboard most stations."
- icon = 'icons/obj/bureaucracy.dmi'
- icon_state = "newspaper"
- w_class = ITEMSIZE_SMALL //Let's make it fit in trashbags!
- attack_verb = list("bapped")
- var/screen = 0
- var/pages = 0
- var/curr_page = 0
- var/list/datum/feed_channel/news_content = list()
- var/datum/feed_message/important_message = null
- var/scribble=""
- var/scribble_page = null
- drop_sound = 'sound/items/drop/wrapper.ogg'
- pickup_sound = 'sound/items/pickup/wrapper.ogg'
-
-obj/item/weapon/newspaper/attack_self(mob/user)
- if(ishuman(user))
- var/mob/living/carbon/human/human_user = user
- var/dat
- pages = 0
- switch(screen)
- if(0) //Cover
- dat+="
The Griffon
"
- dat+="[using_map.company_name]-standard newspaper, for use on [using_map.company_name]© Space Facilities
"
- if(isemptylist(news_content))
- if(important_message)
- dat+="Contents:
**Important Security Announcement** \[page [pages+2]\]
"
- else
- dat+="Other than the title, the rest of the newspaper is unprinted..."
- else
- dat+="Contents:
"
- for(var/datum/feed_channel/NP in news_content)
- pages++
- if(important_message)
- dat+="**Important Security Announcement** \[page [pages+2]\]
"
- var/temp_page=0
- for(var/datum/feed_channel/NP in news_content)
- temp_page++
- dat+="[NP.channel_name] \[page [temp_page+1]\]
"
- dat+="
"
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= "
"
- if(1) // X channel pages inbetween.
- for(var/datum/feed_channel/NP in news_content)
- pages++ //Let's get it right again.
- var/datum/feed_channel/C = news_content[curr_page]
- dat+="[C.channel_name] \[created by: [C.author]\]
"
- if(C.censored)
- dat+="This channel was deemed dangerous to the general welfare of the station and therefore marked with a D-Notice. Its contents were not transferred to the newspaper at the time of printing."
- else
- if(isemptylist(C.messages))
- dat+="No Feed stories stem from this channel..."
- else
- dat+=""
- var/i = 0
- for(var/datum/feed_message/MESSAGE in C.messages)
- i++
- dat+="-[MESSAGE.body]
"
- if(MESSAGE.img)
- user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+="
"
- dat+="\[[MESSAGE.message_type] by [MESSAGE.author]\]
"
- dat+="
"
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= "
"
- if(2) //Last page
- for(var/datum/feed_channel/NP in news_content)
- pages++
- if(important_message!=null)
- dat+="Wanted Issue:
"
- dat+="Criminal name: [important_message.author]
"
- dat+="Description: [important_message.body]
"
- dat+="Photo:: "
- if(important_message.img)
- user << browse_rsc(important_message.img, "tmp_photow.png")
- dat+="
"
- else
- dat+="None"
- else
- dat+="Apart from some uninteresting Classified ads, there's nothing on this page..."
- if(scribble_page==curr_page)
- dat+="
There is a small scribble near the end of this page... It reads: \"[scribble]\""
- dat+= "
"
- else
- dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
-
- dat+="
[curr_page+1]
"
- human_user << browse(dat, "window=newspaper_main;size=300x400")
- onclose(human_user, "newspaper_main")
- else
- to_chat(user, "The paper is full of intelligible symbols!")
-
-obj/item/weapon/newspaper/Topic(href, href_list)
- var/mob/living/U = usr
- ..()
- if((src in U.contents) || (istype(loc, /turf) && in_range(src, U)))
- U.set_machine(src)
- if(href_list["next_page"])
- if(curr_page == pages+1)
- return //Don't need that at all, but anyway.
- if(curr_page == pages) //We're at the middle, get to the end
- screen = 2
- else
- if(curr_page == 0) //We're at the start, get to the middle
- screen = 1
- curr_page++
- playsound(src, "pageturn", 50, 1)
-
- else if(href_list["prev_page"])
- if(curr_page == 0)
- return
- if(curr_page == 1)
- screen = 0
-
- else
- if(curr_page == pages+1) //we're at the end, let's go back to the middle.
- screen = 1
- curr_page--
- playsound(src, "pageturn", 50, 1)
-
- if(istype(src.loc, /mob))
- attack_self(src.loc)
-
-obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user)
- if(istype(W, /obj/item/weapon/pen))
- if(scribble_page == curr_page)
- to_chat(user, "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?")
- else
- var/s = sanitize(input(user, "Write something", "Newspaper", ""))
- s = sanitize(s)
- if(!s)
- return
- if(!in_range(src, usr) && src.loc != usr)
- return
- scribble_page = curr_page
- scribble = s
- attack_self(user)
- return
-
////////////////////////////////////helper procs
/obj/machinery/newscaster/proc/tgui_user_name(mob/user)
if(ishuman(user))
diff --git a/code/game/machinery/transportpod.dm b/code/game/machinery/transportpod.dm
index 0b499096fea..4a43cb18904 100644
--- a/code/game/machinery/transportpod.dm
+++ b/code/game/machinery/transportpod.dm
@@ -32,7 +32,7 @@
sleep(2)
go_out()
sleep(2)
- del(src)
+ qdel(src)
/obj/machinery/transportpod/relaymove(mob/user as mob)
if(user.stat)
diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm
index 4052afe8e6a..fecb361f1a2 100644
--- a/code/game/mecha/combat/gorilla.dm
+++ b/code/game/mecha/combat/gorilla.dm
@@ -31,7 +31,7 @@
thrusters_possible = 1
/obj/mecha/combat/gorilla/Initialize()
- ..()
+ . = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) // This thing basically cannot function without an external power supply.
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/cannon(src)
diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm
index 3ae3e41e131..a1ea2ab4519 100644
--- a/code/game/mecha/combat/phazon.dm
+++ b/code/game/mecha/combat/phazon.dm
@@ -40,7 +40,7 @@
switch_dmg_type_possible = TRUE
/obj/mecha/combat/phazon/equipped/Initialize()
- ..()
+ . = ..()
starting_equipment = list(
/obj/item/mecha_parts/mecha_equipment/tool/rcd,
/obj/item/mecha_parts/mecha_equipment/gravcatapult
diff --git a/code/game/mecha/components/_component.dm b/code/game/mecha/components/_component.dm
index aadf390c615..3d770e0dce0 100644
--- a/code/game/mecha/components/_component.dm
+++ b/code/game/mecha/components/_component.dm
@@ -43,7 +43,7 @@
. += "It is completely destroyed."
/obj/item/mecha_parts/component/Initialize()
- ..()
+ . = ..()
integrity = max_integrity
if(start_damaged)
diff --git a/code/game/mecha/equipment/tools/inflatables.dm b/code/game/mecha/equipment/tools/inflatables.dm
index b18ba2eae11..ff766577ded 100644
--- a/code/game/mecha/equipment/tools/inflatables.dm
+++ b/code/game/mecha/equipment/tools/inflatables.dm
@@ -14,7 +14,7 @@
var/obj/item/weapon/inflatable_dispenser/my_deployer = null
/obj/item/mecha_parts/mecha_equipment/tool/powertool/inflatables/Initialize()
- ..()
+ . = ..()
my_deployer = my_tool
/obj/item/mecha_parts/mecha_equipment/tool/powertool/inflatables/Topic(href, href_list)
diff --git a/code/game/mecha/equipment/tools/syringe_gun.dm b/code/game/mecha/equipment/tools/syringe_gun.dm
index 1658a01df6d..fd73d74fc2e 100644
--- a/code/game/mecha/equipment/tools/syringe_gun.dm
+++ b/code/game/mecha/equipment/tools/syringe_gun.dm
@@ -318,7 +318,7 @@
equip_type = EQUIP_HULL
/obj/item/mecha_parts/mecha_equipment/crisis_drone/Initialize()
- ..()
+ . = ..()
drone_overlay = new(src.icon, icon_state = droid_state)
/obj/item/mecha_parts/mecha_equipment/crisis_drone/Destroy()
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index bd2cf8460f0..60bb48c5f6b 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -198,7 +198,7 @@
var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times.
/obj/mecha/Initialize()
- ..()
+ . = ..()
for(var/path in starting_components)
var/obj/item/mecha_parts/component/C = new path(src)
diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm
index 4db6332cb10..316d39bacee 100644
--- a/code/game/mecha/medical/odysseus.dm
+++ b/code/game/mecha/medical/odysseus.dm
@@ -127,7 +127,7 @@
C.images += holder
*/
/obj/mecha/medical/odysseus/loaded/Initialize()
- ..()
+ . = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/sleeper
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tool/sleeper
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index def044c9bbc..4e92f757d27 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -70,7 +70,7 @@
max_special_equip = 1
/obj/mecha/working/ripley/deathripley/Initialize()
- ..()
+ . = ..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/safety
ME.attach(src)
return
@@ -80,7 +80,7 @@
name = "APLU \"Miner\""
/obj/mecha/working/ripley/mining/Initialize()
- ..()
+ . = ..()
//Attach drill
if(prob(25)) //Possible diamond drill... Feeling lucky?
var/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill/D = new /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 533414d50cc..088ed16440d 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -40,10 +40,7 @@
return TRUE
/atom/movable/proc/has_buckled_mobs()
- if(!buckled_mobs)
- return FALSE
- if(buckled_mobs.len)
- return TRUE
+ return LAZYLEN(buckled_mobs)
/atom/movable/Destroy()
unbuckle_all_mobs()
diff --git a/code/game/objects/effects/chem/coating.dm b/code/game/objects/effects/chem/coating.dm
index a777bbe5e05..2e9ad26049c 100644
--- a/code/game/objects/effects/chem/coating.dm
+++ b/code/game/objects/effects/chem/coating.dm
@@ -11,7 +11,7 @@
create_reagents(100)
/obj/effect/decal/cleanable/chemcoating/Initialize()
- ..()
+ . = ..()
var/turf/T = get_turf(src)
if(T)
for(var/obj/O in get_turf(src))
diff --git a/code/game/objects/effects/decals/warning_stripes.dm b/code/game/objects/effects/decals/warning_stripes.dm
index db7c4bf74f1..0e3d12897d8 100644
--- a/code/game/objects/effects/decals/warning_stripes.dm
+++ b/code/game/objects/effects/decals/warning_stripes.dm
@@ -1,10 +1,10 @@
/obj/effect/decal/warning_stripes
icon = 'icons/effects/warning_stripes.dmi'
-/obj/effect/decal/warning_stripes/New()
+/obj/effect/decal/warning_stripes/Initialize()
. = ..()
var/turf/T=get_turf(src)
var/image/I=image(icon, icon_state = icon_state, dir = dir)
I.color=color
T.overlays += I
- qdel(src)
+ return INITIALIZE_HINT_QDEL
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index c5e1f26c615..c49a4e06665 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -10,32 +10,37 @@
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
var/panel_open = 0
var/datum/wires/mines/wires = null
- register_as_dangerous_object = TRUE
-
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
var/obj/item/trap = null
-/obj/effect/mine/New()
+/obj/effect/mine/Initialize()
icon_state = "uglyminearmed"
wires = new(src)
-
+ . = ..()
if(ispath(trap))
trap = new trap(src)
-
-/obj/effect/mine/Initialize()
- ..()
-
+ register_dangerous_to_step()
if(camo_net)
alpha = 50
/obj/effect/mine/Destroy()
+ unregister_dangerous_to_step()
if(trap)
QDEL_NULL(trap)
qdel_null(wires)
return ..()
+/obj/effect/mine/Moved(atom/oldloc)
+ . = ..()
+ if(.)
+ var/turf/old_turf = get_turf(oldloc)
+ var/turf/new_turf = get_turf(src)
+ if(old_turf != new_turf)
+ old_turf.unregister_dangerous_object(src)
+ new_turf.register_dangerous_object(src)
+
/obj/effect/mine/proc/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
diff --git a/code/game/objects/effects/prop/columnblast.dm b/code/game/objects/effects/prop/columnblast.dm
index fc604235c82..ce0e4b2aadb 100644
--- a/code/game/objects/effects/prop/columnblast.dm
+++ b/code/game/objects/effects/prop/columnblast.dm
@@ -17,7 +17,7 @@
..()
/obj/effect/temporary_effect/eruption/Initialize()
- ..()
+ . = ..()
flick("[icon_state]_create",src)
/obj/effect/temporary_effect/eruption/Destroy()
diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm
index c848a2f1dfe..eb025f9ba40 100644
--- a/code/game/objects/effects/spawners/bombspawner.dm
+++ b/code/game/objects/effects/spawners/bombspawner.dm
@@ -159,7 +159,6 @@
/obj/effect/spawner/newbomb/Initialize(newloc)
..(newloc)
-
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/phoron/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
@@ -183,19 +182,14 @@
OT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
OT.air_contents.update_values()
-
var/obj/item/device/assembly/S = new assembly_type(V)
-
-
V.attached_device = S
S.holder = V
S.toggle_secure()
V.update_icon()
-
- qdel(src)
-
+ return INITIALIZE_HINT_QDEL
///////////////////////
diff --git a/code/game/objects/items/devices/communicator/communicator.dm b/code/game/objects/items/devices/communicator/communicator.dm
index 46c89b0683b..6adbbf811cd 100644
--- a/code/game/objects/items/devices/communicator/communicator.dm
+++ b/code/game/objects/items/devices/communicator/communicator.dm
@@ -26,7 +26,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
show_messages = 1
origin_tech = list(TECH_ENGINEERING = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2, TECH_DATA = 2)
- matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 10, MAT_COPPER = 10)
var/video_range = 3
var/obj/machinery/camera/communicator/video_source // Their camera
@@ -131,7 +131,7 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
for(var/mob/living/voice/voice in contents)
. += "On the screen, you can see a image feed of [voice]."
-
+
if(voice && voice.key)
switch(voice.stat)
if(CONSCIOUS)
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 2247674f60c..facc87ae64a 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -33,7 +33,7 @@
var/cell_type = /obj/item/weapon/cell/device
/obj/item/device/flash/Initialize()
- ..()
+ . = ..()
power_supply = new cell_type(src)
/obj/item/device/flash/attackby(var/obj/item/W, var/mob/user)
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index e14a4c0edf6..610ebbc26cd 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -9,24 +9,119 @@ var/list/GPS_list = list()
slot_flags = SLOT_BELT
origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_MAGNET = 1)
matter = list(DEFAULT_WALL_MATERIAL = 500)
+
var/gps_tag = "GEN0"
var/emped = FALSE
- var/updating = TRUE // Lets users lock the UI so they don't have to deal with constantly shifting signals
var/tracking = FALSE // Will not show other signals or emit its own signal if false.
var/long_range = FALSE // If true, can see farther, depending on get_map_levels().
var/local_mode = FALSE // If true, only GPS signals of the same Z level are shown.
var/hide_signal = FALSE // If true, signal is not visible to other GPS devices.
var/can_hide_signal = FALSE // If it can toggle the above var.
+ var/mob/holder
+ var/is_in_processing_list = FALSE
+ var/list/tracking_devices
+ var/list/showing_tracked_names
+ var/obj/compass_holder/compass
+
/obj/item/device/gps/Initialize()
. = ..()
+ compass = new(src)
GPS_list += src
name = "global positioning system ([gps_tag])"
+ update_holder()
update_icon()
+/obj/item/device/gps/proc/check_visible_to_holder()
+ . = (holder && (holder.get_active_hand() == src || holder.get_inactive_hand() == src))
+
+/obj/item/device/gps/proc/update_holder()
+
+ if(holder && loc != holder)
+ GLOB.moved_event.unregister(holder, src)
+ GLOB.dir_set_event.unregister(holder, src)
+ holder.client?.screen -= compass
+ holder = null
+
+ if(istype(loc, /mob))
+ holder = loc
+ GLOB.moved_event.register(holder, src, .proc/update_compass)
+ GLOB.dir_set_event.register(holder, src, .proc/update_compass)
+
+ if(holder && tracking)
+ if(!is_in_processing_list)
+ START_PROCESSING(SSobj, src)
+ is_in_processing_list = TRUE
+ if(holder.client)
+ if(check_visible_to_holder())
+ holder.client.screen |= compass
+ else
+ holder.client.screen -= compass
+ else
+ STOP_PROCESSING(SSobj, src)
+ is_in_processing_list = FALSE
+ if(holder?.client)
+ holder.client.screen -= compass
+
+/obj/item/device/gps/pickup()
+ . = ..()
+ update_holder()
+
+/obj/item/device/gps/equipped()
+ . = ..()
+ update_holder()
+
+/obj/item/device/gps/dropped()
+ . = ..()
+ update_holder()
+
+/obj/item/device/gps/process()
+ if(!tracking)
+ is_in_processing_list = FALSE
+ return PROCESS_KILL
+ update_holder()
+ if(holder)
+ update_compass(TRUE)
+
/obj/item/device/gps/Destroy()
+ STOP_PROCESSING(SSobj, src)
+ is_in_processing_list = FALSE
GPS_list -= src
- return ..()
+ . = ..()
+ update_holder()
+ QDEL_NULL(compass)
+
+/obj/item/device/gps/proc/can_track(var/obj/item/device/gps/other, var/reachable_z_levels)
+ if(!other.tracking || other.emped || other.hide_signal)
+ return FALSE
+ var/turf/origin = get_turf(src)
+ var/turf/target = get_turf(other)
+ if(!istype(origin) || !istype(target))
+ return FALSE
+ if(origin.z == target.z)
+ return TRUE
+ if(local_mode)
+ return FALSE
+ reachable_z_levels = reachable_z_levels || using_map.get_map_levels(origin.z, long_range)
+ return (target.z in reachable_z_levels)
+
+/obj/item/device/gps/proc/update_compass(var/update_compass_icon)
+ compass.hide_waypoints(FALSE)
+ for(var/thing in tracking_devices)
+ var/obj/item/device/gps/gps = locate(thing)
+ if(!istype(gps) || QDELETED(gps))
+ LAZYREMOVE(tracking_devices, thing)
+ LAZYREMOVE(showing_tracked_names, thing)
+ continue
+ var/turf/gps_turf = get_turf(gps)
+ var/gps_tag = LAZYACCESS(showing_tracked_names, thing) ? gps.gps_tag : null
+ if(istype(gps_turf))
+ compass.set_waypoint("\ref[gps]", gps_tag, gps_turf.x, gps_turf.y, gps_turf.z, LAZYACCESS(tracking_devices, "\ref[gps]"))
+ else
+ compass.set_waypoint("\ref[gps]", gps_tag, 0, 0, 0, LAZYACCESS(tracking_devices, "\ref[gps]"))
+ if(can_track(gps))
+ compass.show_waypoint("\ref[gps]")
+ compass.rebuild_overlay_lists(update_compass_icon)
/obj/item/device/gps/AltClick(mob/user)
toggletracking(user)
@@ -37,14 +132,25 @@ var/list/GPS_list = list()
if(emped)
to_chat(user, "It's busted!")
return
+
+ toggle_tracking()
if(tracking)
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
- tracking = FALSE
- update_icon()
else
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
- tracking = TRUE
- update_icon()
+
+/obj/item/device/gps/proc/toggle_tracking()
+ tracking = !tracking
+ if(tracking)
+ if(!is_in_processing_list)
+ is_in_processing_list = TRUE
+ START_PROCESSING(SSobj, src)
+ else
+ is_in_processing_list = FALSE
+ STOP_PROCESSING(SSobj, src)
+ update_compass()
+ update_holder()
+ update_icon()
/obj/item/device/gps/emp_act(severity)
if(emped) // Without a fancy callback system, this will have to do.
@@ -67,11 +173,7 @@ var/list/GPS_list = list()
add_overlay("working")
/obj/item/device/gps/attack_self(mob/user)
- tgui_interact(user)
-
-/obj/item/device/gps/examine(mob/user)
- . = ..()
- . += display()
+ display(user)
// Compiles all the data not available directly from the GPS
// Like the positions and directions to all other GPS units
@@ -90,15 +192,8 @@ var/list/GPS_list = list()
dat["z_level_detection"] = using_map.get_map_levels(curr.z, long_range)
for(var/obj/item/device/gps/G in GPS_list - src)
- if(!G.tracking || G.emped || G.hide_signal)
- continue
- var/turf/T = get_turf(G)
- if(!T)
- continue
- if(local_mode && curr.z != T.z)
- continue
- if(!(T.z in dat["z_level_detection"]))
+ if(!can_track(G, dat["z_level_detection"]))
continue
var/gps_data[0]
@@ -108,6 +203,7 @@ var/list/GPS_list = list()
var/area/A = get_area(G)
gps_data["area_name"] = A.get_name()
+ var/turf/T = get_turf(G)
gps_data["z_name"] = using_map.get_zlevel_name(T.z)
gps_data["direction"] = get_adir(curr, T)
gps_data["degrees"] = round(Get_Angle(curr,T))
@@ -122,37 +218,102 @@ var/list/GPS_list = list()
return dat
-/obj/item/device/gps/proc/display()
- if(!tracking)
- . = "The device is off. Alt-click it to turn it on."
- return
+/obj/item/device/gps/proc/display(mob/user)
+
if(emped)
- . = "It's busted!"
+ to_chat(user, "It's busted!")
return
var/list/dat = list()
var/list/gps_data = display_list()
- dat += "Current location: [gps_data["my_area_name"]] ([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])"
- dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. \[Change Tag\] \
- \[Toggle Scan Range\] \
- [can_hide_signal ? "\[Toggle Signal Visibility\]":""]"
-
- if(gps_data["gps_list"].len)
- dat += "Detected signals;"
- for(var/gps in gps_data["gps_list"])
- if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
- dat += " [gps["gps_tag"]]: [gps["area_name"]] - [gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "in \the [gps["z_name"]]"]"
- else
- dat += " [gps["gps_tag"]]: [gps["area_name"]], ([gps["x"]], [gps["y"]]) - [gps["local"] ? "[gps["direction"]] Dist: [gps["distX"] ? "[abs(round(gps["distX"], 1))]m [(gps["distX"] > 0) ? "E" : "W"], " : ""][gps["distY"] ? "[abs(round(gps["distY"], 1))]m [(gps["distY"] > 0) ? "N" : "S"]" : ""]" : "in \the [gps["z_name"]]"]"
+ dat += ""
+ if(!tracking)
+ dat += " | \[Switch On]\]
"
else
- dat += "No other signals detected."
+ dat += " | \[Switch Off]\]
"
+ dat += "| Current location | [gps_data["my_area_name"]] | ([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]]) |
"
+ dat += "| [hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. | "
+ dat += "\[Change Tag\]\[Toggle Scan Range\][can_hide_signal ? "\[Toggle Signal Visibility\]":""] |
"
- . = dat
+ if(gps_data["gps_list"].len)
+ dat += "| Detected signals |
"
+ for(var/gps in gps_data["gps_list"])
+ dat += ""
+ var/gps_ref = "\ref[gps["ref"]]"
+ dat += "| [gps["gps_tag"]] | [gps["area_name"]] | "
+
+ if(istype(gps_data["ref"], /obj/item/device/gps/internal/poi))
+ dat += "[gps["local"] ? "[gps["direction"]] Dist: [round(gps["distance"], 10)]m" : "in \the [gps["z_name"]]"] | "
+ else
+ dat += "([gps["x"]], [gps["y"]], [gps["z_name"]]) | "
+
+ if(gps["local"])
+ dat += "[gps["distance"]]m | "
+ dat += "[gps["degrees"]]° ([gps["direction"]]) | "
+ else
+ dat += "Non-local signal. | "
+
+ if(LAZYACCESS(tracking_devices, gps_ref))
+ dat += "\[Stop Tracking\] \[Colour [color_square(hex = LAZYACCESS(tracking_devices, gps_ref))]\] Show/Hide Label | "
+ else
+ dat += "\[Start Tracking\] | "
+ dat += "
"
+ else
+ dat += "| No other signals detected. |
"
+ dat += "
"
+
+ var/datum/browser/popup = new(user, "gps_\ref[src]", "Global Positioning System", 700, 1000)
+ popup.set_content(dat.Join(null))
+ popup.open()
/obj/item/device/gps/Topic(var/href, var/list/href_list)
if(..())
- return 1
+ return TRUE
+
+ if(href_list["toggle_power"])
+ toggle_tracking()
+ . = TRUE
+
+ if(href_list["track_label"])
+ var/gps_ref = href_list["track_label"]
+ var/obj/item/device/gps/gps = locate(gps_ref)
+ if(istype(gps) && !QDELETED(gps) && !LAZYACCESS(showing_tracked_names, gps_ref))
+ LAZYSET(showing_tracked_names, gps_ref, TRUE)
+ else
+ LAZYREMOVE(showing_tracked_names, gps_ref)
+ to_chat(usr, SPAN_NOTICE("\The [src] is [LAZYACCESS(showing_tracked_names, gps_ref) ? "now showing" : "no longer showing"] labels for [gps.gps_tag]."))
+
+ if(href_list["stop_track"])
+ var/gps_ref = href_list["stop_track"]
+ var/obj/item/device/gps/gps = locate(gps_ref)
+ compass.clear_waypoint(gps_ref)
+ LAZYREMOVE(tracking_devices, gps_ref)
+ LAZYREMOVE(showing_tracked_names, gps_ref)
+ if(istype(gps) && !QDELETED(gps))
+ to_chat(usr, SPAN_NOTICE("\The [src] is no longer tracking [gps.gps_tag]."))
+ update_compass()
+ . = TRUE
+
+ if(href_list["start_track"])
+ var/gps_ref = href_list["start_track"]
+ var/obj/item/device/gps/gps = locate(gps_ref)
+ if(istype(gps) && !QDELETED(gps))
+ LAZYSET(tracking_devices, gps_ref, "#00ffff")
+ LAZYSET(showing_tracked_names, gps_ref, TRUE)
+ to_chat(usr, SPAN_NOTICE("\The [src] is now tracking [gps.gps_tag]."))
+ update_compass()
+ . = TRUE
+
+ if(href_list["track_color"])
+ var/obj/item/device/gps/gps = locate(href_list["track_color"])
+ if(istype(gps) && !QDELETED(gps))
+ var/new_colour = input("Enter a new tracking color.", "GPS Waypoint Color") as color|null
+ if(new_colour && istype(gps) && !QDELETED(gps) && holder == usr && !usr.incapacitated())
+ to_chat(usr, SPAN_NOTICE("You adjust the colour \the [src] is using to highlight [gps.gps_tag]."))
+ LAZYSET(tracking_devices, href_list["track_color"], new_colour)
+ update_compass()
+ . = TRUE
if(href_list["tag"])
var/a = input("Please enter desired tag.", name, gps_tag) as text
@@ -161,95 +322,22 @@ var/list/GPS_list = list()
gps_tag = a
name = "global positioning system ([gps_tag])"
to_chat(usr, "You set your GPS's tag to '[gps_tag]'.")
+ . = TRUE
if(href_list["range"])
local_mode = !local_mode
to_chat(usr, "You set the signal receiver to [local_mode ? "'NARROW'" : "'BROAD'"].")
+ . = TRUE
if(href_list["hide"])
if(!can_hide_signal)
return
hide_signal = !hide_signal
to_chat(usr, "You set the device to [hide_signal ? "not " : ""]broadcast a signal while scanning for other signals.")
+ . = TRUE
-/obj/item/device/gps/tgui_interact(mob/user, datum/tgui/ui)
- if(emped)
- to_chat(user, "[src] fizzles weakly.")
- return
- ui = SStgui.try_update_ui(user, src, ui)
- if(!ui)
- ui = new(user, src, "Gps", name)
- ui.open()
- ui.set_autoupdate(updating)
-
-/obj/item/device/gps/tgui_data(mob/user)
- var/list/data = list()
- data["power"] = tracking
- data["tag"] = gps_tag
- data["updating"] = updating
- data["globalmode"] = !local_mode
- if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
- return data
-
- var/turf/curr = get_turf(src)
- data["currentArea"] = "[get_area_name(curr, TRUE)]"
- data["currentCoords"] = list(curr.x, curr.y, curr.z)
- data["currentCoordsText"] = "[curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)]"
-
- data["zLevelDetection"] = using_map.get_map_levels(curr.z, long_range)
-
- var/list/signals = list()
- data["signals"] = list()
-
- for(var/obj/item/device/gps/G in GPS_list - src)
- if(!G.tracking || G.emped || G.hide_signal)
- continue
-
- var/turf/T = get_turf(G)
- if(!T)
- continue
- if(local_mode && curr.z != T.z)
- continue
- if(!(T.z in data["zLevelDetection"]))
- continue
-
- var/list/signal = list()
- signal["entrytag"] = G.gps_tag //Name or 'tag' of the GPS
- signal["coords"] = list(T.x, T.y, T.z)
- signal["coordsText"] = "[T.x], [T.y], [using_map.get_zlevel_name(T.z)]"
- if(T.z == curr.z) //Distance/Direction calculations for same z-level only
- signal["dist"] = max(get_dist(curr, T), 0) //Distance between the src and remote GPS turfs
- signal["degrees"] = round(Get_Angle(curr, T)) //0-360 degree directional bearing, for more precision.
- signals += list(signal) //Add this signal to the list of signals
- data["signals"] = signals
- return data
-
-/obj/item/device/gps/tgui_act(action, params)
- if(..())
- return TRUE
-
- switch(action)
- if("rename")
- var/a = stripped_input(usr, "Please enter desired tag.", name, gps_tag, 20)
-
- if(!a)
- return
-
- gps_tag = a
- name = "global positioning system ([gps_tag])"
- . = TRUE
-
- if("power")
- toggletracking(usr)
- . = TRUE
-
- if("updating")
- updating = !updating
- . = TRUE
-
- if("globalmode")
- local_mode = !local_mode
- . = TRUE
+ if(. && loc == usr)
+ display(usr)
/obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these.
tracking = TRUE
@@ -373,26 +461,43 @@ var/list/GPS_list = list()
can_hide_signal = TRUE
/obj/item/device/gps/syndie/display(mob/user)
- if(!tracking)
- . = "The device is off. Alt-click it to turn it on."
- return
+
if(emped)
- . = "It's busted!"
+ to_chat(user, "It's busted!")
return
var/list/dat = list()
var/list/gps_data = display_list()
- dat += "Current location: [gps_data["my_area_name"]] ([gps_data["curr_x"]], [gps_data["curr_y"]], [gps_data["curr_z_name"]])"
- dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. \[Change Tag\] \
- \[Toggle Scan Range\] \
- [can_hide_signal ? "\[Toggle Signal Visibility\]":""]"
-
- if(gps_data["gps_list"].len)
- dat += "Detected signals;"
- for(var/gps in gps_data["gps_list"])
- dat += " [gps["gps_tag"]]: [gps["area_name"]] ([gps["x"]], [gps["y"]], [gps["z_name"]]) [gps["local"] ? "Dist: [gps["distance"]]m Dir: [gps["degrees"]]° ([gps["direction"]])" :""]"
+ dat += ""
+
+ var/datum/browser/popup = new(user, "gps_\ref[src]", "Global Positioning System", 700, 1000)
+ popup.set_content(dat.Join(null))
+ popup.open()
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
index 810147dbc44..7ccad467f66 100644
--- a/code/game/objects/items/devices/laserpointer.dm
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -6,7 +6,7 @@
item_state = "pen"
var/pointer_icon_state
slot_flags = SLOT_BELT
- matter = list("glass" = 500,"metal" = 500)
+ matter = list("glass" = 500,"metal" = 500, MAT_COPPER = 10)
w_class = 2 //Increased to 2, because diodes are w_class 2. Conservation of matter.
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
var/turf/pointer_loc
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 837c6616f78..8ac7a071996 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -17,7 +17,7 @@
drop_sound = 'sound/items/drop/multitool.ogg'
pickup_sound = 'sound/items/pickup/multitool.ogg'
- matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
+ matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20, MAT_COPPER = 10)
var/mode_index = 1
var/toolmode = MULTITOOL_MODE_STANDARD
diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm
index cc555f80730..55b79eaef3f 100644
--- a/code/game/objects/items/devices/radio/electropack.dm
+++ b/code/game/objects/items/devices/radio/electropack.dm
@@ -11,7 +11,7 @@
slot_flags = SLOT_BACK
w_class = ITEMSIZE_HUGE
- matter = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 2500)
+ matter = list(DEFAULT_WALL_MATERIAL = 10000,"glass" = 2500, MAT_COPPER = 1550)
var/code = 2
diff --git a/code/game/objects/items/devices/radio/headset_vr.dm b/code/game/objects/items/devices/radio/headset_vr.dm
index 9204c81dd17..2682d9db97c 100644
--- a/code/game/objects/items/devices/radio/headset_vr.dm
+++ b/code/game/objects/items/devices/radio/headset_vr.dm
@@ -84,7 +84,6 @@
desc = "A headset used by pilots, has access to the explorer channel."
icon_state = "pilot_headset"
adhoc_fallback = TRUE
- ks2type = /obj/item/device/encryptionkey/pilot
/obj/item/device/radio/headset/pilot/alt
name = "pilot's bowman headset"
@@ -120,7 +119,7 @@
desc = "A headset used by volunteers to expedition teams, has access to the exploration channel."
icon_state = "pilot_headset"
adhoc_fallback = TRUE
- ks2type = /obj/item/device/encryptionkey/pilot
+ ks2type = /obj/item/device/encryptionkey/explorer
/obj/item/device/radio/headset/talon
name = "talon headset"
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 366853a7bf3..88e957f76ed 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -61,7 +61,7 @@ var/global/list/default_medbay_channels = list(
var/bs_tx_preload_id
var/bs_rx_preload_id
- matter = list("glass" = 25,DEFAULT_WALL_MATERIAL = 75)
+ matter = list("glass" = 25, DEFAULT_WALL_MATERIAL = 75, MAT_COPPER = 15)
var/const/FREQ_LISTENING = 1
var/list/internal_channels
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index c949884c6f0..291202f41f2 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -21,7 +21,7 @@ HALOGEN COUNTER - Radcount on mobs
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
- matter = list(DEFAULT_WALL_MATERIAL = 200)
+ matter = list(DEFAULT_WALL_MATERIAL = 200, MAT_COPPER = 25)
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
var/mode = 1;
var/advscan = 0
diff --git a/code/game/objects/items/stacks/fifty_spawner.dm b/code/game/objects/items/stacks/fifty_spawner.dm
index 81dfce96913..e3ba667703a 100644
--- a/code/game/objects/items/stacks/fifty_spawner.dm
+++ b/code/game/objects/items/stacks/fifty_spawner.dm
@@ -7,15 +7,12 @@
var/obj/item/stack/type_to_spawn = null
/obj/fiftyspawner/Initialize()
- ..() //We're not returning . because we're going to ask to be deleted.
-
+ ..()
var/turf/T = get_turf(src)
- var/obj/item/stack/M = new type_to_spawn(T)
+ var/obj/structure/closet/C = locate() in T
+ var/obj/item/stack/M = new type_to_spawn(C || T)
M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty
M.update_icon() // Some stacks have different sprites depending on how full they are.
- var/obj/structure/closet/C = locate() in T
- if(C)
- C.contents += M
return INITIALIZE_HINT_QDEL //Bye!
/obj/fiftyspawner/rods
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index 6ffa7100ca8..9844ae1cba9 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -14,6 +14,8 @@
max_amount = 60
attack_verb = list("hit", "bludgeoned", "whacked")
+ color = "#666666"
+
/obj/item/stack/rods/cyborg
name = "metal rod synthesizer"
desc = "A device that makes metal rods."
@@ -24,8 +26,8 @@
stacktype = /obj/item/stack/rods
no_variants = TRUE
-/obj/item/stack/rods/New()
- ..()
+/obj/item/stack/rods/Initialize()
+ . = ..()
recipes = rods_recipes
update_icon()
diff --git a/code/game/objects/items/stacks/sandbags.dm b/code/game/objects/items/stacks/sandbags.dm
index c4e755c4852..6eff93bfc5f 100644
--- a/code/game/objects/items/stacks/sandbags.dm
+++ b/code/game/objects/items/stacks/sandbags.dm
@@ -32,19 +32,15 @@
bag_material = MAT_SYNCLOTH
-/obj/item/stack/sandbags/New(var/newloc, var/amt, var/bag_mat)
- ..()
+/obj/item/stack/sandbags/Initialize(var/ml, var/amt, var/bag_mat)
+ . = ..(ml, amt)
recipes = sandbag_recipes
update_icon()
-
if(bag_mat)
bag_material = bag_mat
-
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
- qdel(src)
- return
-
+ return INITIALIZE_HINT_QDEL
color = M.icon_colour
/obj/item/stack/sandbags/update_icon()
@@ -136,17 +132,13 @@ var/global/list/datum/stack_recipe/sandbag_recipes = list( \
var/bag_material = "cloth"
-/obj/item/stack/emptysandbag/New(var/newloc, var/amt, var/bag_mat)
- ..(newloc, amt)
-
+/obj/item/stack/emptysandbag/Initialize(var/ml, var/amt, var/bag_mat)
+ . = ..(ml, amt)
if(bag_mat)
bag_material = bag_mat
-
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
- qdel(src)
- return
-
+ return INITIALIZE_HINT_QDEL
color = M.icon_colour
/obj/item/stack/emptysandbag/attack_self(var/mob/user)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index d42d6c0e563..f4b52f07aaf 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -29,14 +29,13 @@
var/pass_color = FALSE // Will the item pass its own color var to the created item? Dyed cloth, wood, etc.
var/strict_color_stacking = FALSE // Will the stack merge with other stacks that are different colors? (Dyed cloth, wood, etc)
-/obj/item/stack/New(var/loc, var/amount=null)
- ..()
- if (!stacktype)
+/obj/item/stack/Initialize(var/ml, var/amount)
+ . = ..()
+ if(!stacktype)
stacktype = type
- if (amount)
+ if(amount)
src.amount = amount
update_icon()
- return
/obj/item/stack/Destroy()
if(uses_charge)
@@ -170,8 +169,37 @@
var/atom/O
if(recipe.use_material)
O = new recipe.result_type(user.loc, recipe.use_material)
+
+ if(istype(O, /obj))
+ var/obj/Ob = O
+
+ if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
+ Ob.matter.Cut()
+
+ else
+ Ob.matter = list()
+
+ var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
+
+ Ob.matter[recipe.use_material] = mattermult / produced * required
+
else
O = new recipe.result_type(user.loc)
+
+ if(recipe.matter_material)
+ if(istype(O, /obj))
+ var/obj/Ob = O
+
+ if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
+ Ob.matter.Cut()
+
+ else
+ Ob.matter = list()
+
+ var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
+
+ Ob.matter[recipe.use_material] = mattermult / produced * required
+
O.set_dir(user.dir)
O.add_fingerprint(user)
@@ -379,8 +407,9 @@
var/on_floor = 0
var/use_material
var/pass_color
+ var/matter_material // Material type used for recycling. Default, uses use_material. For non-material-based objects however, matter_material is needed.
-/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color)
+/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color, recycle_material = null)
src.title = title
src.result_type = result_type
src.req_amount = req_amount
@@ -392,6 +421,12 @@
src.use_material = supplied_material
src.pass_color = pass_stack_color
+ if(!recycle_material && src.use_material)
+ src.matter_material = src.use_material
+
+ else if(recycle_material)
+ src.matter_material = recycle_material
+
/*
* Recipe list datum
*/
diff --git a/code/game/objects/items/stacks/tickets.dm b/code/game/objects/items/stacks/tickets.dm
index 1d9cbf047ee..6681934f7ce 100644
--- a/code/game/objects/items/stacks/tickets.dm
+++ b/code/game/objects/items/stacks/tickets.dm
@@ -7,7 +7,7 @@
w_class = ITEMSIZE_TINY
max_amount = 30
-/obj/item/stack/arcadeticket/New(loc, amount = null)
+/obj/item/stack/arcadeticket/Initialize()
. = ..()
update_icon()
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 5e5ac1a746d..aefe9a0cd0d 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -20,8 +20,8 @@
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
-/obj/item/stack/tile/New()
- ..()
+/obj/item/stack/tile/Initialize()
+ . = ..()
randpixel_xy()
/*
diff --git a/code/game/objects/items/weapons/circuitboards/circuitboard.dm b/code/game/objects/items/weapons/circuitboards/circuitboard.dm
index 8b913eaf45d..c8a3a672a7f 100644
--- a/code/game/objects/items/weapons/circuitboards/circuitboard.dm
+++ b/code/game/objects/items/weapons/circuitboards/circuitboard.dm
@@ -23,6 +23,8 @@
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
+
//Called when the circuitboard is used to contruct a new machine.
/obj/item/weapon/circuitboard/proc/construct(var/obj/machinery/M)
if(istype(M, build_path))
diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm
index e9c0ee728a5..1b95cc131ed 100644
--- a/code/game/objects/items/weapons/circuitboards/frame.dm
+++ b/code/game/objects/items/weapons/circuitboards/frame.dm
@@ -10,37 +10,37 @@
name = T_BOARD("guestpass console")
build_path = /obj/machinery/computer/guestpass
board_type = new /datum/frame/frame_types/guest_pass_console
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/status_display
name = T_BOARD("status display")
build_path = /obj/machinery/status_display
board_type = new /datum/frame/frame_types/display
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/ai_status_display
name = T_BOARD("ai status display")
build_path = /obj/machinery/ai_status_display
board_type = new /datum/frame/frame_types/display
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/newscaster
name = T_BOARD("newscaster")
build_path = /obj/machinery/newscaster
board_type = new /datum/frame/frame_types/newscaster
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/atm
name = T_BOARD("atm")
build_path = /obj/machinery/atm
board_type = new /datum/frame/frame_types/atm
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/request
name = T_BOARD("request console")
build_path = /obj/machinery/requests_console
board_type = new /datum/frame/frame_types/supply_request_console
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
//Alarm
@@ -48,25 +48,25 @@
name = T_BOARD("fire alarm")
build_path = /obj/machinery/firealarm
board_type = new /datum/frame/frame_types/fire_alarm
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/airalarm
name = T_BOARD("air alarm")
build_path = /obj/machinery/alarm
board_type = new /datum/frame/frame_types/air_alarm
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/intercom
name = T_BOARD("intercom")
build_path = /obj/item/device/radio/intercom
board_type = new /datum/frame/frame_types/intercom
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/keycard_auth
name = T_BOARD("keycard authenticator")
build_path = /obj/machinery/keycard_auth
board_type = new /datum/frame/frame_types/keycard_authenticator
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
//Computer
@@ -74,7 +74,7 @@
name = T_BOARD("holopad")
build_path = /obj/machinery/hologram/holopad
board_type = new /datum/frame/frame_types/holopad
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/scanner_console
name = T_BOARD("body scanner console")
@@ -94,7 +94,7 @@
name = T_BOARD("photocopier")
build_path = /obj/machinery/photocopier
board_type = new /datum/frame/frame_types/photocopier
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/motor = 1,
@@ -105,7 +105,7 @@
name = T_BOARD("fax")
build_path = /obj/machinery/photocopier/faxmachine
board_type = new /datum/frame/frame_types/fax
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/motor = 1,
@@ -116,6 +116,7 @@
name = T_BOARD("conveyor")
build_path = /obj/machinery/conveyor
board_type = new /datum/frame/frame_types/conveyor
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/gear = 2,
/obj/item/weapon/stock_parts/motor = 2,
@@ -125,6 +126,7 @@
name = T_BOARD("recharger")
build_path = /obj/machinery/recharger
board_type = new /datum/frame/frame_types/recharger
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/stack/cable_coil = 5)
@@ -138,6 +140,7 @@
name = T_BOARD("heavy-duty cell charger")
build_path = /obj/machinery/cell_charger
board_type = new /datum/frame/frame_types/cell_charger
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/stack/cable_coil = 5)
@@ -146,7 +149,7 @@
name = T_BOARD("washing machine")
build_path = /obj/machinery/washing_machine
board_type = new /datum/frame/frame_types/washing_machine
- matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/stock_parts/gear = 2)
@@ -155,6 +158,7 @@
name = T_BOARD("reagent grinder")
build_path = /obj/machinery/reagentgrinder
board_type = new /datum/frame/frame_types/grinder
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/stock_parts/gear = 1,
@@ -163,6 +167,7 @@
/obj/item/weapon/circuitboard/distiller
build_path = /obj/machinery/portable_atmospherics/powered/reagent_distillery
board_type = new /datum/frame/frame_types/reagent_distillery
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/weapon/stock_parts/micro_laser = 1,
@@ -173,6 +178,7 @@
name = T_BOARD("teleporter hub")
build_path = /obj/machinery/teleport/hub
board_type = "teleporter_hub"
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
// origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 4)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 4,
@@ -183,6 +189,7 @@
name = T_BOARD("teleporter station")
build_path = /obj/machinery/teleport/station
board_type = "teleporter_station"
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
// origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 3)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
@@ -194,6 +201,7 @@
build_path = /obj/machinery/bodyscanner
board_type = new /datum/frame/frame_types/medical_pod
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 3,
/obj/item/stack/material/glass/reinforced = 2)
@@ -202,6 +210,7 @@
name = T_BOARD("sleeper")
build_path = /obj/machinery/sleeper
board_type = new /datum/frame/frame_types/medical_pod
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
req_components = list(
/obj/item/weapon/stock_parts/manipulator = 1,
@@ -214,6 +223,7 @@
name = T_BOARD("VR sleeper")
build_path = /obj/machinery/vr_sleeper
board_type = new /datum/frame/frame_types/medical_pod
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 1,
@@ -223,6 +233,7 @@
name = T_BOARD("dna analyzer")
build_path = /obj/machinery/dnaforensics
board_type = new /datum/frame/frame_types/dna_analyzer
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2, TECH_DATA = 2)
req_components = list(
/obj/item/weapon/stock_parts/scanning_module = 2,
@@ -233,6 +244,7 @@
name = T_BOARD("mass driver")
build_path = /obj/machinery/mass_driver
board_type = new /datum/frame/frame_types/mass_driver
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_GOLD = 100)
req_components = list(
/obj/item/weapon/stock_parts/gear = 2,
/obj/item/weapon/stock_parts/motor = 2,
diff --git a/code/game/objects/items/weapons/circuitboards/mecha.dm b/code/game/objects/items/weapons/circuitboards/mecha.dm
index 777146f385d..132cf65de6b 100644
--- a/code/game/objects/items/weapons/circuitboards/mecha.dm
+++ b/code/game/objects/items/weapons/circuitboards/mecha.dm
@@ -8,6 +8,7 @@
icon = 'icons/obj/module.dmi'
icon_state = "std_mod"
board_type = "other"
+ matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50, MAT_COPPER = 100)
/obj/item/weapon/circuitboard/mecha/ripley
origin_tech = list(TECH_DATA = 3)
diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm
index c4040890283..9162be15eb5 100644
--- a/code/game/objects/items/weapons/implants/implantcase.dm
+++ b/code/game/objects/items/weapons/implants/implantcase.dm
@@ -299,3 +299,13 @@
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
..()
return
+
+/obj/item/weapon/implantcase/restrainingbolt
+ name = "glass case - 'Restraining Bolt'"
+ desc = "A case containing a restraining bolt."
+ icon_state = "implantcase-b"
+
+/obj/item/weapon/implantcase/restrainingbolt/New()
+ src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
+ ..()
+ return
diff --git a/code/game/objects/items/weapons/implants/implantdud.dm b/code/game/objects/items/weapons/implants/implantdud.dm
index 110051e58d6..cabf5bc9069 100644
--- a/code/game/objects/items/weapons/implants/implantdud.dm
+++ b/code/game/objects/items/weapons/implants/implantdud.dm
@@ -4,18 +4,6 @@
icon = 'icons/obj/device.dmi'
icon_state = "implant"
initialize_loc = BP_HEAD
- var/roundstart = TRUE
/obj/item/weapon/implant/dud/torso
- name = "unknown implant"
- desc = "A small device with small connector wires."
- icon = 'icons/obj/device.dmi'
- icon_state = "implant"
initialize_loc = BP_TORSO
-
-/obj/item/weapon/implant/dud/old
- name = "old implant"
- desc = "A small device with small connector wires."
- icon = 'icons/obj/device.dmi'
- icon_state = "implant"
- roundstart = FALSE
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index c1b0d5db8dd..adb79364dcd 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -150,3 +150,12 @@
S.remove_from_storage(A)
A.loc.contents.Remove(A)
update()
+
+/obj/item/weapon/implanter/restrainingbolt
+ name = "implanter (bolt)"
+
+/obj/item/weapon/implanter/restrainingbolt/New()
+ src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
+ ..()
+ update()
+ return
diff --git a/code/game/objects/items/weapons/implants/implantrestrainingbolt.dm b/code/game/objects/items/weapons/implants/implantrestrainingbolt.dm
new file mode 100644
index 00000000000..7f4a562297c
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implantrestrainingbolt.dm
@@ -0,0 +1,5 @@
+
+/obj/item/weapon/implant/restrainingbolt
+ name = "\improper restraining bolt"
+ icon = 'icons/obj/device.dmi'
+ icon_state = "implant"
diff --git a/code/game/objects/items/weapons/material/material_armor.dm b/code/game/objects/items/weapons/material/material_armor.dm
index 3d3f7a3c38c..96496d2f8f5 100644
--- a/code/game/objects/items/weapons/material/material_armor.dm
+++ b/code/game/objects/items/weapons/material/material_armor.dm
@@ -31,7 +31,9 @@ Protectiveness | Armor %
var/applies_material_color = TRUE
var/unbreakable = FALSE
var/default_material = null // Set this to something else if you want material attributes on init.
- var/material_armor_modifer = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
+ var/material_armor_modifier = 1 // Adjust if you want seperate types of armor made from the same material to have different protectiveness (e.g. makeshift vs real armor)
+ var/material_slowdown_modifier = 0
+ var/material_slowdown_multiplier = 1
/obj/item/clothing/New(var/newloc, var/material_key)
..(newloc)
@@ -138,7 +140,7 @@ Protectiveness | Armor %
return ..()
var/reflectchance = (40 * material.reflectivity) - round(damage/3)
- reflectchance *= material_armor_modifer
+ reflectchance *= material_armor_modifier
if(!(def_zone in list(BP_TORSO, BP_GROIN)))
reflectchance /= 2
if(P.starting && prob(reflectchance))
@@ -166,17 +168,17 @@ Protectiveness | Armor %
if(material)
var/melee_armor = 0, bullet_armor = 0, laser_armor = 0, energy_armor = 0, bomb_armor = 0
- melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifer)
+ melee_armor = calculate_material_armor(material.protectiveness * material_armor_modifier)
- bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifer) * 0.7)
+ bullet_armor = calculate_material_armor((material.protectiveness * (material.hardness / 100) * material_armor_modifier) * 0.7)
- laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifer) * 0.7)
+ laser_armor = calculate_material_armor((material.protectiveness * (material.reflectivity + 1) * material_armor_modifier) * 0.7)
if(material.opacity != 1)
laser_armor *= max(material.opacity - 0.3, 0) // Glass and such has an opacity of 0.3, but lasers should go through glass armor entirely.
- energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.4)
+ energy_armor = calculate_material_armor((material.protectiveness * material_armor_modifier) * 0.4)
- bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifer) * 0.5)
+ bomb_armor = calculate_material_armor((material.protectiveness * material_armor_modifier) * 0.5)
// Makes sure the numbers stay capped.
for(var/number in list(melee_armor, bullet_armor, laser_armor, energy_armor, bomb_armor))
@@ -190,7 +192,12 @@ Protectiveness | Armor %
if(!isnull(material.conductivity))
siemens_coefficient = between(0, material.conductivity / 10, 10)
- slowdown = between(0, round(material.weight / 10, 0.1), 6)
+
+ var/slowdownModified = between(0, round(material.weight / 10, 0.1), 6)
+
+ var/slowdownUncapped = (material_slowdown_multiplier * slowdownModified) - material_slowdown_modifier
+
+ slowdown = max(slowdownUncapped, 0)
/obj/item/clothing/suit/armor/material
name = "armor"
@@ -201,6 +208,67 @@ Protectiveness | Armor %
desc = "This appears to be two 'sheets' of a material held together by cable. If the sheets are strong, this could be rather protective."
icon_state = "material_armor_makeshift"
+/obj/item/clothing/accessory/material/makeshift/light //Craftable with 4 material sheets, less slowdown, less armour
+ name = "light armor plate"
+ desc = "A thin plate of padded material, designed to fit into a plate carrier. Attaches to a plate carrier."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_state = "armor_light"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO
+ slot = ACCESSORY_SLOT_ARMOR_C
+ material_armor_modifier = 0.8
+ material_slowdown_modifier = 0.5 //Subtracted from total slowdown
+ material_slowdown_multiplier = 0.8 //Multiplied by total slowdown
+
+/obj/item/clothing/accessory/material/makeshift/heavy //Craftable with 8 material sheets, more slowdown, more armour
+ name = "heavy armor plate"
+ desc = "A thick plate of padded material, designed to fit into a plate carrier. Attaches to a plate carrier."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_state = "armor_medium"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO
+ slot = ACCESSORY_SLOT_ARMOR_C
+ material_armor_modifier = 1.2
+ material_slowdown_modifier = 0
+ material_slowdown_multiplier = 1
+
+/obj/item/clothing/accessory/material/custom //Not yet craftable, advanced version made with science!
+ name = "custom armor plate"
+ desc = "A composite plate of custom machined material, designed to fit into a plate carrier. Attaches to a plate carrier."
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_state = "armor_tactical"
+ body_parts_covered = UPPER_TORSO|LOWER_TORSO
+ slot = ACCESSORY_SLOT_ARMOR_C
+ material_armor_modifier = 1.2
+ material_slowdown_modifier = 0.5
+ material_slowdown_multiplier = 0.8
+
+/obj/item/clothing/accessory/material/makeshift/armguards
+ name = "arm guards"
+ desc = "A pair of arm pads reinforced with material. Attaches to a plate carrier."
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon_state = "armguards_material"
+ gender = PLURAL
+ body_parts_covered = ARMS
+ slot = ACCESSORY_SLOT_ARMOR_A
+ material_armor_modifier = 0.8
+ material_slowdown_modifier = 0.8
+ material_slowdown_multiplier = 0.8
+
+/obj/item/clothing/accessory/material/makeshift/legguards
+ name = "leg guards"
+ desc = "A pair of leg guards reinforced with material. Attaches to a plate carrier."
+// accessory_icons = list(slot_tie_str = 'icons/mob/modular_armor.dmi', slot_wear_suit_str = 'icons/mob/modular_armor.dmi')
+ icon = 'icons/obj/clothing/modular_armor.dmi'
+ icon_override = 'icons/mob/modular_armor.dmi'
+ icon_state = "legguards_material"
+ gender = PLURAL
+ body_parts_covered = LEGS
+ slot = ACCESSORY_SLOT_ARMOR_L
+ material_armor_modifier = 0.8
+ material_slowdown_modifier = 0.8
+ material_slowdown_multiplier = 0.8
+
/obj/item/clothing/suit/armor/material/makeshift/durasteel
default_material = "durasteel"
@@ -218,6 +286,9 @@ Protectiveness | Armor %
thrown_force_divisor = 0.2
var/wired = FALSE
+/obj/item/weapon/material/armor_plating/insert
+ unbreakable = FALSE
+
/obj/item/weapon/material/armor_plating/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/S = O
@@ -249,6 +320,54 @@ Protectiveness | Armor %
else
..()
+//Make plating inserts for modular armour.
+/obj/item/weapon/material/armor_plating/insert/attackby(var/obj/O, mob/user)
+
+ . = ..()
+
+ if(istype(O, /obj/item/weapon/weldingtool))
+ var /obj/item/weapon/weldingtool/S = O
+ if(S.remove_fuel(0,user))
+ if(!src || !S.isOn()) return
+ to_chat(user, "You trim down the edges to size.")
+ user.drop_from_inventory(src)
+ var/obj/item/clothing/accessory/material/makeshift/light/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(src)
+ return
+
+ if(istype(O, /obj/item/weapon/material/armor_plating/insert))
+ var/obj/item/weapon/material/armor_plating/insert/second_plate = O
+ if(second_plate.material != src.material)
+ to_chat(user, "Both plates need to be the same type of material.")
+ return
+ to_chat(user, "You bond the two plates together.")
+ user.drop_from_inventory(src)
+ user.drop_from_inventory(second_plate)
+ var/obj/item/clothing/accessory/material/makeshift/heavy/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(second_plate)
+ qdel(src)
+ return
+
+ if(istype(O, /obj/item/weapon/tool/wirecutters))
+ to_chat(user, "You split the plate down the middle, and joint it at the elbow.")
+ user.drop_from_inventory(src)
+ var/obj/item/clothing/accessory/material/makeshift/armguards/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(src)
+ return
+
+ if(istype(O, /obj/item/stack/material))
+ var/obj/item/stack/material/S = O
+ if(S.material == get_material_by_name("leather"))
+ if(S.use(2))
+ to_chat(user, "You curve the plate inwards, and add a strap for adjustment.")
+ user.drop_from_inventory(src)
+ var/obj/item/clothing/accessory/material/makeshift/legguards/new_armor = new(null, src.material.name)
+ user.put_in_hands(new_armor)
+ qdel(src)
+ return
// Used to craft the makeshift helmet
/obj/item/clothing/head/helmet/bucket
diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm
index d8906955a15..bfa8b616805 100644
--- a/code/game/objects/items/weapons/material/misc.dm
+++ b/code/game/objects/items/weapons/material/misc.dm
@@ -77,14 +77,14 @@
//visible_message("[user] has smashed the snowball in their hand!", "You smash the snowball in your hand.")
to_chat(user, "You smash the snowball in your hand.")
var/atom/S = new /obj/item/stack/material/snow(user.loc)
- del(src)
+ qdel(src)
user.put_in_hands(S)
else
//visible_message("[user] starts compacting the snowball.", "You start compacting the snowball.")
to_chat(user, "You start compacting the snowball.")
if(do_after(user, 2 SECONDS))
var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc)
- del(src)
+ qdel(src)
user.put_in_hands(S)
/obj/item/weapon/material/snow/snowball/reinforced
diff --git a/code/game/objects/items/weapons/storage/backpack_vr.dm b/code/game/objects/items/weapons/storage/backpack_vr.dm
index b7485be674a..c201dd5c72e 100644
--- a/code/game/objects/items/weapons/storage/backpack_vr.dm
+++ b/code/game/objects/items/weapons/storage/backpack_vr.dm
@@ -6,7 +6,7 @@
item_state = "saddlebag"
icon_state = "saddlebag"
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
- slowdown = 1 //And are slower, too...Unless you're a macro, that is.
+ slowdown = 1 //And are slower, too...
var/taurtype = /datum/sprite_accessory/tail/taur/horse //Acceptable taur type to be wearing this
var/no_message = "You aren't the appropriate taur type to wear this!"
@@ -35,7 +35,7 @@
icon_state = "saddlebag"
var/icon_base = "saddlebag"
max_storage_space = INVENTORY_DUFFLEBAG_SPACE //Saddlebags can hold more, like dufflebags
- slowdown = 1 //And are slower, too...Unless you're a macro, that is.
+ slowdown = 1 //And are slower, too...
var/no_message = "You aren't the appropriate taur type to wear this!"
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
@@ -44,11 +44,6 @@
log_runtime("[H] was not a valid human!")
return
- if(H.size_multiplier >= RESIZE_BIG) //Are they a macro? If yes, they get no slowdown.
- slowdown = 0
- else
- slowdown = initial(slowdown)
-
var/datum/sprite_accessory/tail/taur/TT = H.tail_style
item_state = "[icon_base]_[TT.icon_sprite_tag]" //icon_sprite_tag is something like "deer"
return 1
diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm
index 277a083d545..1764b0d8bec 100644
--- a/code/game/objects/items/weapons/tanks/tank_types.dm
+++ b/code/game/objects/items/weapons/tanks/tank_types.dm
@@ -174,7 +174,7 @@
gauge_icon = "indicator_emergency"
/obj/item/weapon/tank/emergency/nitrogen/Initialize()
- ..()
+ . = ..()
src.air_contents.adjust_gas("nitrogen", (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/weapon/tank/emergency/nitrogen/double
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm
index f3158726697..bd5b5a57c34 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/weapons/tools/weldingtool.dm
@@ -671,7 +671,7 @@
always_process = TRUE
/obj/item/weapon/weldingtool/electric/mounted/exosuit/Initialize()
- ..()
+ . = ..()
if(istype(loc, /obj/item/mecha_parts/mecha_equipment))
equip_mount = loc
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 688236eda85..0bf22938021 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -19,29 +19,11 @@
var/can_speak = 0 //For MMIs and admin trickery. If an object has a brainmob in its contents, set this to 1 to allow it to speak.
var/show_examine = TRUE // Does this pop up on a mob when the mob is examined?
- var/register_as_dangerous_object = FALSE // Should this tell its turf that it is dangerous automatically?
-
-/obj/Initialize()
- if(register_as_dangerous_object)
- register_dangerous_to_step()
- return ..()
/obj/Destroy()
STOP_PROCESSING(SSobj, src)
- if(register_as_dangerous_object)
- unregister_dangerous_to_step()
return ..()
-/obj/Moved(atom/oldloc)
- . = ..()
- if(register_as_dangerous_object)
- var/turf/old_turf = get_turf(oldloc)
- var/turf/new_turf = get_turf(src)
-
- if(old_turf != new_turf)
- old_turf.unregister_dangerous_object(src)
- new_turf.register_dangerous_object(src)
-
/obj/Topic(href, href_list, var/datum/tgui_state/state = GLOB.tgui_default_state)
if(usr && ..())
return 1
diff --git a/code/game/objects/random/_random.dm b/code/game/objects/random/_random.dm
index 67f82ea1551..7b9cc60617f 100644
--- a/code/game/objects/random/_random.dm
+++ b/code/game/objects/random/_random.dm
@@ -8,7 +8,7 @@
// creates a new object and deletes itself
/obj/random/Initialize()
- . = ..()
+ ..()
if (!prob(spawn_nothing_percentage))
spawn_item()
return INITIALIZE_HINT_QDEL
diff --git a/code/game/objects/structures/cliff.dm b/code/game/objects/structures/cliff.dm
index 66fb9459882..ad4b23bdb86 100644
--- a/code/game/objects/structures/cliff.dm
+++ b/code/game/objects/structures/cliff.dm
@@ -1,236 +1,252 @@
-GLOBAL_LIST_EMPTY(cliff_icon_cache)
-
-/*
-Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
-
-Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
-where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
-
-Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
-
-Flying mobs can pass over all cliffs with no risk of falling.
-
-Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
-This makes fighting something that is on top of a cliff more challenging.
-
-As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
-
-When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
-two tiles on initialization, and which way a cliff is facing may change during maploading.
-*/
-
-/obj/structure/cliff
- name = "cliff"
- desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
- description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.
\
- You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.
\
- Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
- on top."
- icon = 'icons/obj/flora/rocks.dmi'
-
- anchored = TRUE
- density = TRUE
- opacity = FALSE
- climbable = TRUE
- climb_delay = 10 SECONDS
- block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
- register_as_dangerous_object = TRUE
-
- var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
- var/corner = FALSE // Used for icon things.
- var/ramp = FALSE // Ditto.
- var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
-
- var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
- var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
-
-// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
-/obj/structure/cliff/automatic
- icon_state = "cliffbuilder"
- dir = NORTH
-
-/obj/structure/cliff/automatic/corner
- icon_state = "cliffbuilder-corner"
- dir = NORTHEAST
- corner = TRUE
-
-// Tiny part that doesn't block, used for making 'ramps'.
-/obj/structure/cliff/automatic/ramp
- icon_state = "cliffbuilder-ramp"
- dir = NORTHEAST
- density = FALSE
- ramp = TRUE
-
-// Made automatically as needed by automatic cliffs.
-/obj/structure/cliff/bottom
- bottom = TRUE
-
-/obj/structure/cliff/automatic/Initialize()
- ..()
- return INITIALIZE_HINT_LATELOAD
-
-// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
-/obj/structure/cliff/automatic/LateInitialize()
- if(dir in GLOB.cardinal)
- icon_variant = pick("a", "b", "c")
-
- if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
- make_bottom()
-
- update_icon()
-
-/obj/structure/cliff/proc/make_bottom()
- // First, make sure there's room to put the bottom side.
- var/turf/T = locate(x, y - 1, z)
- if(!istype(T))
- return FALSE
-
- // Now make the bottom cliff have mostly the same variables.
- var/obj/structure/cliff/bottom/bottom = new(T)
- is_double_cliff = TRUE
- climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
-
- bottom.dir = dir
- bottom.is_double_cliff = TRUE
- bottom.climb_delay = climb_delay
- bottom.icon_variant = icon_variant
- bottom.corner = corner
- bottom.ramp = ramp
- bottom.layer = layer - 0.1
- bottom.density = density
- bottom.update_icon()
-
-/obj/structure/cliff/set_dir(new_dir)
- ..()
- update_icon()
-
-/obj/structure/cliff/update_icon()
- icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
-
- // Now for making the top-side look like a different turf.
- var/turf/T = get_step(src, dir)
- if(!istype(T))
- return
-
- var/subtraction_icon_state = "[icon_state]-subtract"
- var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
- if(T && subtraction_icon_state in cached_icon_states(icon))
- cut_overlays()
- // If we've made the same icon before, just recycle it.
- if(cache_string in GLOB.cliff_icon_cache)
- add_overlay(GLOB.cliff_icon_cache[cache_string])
-
- else // Otherwise make a new one, but only once.
- var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
- var/icon/subtract = icon(icon, subtraction_icon_state)
- underlying_ground.Blend(subtract, ICON_SUBTRACT)
- var/image/final = image(underlying_ground)
- final.layer = src.layer - 0.2
- GLOB.cliff_icon_cache[cache_string] = final
- add_overlay(final)
-
-
-// Movement-related code.
-
-/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
- if(isliving(mover))
- var/mob/living/L = mover
- if(L.hovering) // Flying mobs can always pass.
- return TRUE
- return ..()
-
- // Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
- else if(istype(mover, /obj))
- var/obj/O = mover
- if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
- if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
- return FALSE
- return TRUE
-
-/obj/structure/cliff/Bumped(atom/A)
- if(isliving(A))
- var/mob/living/L = A
- if(should_fall(L))
- fall_off_cliff(L)
- return
- ..()
-
-/obj/structure/cliff/proc/should_fall(mob/living/L)
- if(L.hovering)
- return FALSE
-
- var/turf/T = get_turf(L)
- if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
- return TRUE
- return FALSE
-
-/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
- if(!istype(L))
- return FALSE
- var/turf/T = get_step(src, reverse_dir[dir])
- var/displaced = FALSE
-
- if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
- for(var/i = 1 to 2)
- var/turf/new_T = locate(T.x, T.y - i, T.z)
- if(!new_T || locate(/obj/structure/cliff) in new_T)
- break
- T = new_T
- displaced = TRUE
-
- if(istype(T))
- visible_message(span("danger", "\The [L] falls off \the [src]!"))
- L.forceMove(T)
-
- // Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
- var/harm = !is_double_cliff ? 1 : 0.5
- if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
- var/obj/vehicle/vehicle = L.buckled
- vehicle.adjust_health(40 * harm)
- to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
- harm /= 2
-
- playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
- L.Weaken(5 * harm)
- var/fall_time = 3
- if(displaced) // Make the fall look more natural when falling sideways.
- L.pixel_z = 32 * 2
- animate(L, pixel_z = 0, time = fall_time)
- sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
- playsound(L, "punch", 70, 1)
- shake_camera(L, 1, 1)
- visible_message(span("danger", "\The [L] hits the ground!"))
-
- // The bigger they are, the harder they fall.
- // They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
- // This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
- var/damage = between(20, L.getMaxHealth() * 0.4, 100)
- var/target_zone = ran_zone()
- var/blocked = L.run_armor_check(target_zone, "melee") * harm
- var/soaked = L.get_armor_soak(target_zone, "melee") * harm
-
- L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
-
- // Now fall off more cliffs below this one if they exist.
- var/obj/structure/cliff/bottom_cliff = locate() in T
- if(bottom_cliff)
- visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
- sleep(5)
- bottom_cliff.fall_off_cliff(L)
-
-/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
- // Cliff climbing requires climbing gear.
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- var/obj/item/clothing/shoes/shoes = H.shoes
- if(shoes && shoes.rock_climbing)
- return ..() // Do the other checks too.
-
- to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
- return FALSE
-
-// This tells AI mobs to not be dumb and step off cliffs willingly.
-/obj/structure/cliff/is_safe_to_step(mob/living/L)
- if(should_fall(L))
- return FALSE
- return ..()
+GLOBAL_LIST_EMPTY(cliff_icon_cache)
+
+/*
+Cliffs give a visual illusion of depth by seperating two places while presenting a 'top' and 'bottom' side.
+
+Mobs moving into a cliff from the bottom side will simply bump into it and be denied moving into the tile,
+where as mobs moving into a cliff from the top side will 'fall' off the cliff, forcing them to the bottom, causing significant damage and stunning them.
+
+Mobs can climb this while wearing climbing equipment by clickdragging themselves onto a cliff, as if it were a table.
+
+Flying mobs can pass over all cliffs with no risk of falling.
+
+Projectiles and thrown objects can pass, however if moving upwards, there is a chance for it to be stopped by the cliff.
+This makes fighting something that is on top of a cliff more challenging.
+
+As a note, dir points upwards, e.g. pointing WEST means the left side is 'up', and the right side is 'down'.
+
+When mapping these in, be sure to give at least a one tile clearance, as NORTH facing cliffs expand to
+two tiles on initialization, and which way a cliff is facing may change during maploading.
+*/
+
+/obj/structure/cliff
+ name = "cliff"
+ desc = "A steep rock ledge. You might be able to climb it if you feel bold enough."
+ description_info = "Walking off the edge of a cliff while on top will cause you to fall off, causing severe injury.
\
+ You can climb this cliff if wearing special climbing equipment, by click-dragging yourself onto the cliff.
\
+ Projectiles traveling up a cliff may hit the cliff instead, making it more difficult to fight something \
+ on top."
+ icon = 'icons/obj/flora/rocks.dmi'
+
+ anchored = TRUE
+ density = TRUE
+ opacity = FALSE
+ climbable = TRUE
+ climb_delay = 10 SECONDS
+ block_turf_edges = TRUE // Don't want turf edges popping up from the cliff edge.
+
+ var/icon_variant = null // Used to make cliffs less repeative by having a selection of sprites to display.
+ var/corner = FALSE // Used for icon things.
+ var/ramp = FALSE // Ditto.
+ var/bottom = FALSE // Used for 'bottom' typed cliffs, to avoid infinite cliffs, and for icons.
+
+ var/is_double_cliff = FALSE // Set to true when making the two-tile cliffs, used for projectile checks.
+ var/uphill_penalty = 30 // Odds of a projectile not making it up the cliff.
+
+/obj/structure/cliff/Initialize()
+ . = ..()
+ register_dangerous_to_step()
+
+/obj/structure/cliff/Destroy()
+ unregister_dangerous_to_step()
+ . = ..()
+
+/obj/structure/cliff/Moved(atom/oldloc)
+ . = ..()
+ if(.)
+ var/turf/old_turf = get_turf(oldloc)
+ var/turf/new_turf = get_turf(src)
+ if(old_turf != new_turf)
+ old_turf.unregister_dangerous_object(src)
+ new_turf.register_dangerous_object(src)
+
+// These arrange their sprites at runtime, as opposed to being statically placed in the map file.
+/obj/structure/cliff/automatic
+ icon_state = "cliffbuilder"
+ dir = NORTH
+
+/obj/structure/cliff/automatic/corner
+ icon_state = "cliffbuilder-corner"
+ dir = NORTHEAST
+ corner = TRUE
+
+// Tiny part that doesn't block, used for making 'ramps'.
+/obj/structure/cliff/automatic/ramp
+ icon_state = "cliffbuilder-ramp"
+ dir = NORTHEAST
+ density = FALSE
+ ramp = TRUE
+
+// Made automatically as needed by automatic cliffs.
+/obj/structure/cliff/bottom
+ bottom = TRUE
+
+/obj/structure/cliff/automatic/Initialize()
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+// Paranoid about the maploader, direction is very important to cliffs, since they may get bigger if initialized while facing NORTH.
+/obj/structure/cliff/automatic/LateInitialize()
+ if(dir in GLOB.cardinal)
+ icon_variant = pick("a", "b", "c")
+
+ if(dir & NORTH && !bottom) // North-facing cliffs require more cliffs to be made.
+ make_bottom()
+
+ update_icon()
+
+/obj/structure/cliff/proc/make_bottom()
+ // First, make sure there's room to put the bottom side.
+ var/turf/T = locate(x, y - 1, z)
+ if(!istype(T))
+ return FALSE
+
+ // Now make the bottom cliff have mostly the same variables.
+ var/obj/structure/cliff/bottom/bottom = new(T)
+ is_double_cliff = TRUE
+ climb_delay /= 2 // Since there are two cliffs to climb when going north, both take half the time.
+
+ bottom.dir = dir
+ bottom.is_double_cliff = TRUE
+ bottom.climb_delay = climb_delay
+ bottom.icon_variant = icon_variant
+ bottom.corner = corner
+ bottom.ramp = ramp
+ bottom.layer = layer - 0.1
+ bottom.density = density
+ bottom.update_icon()
+
+/obj/structure/cliff/set_dir(new_dir)
+ ..()
+ update_icon()
+
+/obj/structure/cliff/update_icon()
+ icon_state = "cliff-[dir][icon_variant][bottom ? "-bottom" : ""][corner ? "-corner" : ""][ramp ? "-ramp" : ""]"
+
+ // Now for making the top-side look like a different turf.
+ var/turf/T = get_step(src, dir)
+ if(!istype(T))
+ return
+
+ var/subtraction_icon_state = "[icon_state]-subtract"
+ var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
+ if(T && subtraction_icon_state in cached_icon_states(icon))
+ cut_overlays()
+ // If we've made the same icon before, just recycle it.
+ if(cache_string in GLOB.cliff_icon_cache)
+ add_overlay(GLOB.cliff_icon_cache[cache_string])
+
+ else // Otherwise make a new one, but only once.
+ var/icon/underlying_ground = icon(T.icon, T.icon_state, T.dir)
+ var/icon/subtract = icon(icon, subtraction_icon_state)
+ underlying_ground.Blend(subtract, ICON_SUBTRACT)
+ var/image/final = image(underlying_ground)
+ final.layer = src.layer - 0.2
+ GLOB.cliff_icon_cache[cache_string] = final
+ add_overlay(final)
+
+
+// Movement-related code.
+
+/obj/structure/cliff/CanPass(atom/movable/mover, turf/target)
+ if(isliving(mover))
+ var/mob/living/L = mover
+ if(L.hovering) // Flying mobs can always pass.
+ return TRUE
+ return ..()
+
+ // Projectiles and objects flying 'upward' have a chance to hit the cliff instead, wasting the shot.
+ else if(istype(mover, /obj))
+ var/obj/O = mover
+ if(check_shield_arc(src, dir, O)) // This is actually for mobs but it will work for our purposes as well.
+ if(prob(uphill_penalty / (1 + is_double_cliff) )) // Firing upwards facing NORTH means it will likely have to pass through two cliffs, so the chance is halved.
+ return FALSE
+ return TRUE
+
+/obj/structure/cliff/Bumped(atom/A)
+ if(isliving(A))
+ var/mob/living/L = A
+ if(should_fall(L))
+ fall_off_cliff(L)
+ return
+ ..()
+
+/obj/structure/cliff/proc/should_fall(mob/living/L)
+ if(L.hovering)
+ return FALSE
+
+ var/turf/T = get_turf(L)
+ if(T && get_dir(T, loc) & reverse_dir[dir]) // dir points 'up' the cliff, e.g. cliff pointing NORTH will cause someone to fall if moving SOUTH into it.
+ return TRUE
+ return FALSE
+
+/obj/structure/cliff/proc/fall_off_cliff(mob/living/L)
+ if(!istype(L))
+ return FALSE
+ var/turf/T = get_step(src, reverse_dir[dir])
+ var/displaced = FALSE
+
+ if(dir in list(EAST, WEST)) // Apply an offset if flying sideways, to help maintain the illusion of depth.
+ for(var/i = 1 to 2)
+ var/turf/new_T = locate(T.x, T.y - i, T.z)
+ if(!new_T || locate(/obj/structure/cliff) in new_T)
+ break
+ T = new_T
+ displaced = TRUE
+
+ if(istype(T))
+ visible_message(span("danger", "\The [L] falls off \the [src]!"))
+ L.forceMove(T)
+
+ // Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice.
+ var/harm = !is_double_cliff ? 1 : 0.5
+ if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely.
+ var/obj/vehicle/vehicle = L.buckled
+ vehicle.adjust_health(40 * harm)
+ to_chat(L, span("warning", "\The [vehicle] absorbs some of the impact, damaging it."))
+ harm /= 2
+
+ playsound(L, 'sound/effects/break_stone.ogg', 70, 1)
+ L.Weaken(5 * harm)
+ var/fall_time = 3
+ if(displaced) // Make the fall look more natural when falling sideways.
+ L.pixel_z = 32 * 2
+ animate(L, pixel_z = 0, time = fall_time)
+ sleep(fall_time) // A brief delay inbetween the two sounds helps sell the 'ouch' effect.
+ playsound(L, "punch", 70, 1)
+ shake_camera(L, 1, 1)
+ visible_message(span("danger", "\The [L] hits the ground!"))
+
+ // The bigger they are, the harder they fall.
+ // They will take at least 20 damage at the minimum, and tries to scale up to 40% of their max health.
+ // This scaling is capped at 100 total damage, which occurs if the thing that fell has more than 250 health.
+ var/damage = between(20, L.getMaxHealth() * 0.4, 100)
+ var/target_zone = ran_zone()
+ var/blocked = L.run_armor_check(target_zone, "melee") * harm
+ var/soaked = L.get_armor_soak(target_zone, "melee") * harm
+
+ L.apply_damage(damage * harm, BRUTE, target_zone, blocked, soaked, used_weapon=src)
+
+ // Now fall off more cliffs below this one if they exist.
+ var/obj/structure/cliff/bottom_cliff = locate() in T
+ if(bottom_cliff)
+ visible_message(span("danger", "\The [L] rolls down towards \the [bottom_cliff]!"))
+ sleep(5)
+ bottom_cliff.fall_off_cliff(L)
+
+/obj/structure/cliff/can_climb(mob/living/user, post_climb_check = FALSE)
+ // Cliff climbing requires climbing gear.
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ var/obj/item/clothing/shoes/shoes = H.shoes
+ if(shoes && shoes.rock_climbing)
+ return ..() // Do the other checks too.
+
+ to_chat(user, span("warning", "\The [src] is too steep to climb unassisted."))
+ return FALSE
+
+// This tells AI mobs to not be dumb and step off cliffs willingly.
+/obj/structure/cliff/is_safe_to_step(mob/living/L)
+ if(should_fall(L))
+ return FALSE
+ return ..()
diff --git a/code/game/objects/structures/crates_lockers/__closets.dm b/code/game/objects/structures/crates_lockers/__closets.dm
index f7e399a267b..4e18d87207b 100644
--- a/code/game/objects/structures/crates_lockers/__closets.dm
+++ b/code/game/objects/structures/crates_lockers/__closets.dm
@@ -37,7 +37,6 @@
/obj/structure/closet/Initialize()
..()
- // Closets need to come later because of spawners potentially creating objects during init.
return INITIALIZE_HINT_LATELOAD
/obj/structure/closet/LateInitialize()
diff --git a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
index 2ee0c7915ee..aa7a55dff6f 100644
--- a/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
+++ b/code/game/objects/structures/crates_lockers/closets/misc_vr.dm
@@ -133,7 +133,6 @@
/obj/item/clothing/gloves/fingerless,
/obj/item/device/radio/headset/pilot,
/obj/item/device/radio/headset/pilot/alt,
- /obj/item/weapon/cartridge/explorer,
/obj/item/device/flashlight,
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
/obj/item/weapon/reagent_containers/food/snacks/liquidprotein,
diff --git a/code/game/objects/structures/dancepole_vr.dm b/code/game/objects/structures/dancepole_vr.dm
new file mode 100644
index 00000000000..0c9397142d2
--- /dev/null
+++ b/code/game/objects/structures/dancepole_vr.dm
@@ -0,0 +1,25 @@
+//Dance pole
+/obj/structure/dancepole
+ name = "dance pole"
+ desc = "Engineered for your entertainment"
+ icon = 'icons/obj/objects_vr.dmi'
+ icon_state = "dancepole"
+ density = 0
+ anchored = 1
+
+/obj/structure/dancepole/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(O.is_screwdriver())
+ anchored = !anchored
+ playsound(src, O.usesound, 50, 1)
+ if(anchored)
+ to_chat(user, "You secure \the [src].")
+ else
+ to_chat(user, "You unsecure \the [src].")
+ if(O.is_wrench())
+ playsound(src, O.usesound, 50, 1)
+ to_chat(user, "Now disassembling \the [src]...")
+ if(do_after(user, 30 * O.toolspeed))
+ if(!src) return
+ to_chat(user, "You dissasembled \the [src]!")
+ new /obj/item/stack/material/steel(src.loc, 1)
+ qdel(src)
\ No newline at end of file
diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm
index bccdcf56c34..f584fd8838b 100644
--- a/code/game/objects/structures/fireaxe.dm
+++ b/code/game/objects/structures/fireaxe.dm
@@ -14,7 +14,7 @@
var/smashed = 0
/obj/structure/fireaxecabinet/Initialize()
- ..()
+ . = ..()
fireaxe = new /obj/item/weapon/material/twohanded/fireaxe()
/obj/structure/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
diff --git a/code/game/objects/structures/flora/flora.dm b/code/game/objects/structures/flora/flora.dm
index cc5c5b510f4..e97c7b84bb6 100644
--- a/code/game/objects/structures/flora/flora.dm
+++ b/code/game/objects/structures/flora/flora.dm
@@ -22,7 +22,7 @@
var/list/harvest_loot = null // Should be an associative list for things to spawn, and their weights. An example would be a branch from a tree.
/obj/structure/flora/Initialize()
- ..()
+ . = ..()
if(randomize_size)
icon_scale_x = rand(min_x_scale * 100, max_x_scale * 100) / 100
diff --git a/code/game/objects/structures/ghost_pods/ghost_pods.dm b/code/game/objects/structures/ghost_pods/ghost_pods.dm
index 386d493d2db..7649c8573fb 100644
--- a/code/game/objects/structures/ghost_pods/ghost_pods.dm
+++ b/code/game/objects/structures/ghost_pods/ghost_pods.dm
@@ -28,7 +28,7 @@
icon_state = icon_state_opened
if(needscharger)
new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc)
- del(src)
+ qdel(src)
return TRUE
else
return FALSE
diff --git a/code/game/objects/structures/ghost_pods/human.dm b/code/game/objects/structures/ghost_pods/human.dm
index 814db9cd757..f2b32915975 100644
--- a/code/game/objects/structures/ghost_pods/human.dm
+++ b/code/game/objects/structures/ghost_pods/human.dm
@@ -25,7 +25,7 @@
var/list/clothing_possibilities
/obj/structure/ghost_pod/ghost_activated/human/Initialize()
- ..()
+ . = ..()
handle_clothing_setup()
@@ -153,7 +153,7 @@
var/list/clothing_possibilities
/obj/structure/ghost_pod/manual/human/Initialize()
- ..()
+ . = ..()
handle_clothing_setup()
diff --git a/code/game/objects/structures/ghost_pods/silicon.dm b/code/game/objects/structures/ghost_pods/silicon.dm
index 32a26ce479d..74f53e92045 100644
--- a/code/game/objects/structures/ghost_pods/silicon.dm
+++ b/code/game/objects/structures/ghost_pods/silicon.dm
@@ -89,7 +89,7 @@
qdel(src)
/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/Initialize()
- ..()
+ . = ..()
var/turf/T = get_turf(src)
say_dead_object("A [drone_class] swarm drone shell is now available in \the [T.loc].", src)
diff --git a/code/game/objects/structures/props/nest.dm b/code/game/objects/structures/props/nest.dm
index 4cb515fc36b..ba16b0b0556 100644
--- a/code/game/objects/structures/props/nest.dm
+++ b/code/game/objects/structures/props/nest.dm
@@ -20,7 +20,7 @@
var/total_creature_max //If set, it can spawn this many creatures, total, ever.
/obj/structure/prop/nest/Initialize()
- ..()
+ . = ..()
den_mobs = list()
START_PROCESSING(SSobj, src)
last_spawn = world.time
diff --git a/code/game/objects/structures/props/swarm.dm b/code/game/objects/structures/props/swarm.dm
index 128254a456e..51f59072f40 100644
--- a/code/game/objects/structures/props/swarm.dm
+++ b/code/game/objects/structures/props/swarm.dm
@@ -23,7 +23,7 @@
return ..()
/obj/structure/cult/pylon/swarm/Initialize()
- ..()
+ . = ..()
active_beams = list()
/obj/structure/cult/pylon/swarm/Destroy()
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 089e65fc041..7459fcab6c3 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -1,26 +1,59 @@
/obj/structure/bed/chair/wheelchair
name = "wheelchair"
desc = "You sit in this. Either by will or force."
+ icon = 'icons/obj/wheelchair.dmi'
icon_state = "wheelchair"
anchored = 0
buckle_movable = 1
+ var/folded_type = /obj/item/wheelchair
var/driving = 0
var/mob/living/pulling = null
var/bloodiness
+ var/min_mob_buckle_size = MOB_SMALL
+ var/max_mob_buckle_size = MOB_LARGE
+
+/obj/structure/bed/chair/wheelchair/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/structure/bed/chair/wheelchair/motor
+ name = "electric wheelchair"
+ desc = "A motorized wheelchair controlled with a joystick on one armrest"
+ icon_state = "motorchair"
+ folded_type = /obj/item/wheelchair/motor
+
+/obj/structure/bed/chair/wheelchair/smallmotor
+ name = "small electric wheelchair"
+ desc = "A small motorized wheelchair, it looks around the right size for a Teshari"
+ icon_state = "teshchair"
+ min_mob_buckle_size = MOB_SMALL
+ max_mob_buckle_size = MOB_MEDIUM
+ folded_type = /obj/item/wheelchair/motor/small
+
+/obj/structure/bed/chair/wheelchair/can_buckle_check(mob/living/M, forced = FALSE)
+ . = ..()
+ if(.)
+ if(M.mob_size < min_mob_buckle_size)
+ to_chat(M, SPAN_WARNING("You are too small to use \the [src]."))
+ . = FALSE
+ else if(M.mob_size >= max_mob_buckle_size)
+ to_chat(M, SPAN_WARNING("You are too large to use \the [src]."))
+ . = FALSE
/obj/structure/bed/chair/wheelchair/update_icon()
- return
+ cut_overlays()
+ var/image/O = image(icon = icon, icon_state = "[icon_state]_overlay", layer = ABOVE_MOB_LAYER)
+ O.plane = MOB_PLANE
+ add_overlay(O)
/obj/structure/bed/chair/wheelchair/set_dir()
- ..()
- cut_overlays()
- var/image/O = image(icon = 'icons/obj/furniture.dmi', icon_state = "w_overlay", layer = FLY_LAYER, dir = src.dir)
- add_overlay(O)
- if(has_buckled_mobs())
- for(var/A in buckled_mobs)
- var/mob/living/L = A
- L.set_dir(dir)
+ . = ..()
+ if(.)
+ if(has_buckled_mobs())
+ for(var/A in buckled_mobs)
+ var/mob/living/L = A
+ L.set_dir(dir)
/obj/structure/bed/chair/wheelchair/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.is_wrench() || W.is_wirecutter() || istype(W,/obj/item/stack))
@@ -93,8 +126,6 @@
/obj/structure/bed/chair/wheelchair/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
-
- cut_overlays()
playsound(src, 'sound/effects/roll.ogg', 75, 1)
if(has_buckled_mobs())
for(var/A in buckled_mobs)
@@ -203,28 +234,13 @@
usr.pulledby = null
..()
-/obj/item/wheelchair
- name = "wheelchair"
- desc = "A folded wheelchair that can be carried around."
- icon = 'icons/obj/furniture.dmi'
- icon_state = "wheelchair_folded"
- item_state = "wheelchair"
- w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
-
-/obj/item/wheelchair/attack_self(mob/user)
- var/obj/structure/bed/chair/wheelchair/R = new /obj/structure/bed/chair/wheelchair(user.loc)
- R.add_fingerprint(user)
- R.name = src.name
- R.color = src.color
- qdel(src)
-
/obj/structure/bed/chair/wheelchair/MouseDrop(over_object, src_location, over_location)
..()
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
if(!ishuman(usr)) return
if(has_buckled_mobs()) return 0
visible_message("[usr] collapses \the [src.name].")
- var/obj/item/wheelchair/R = new/obj/item/wheelchair(get_turf(src))
+ var/obj/item/wheelchair/R = new folded_type(get_turf(src))
R.name = src.name
R.color = src.color
spawn(0)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair_item.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair_item.dm
new file mode 100644
index 00000000000..d18a9a88f1a
--- /dev/null
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair_item.dm
@@ -0,0 +1,29 @@
+/obj/item/wheelchair
+ name = "wheelchair"
+ desc = "A folded wheelchair that can be carried around."
+ icon = 'icons/obj/wheelchair.dmi'
+ icon_state = "wheelchair_folded"
+ item_state = "wheelchair"
+ w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well.
+ var/unfolded_type = /obj/structure/bed/chair/wheelchair
+
+/obj/item/wheelchair/attack_self(mob/user)
+ var/obj/structure/bed/chair/wheelchair/R = new unfolded_type(user.loc)
+ R.add_fingerprint(user)
+ R.name = src.name
+ R.color = src.color
+ qdel(src)
+
+/obj/item/wheelchair/motor
+ name = "electric wheelchair"
+ desc = "A motorized wheelchair controlled with a joystick on one armrest"
+ icon_state = "motorchair_folded"
+ item_state = "motorchair"
+ unfolded_type = /obj/structure/bed/chair/wheelchair/motor
+
+/obj/item/wheelchair/motor/small
+ name = "small electric wheelchair"
+ desc = "A small motorized wheelchair, it looks around the right size for a Teshari."
+ icon_state = "teshchair_folded"
+ item_state = "teshchair"
+ unfolded_type = /obj/structure/bed/chair/wheelchair/smallmotor
diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm
index d2772caa4bd..297e514e0d4 100644
--- a/code/game/objects/structures/trash_pile_vr.dm
+++ b/code/game/objects/structures/trash_pile_vr.dm
@@ -180,6 +180,7 @@
prob(2);/obj/item/clothing/shoes/galoshes,
prob(2);/obj/item/clothing/under/pants/camo,
prob(2);/obj/item/clothing/under/syndicate/tacticool,
+ prob(2);/obj/item/clothing/under/hyperfiber,
prob(2);/obj/item/device/camera,
prob(2);/obj/item/device/flashlight/flare,
prob(2);/obj/item/device/flashlight/glowstick,
@@ -240,6 +241,7 @@
prob(2);/obj/item/weapon/handcuffs/legcuffs/fuzzy,
prob(2);/obj/item/weapon/storage/box/syndie_kit/spy,
prob(2);/obj/item/weapon/grenade/anti_photon,
+ prob(2);/obj/item/clothing/under/hyperfiber/bluespace,
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
prob(1);/obj/item/device/nif/bad,
prob(1);/obj/item/device/radio_jammer,
diff --git a/code/game/objects/structures/window_spawner.dm b/code/game/objects/structures/window_spawner.dm
index bb8b5cff6bd..dfeecb7be72 100644
--- a/code/game/objects/structures/window_spawner.dm
+++ b/code/game/objects/structures/window_spawner.dm
@@ -27,11 +27,10 @@
return FALSE
/obj/effect/wingrille_spawn/Initialize()
- . = ..()
- if(!win_path)
- return
- if(ticker && ticker.current_state < GAME_STATE_PLAYING)
+ if(win_path && ticker && ticker.current_state < GAME_STATE_PLAYING)
activate()
+ ..()
+ return INITIALIZE_HINT_QDEL
/obj/effect/wingrille_spawn/proc/activate()
if(activated) return
@@ -58,7 +57,8 @@
activated = 1
for(var/obj/effect/wingrille_spawn/other in neighbours)
if(!other.activated) other.activate()
- qdel(src)
+ if(initialized && !QDELETED(src))
+ qdel(src)
/obj/effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/W)
return
diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm
index 0fe768f9447..578fb80f547 100644
--- a/code/game/turfs/flooring/flooring_decals.dm
+++ b/code/game/turfs/flooring/flooring_decals.dm
@@ -12,9 +12,13 @@ var/list/floor_decals = list()
/obj/effect/floor_decal/New(var/newloc, var/newdir, var/newcolour)
supplied_dir = newdir
- if(newcolour) color = newcolour
+ if(newcolour)
+ color = newcolour
..(newloc)
+// TODO: identify what is causing these atoms to be qdeleted in New()/Initialize()
+// somewhere in this chain. Alternatively repath to /obj/floor_decal or some other
+// abstract handler that explicitly doesn't invoke any obj behavior.
/obj/effect/floor_decal/Initialize()
add_to_turf_decals()
initialized = TRUE
@@ -42,11 +46,11 @@ var/list/floor_decals = list()
name = "reset marker"
/obj/effect/floor_decal/reset/Initialize()
+ ..()
var/turf/T = get_turf(src)
if(T.decals && T.decals.len)
T.decals.Cut()
T.update_icon()
- initialized = TRUE
return INITIALIZE_HINT_QDEL
/obj/effect/floor_decal/corner
diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm
index d8e4d954ae5..4fa51f76bc5 100644
--- a/code/game/turfs/flooring/flooring_premade.dm
+++ b/code/game/turfs/flooring/flooring_premade.dm
@@ -317,7 +317,6 @@
name = "tiles"
icon_state = "freezer"
initial_flooring = /decl/flooring/tiling/freezer
- temperature = T0C - 5 // VOREStation Edit: Chillier Freezer Tiles on-start
/turf/simulated/floor/lino
name = "lino"
diff --git a/code/game/turfs/flooring/flooring_vr.dm b/code/game/turfs/flooring/flooring_vr.dm
index 2567ffd1a6d..787c6bd10c2 100644
--- a/code/game/turfs/flooring/flooring_vr.dm
+++ b/code/game/turfs/flooring/flooring_vr.dm
@@ -23,4 +23,7 @@
/decl/flooring/grass/outdoors/forest
icon = 'icons/turf/outdoors.dmi'
- icon_base = "grass-dark"
\ No newline at end of file
+ icon_base = "grass-dark"
+
+/turf/simulated/floor/tiled/freezer/cold
+ temperature = T0C - 5
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm
index 151efd819c4..437912b4d26 100644
--- a/code/game/turfs/simulated/floor_types.dm
+++ b/code/game/turfs/simulated/floor_types.dm
@@ -86,7 +86,7 @@
var/static/list/antilight_cache
/turf/simulated/shuttle/Initialize(mapload)
- ..()
+ . = ..()
if(!antilight_cache)
antilight_cache = list()
for(var/diag in cornerdirs)
diff --git a/code/game/turfs/simulated/floor_types_eris.dm b/code/game/turfs/simulated/floor_types_eris.dm
index bfc9945678a..1cd067b957e 100644
--- a/code/game/turfs/simulated/floor_types_eris.dm
+++ b/code/game/turfs/simulated/floor_types_eris.dm
@@ -1014,10 +1014,3 @@
oxygen = 0
nitrogen = 0
temperature = TCMB
-
-/*
-/turf/simulated/floor/hull/New()
- if(icon_state != "hullcenter0")
- overrided_icon_state = icon_state
- ..()
-*/
\ No newline at end of file
diff --git a/code/game/turfs/simulated/outdoors/snow.dm b/code/game/turfs/simulated/outdoors/snow.dm
index cccc028fa30..366fdfa5e69 100644
--- a/code/game/turfs/simulated/outdoors/snow.dm
+++ b/code/game/turfs/simulated/outdoors/snow.dm
@@ -31,7 +31,8 @@
to_chat(user, "You begin to remove \the [src] with your [W].")
if(do_after(user, 4 SECONDS * W.toolspeed))
to_chat(user, "\The [src] has been dug up, and now lies in a pile nearby.")
- new /obj/item/stack/material/snow(src)
+ var/obj/item/stack/material/snow/S = new(src)
+ S.amount = 10
demote()
else
to_chat(user, "You decide to not finish removing \the [src].")
diff --git a/code/game/turfs/space/cracked_asteroid.dm b/code/game/turfs/space/cracked_asteroid.dm
index ca77a8cd2c8..224997ca8d3 100644
--- a/code/game/turfs/space/cracked_asteroid.dm
+++ b/code/game/turfs/space/cracked_asteroid.dm
@@ -11,9 +11,3 @@
/turf/space/cracked_asteroid/is_space() // So people don't start floating when standing on it.
return FALSE
-
-// u wot m8? ~Leshana
-// /turf/space/cracked_asteroid/New()
-// ..()
-// spawn(2 SECONDS)
-// overlays.Cut()
diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated.dm
index 584137ff45a..39c217a0068 100644
--- a/code/game/turfs/unsimulated.dm
+++ b/code/game/turfs/unsimulated.dm
@@ -2,7 +2,13 @@
name = "command"
oxygen = MOLES_O2STANDARD
nitrogen = MOLES_N2STANDARD
- initialized = TRUE // Don't call init on unsimulated turfs (at least not yet)
+ var/skip_init = TRUE // Don't call down the chain, apparently for performance when loading maps at runtime.
+
+/turf/unsimulated/Initialize(mapload)
+ if(skip_init)
+ initialized = TRUE
+ return INITIALIZE_HINT_NORMAL
+ . = ..()
//VOREStation Add
/turf/unsimulated/fake_space
diff --git a/code/game/turfs/unsimulated/beach.dm b/code/game/turfs/unsimulated/beach.dm
index c5338b3db96..b1841dadad8 100644
--- a/code/game/turfs/unsimulated/beach.dm
+++ b/code/game/turfs/unsimulated/beach.dm
@@ -14,7 +14,7 @@
/turf/unsimulated/beach/water
name = "Water"
icon_state = "water"
- initialized = FALSE
+ skip_init = FALSE
movement_cost = 4 // Water should slow you down, just like simulated turf.
/turf/unsimulated/beach/water/Initialize()
diff --git a/code/game/turfs/unsimulated/planetary.dm b/code/game/turfs/unsimulated/planetary.dm
index 4fb26f16b6a..9fe487410f9 100644
--- a/code/game/turfs/unsimulated/planetary.dm
+++ b/code/game/turfs/unsimulated/planetary.dm
@@ -9,7 +9,6 @@
density = 1
alpha = 0
blocks_air = 0
- initialized = FALSE
// Set these to get your desired planetary atmosphere.
oxygen = 0
@@ -17,6 +16,7 @@
carbon_dioxide = 0
phoron = 0
temperature = T20C
+ skip_init = FALSE
/turf/unsimulated/wall/planetary/Initialize()
. = ..()
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 49c14a35502..b655d8b5e75 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -407,7 +407,7 @@ proc/admin_notice(var/message, var/rights)
dat+="ERROR: Could not submit Feed story to Network.
"
if(src.admincaster_feed_channel.channel_name=="")
dat+="•Invalid receiving channel name.
"
- if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]")
+ if(src.admincaster_feed_message.body == "" || src.admincaster_feed_message.body == "\[REDACTED\]" || admincaster_feed_message.title == "")
dat+="•Invalid message body.
"
dat+="
Return
"
if(7)
@@ -436,11 +436,14 @@ proc/admin_notice(var/message, var/rights)
var/i = 0
for(var/datum/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
i++
- dat+="-[MESSAGE.body]
"
+ //dat+="-[MESSAGE.body]
"
+ var/pic_data
if(MESSAGE.img)
usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
- dat+="
"
- dat+="\[Story by [MESSAGE.author]\]
"
+ pic_data+="
"
+ dat+= get_newspaper_content(MESSAGE.title, MESSAGE.body, MESSAGE.author,"#d4cec1", pic_data)
+ dat+="
"
+ dat+="\[Story by [MESSAGE.author] - [MESSAGE.time_stamp]\]
"
dat+={"
Refresh
Back
@@ -1424,6 +1427,11 @@ var/datum/announcement/minor/admin_min_announcer = new
return 1
if(tomob.client) //No need to ghostize if there is no client
tomob.ghostize(0)
+ if(frommob.mind && frommob.mind.current) //Preserve teleop for original body when adminghosting.
+ var/mob/body = frommob.mind.current
+ if(body)
+ if(body.teleop)
+ body.teleop = tomob
message_admins("[key_name_admin(usr)] has put [frommob.ckey] in control of [tomob.name].")
log_admin("[key_name(usr)] stuffed [frommob.ckey] into [tomob.name].")
feedback_add_details("admin_verb","CGD")
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index d09174c8d72..2c80b58274e 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1742,16 +1742,20 @@
src.admincaster_feed_channel.channel_name = sanitizeSafe(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels )
src.access_news_network()
+ else if(href_list["ac_set_new_title"])
+ src.admincaster_feed_message.title = sanitize(input(usr, "Enter the Feed title", "Network Channel Handler", ""))
+ src.access_news_network()
+
else if(href_list["ac_set_new_message"])
- src.admincaster_feed_message.body = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", ""))
+ src.admincaster_feed_message.body = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", "") as message)
src.access_news_network()
else if(href_list["ac_submit_new_message"])
- if(src.admincaster_feed_message.body =="" || src.admincaster_feed_message.body =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" )
+ if(src.admincaster_feed_message.body =="" || admincaster_feed_message.title == "" || admincaster_feed_message.body =="\[REDACTED\]" || admincaster_feed_channel.channel_name == "" )
src.admincaster_screen = 6
else
feedback_inc("newscaster_stories",1)
- news_network.SubmitArticle(src.admincaster_feed_message.body, src.admincaster_signature, src.admincaster_feed_channel.channel_name, null, 1)
+ news_network.SubmitArticle(admincaster_feed_message.body, admincaster_signature, admincaster_feed_channel.channel_name, null, 1, "", admincaster_feed_message.title)
src.admincaster_screen=4
log_admin("[key_name_admin(usr)] submitted a feed story to channel: [src.admincaster_feed_channel.channel_name]!")
diff --git a/code/modules/artifice/cursedform.dm b/code/modules/artifice/cursedform.dm
index 17f8fbf6183..43acac8bf3d 100644
--- a/code/modules/artifice/cursedform.dm
+++ b/code/modules/artifice/cursedform.dm
@@ -2,7 +2,7 @@
name = "Form - Inventory Requisition r10.7.1E"
/obj/item/weapon/paper/carbon/cursedform/Initialize()
- ..()
+ . = ..()
info = {"
Form - Inventory Requisition r10.7.1E
General Request Form
General
Name:
Department:
Departmental Rank:
Organization(If not Nanotrasen):
Date:
Requested Item(s):
Quantity:
Reason for request:
Is this replacement equipment?:
If `Yes`; above, specify equiment and reason for replacement:
Authorization
Authorizing Department:
Authorizing Dept. Head:
Contact and Delivery
EPv2 Address of requesting party(Do not leave blank):
Delivery location or department:
Nanotrasen Employee Identification Number:
Signature of Requester and Date
Authorizor`s Nanotrasen Employee Identification Number:
Authorizing Signature and Date(Include authorizing department`s stamp below)
Shipping Department Only
(Do not write below this line)
Nanotrasen Purchasing Approval Code:
Nanotrasen Employee Identification Number:
Receiving Shipping Employee:
Signature and Date
"}
info_links = {"
Form - Inventory Requisition r10.7.1E
General Request Form
General
Name: write
Department: write
Departmental Rank: write
Organization(If not Nanotrasen): write
Date: write
Requested Item(s): write
Quantity: write
Reason for request: write
Is this replacement equipment?: write
If `Yes` above, specify equiment and reason for replacement: write
Authorization
Authorizing Department: write
Authorizing Dept. Head: write
Contact and Delivery
EPv2 Address of requesting party(Do not leave blank): write
Delivery location or department: write
Nanotrasen Employee Identification Number: write
Signature of Requester and Date
write
Authorizor`s Nanotrasen Employee Identification Number: write
Authorizing Signature and Date(Include authorizing department`s stamp below)
write
Shipping Department Only
(Do not write below this line)
Nanotrasen Purchasing Approval Code: write
Nanotrasen Employee Identification Number: write
Receiving Shipping Employee: write
Signature and Date
write
write"}
diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm
index 5344d4b15bb..5a673280ceb 100644
--- a/code/modules/assembly/igniter.dm
+++ b/code/modules/assembly/igniter.dm
@@ -3,7 +3,7 @@
desc = "A small electronic device able to ignite combustable substances."
icon_state = "igniter"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, MAT_COPPER = 10, "waste" = 10)
secured = 1
wires = WIRE_RECEIVE
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 853f2f230be..3a7952ecfe6 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -5,7 +5,7 @@
desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted."
icon_state = "infrared"
origin_tech = list(TECH_MAGNET = 2)
- matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500, "waste" = 100)
+ matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500, MAT_COPPER = 10, "waste" = 100)
wires = WIRE_PULSE
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index b292d3f7531..de764c50111 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -3,7 +3,7 @@
desc = "Used for scanning and alerting when someone enters a certain proximity."
icon_state = "prox"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 800, "glass" = 200, "waste" = 50)
+ matter = list(DEFAULT_WALL_MATERIAL = 800, "glass" = 200, MAT_COPPER = 10, "waste" = 50)
wires = WIRE_PULSE
secured = 0
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index e98ff5372cf..392a7efdfe7 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -4,7 +4,7 @@
icon_state = "signaller"
item_state = "signaler"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200, "waste" = 100)
+ matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200, MAT_COPPER = 10, "waste" = 100)
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
secured = TRUE
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index fa8b7838157..144a21bcd05 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -3,7 +3,7 @@
desc = "Used to time things. Works well with contraptions which has to count down. Tick tock."
icon_state = "timer"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, MAT_COPPER = 10, "waste" = 10)
wires = WIRE_PULSE
diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm
index 8990e01d637..c608db5ff15 100644
--- a/code/modules/assembly/voice.dm
+++ b/code/modules/assembly/voice.dm
@@ -3,7 +3,7 @@
desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated."
icon_state = "voice"
origin_tech = list(TECH_MAGNET = 1)
- matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
+ matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, MAT_COPPER = 10, "waste" = 10)
var/listening = 0
var/recorded //the activation message
diff --git a/code/modules/awaymissions/loot.dm b/code/modules/awaymissions/loot.dm
index 1c1d9011617..530358940c2 100644
--- a/code/modules/awaymissions/loot.dm
+++ b/code/modules/awaymissions/loot.dm
@@ -8,18 +8,14 @@
/obj/effect/spawner/lootdrop/Initialize()
..()
var/list/things = params2list(loot)
-
if(things && things.len)
for(var/i = lootcount, i > 0, i--)
if(!things.len)
return
-
var/loot_spawn = pick(things)
var/loot_path = text2path(loot_spawn)
-
if(!loot_path || !lootdoubles)
things.Remove(loot_spawn)
continue
-
new loot_path(get_turf(src))
return INITIALIZE_HINT_QDEL
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index dfa181ee910..9fb7295266c 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -26,6 +26,7 @@
var/datum/chatOutput/chatOutput
var/datum/volume_panel/volume_panel = null // Initialized by /client/verb/volume_panel()
var/chatOutputLoadedAt
+ var/seen_news = 0
var/adminhelped = 0
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 83164afd3c3..3513e9b99d3 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -45,7 +45,6 @@
if( findtext(href,"