| Job | Slots | Open job | Close job | Prioritize |
| Job | Slots | +Open job | Close job | Prioritize | |||
| [job.title] | " - dat += "[job.current_positions]/[job.total_positions] | " - dat += "" + dat += {" | [job.title] | +[job.current_positions]/[job.total_positions] | +"}
switch(can_open_job(job))
- if(1)
- if(ID)
+ if(JOB_ALLOWED)
+ if(authenticated == 2)
dat += "Open Position " else dat += "Open Position" - if(-1) - dat += "Denied" - if(-2) + if(JOB_COOLDOWN) var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) var/mins = round(time_to_wait / 60) var/seconds = time_to_wait - (60*mins) dat += "Cooldown ongoing: [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"]" - if(0) + else dat += "Denied" dat += " | " switch(can_close_job(job)) - if(1) - if(ID) + if(JOB_ALLOWED) + if(authenticated == 2) dat += "Close Position" else dat += "Close Position" - if(-1) - dat += "Denied" - if(-2) + if(-JOB_COOLDOWN) var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) var/mins = round(time_to_wait / 60) var/seconds = time_to_wait - (60*mins) dat += "Cooldown ongoing: [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"]" - if(0) + else dat += "Denied" dat += " | " switch(job.total_positions) if(0) dat += "Denied" else - if(ID) + if(authenticated == 2) if(job in SSjob.prioritized_jobs) dat += "Deprioritize" else @@ -255,57 +250,35 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) dat += " |
| "
for(var/A in get_region_accesses(i))
if(A in inserted_modify_id.access)
- accesses += "[replacetext(get_access_desc(A), " ", " ")] "
+ accesses += "[replacetext(get_access_desc(A), " ", " ")] "
else
accesses += "[replacetext(get_access_desc(A), " ", " ")] "
accesses += " " accesses += " | "
accesses += "
You start skimming through the manual...
@@ -295,7 +295,7 @@ function pageloaded(myframe) { document.getElementById("loading").style.display = "none"; myframe.style.display = "block"; - } + }You start skimming through the manual...
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 10b84917bb..d7c2f7f4f6 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -265,7 +265,7 @@ if (B && !QDELETED(B)) H.internal_organs -= B qdel(B) - new /obj/effect/gibspawner/generic(get_turf(H), H.dna) + H.spawn_gibs() return (BRUTELOSS) /obj/item/melee/classic_baton/telescopic/attack_self(mob/user) diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 973fb0c0ab..90e2efabc4 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -558,6 +558,37 @@ item_state = "almaz" squeak_override = list('modular_citadel/sound/voice/raptor_purr.ogg' = 1) +/obj/item/toy/plush/lizardplushie/garou + icon_state = "garou" + item_state = "garou" + +/obj/item/toy/plush/lizardplushie/augments + icon_state = "augments" + item_state = "augments" + squeak_override = list('modular_citadel/sound/voice/weh.ogg' = 1) //I have no mouth and I must weh + attack_verb = list("hugged", "patted", "snugged", "booped") + +/obj/item/toy/plush/lizardplushie/xekov + icon_state = "xekov" + item_state = "xekov" + +/obj/item/toy/plush/lizardplushie/greg + icon_state = "greg" + item_state = "greg" + +/obj/item/toy/plush/lizardplushie/sin + icon_state = "sin" + item_state = "sin" + desc = "An adorable stuffed toy that resembles a lizardperson.. It faintly smells of sulfur." + +/obj/item/toy/plush/lizardplushie/ends + icon_state = "ends" + item_state = "ends" + +/obj/item/toy/plush/lizardplushie/lyssa + icon_state = "lyssa" + item_state = "lyssa" + /obj/item/toy/plush/snakeplushie name = "snake plushie" desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing." @@ -715,6 +746,14 @@ item_state = "bhijn" attack_verb = list("closed", "reworked", "merged") +/obj/item/toy/plush/aiplush + name = "AI plushie" + desc = "A little stuffed toy AI core... it appears to be malfunctioning." + icon_state = "exo" + item_state = "exo" + attack_verb = list("hacked", "detonated", "overloaded") + squeak_override = list('sound/machines/beep.ogg' = 9, 'sound/machines/buzz-two.ogg' = 1) + /obj/item/toy/plush/bird name = "bird plushie" desc = "An adorable stuffed plushie that resembles an avian." @@ -862,6 +901,18 @@ item_state = "redwood" attack_verb = list("ordered", "bapped", "reprimanded") +/obj/item/toy/plush/mammal/marisol + desc = "An adorable stuffed toy resembling a demi-wolf security officer." + icon_state = "marisol" + item_state = "marisol" + attack_verb = list("arrested", "harmbattoned", "lasered") + +/obj/item/toy/plush/mammal/minty + desc = "An adorable stuffed toy resembling some sort of crew member. It smells like mint.." + icon_state = "minty" + item_state = "minty" + attack_verb = list("freshened", "brushed") + /obj/item/toy/plush/mammal/dog desc = "An adorable stuffed toy that resembles a canine." icon_state = "katlin" @@ -929,8 +980,8 @@ /obj/item/toy/plush/catgirl/skylar desc = "An adorable stuffed toy that resembles a degenerate." - icon_state = "skylar" - item_state = "skylar" + icon_state = "skylar2" + item_state = "skylar2" attack_verb = list("powergamed", "merged", "tabled") squeak_override = list('sound/effects/meow1.ogg' = 1) @@ -942,15 +993,15 @@ desc = "A masked stuffed toy that resembles a feline scientist." icon_state = "trilby" item_state = "trilby" - attack_verb = list("pred", "coded", "remembered") + attack_verb = list("PR'd", "coded", "remembered") /obj/item/toy/plush/catgirl/fermis - name = "medcat plushie" - desc = "An affectionate stuffed toy that resembles a certain medcat, comes complete with battery operated wagging tail!! You get the impression she's cheering you on to to find happiness and be kind to people." - icon_state = "fermis" - item_state = "fermis" - attack_verb = list("cuddled", "petpatted", "wigglepurred") - squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1) + name = "medcat plushie" + desc = "An affectionate stuffed toy that resembles a certain medcat, comes complete with battery operated wagging tail!! You get the impression she's cheering you on to to find happiness and be kind to people." + icon_state = "fermis" + item_state = "fermis" + attack_verb = list("cuddled", "petpatted", "wigglepurred") + squeak_override = list('modular_citadel/sound/voice/merowr.ogg' = 1) /obj/item/toy/plush/catgirl/mariaf desc = "An adorable stuffed toy that resembles a very tall cat girl." diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index c085306892..0aa19b13ef 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -10,6 +10,7 @@ * Runed Metal (cult) * Brass (clockwork cult) * Bronze (bake brass) + * Cotton/Duracotton */ /* @@ -186,31 +187,37 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ */ GLOBAL_LIST_INIT(wood_recipes, list ( \ new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \ + new/datum/stack_recipe("tiki mask", /obj/item/clothing/mask/gas/tiki_mask, 2), \ new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \ new/datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \ + null, \ new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \ new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \ + new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \ + new/datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15),\ + null, \ new/datum/stack_recipe("wooden chair", /obj/structure/chair/wood/, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("winged wooden chair", /obj/structure/chair/wood/wings, 3, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("plywood chair", /obj/structure/chair/comfy/plywood, 4, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ + null, \ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("rustic wooden door", /obj/structure/mineral_door/woodrustic, 10, time = 20, one_per_turf = TRUE, on_floor = TRUE), \ + null, \ + new/datum/stack_recipe("wooden barrel", /obj/structure/fermenting_barrel, 10, time = 20, one_per_turf = TRUE, on_floor = TRUE),\ new/datum/stack_recipe("coffin", /obj/structure/closet/crate/coffin, 5, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("dog bed", /obj/structure/bed/dogbed, 10, time = 10, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("dresser", /obj/structure/dresser, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\ - new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("loom", /obj/structure/loom, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ - new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \ - new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\ - new/datum/stack_recipe("tiki mask", /obj/item/clothing/mask/gas/tiki_mask, 2), \ - new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\ new/datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = TRUE, on_floor = TRUE),\ new/datum/stack_recipe("wooden crate", /obj/structure/closet/crate/wooden, 6, time = 50, one_per_turf = TRUE, on_floor = TRUE),\ - new/datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15),\ + new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("loom", /obj/structure/loom, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \ + new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\ + null, \ + new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\ + new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\ )) /obj/item/stack/sheet/mineral/wood @@ -272,6 +279,9 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ resistance_flags = FLAMMABLE force = 0 throwforce = 0 + pull_effort = 90 + is_fabric = TRUE + loom_result = /obj/item/stack/sheet/silk merge_type = /obj/item/stack/sheet/cloth /obj/item/stack/sheet/cloth/Initialize(mapload, new_amount, merge = TRUE) @@ -281,6 +291,22 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ /obj/item/stack/sheet/cloth/ten amount = 10 +/obj/item/stack/sheet/cloth/thirty + amount = 30 + +/obj/item/stack/sheet/silk + name = "silk" + desc = "A long soft material. This one is just made out of cotton rather then any spiders or wyrms" + singular_name = "silk sheet" + icon_state = "sheet-silk" + item_state = "sheet-cloth" + novariants = TRUE + merge_type = /obj/item/stack/sheet/silk + +//obj/item/stack/sheet/silk/Initialize(mapload, new_amount, merge = TRUE) +// recipes = GLOB.silk_recipes +// return ..() + //Durathread fuck slash-asterisk comments GLOBAL_LIST_INIT(durathread_recipes, list ( \ new/datum/stack_recipe("durathread jumpsuit", /obj/item/clothing/under/durathread, 4, time = 40), @@ -649,6 +675,12 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra pull_effort = 30 loom_result = /obj/item/stack/sheet/cloth +/obj/item/stack/sheet/cotton/ten + amount = 10 + +/obj/item/stack/sheet/cotton/thirty + amount = 30 + /obj/item/stack/sheet/cotton/durathread name = "raw durathread bundle" desc = "A bundle of raw durathread ready to be spun on the loom." diff --git a/code/game/objects/items/storage/dakis.dm b/code/game/objects/items/storage/dakis.dm index 2703581a94..1939593c8e 100644 --- a/code/game/objects/items/storage/dakis.dm +++ b/code/game/objects/items/storage/dakis.dm @@ -7,7 +7,7 @@ desc = "A large pillow depicting a girl in a compromising position. Featuring as many dimensions as you." icon = 'icons/obj/daki.dmi' icon_state = "daki_base" - slot_flags = SLOT_BACK + slot_flags = ITEM_SLOT_BACK var/cooldowntime = 20 var/static/list/dakimakura_options = list("Callie","Casca","Chaika","Elisabeth","Foxy Grandpa","Haruko","Holo","Ian","Jolyne","Kurisu","Marie","Mugi","Nar'Sie","Patchouli","Plutia","Rei","Reisen","Naga","Squid","Squigly","Tomoko","Toriel","Umaru","Yaranaika","Yoko") //Kurisu is the ideal girl." - Me, Logos. diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 251703f907..ca7f7fe31a 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -288,7 +288,6 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons) generate_rubber_toolbox_icon() icon = GLOB.rubber_toolbox_icons[icon_state] AddComponent(/datum/component/bouncy) - . = ..() /obj/item/storage/toolbox/proc/generate_rubber_toolbox_icon() var/icon/new_icon = icon(icon, icon_state) diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 7a6899ad15..891a4689d0 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -68,6 +68,21 @@ /obj/item/storage/wallet/GetID() return front_id +/obj/item/storage/wallet/RemoveID() + if(!front_id) + return + . = front_id + front_id.forceMove(get_turf(src)) + +/obj/item/storage/wallet/InsertID(obj/item/inserting_item) + var/obj/item/card/inserting_id = inserting_item.RemoveID() + if(!inserting_id) + return FALSE + attackby(inserting_id) + if(inserting_id in contents) + return TRUE + return FALSE + /obj/item/storage/wallet/GetAccess() if(LAZYLEN(combined_access)) return combined_access diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index ee126971a7..47d9af2795 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -191,7 +191,7 @@ L.Knockdown(stunpwr) - L.adjustStaminaLoss(stunpwr*0.1, affected_zone = (istype(user) ? user.zone_selected : BODY_ZONE_CHEST))//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented. + L.adjustStaminaLoss(stunpwr*0.1)//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented. L.apply_effect(EFFECT_STUTTER, stunforce) SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK) if(user) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index e16b0dd690..e0e875b739 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -79,7 +79,7 @@ continue var/mob/living/M = W.imp_in if (M.stat == DEAD) - if (M.timeofdeath + 6000 < world.time) + if (M.timeofdeath + W.lifespan_postmortem < world.time) continue var/turf/tr = get_turf(M) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index de5a53fd9c..d78338d390 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1293,8 +1293,8 @@ var/toysound = 'sound/machines/click.ogg' /obj/item/toy/figure/New() - desc = "A \"Space Life\" brand [src]." - ..() + desc = "A \"Space Life\" brand [src]." + ..() /obj/item/toy/figure/attack_self(mob/user as mob) if(cooldown <= world.time) @@ -1517,3 +1517,18 @@ /obj/item/toy/dummy/GetVoice() return doll_name + +/obj/item/toy/seashell + name = "seashell" + desc = "May you always have a shell in your pocket and sand in your shoes. Whatever that's supposed to mean." + icon = 'icons/misc/beach.dmi' + icon_state = "shell1" + var/static/list/possible_colors = list("" = 2, COLOR_PURPLE_GRAY = 1, COLOR_OLIVE = 1, COLOR_PALE_BLUE_GRAY = 1, COLOR_RED_GRAY = 1) + +/obj/item/toy/seashell/Initialize() + . = ..() + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + icon_state = "shell[rand(1,3)]" + color = pickweight(possible_colors) + setDir(pick(GLOB.cardinals)) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 172120861b..b9b08802d0 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -44,7 +44,7 @@ update_icon() PopulateContents() if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents - take_contents() + addtimer(CALLBACK(src, .proc/take_contents), 0) if(secure) lockerelectronics = new(src) lockerelectronics.accesses = req_access diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index 9dab3679fa..dd72eb6b5d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -61,6 +61,11 @@ ..() for(var/i = 0, i < 4, i++) new /obj/item/reagent_containers/food/snacks/meat/slab/monkey(src) + +/obj/structure/closet/secure_closet/freezer/meat/open + req_access = null + locked = FALSE + /obj/structure/closet/secure_closet/freezer/fridge name = "refrigerator" @@ -73,6 +78,10 @@ for(var/i = 0, i < 2, i++) new /obj/item/storage/fancy/egg_box(src) +/obj/structure/closet/secure_closet/freezer/fridge/open + req_access = null + locked = FALSE + /obj/structure/closet/secure_closet/freezer/money name = "freezer" desc = "This contains cold hard cash." diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index 585f60a347..6ef6f2d5ce 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -26,7 +26,7 @@ if (prob(40)) new /obj/item/storage/toolbox/emergency(src) - switch (pickweight(list("small" = 40, "aid" = 25, "tank" = 20, "both" = 10, "nothing" = 4, "delete" = 1))) + switch (pickweight(list("small" = 40, "aid" = 25, "tank" = 20, "both" = 10, "nothing" = 5))) if ("small") new /obj/item/tank/internals/emergency_oxygen(src) new /obj/item/tank/internals/emergency_oxygen(src) @@ -49,9 +49,7 @@ if ("nothing") // doot - // teehee - if ("delete") - qdel(src) + return /* * Fire Closet diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm index baf0cf312f..736e58143e 100644 --- a/code/game/objects/structures/fluff.dm +++ b/code/game/objects/structures/fluff.dm @@ -182,3 +182,59 @@ icon_state = "snowlegion" anchored = TRUE deconstructible = FALSE + +/obj/structure/fluff/big_chain + name = "giant chain" + desc = "A towering link of chains leading up to the ceiling." + icon = 'icons/effects/32x96.dmi' + icon_state = "chain" + layer = ABOVE_OBJ_LAYER + anchored = TRUE + density = TRUE + deconstructible = FALSE + +/obj/structure/fluff/railing + name = "railing" + desc = "Basic railing meant to protect idiots like you from falling." + icon = 'icons/obj/fluff.dmi' + icon_state = "railing" + density = TRUE + anchored = TRUE + deconstructible = FALSE + +/obj/structure/fluff/railing/corner + icon_state = "railing_corner" + density = FALSE + +/obj/structure/fluff/beach_towel + name = "beach towel" + desc = "A towel decorated in various beach-themed designs." + icon = 'icons/obj/fluff.dmi' + icon_state = "railing" + density = FALSE + anchored = TRUE + deconstructible = FALSE + +/obj/structure/fluff/beach_umbrella + name = "beach umbrella" + desc = "A fancy umbrella designed to keep the sun off beach-goers." + icon = 'icons/obj/fluff.dmi' + icon_state = "brella" + density = FALSE + anchored = TRUE + deconstructible = FALSE + +/obj/structure/fluff/beach_umbrella/security + icon_state = "hos_brella" + +/obj/structure/fluff/beach_umbrella/science + icon_state = "rd_brella" + +/obj/structure/fluff/beach_umbrella/engine + icon_state = "ce_brella" + +/obj/structure/fluff/beach_umbrella/cap + icon_state = "cap_brella" + +/obj/structure/fluff/beach_umbrella/syndi + icon_state = "syndi_brella" diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index b820e93c7b..10f1f30e13 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -66,7 +66,7 @@ . = ..() var/area/A = get_area(src) if(A) - notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER) + notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER, ignore_dnr_observers = TRUE) /datum/outfit/ashwalker name ="Ashwalker" @@ -133,7 +133,7 @@ . = ..() var/area/A = get_area(src) if(!mapload && A) - notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM) + notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM, ignore_dnr_observers = TRUE) if(has_owner && creator) flavour_text = "You are a Golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \ Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost." @@ -372,7 +372,7 @@ flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell." var/area/A = get_area(src) if(!mapload && A) - notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE) + notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) objectives = "Be [owner.name]'s friend, and keep [owner.name] alive, so you don't get sent back to hell." spell = summoning_spell diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index d6f304653d..a6ba6424b1 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -100,6 +100,7 @@ number_of_rods = 2 smooth = SMOOTH_TRUE canSmoothWith = null + obj_flags = CAN_BE_HIT | BLOCK_Z_FALL /obj/structure/lattice/catwalk/deconstruction_hints(mob/user) to_chat(user, "The supporting rods look like they could be cut.") diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm index 0e2f951f38..36dbcc1e28 100644 --- a/code/game/objects/structures/musician.dm +++ b/code/game/objects/structures/musician.dm @@ -104,12 +104,12 @@ playing = FALSE hearing_mobs = null return - if(!lentext(note)) + if(!length(note)) continue var/cur_note = text2ascii(note) - 96 if(cur_note < 1 || cur_note > 7) continue - for(var/i=2 to lentext(note)) + for(var/i=2 to length(note)) var/ni = copytext(note,i,i+1) if(!text2num(ni)) if(ni == "#" || ni == "b" || ni == "n") @@ -209,7 +209,7 @@ lines.Cut(MUSIC_MAXLINES + 1) var/linenum = 1 for(var/l in lines) - if(lentext(l) > MUSIC_MAXLINECHARS) + if(length(l) > MUSIC_MAXLINECHARS) to_chat(usr, "Line [linenum] too long!") lines.Remove(l) else @@ -236,11 +236,11 @@ if(!in_range(instrumentObj, usr)) return - if(lentext(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS) + if(length(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS) var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") if(cont == "no") break - while(lentext(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS) + while(length(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS) ParseSong(t) else if(href_list["help"]) @@ -272,7 +272,7 @@ return if(lines.len > MUSIC_MAXLINES) return - if(lentext(newline) > MUSIC_MAXLINECHARS) + if(length(newline) > MUSIC_MAXLINECHARS) newline = copytext(newline, 1, MUSIC_MAXLINECHARS) lines.Add(newline) @@ -287,7 +287,7 @@ var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null) if(!content || !in_range(instrumentObj, usr)) return - if(lentext(content) > MUSIC_MAXLINECHARS) + if(length(content) > MUSIC_MAXLINECHARS) content = copytext(content, 1, MUSIC_MAXLINECHARS) if(num > lines.len || num < 1) return diff --git a/code/game/objects/structures/signs/signs_maps.dm b/code/game/objects/structures/signs/signs_maps.dm index f3188b90c2..1e3bfd6d36 100644 --- a/code/game/objects/structures/signs/signs_maps.dm +++ b/code/game/objects/structures/signs/signs_maps.dm @@ -50,7 +50,8 @@ name = "bar" desc = "A direction sign, pointing out which way the Bar is." icon_state = "direction_bar" - /obj/structure/sign/directions/cafe + +/obj/structure/sign/directions/cafe name = "cafe" desc = "A direction sign, pointing out which way the Cafe is." icon_state = "direction_cafe" diff --git a/code/game/objects/structures/stairs.dm b/code/game/objects/structures/stairs.dm new file mode 100644 index 0000000000..bd657fe1e8 --- /dev/null +++ b/code/game/objects/structures/stairs.dm @@ -0,0 +1,130 @@ +#define STAIR_TERMINATOR_AUTOMATIC 0 +#define STAIR_TERMINATOR_NO 1 +#define STAIR_TERMINATOR_YES 2 + +// dir determines the direction of travel to go upwards (due to lack of sprites, currently only 1 and 2 make sense) +// stairs require /turf/open/openspace as the tile above them to work +// multiple stair objects can be chained together; the Z level transition will happen on the final stair object in the chain + +/obj/structure/stairs + name = "stairs" + icon = 'icons/obj/stairs.dmi' + icon_state = "stairs" + anchored = TRUE + + var/force_open_above = FALSE // replaces the turf above this stair obj with /turf/open/openspace + var/terminator_mode = STAIR_TERMINATOR_AUTOMATIC + var/turf/listeningTo + +/obj/structure/stairs/Initialize(mapload) + if(force_open_above) + force_open_above() + build_signal_listener() + update_surrounding() + return ..() + +/obj/structure/stairs/Destroy() + listeningTo = null + return ..() + +/obj/structure/stairs/Move() //Look this should never happen but... + . = ..() + if(force_open_above) + build_signal_listener() + update_surrounding() + +/obj/structure/stairs/proc/update_surrounding() + update_icon() + for(var/i in GLOB.cardinals) + var/turf/T = get_step(get_turf(src), i) + var/obj/structure/stairs/S = locate() in T + if(S) + S.update_icon() + +/obj/structure/stairs/Uncross(atom/movable/AM, turf/newloc) + if(!newloc || !AM) + return ..() + if(!isobserver(AM) && isTerminator() && (get_dir(src, newloc) == dir)) + stair_ascend(AM) + return FALSE + return ..() + +/obj/structure/stairs/Cross(atom/movable/AM) + if(isTerminator() && (get_dir(src, AM) == dir)) + return FALSE + return ..() + +/obj/structure/stairs/update_icon() + if(isTerminator()) + icon_state = "stairs_t" + else + icon_state = "stairs" + +/obj/structure/stairs/proc/stair_ascend(atom/movable/AM) + var/turf/checking = get_step_multiz(get_turf(src), UP) + if(!istype(checking)) + return + if(!checking.zPassIn(AM, UP, get_turf(src))) + return + var/turf/target = get_step_multiz(get_turf(src), (dir|UP)) + if(istype(target) && !target.can_zFall(AM, null, get_step_multiz(target, DOWN))) //Don't throw them into a tile that will just dump them back down. + if(isliving(AM)) + var/mob/living/L = AM + var/pulling = L.pulling + if(pulling) + L.pulling.forceMove(target) + L.forceMove(target) + L.start_pulling(pulling) + else + AM.forceMove(target) + +/obj/structure/stairs/vv_edit_var(var_name, var_value) + . = ..() + if(!.) + return + if(var_name != NAMEOF(src, force_open_above)) + return + if(!var_value) + if(listeningTo) + UnregisterSignal(listeningTo, COMSIG_TURF_MULTIZ_NEW) + listeningTo = null + else + build_signal_listener() + force_open_above() + +/obj/structure/stairs/proc/build_signal_listener() + if(listeningTo) + UnregisterSignal(listeningTo, COMSIG_TURF_MULTIZ_NEW) + var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP) + RegisterSignal(T, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_new) + listeningTo = T + +/obj/structure/stairs/proc/force_open_above() + var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP) + if(T && !istype(T)) + T.ChangeTurf(/turf/open/openspace) + +/obj/structure/stairs/proc/on_multiz_new(turf/source, dir) + if(dir == UP) + var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP) + if(T && !istype(T)) + T.ChangeTurf(/turf/open/openspace) + +/obj/structure/stairs/intercept_zImpact(atom/movable/AM, levels = 1) + . = ..() + if(isTerminator()) + . |= FALL_INTERCEPTED | FALL_NO_MESSAGE + +/obj/structure/stairs/proc/isTerminator() //If this is the last stair in a chain and should move mobs up + if(terminator_mode != STAIR_TERMINATOR_AUTOMATIC) + return (terminator_mode == STAIR_TERMINATOR_YES) + var/turf/T = get_turf(src) + if(!T) + return FALSE + var/turf/them = get_step(T, dir) + if(!them) + return FALSE + for(var/obj/structure/stairs/S in them) + if(S.dir == dir) + return FALSE + return TRUE diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index f1c5080c8f..6a055bbd35 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -15,7 +15,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( if(turf_type) var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags) SSair.remove_from_active(newT) - newT.CalculateAdjacentTurfs() + CALCULATE_ADJACENT_TURFS(newT) SSair.add_to_active(newT,1) /turf/proc/copyTurf(turf/T) @@ -140,6 +140,8 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( newTurf.air = stashed_air SSair.add_to_active(newTurf) else + if(ispath(path,/turf/closed)) + flags |= CHANGETURF_RECALC_ADJACENT return ..() // Take off the top layer turf and replace it with the next baseturf down @@ -263,7 +265,10 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( //If you modify this function, ensure it works correctly with lateloaded map templates. /turf/proc/AfterChange(flags) //called after a turf has been replaced in ChangeTurf() levelupdate() - CalculateAdjacentTurfs() + if(flags & CHANGETURF_RECALC_ADJACENT) + ImmediateCalculateAdjacentTurfs() + else + CALCULATE_ADJACENT_TURFS(src) //update firedoor adjacency var/list/turfs_to_check = get_adjacent_open_turfs(src) | src diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index bd24e0ff93..efee9cfa5a 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -16,6 +16,22 @@ if(wet) AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE) +//direction is direction of travel of A +/turf/open/zPassIn(atom/movable/A, direction, turf/source) + return (direction == DOWN) + +//direction is direction of travel of A +/turf/open/zPassOut(atom/movable/A, direction, turf/destination) + return (direction == UP) + +//direction is direction of travel of air +/turf/open/zAirIn(direction, turf/source) + return (direction == DOWN) + +//direction is direction of travel of air +/turf/open/zAirOut(direction, turf/source) + return (direction == UP) + /turf/open/MouseDrop_T(atom/dropping, mob/user) . = ..() if(dropping == user && isliving(user)) @@ -184,43 +200,14 @@ update_visuals() current_cycle = times_fired - - //cache some vars - var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs - - for(var/direction in GLOB.cardinals) - var/turf/open/enemy_tile = get_step(src, direction) - if(!istype(enemy_tile)) - if (atmos_adjacent_turfs) - atmos_adjacent_turfs -= enemy_tile - continue + ImmediateCalculateAdjacentTurfs() + for(var/i in atmos_adjacent_turfs) + var/turf/open/enemy_tile = i var/datum/gas_mixture/enemy_air = enemy_tile.return_air() - - //only check this turf, if it didn't check us when it was initalized - if(enemy_tile.current_cycle < times_fired) - if(CANATMOSPASS(src, enemy_tile)) - LAZYINITLIST(atmos_adjacent_turfs) - LAZYINITLIST(enemy_tile.atmos_adjacent_turfs) - atmos_adjacent_turfs[enemy_tile] = TRUE - enemy_tile.atmos_adjacent_turfs[src] = TRUE - else - if (atmos_adjacent_turfs) - atmos_adjacent_turfs -= enemy_tile - if (enemy_tile.atmos_adjacent_turfs) - enemy_tile.atmos_adjacent_turfs -= src - UNSETEMPTY(enemy_tile.atmos_adjacent_turfs) - continue - else - if (!atmos_adjacent_turfs || !atmos_adjacent_turfs[enemy_tile]) - continue - if(!excited && air.compare(enemy_air)) //testing("Active turf found. Return value of compare(): [is_active]") excited = TRUE SSair.active_turfs |= src - UNSETEMPTY(atmos_adjacent_turfs) - if (atmos_adjacent_turfs) - src.atmos_adjacent_turfs = atmos_adjacent_turfs /turf/open/proc/GetHeatCapacity() . = air.heat_capacity() @@ -267,14 +254,15 @@ if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube. return 0 else - if(C.lying || !(C.status_flags & CANKNOCKDOWN)) // can't slip unbuckled mob if they're lying or can't fall. + if(!(lube&SLIP_WHEN_CRAWLING) && (C.lying || !(C.status_flags & CANKNOCKDOWN))) // can't slip unbuckled mob if they're lying or can't fall. return 0 - if(C.m_intent == MOVE_INTENT_WALK && (lube&NO_SLIP_WHEN_WALKING)) - return 0 - if(ishuman(C) && (lube&NO_SLIP_WHEN_WALKING)) - var/mob/living/carbon/human/H = C - if(!H.sprinting && H.getStaminaLoss() <= 20) + if(lube & NO_SLIP_WHEN_WALKING) + if(C.m_intent == MOVE_INTENT_WALK) return 0 + if(ishuman(C) && !(lube & SLIP_WHEN_JOGGING)) + var/mob/living/carbon/human/H = C + if(!H.sprinting && H.getStaminaLoss() <= 20) + return 0 if(!(lube&SLIDE_ICE)) to_chat(C, "You slipped[ O ? " on the [O.name]" : ""]!") playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3) diff --git a/code/game/turfs/openspace/openspace.dm b/code/game/turfs/openspace/openspace.dm new file mode 100644 index 0000000000..e68aabcd08 --- /dev/null +++ b/code/game/turfs/openspace/openspace.dm @@ -0,0 +1,134 @@ +/turf/open/openspace + name = "open space" + desc = "Watch your step!" + icon_state = "grey" + baseturfs = /turf/open/openspace + CanAtmosPassVertical = ATMOS_PASS_YES + //mouse_opacity = MOUSE_OPACITY_TRANSPARENT + var/can_cover_up = TRUE + var/can_build_on = TRUE + +/turf/open/openspace/debug/update_multiz() + ..() + return TRUE + +/turf/open/openspace/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker + . = ..() + plane = FLOOR_OPENSPACE_PLANE + layer = OPENSPACE_LAYER + return INITIALIZE_HINT_LATELOAD + +/turf/open/openspace/LateInitialize() + update_multiz(TRUE, TRUE) + +/turf/open/openspace/Destroy() + vis_contents.len = 0 + return ..() + +/turf/open/openspace/update_multiz(prune_on_fail = FALSE, init = FALSE) + . = ..() + var/turf/T = below() + if(!T) + vis_contents.len = 0 + if(prune_on_fail) + ChangeTurf(/turf/open/floor/plating) + return FALSE + if(init) + vis_contents += T + return TRUE + +/turf/open/openspace/multiz_turf_del(turf/T, dir) + if(dir != DOWN) + return + update_multiz() + +/turf/open/openspace/multiz_turf_new(turf/T, dir) + if(dir != DOWN) + return + update_multiz() + +/turf/open/openspace/zAirIn() + return TRUE + +/turf/open/openspace/zAirOut() + return TRUE + +/turf/open/openspace/zPassIn(atom/movable/A, direction, turf/source) + return TRUE + +/turf/open/openspace/zPassOut(atom/movable/A, direction, turf/destination) + if(A.anchored) + return FALSE + for(var/obj/O in contents) + if(O.obj_flags & BLOCK_Z_FALL) + return FALSE + return TRUE + +/turf/open/openspace/proc/CanCoverUp() + return can_cover_up + +/turf/open/openspace/proc/CanBuildHere() + return can_build_on + +/turf/open/openspace/attackby(obj/item/C, mob/user, params) + ..() + if(!CanBuildHere()) + return + if(istype(C, /obj/item/stack/rods)) + var/obj/item/stack/rods/R = C + var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) + var/obj/structure/lattice/catwalk/W = locate(/obj/structure/lattice/catwalk, src) + if(W) + to_chat(user, "There is already a catwalk here!") + return + if(L) + if(R.use(1)) + to_chat(user, "You construct a catwalk.") + playsound(src, 'sound/weapons/genhit.ogg', 50, 1) + new/obj/structure/lattice/catwalk(src) + else + to_chat(user, "You need two rods to build a catwalk!") + return + if(R.use(1)) + to_chat(user, "You construct a lattice.") + playsound(src, 'sound/weapons/genhit.ogg', 50, 1) + ReplaceWithLattice() + else + to_chat(user, "You need one rod to build a lattice.") + return + if(istype(C, /obj/item/stack/tile/plasteel)) + if(!CanCoverUp()) + return + var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) + if(L) + var/obj/item/stack/tile/plasteel/S = C + if(S.use(1)) + qdel(L) + playsound(src, 'sound/weapons/genhit.ogg', 50, 1) + to_chat(user, "You build a floor.") + PlaceOnTop(/turf/open/floor/plating) + else + to_chat(user, "You need one floor tile to build a floor!") + else + to_chat(user, "The plating is going to need some support! Place metal rods first.") + +/turf/open/openspace/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if(!CanBuildHere()) + return FALSE + + switch(the_rcd.mode) + if(RCD_FLOORWALL) + var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) + if(L) + return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1) + else + return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3) + return FALSE + +/turf/open/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_FLOORWALL) + to_chat(user, "You build a floor.") + PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + return TRUE + return FALSE diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 036f54c710..191d9b0242 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -144,5 +144,5 @@ ..() ScrapeAway() -/turf/open/floor/plating/foam/tool_act(mob/living/user, obj/tool/I, tool_type) +/turf/open/floor/plating/foam/tool_act(mob/living/user, obj/item/I, tool_type) return diff --git a/code/game/turfs/simulated/wall/reinf_walls.dm b/code/game/turfs/simulated/wall/reinf_walls.dm index d52a3bcc23..0d9bff1bdf 100644 --- a/code/game/turfs/simulated/wall/reinf_walls.dm +++ b/code/game/turfs/simulated/wall/reinf_walls.dm @@ -227,3 +227,29 @@ /turf/closed/wall/r_wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) if(the_rcd.canRturf) return ..() + +/turf/closed/wall/r_wall/syndicate + name = "hull" + desc = "The armored hull of an ominous looking ship." + icon = 'icons/turf/walls/plastitanium_wall.dmi' + icon_state = "map-shuttle" + explosion_block = 20 + sheet_type = /obj/item/stack/sheet/mineral/plastitanium + smooth = SMOOTH_MORE|SMOOTH_DIAGONAL + canSmoothWith = list(/turf/closed/wall/r_wall/syndicate, /turf/closed/wall/mineral/plastitanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/plastitanium, /obj/structure/shuttle/engine, /obj/structure/falsewall/plastitanium) + +/turf/closed/wall/r_wall/syndicate/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + return FALSE + +/turf/closed/wall/r_wall/syndicate/nodiagonal + smooth = SMOOTH_MORE + icon_state = "map-shuttle_nd" + +/turf/closed/wall/r_wall/syndicate/nosmooth + icon = 'icons/turf/shuttle.dmi' + icon_state = "wall" + smooth = SMOOTH_FALSE + +/turf/closed/wall/r_wall/syndicate/overspace + icon_state = "map-overspace" + fixed_underlay = list("space"=1) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 9ebe8f3c19..a5931abf9d 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -12,7 +12,7 @@ var/destination_x var/destination_y - var/global/datum/gas_mixture/immutable/space/space_gas = new + var/static/datum/gas_mixture/immutable/space/space_gas = new plane = PLANE_SPACE layer = SPACE_LAYER light_power = 0.25 diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index ebf6f6626c..d618e457b0 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -39,7 +39,7 @@ return FALSE . = ..() -/turf/Initialize() +/turf/Initialize(mapload) if(flags_1 & INITIALIZED_1) stack_trace("Warning: [src]([type]) initialized multiple times!") flags_1 |= INITIALIZED_1 @@ -62,12 +62,21 @@ add_overlay(/obj/effect/fullbright) if(requires_activation) - CalculateAdjacentTurfs() + CALCULATE_ADJACENT_TURFS(src) SSair.add_to_active(src) if (light_power && light_range) update_light() + var/turf/T = SSmapping.get_turf_above(src) + if(T) + T.multiz_turf_new(src, DOWN) + SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, DOWN) + T = SSmapping.get_turf_below(src) + if(T) + T.multiz_turf_new(src, UP) + SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, UP) + if (opacity) has_opaque_atom = TRUE @@ -76,13 +85,19 @@ return INITIALIZE_HINT_NORMAL /turf/proc/Initalize_Atmos(times_fired) - CalculateAdjacentTurfs() + CALCULATE_ADJACENT_TURFS(src) /turf/Destroy(force) . = QDEL_HINT_IWILLGC if(!changing_turf) stack_trace("Incorrect turf deletion") changing_turf = FALSE + var/turf/T = SSmapping.get_turf_above(src) + if(T) + T.multiz_turf_del(src, DOWN) + T = SSmapping.get_turf_below(src) + if(T) + T.multiz_turf_del(src, UP) if(force) ..() //this will completely wipe turf state @@ -105,6 +120,60 @@ return user.Move_Pulled(src) +/turf/proc/multiz_turf_del(turf/T, dir) + +/turf/proc/multiz_turf_new(turf/T, dir) + +//zPassIn doesn't necessarily pass an atom! +//direction is direction of travel of air +/turf/proc/zPassIn(atom/movable/A, direction, turf/source) + return FALSE + +//direction is direction of travel of air +/turf/proc/zPassOut(atom/movable/A, direction, turf/destination) + return FALSE + +//direction is direction of travel of air +/turf/proc/zAirIn(direction, turf/source) + return FALSE + +//direction is direction of travel of air +/turf/proc/zAirOut(direction, turf/source) + return FALSE + +/turf/proc/zImpact(atom/movable/A, levels = 1, turf/prev_turf) + var/flags = NONE + var/mov_name = A.name + for(var/i in contents) + var/atom/thing = i + flags |= thing.intercept_zImpact(A, levels) + if(flags & FALL_STOP_INTERCEPTING) + break + if(prev_turf && !(flags & FALL_NO_MESSAGE)) + prev_turf.visible_message("[mov_name] falls through [prev_turf]!") + if(flags & FALL_INTERCEPTED) + return + if(zFall(A, ++levels)) + return FALSE + A.visible_message("[A] crashes into [src]!") + A.onZImpact(src, levels) + return TRUE + +/turf/proc/can_zFall(atom/movable/A, levels = 1, turf/target) + return zPassOut(A, DOWN, target) && target.zPassIn(A, DOWN, src) + +/turf/proc/zFall(atom/movable/A, levels = 1, force = FALSE) + var/turf/target = get_step_multiz(src, DOWN) + if(!target || (!isobj(A) && !ismob(A))) + return FALSE + if(!force && (!can_zFall(A, levels, target) || !A.can_zFall(src, levels, target, DOWN))) + return FALSE + A.zfalling = TRUE + A.forceMove(target) + A.zfalling = FALSE + target.zImpact(A, levels, src) + return TRUE + /turf/proc/handleRCL(obj/item/twohanded/rcl/C, mob/user) if(C.loaded) for(var/obj/structure/cable/LC in src) @@ -196,6 +265,9 @@ if(O.obj_flags & FROZEN) O.make_unfrozen() + if(!AM.zfalling) + zFall(AM) + /turf/proc/is_plasteel_floor() return FALSE diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 7fafca69f0..87db105072 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -686,6 +686,20 @@ log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/toggledynamicvote() + set category = "Server" + set desc="Switches between secret/extended and dynamic voting" + set name="Toggle Dynamic Vote" + var/prev_dynamic_voting = CONFIG_GET(flag/dynamic_voting) + CONFIG_SET(flag/dynamic_voting,!prev_dynamic_voting) + if (!prev_dynamic_voting) + to_chat(world, "Vote is now between extended and dynamic chaos.") + else + to_chat(world, "Vote is now between extended and secret.") + log_admin("[key_name(usr)] [prev_dynamic_voting ? "disabled" : "enabled"] dynamic voting.") + message_admins("[key_name_admin(usr)] toggled dynamic voting.") + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dynamic Voting", "[prev_dynamic_voting ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /datum/admins/proc/unprison(mob/M in GLOB.mob_list) set category = "Admin" set name = "Unprison" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 626fa7f66f..5900847ef5 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1,7 +1,7 @@ //admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless //the procs are cause you can't put the comments in the GLOB var define -GLOBAL_PROTECT(admin_verbs_default) GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault()) +GLOBAL_PROTECT(admin_verbs_default) /world/proc/AVerbsDefault() return list( /client/proc/deadmin, /*destroys our own admin datum so we can play as a regular player*/ @@ -13,8 +13,8 @@ GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault()) /client/proc/toggleprayers, /client/proc/toggleadminhelpsound ) -GLOBAL_PROTECT(admin_verbs_admin) GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) +GLOBAL_PROTECT(admin_verbs_admin) /world/proc/AVerbsAdmin() return list( /client/proc/invisimin, /*allows our mob to go invisible/visible*/ @@ -78,11 +78,10 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) /client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/ /datum/admins/proc/open_borgopanel ) -GLOBAL_PROTECT(admin_verbs_ban) GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/DB_ban_panel, /client/proc/stickybanpanel)) -GLOBAL_PROTECT(admin_verbs_sounds) +GLOBAL_PROTECT(admin_verbs_ban) GLOBAL_LIST_INIT(admin_verbs_sounds, list(/client/proc/play_local_sound, /client/proc/play_sound, /client/proc/set_round_end_sound)) -GLOBAL_PROTECT(admin_verbs_fun) +GLOBAL_PROTECT(admin_verbs_sounds) GLOBAL_LIST_INIT(admin_verbs_fun, list( /client/proc/cmd_admin_dress, /client/proc/cmd_admin_gib_self, @@ -108,9 +107,9 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list( /client/proc/admin_away, /client/proc/roll_dices //CIT CHANGE - Adds dice verb )) -GLOBAL_PROTECT(admin_verbs_spawn) +GLOBAL_PROTECT(admin_verbs_fun) GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character)) -GLOBAL_PROTECT(admin_verbs_server) +GLOBAL_PROTECT(admin_verbs_spawn) GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) /world/proc/AVerbsServer() return list( @@ -122,6 +121,7 @@ GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) /client/proc/everyone_random, /datum/admins/proc/toggleAI, /datum/admins/proc/toggleMulticam, + /datum/admins/proc/toggledynamicvote, /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_debug_del_all, /client/proc/toggle_random_events, @@ -129,7 +129,7 @@ GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) /client/proc/adminchangemap, /client/proc/toggle_hub ) -GLOBAL_PROTECT(admin_verbs_debug) +GLOBAL_PROTECT(admin_verbs_server) GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug()) /world/proc/AVerbsDebug() return list( @@ -171,15 +171,15 @@ GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug()) /datum/admins/proc/create_or_modify_area, /client/proc/generate_wikichem_list //DO NOT PRESS UNLESS YOU WANT SUPERLAG ) -GLOBAL_PROTECT(admin_verbs_possess) +GLOBAL_PROTECT(admin_verbs_debug) GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release)) -GLOBAL_PROTECT(admin_verbs_permissions) +GLOBAL_PROTECT(admin_verbs_possess) GLOBAL_LIST_INIT(admin_verbs_permissions, list(/client/proc/edit_admin_permissions)) -GLOBAL_PROTECT(admin_verbs_poll) +GLOBAL_PROTECT(admin_verbs_permissions) GLOBAL_LIST_INIT(admin_verbs_poll, list(/client/proc/create_poll)) //verbs which can be hidden - needs work -GLOBAL_PROTECT(admin_verbs_hideable) +GLOBAL_PROTECT(admin_verbs_poll) GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/set_ooc, /client/proc/reset_ooc, @@ -247,6 +247,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/cmd_admin_man_up, //CIT CHANGE - adds man up verb /client/proc/cmd_admin_man_up_global //CIT CHANGE - ditto )) +GLOBAL_PROTECT(admin_verbs_hideable) /client/proc/add_admin_verbs() if(holder) diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 72ec3da8f9..7b59e72403 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -504,7 +504,7 @@ output += ruler var/datum/browser/browser = new(usr, "Note panel", "Manage player notes", 1000, 500) var/datum/asset/notes_assets = get_asset_datum(/datum/asset/simple/notes) - notes_assets.send(src) + notes_assets.send(usr.client) browser.set_content(jointext(output, "")) browser.open() @@ -556,7 +556,7 @@ /proc/convert_notes_sql(ckey) if(!fexists(NOTESFILE)) return - + var/savefile/notesfile = new(NOTESFILE) if(!notesfile) log_game("Error: Cannot access [NOTESFILE]") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b0b9190556..4de2d9b5ca 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1347,7 +1347,7 @@ else if(href_list["f_secret"]) return HandleFSecret() - + else if(href_list["f_dynamic_roundstart"]) if(!check_rights(R_ADMIN)) return @@ -1449,9 +1449,7 @@ if(GLOB.master_mode != "dynamic") return alert(usr, "The game mode has to be dynamic mode!", null, null, null, null) - var/new_centre = input(usr,"Change the centre of the dynamic mode threat curve. A negative value will give a more peaceful round ; a positive value, a round with higher threat. Any number between -5 and +5 is allowed.", "Change curve centre", null) as num - if (new_centre < -5 || new_centre > 5) - return alert(usr, "Only values between -5 and +5 are allowed.", null, null, null, null) + var/new_centre = input(usr,"Change the centre of the dynamic mode threat curve. A negative value will give a more peaceful round ; a positive value, a round with higher threat. Any number is allowed. This is adjusted by dynamic voting.", "Change curve centre", null) as num log_admin("[key_name(usr)] changed the distribution curve center to [new_centre].") message_admins("[key_name(usr)] changed the distribution curve center to [new_centre]", 1) @@ -1593,7 +1591,7 @@ GLOB.dynamic_stacking_limit = input(usr,"Change the threat limit at which round-endings rulesets will start to stack.", "Change stacking limit", null) as num log_admin("[key_name(usr)] set 'stacking_limit' to [GLOB.dynamic_stacking_limit].") message_admins("[key_name(usr)] set 'stacking_limit' to [GLOB.dynamic_stacking_limit].") - dynamic_mode_options(usr) + dynamic_mode_options(usr) else if(href_list["f_dynamic_high_pop_limit"]) if(!check_rights(R_ADMIN)) @@ -1612,7 +1610,7 @@ log_admin("[key_name(usr)] set 'high_pop_limit' to [GLOB.dynamic_high_pop_limit].") message_admins("[key_name(usr)] set 'high_pop_limit' to [GLOB.dynamic_high_pop_limit].") - dynamic_mode_options(usr) + dynamic_mode_options(usr) else if(href_list["f_dynamic_forced_threat"]) if(!check_rights(R_ADMIN)) @@ -1631,7 +1629,7 @@ log_admin("[key_name(usr)] set 'forced_threat_level' to [GLOB.dynamic_forced_threat_level].") message_admins("[key_name(usr)] set 'forced_threat_level' to [GLOB.dynamic_forced_threat_level].") - dynamic_mode_options(usr) + dynamic_mode_options(usr) else if(href_list["c_mode2"]) if(!check_rights(R_ADMIN|R_SERVER)) @@ -2442,7 +2440,7 @@ return src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "") while (findtext(src.admincaster_feed_channel.channel_name," ") == 1) - src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) + src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,length(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) @@ -2484,7 +2482,7 @@ return src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", "")) while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1) + src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,length(src.admincaster_feed_message.returnBody(-1))+1) src.access_news_network() else if(href_list["ac_submit_new_message"]) @@ -2545,7 +2543,7 @@ return src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", "")) while(findtext(src.admincaster_wanted_message.criminal," ") == 1) - src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1) + src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,length(admincaster_wanted_message.criminal)+1) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) @@ -2553,7 +2551,7 @@ return src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", "")) while (findtext(src.admincaster_wanted_message.body," ") == 1) - src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1) + src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,length(src.admincaster_wanted_message.body)+1) src.access_news_network() else if(href_list["ac_submit_wanted"]) diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index b19b2a91d8..072fbaa123 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -61,7 +61,7 @@ var/output = "Radio Report