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/species_languages.dm b/code/__defines/species_languages.dm
index f6ca0ea5655..9b9c83d2569 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -24,6 +24,19 @@
#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.
+
// 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_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/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/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/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_movable.dm b/code/game/atoms_movable.dm
index bf5fc0ab18c..510b8bf7620 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)
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/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/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 7ff97c83e85..25299dcda8c 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -1,4 +1,4 @@
-/obj/machinery/computer/arcade/
+/obj/machinery/computer/arcade
name = "random arcade"
desc = "random arcade machine"
icon_state = "arcade"
@@ -25,15 +25,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)
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/security.dm b/code/game/machinery/computer/security.dm
index 1fbd897113d..40a4d594cbd 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:",
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/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm
index f4d9c900ed3..fdd526039b3 100644
--- a/code/game/machinery/doors/brigdoors.dm
+++ b/code/game/machinery/doors/brigdoors.dm
@@ -40,7 +40,6 @@
/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()
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index c23d02f4d01..a1798ea5e42 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -164,7 +164,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
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/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/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/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..c88527608f2 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -24,8 +24,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..7d9783df685 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)
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/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/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/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/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/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/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/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 = {"