diff --git a/baystation12.dme b/baystation12.dme index 8d6c8531830..3dfee0ae2da 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1868,10 +1868,11 @@ #include "code\modules\wireless\interfaces.dm" #include "code\modules\xgm\xgm_gas_data.dm" #include "code\modules\xgm\xgm_gas_mixture.dm" +#include "code\unit_tests\equipment_tests.dm" #include "code\unit_tests\mob_tests.dm" #include "code\unit_tests\unit_test.dm" #include "code\unit_tests\zas_tests.dm" -#include "code\unit_tests\equipment_tests.dm" +#include "code\unit_tests\map_tests.dm" #include "code\ZAS\_docs.dm" #include "code\ZAS\Airflow.dm" #include "code\ZAS\Atom.dm" diff --git a/code/controllers/Processes/scheduler.dm b/code/controllers/Processes/scheduler.dm index aaccf2f00f1..387be2c678c 100644 --- a/code/controllers/Processes/scheduler.dm +++ b/code/controllers/Processes/scheduler.dm @@ -18,7 +18,9 @@ try if(world.time > scheduled_task.trigger_time) unschedule(scheduled_task) + scheduled_task.pre_process() scheduled_task.process() + scheduled_task.post_process() catch(var/exception/e) catchException(e, last_object) SCHECK @@ -40,26 +42,30 @@ * Helpers * **********/ /proc/schedule_task_in(var/in_time, var/procedure, var/list/arguments = list()) - schedule_task(world.time + in_time, procedure, arguments) + return schedule_task(world.time + in_time, procedure, arguments) /proc/schedule_task_with_source_in(var/in_time, var/source, var/procedure, var/list/arguments = list()) - schedule_task_with_source(world.time + in_time, source, procedure, arguments) + return schedule_task_with_source(world.time + in_time, source, procedure, arguments) /proc/schedule_task(var/trigger_time, var/procedure, var/list/arguments) var/datum/scheduled_task/st = new/datum/scheduled_task(trigger_time, procedure, arguments, /proc/destroy_scheduled_task, list()) scheduler.schedule(st) + return st /proc/schedule_task_with_source(var/trigger_time, var/source, var/procedure, var/list/arguments) var/datum/scheduled_task/st = new/datum/scheduled_task/source(trigger_time, source, procedure, arguments, /proc/destroy_scheduled_task, list()) scheduler.schedule(st) + return st /proc/schedule_repeating_task(var/trigger_time, var/repeat_interval, var/procedure, var/list/arguments) var/datum/scheduled_task/st = new/datum/scheduled_task(trigger_time, procedure, arguments, /proc/repeat_scheduled_task, list(repeat_interval)) scheduler.schedule(st) + return st /proc/schedule_repeating_task_with_source(var/trigger_time, var/repeat_interval, var/source, var/procedure, var/list/arguments) var/datum/scheduled_task/st = new/datum/scheduled_task/source(trigger_time, source, procedure, arguments, /proc/repeat_scheduled_task, list(repeat_interval)) scheduler.schedule(st) + return st /************* * Task Datum * @@ -70,6 +76,7 @@ var/list/arguments var/task_after_process var/list/task_after_process_args + var/datum/observ/triggered /datum/scheduled_task/New(var/trigger_time, var/procedure, var/list/arguments, var/proc/task_after_process, var/list/task_after_process_args) ..() @@ -87,13 +94,31 @@ task_after_process_args.Cut() return ..() -/datum/scheduled_task/proc/process() - call(procedure)(arglist(arguments)) - after_process() +/datum/scheduled_task/init_observers() + . = ..() + if(.) + triggered = new() -/datum/scheduled_task/proc/after_process() +/datum/scheduled_task/destroy_observers() + . = ..() + if(.) + qdel(triggered) + triggered = null + +/datum/scheduled_task/proc/pre_process() + triggered.raise_event(list(src)) + +/datum/scheduled_task/proc/process() + if(procedure) + call(procedure)(arglist(arguments)) + +/datum/scheduled_task/proc/post_process() call(task_after_process)(arglist(task_after_process_args)) +// Resets the trigger time, has no effect if the task has already triggered +/datum/scheduled_task/proc/trigger_task_in(var/trigger_in) + src.trigger_time = world.time + trigger_in + /datum/scheduled_task/source var/datum/source @@ -108,7 +133,6 @@ /datum/scheduled_task/source/process() call(source, procedure)(arglist(arguments)) - after_process() /datum/scheduled_task/source/proc/source_destroyed() qdel(src) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 91bf3ff1a7f..43bc5db188f 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -219,6 +219,7 @@ var/list/gamemode_cache = list() var/list/language_prefixes = list(",","#","-")//Default language prefixes var/ghosts_can_possess_animals = 0 + var/delist_when_no_admins = FALSE /datum/configuration/New() var/list/L = typesof(/datum/game_mode) - /datum/game_mode @@ -707,6 +708,9 @@ var/list/gamemode_cache = list() if ("lobby_screens") config.lobby_screens = text2list(value, ";") + if("delist_when_no_admins") + config.delist_when_no_admins = TRUE + else log_misc("Unknown setting in configuration: '[name]'") diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index aa13f07510a..10e620beed9 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -48,7 +48,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle if (evac) emergency_shuttle_docked.Announce("The Emergency Shuttle has docked with the station. You have approximately [round(estimate_launch_time()/60,1)] minutes to board the Emergency Shuttle.") else - priority_announcement.Announce("The scheduled Crew Transfer Shuttle has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.") + priority_announcement.Announce("The scheduled Crew Transfer Shuttle to [dock_name] has docked with the station. It will depart in approximately [round(emergency_shuttle.estimate_launch_time()/60,1)] minutes.") //arm the escape pods if (evac) @@ -94,7 +94,7 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle //reset the shuttle transit time if we need to shuttle.move_time = SHUTTLE_TRANSIT_DURATION - priority_announcement.Announce("A crew transfer has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") + priority_announcement.Announce("A crew transfer to [dock_name] has been scheduled. The shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.") //recalls the shuttle /datum/emergency_shuttle_controller/proc/recall() diff --git a/code/datums/observation/observation.dm b/code/datums/observation/observation.dm index 267afcd6707..eefbcb1fc22 100644 --- a/code/datums/observation/observation.dm +++ b/code/datums/observation/observation.dm @@ -44,6 +44,7 @@ /datum/proc/init_observers() destruction = new() + return TRUE /datum/proc/destroy_observers() if(!destruction) @@ -56,8 +57,8 @@ // This ensures that observer handlers don't create their own observer handlers, which create their own handlers, which create... /datum/observ/init_observers() - return + return FALSE // And this ensures that observer handlers don't attempt to notify others about their own death while being unable to. /datum/observ/destroy_observers() - return + return FALSE diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm index df85773fb2e..b8ecb7f60b9 100644 --- a/code/game/objects/effects/decals/contraband.dm +++ b/code/game/objects/effects/decals/contraband.dm @@ -33,7 +33,7 @@ if (!iswall(W) || !isturf(user.loc)) user << "You can't place this here!" return - + var/placement_dir = get_dir(user, W) if (!(placement_dir in cardinal)) user << "You must stand directly in front of the wall you wish to place that on." @@ -43,7 +43,7 @@ var/stuff_on_wall = 0 if (locate(/obj/structure/sign/poster) in W) stuff_on_wall = 1 - + //crude, but will cover most cases. We could do stuff like check pixel_x/y but it's not really worth it. for (var/dir in cardinal) var/turf/T = get_step(W, dir) @@ -61,7 +61,7 @@ flick("poster_being_set", P) //playsound(W, 'sound/items/poster_being_created.ogg', 100, 1) //why the hell does placing a poster make printer sounds? - + var/oldsrc = src //get a reference to src so we can delete it after detaching ourselves src = null spawn(17) @@ -71,7 +71,7 @@ user << "You place the poster!" else P.roll_and_drop(P.loc) - + qdel(oldsrc) //delete it now to cut down on sanity checks afterwards. Agouri's code supports rerolling it anyway //############################## THE ACTUAL DECALS ########################### @@ -90,11 +90,11 @@ if(!serial) serial = rand(1, poster_designs.len) //use a random serial if none is given - + serial_number = serial var/datum/poster/design = poster_designs[serial_number] set_poster(design) - + switch (placement_dir) if (NORTH) pixel_x = 0 @@ -133,23 +133,23 @@ /obj/structure/sign/poster/attack_hand(mob/user as mob) + if(ruined) return - var/temp_loc = user.loc - switch(alert("Do I want to rip the poster from the wall?","You think...","Yes","No")) - if("Yes") - if(user.loc != temp_loc) - return - visible_message("[user] rips [src] in a single, decisive motion!" ) - playsound(src.loc, 'sound/items/poster_ripped.ogg', 100, 1) - ruined = 1 - icon_state = "poster_ripped" - name = "ripped poster" - desc = "You can't make out anything from the poster's original print. It's ruined." - add_fingerprint(user) - if("No") + + if(alert("Do I want to rip the poster from the wall?","You think...","Yes","No") == "Yes") + + if(ruined || !user.Adjacent(src)) return + visible_message("\The [user] rips \the [src] in a single, decisive motion!" ) + playsound(src.loc, 'sound/items/poster_ripped.ogg', 100, 1) + ruined = 1 + icon_state = "poster_ripped" + name = "ripped poster" + desc = "You can't make out anything from the poster's original print. It's ruined." + add_fingerprint(user) + /obj/structure/sign/poster/proc/roll_and_drop(turf/newloc) var/obj/item/weapon/contraband/poster/P = new(src, serial_number) P.loc = newloc diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm index 4b605c10329..a1362ac8446 100644 --- a/code/game/objects/items/weapons/material/kitchen.dm +++ b/code/game/objects/items/weapons/material/kitchen.dm @@ -14,6 +14,7 @@ force_divisor = 0.1 // 6 when wielded with hardness 60 (steel) thrown_force_divisor = 0.25 // 5 when thrown with weight 20 (steel) var/loaded //Descriptive string for currently loaded food object. + var/scoop_food = 1 /obj/item/weapon/material/kitchen/utensil/New() ..() @@ -80,6 +81,7 @@ desc = "A knife for eating with. Can cut through any food." icon_state = "knife" force_divisor = 0.1 // 6 when wielded with hardness 60 (steel) + scoop_food = 0 // Identical to the tactical knife but nowhere near as stabby. // Kind of like the toy esword compared to the real thing. diff --git a/code/game/objects/structures/window_spawner.dm b/code/game/objects/structures/window_spawner.dm index 96f375d9e5b..6ec446511b5 100644 --- a/code/game/objects/structures/window_spawner.dm +++ b/code/game/objects/structures/window_spawner.dm @@ -13,6 +13,10 @@ var/win_path = /obj/structure/window/basic var/activated +// stops ZAS expanding zones past us, the windows will block the zone anyway +/obj/effect/wingrille_spawn/CanPass() + return 0 + /obj/effect/wingrille_spawn/attack_hand() attack_generic() diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 36a76ed7e5a..bb1b5ba22ac 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -14,24 +14,37 @@ var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to var/dirt = 0 + var/datum/scheduled_task/unwet_task + // This is not great. /turf/simulated/proc/wet_floor(var/wet_val = 1) - spawn(0) - if(wet_val <= wet) - return + if(wet_val < wet) + return + + if(!wet) wet = wet_val - if(wet_overlay) - overlays -= wet_overlay - wet_overlay = null wet_overlay = image('icons/effects/water.dmi',src,"wet_floor") overlays += wet_overlay - sleep(800) - if(wet >= 2) - return - wet = 0 - if(wet_overlay) - overlays -= wet_overlay - wet_overlay = null + + if(unwet_task) + unwet_task.trigger_task_in(8 SECONDS) + else + unwet_task = schedule_task_in(8 SECONDS) + unwet_task.triggered.register(src, /turf/simulated/proc/task_unwet_floor) + +/turf/simulated/proc/task_unwet_floor(var/triggered_task) + if(triggered_task == unwet_task) + unwet_task = null + unwet_floor(TRUE) + +/turf/simulated/proc/unwet_floor(var/check_very_wet) + if(check_very_wet && wet >= 2) + return + + wet = 0 + if(wet_overlay) + overlays -= wet_overlay + wet_overlay = null /turf/simulated/clean_blood() for(var/obj/effect/decal/cleanable/blood/B in contents) @@ -44,6 +57,11 @@ holy = 1 levelupdate() +/turf/simulated/Destroy() + qdel(unwet_task) + unwet_task = null + return ..() + /turf/simulated/proc/initialize() return diff --git a/code/global.dm b/code/global.dm index 0dac2d68d21..de2b8ea92db 100644 --- a/code/global.dm +++ b/code/global.dm @@ -29,6 +29,7 @@ var/diary = null var/href_logfile = null var/station_name = "NSS Exodus" var/station_short = "Exodus" +var/const/dock_name = "N.A.S. Crescent" var/const/boss_name = "Central Command" var/const/boss_short = "Centcomm" var/const/company_name = "NanoTrasen" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 6ad8b95058a..b1e98c8773e 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -725,6 +725,22 @@ proc/admin_notice(var/message, var/rights) message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1) feedback_add_details("admin_verb","TDOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/togglehubvisibility() + set category = "Server" + set desc="Globally Toggles Hub Visibility" + set name="Toggle Hub Visibility" + + if(!check_rights(R_ADMIN)) + return + + world.visibility = !(world.visibility) + var/long_message = " toggled hub visibility. The server is now [world.visibility ? "visible" : "invisible"] ([world.visibility])." + + send2adminirc("[key_name(src)]" + long_message) + message_admins("[key_name_admin(usr)]" + long_message, 1) + log_admin("[key_name(usr)] toggled hub visibility.") + feedback_add_details("admin_verb","THUB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc + /datum/admins/proc/toggletraitorscaling() set category = "Server" set desc="Toggle traitor scaling" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 69798c391a8..f32ab90f539 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -65,6 +65,7 @@ var/list/admin_verbs_admin = list( /datum/admins/proc/toggledsay, //toggles dsay on/off for everyone, /client/proc/game_panel, //game panel, allows to change game-mode etc, /client/proc/cmd_admin_say, //admin-only ooc chat, + /datum/admins/proc/togglehubvisibility, //toggles visibility on the BYOND Hub, /datum/admins/proc/PlayerNotes, /client/proc/cmd_mod_say, /datum/admins/proc/show_player_info, @@ -702,7 +703,7 @@ var/list/admin_verbs_mentor = list( set category = "Admin" if(holder) - if(alert("Confirm self-deadmin for the round? You can't re-admin yourself without someont promoting you.",,"Yes","No") == "Yes") + if(alert("Confirm self-deadmin for the round? You can re-admin yourself at any time.",,"Yes","No") == "Yes") log_admin("[src] deadmined themself.") message_admins("[src] deadmined themself.", 1) deadmin() diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm index f966b37f29e..38e86e5dc9a 100644 --- a/code/modules/clothing/masks/breath.dm +++ b/code/modules/clothing/masks/breath.dm @@ -12,20 +12,18 @@ /obj/item/clothing/mask/breath/proc/adjust_mask(mob/user) if(user.canmove && !user.stat) - if(!src.hanging) - src.hanging = !src.hanging - gas_transfer_coefficient = 1 //gas is now escaping to the turf and vice versa - item_flags &= ~(AIRTIGHT) - body_parts_covered = ~(FACE) + src.hanging = !src.hanging + if (src.hanging) + gas_transfer_coefficient = 1 + body_parts_covered = body_parts_covered & ~FACE + item_flags = item_flags & ~AIRTIGHT icon_state = "breathdown" user << "Your mask is now hanging on your neck." - else - src.hanging = !src.hanging gas_transfer_coefficient = initial(gas_transfer_coefficient) - item_flags |= AIRTIGHT - body_parts_covered |= FACE - icon_state = "breath" + body_parts_covered = initial(body_parts_covered) + item_flags = initial(item_flags) + icon_state = initial(icon_state) user << "You pull the mask up to cover your face." update_clothing_icon() diff --git a/code/modules/games/boardgame.dm b/code/modules/games/boardgame.dm index 54a9866ea4d..1df0ee5ff9f 100644 --- a/code/modules/games/boardgame.dm +++ b/code/modules/games/boardgame.dm @@ -69,7 +69,7 @@ obj/item/weapon/board/attackby(obj/item/I as obj, mob/user as mob) /obj/item/weapon/board/interact(mob/user as mob) - if(user.incapacitated(INCAPACITATION_DISABLED) || (!isAI(user) && !user.Adjacent(src))) //can't see if you arent conscious. If you are not an AI you can't see it unless you are next to it, either. + if(user.is_physically_disabled() || (!isAI(user) && !user.Adjacent(src))) //can't see if you arent conscious. If you are not an AI you can't see it unless you are next to it, either. user << browse(null, "window=boardgame") user.unset_machine() return diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index b511fb432b4..96e43959dce 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -5,19 +5,19 @@ */ /datum/language - var/name = "an unknown language" // Fluff name of language if any. - var/desc = "A language." // Short description for 'Check Languages'. - var/speech_verb = "says" // 'says', 'hisses', 'farts'. - var/ask_verb = "asks" // Used when sentence ends in a ? - var/exclaim_verb = "exclaims" // Used when sentence ends in a ! - var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. - var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags - var/colour = "body" // CSS style to use for strings in this language. - var/key = "x" // Character used to speak in language eg. :o for Unathi. - var/flags = 0 // Various language flags. - var/native // If set, non-native speakers will have trouble speaking. - var/list/syllables // Used when scrambling text for a non-speaker. - var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string + var/name = "an unknown language" // Fluff name of language if any. + var/desc = "A language." // Short description for 'Check Languages'. + var/speech_verb = "says" // 'says', 'hisses', 'farts'. + var/ask_verb = "asks" // Used when sentence ends in a ? + var/exclaim_verb = "exclaims" // Used when sentence ends in a ! + var/whisper_verb = "whispers" // Optional. When not specified speech_verb + quietly/softly is used instead. + var/signlang_verb = list("signs") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags + var/colour = "body" // CSS style to use for strings in this language. + var/key = "x" // Character used to speak in language eg. :o for Unathi. + var/flags = 0 // Various language flags. + var/native // If set, non-native speakers will have trouble speaking. + var/list/syllables // Used when scrambling text for a non-speaker. + var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string /datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2) if(!syllables || !syllables.len) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index f78e2e0aa62..c6ad0e1f55b 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -8,7 +8,7 @@ var/total_burn = 0 var/total_brute = 0 for(var/obj/item/organ/external/O in organs) //hardcoded to streamline things a bit - if(O.status & ORGAN_ROBOT && !O.vital) + if((O.status & ORGAN_ROBOT) && !O.vital) continue //*non-vital* robot limbs don't count towards shock and crit total_brute += O.brute_dam total_burn += O.burn_dam diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index bb01c846caf..dec82697067 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -9,6 +9,9 @@ message_admins("Admin logout: [key_name(src)]") if(admins_number == 0) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell. send2adminirc("[key_name(src)] logged out - no more admins online.") - ..() + if(config.delist_when_no_admins && world.visibility) + world.visibility = FALSE + send2adminirc("Toggled hub visibility. The server is now invisible ([world.visibility]).") - return 1 \ No newline at end of file + ..() + return 1 diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index 21818d06b15..51a2647ab6c 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -80,6 +80,7 @@ return ..() machinery_computer.update_icon() + machinery_computer.use_power = 0 return // Tesla links only work on machinery types, so we'll override the default try_install_component() proc @@ -94,6 +95,7 @@ // Consoles don't usually have internal power source, so we can't disable tesla link in them. if(istype(machinery_computer, /obj/machinery/modular_computer/console)) L.critical = 1 + L.enabled = 1 found = 1 ..(user, H, found) diff --git a/code/modules/modular_computers/file_system/programs/configurator.dm b/code/modules/modular_computers/file_system/programs/configurator.dm index 6a287d2cd15..69afd82342a 100644 --- a/code/modules/modular_computers/file_system/programs/configurator.dm +++ b/code/modules/modular_computers/file_system/programs/configurator.dm @@ -16,25 +16,16 @@ /datum/nano_module/computer_configurator name = "NTOS Computer Configuration Tool" - var/obj/machinery/modular_computer/stationary = null var/obj/item/modular_computer/movable = null /datum/nano_module/computer_configurator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(program) - stationary = program.computer movable = program.computer - - if(!istype(stationary)) - stationary = null if(!istype(movable)) movable = null - if(istype(movable, /obj/item/modular_computer/processor)) - var/obj/item/modular_computer/processor/P = movable - stationary = P.machinery_computer - // No computer connection, we can't get data from that. - if(!movable && !stationary) + if(!movable) return 0 var/list/data = list() @@ -42,27 +33,15 @@ if(program) data = program.get_header_data() - var/list/hardware = list() - if(stationary) - if(stationary.cpu) - movable = stationary.cpu - hardware.Add(stationary.tesla_link) - else - return + var/list/hardware = movable.get_all_components() - if(movable) - hardware.Add(movable.network_card) - hardware.Add(movable.hard_drive) - hardware.Add(movable.card_slot) - hardware.Add(movable.nano_printer) - hardware.Add(movable.battery_module) - data["disk_size"] = movable.hard_drive.max_capacity - data["disk_used"] = movable.hard_drive.used_capacity - data["power_usage"] = movable.last_power_usage - data["battery_exists"] = movable.battery_module ? 1 : 0 - if(movable.battery_module) - data["battery_rating"] = movable.battery_module.battery.maxcharge - data["battery_percent"] = round(movable.battery_module.battery.percent()) + data["disk_size"] = movable.hard_drive.max_capacity + data["disk_used"] = movable.hard_drive.used_capacity + data["power_usage"] = movable.last_power_usage + data["battery_exists"] = movable.battery_module ? 1 : 0 + if(movable.battery_module) + data["battery_rating"] = movable.battery_module.battery.maxcharge + data["battery_percent"] = round(movable.battery_module.battery.percent()) var/list/all_entries[0] for(var/obj/item/weapon/computer_hardware/H in hardware) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index bcc8de7694c..ea92c278f0c 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -89,15 +89,20 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/proc/get_icon(var/skeletal) - var/gender + var/gender = "f" + if(owner && owner.gender == MALE) + gender = "m" + if(force_icon) - mob_icon = new /icon(force_icon, "[icon_name]") + mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]") else if(!dna) - mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_f" : ""]") + mob_icon = new /icon('icons/mob/human_races/r_human.dmi', "[icon_name][gendered_icon ? "_[gender]" : ""]") else - if(gendered_icon) + if(!gendered_icon) + gender = null + else if(dna.GetUIState(DNA_UI_GENDER)) gender = "f" else diff --git a/code/modules/projectiles/targeting/targeting_mob.dm b/code/modules/projectiles/targeting/targeting_mob.dm index dfae47a604c..ae3b46440b7 100644 --- a/code/modules/projectiles/targeting/targeting_mob.dm +++ b/code/modules/projectiles/targeting/targeting_mob.dm @@ -1,6 +1,20 @@ /mob/living/var/obj/aiming_overlay/aiming /mob/living/var/list/aimed = list() +/mob/verb/toggle_gun_mode() + set name = "Toggle Gun Mode" + set desc = "Begin or stop aiming." + set category = "IC" + + if(isliving(src)) + var/mob/living/M = src + if(!M.aiming) + M.aiming = new(src) + M.aiming.toggle_active() + else + src << "This verb may only be used by living mobs, sorry." + return + /mob/living/proc/stop_aiming(var/obj/item/thing, var/no_message = 0) if(!aiming) aiming = new(src) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 78a53445492..f8619ca595e 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -105,11 +105,11 @@ if (bitecount==0) return else if (bitecount==1) - user << "\blue \The [src] was bitten by someone!" + user << "\The [src] was bitten by someone!" else if (bitecount<=3) - user << "\blue \The [src] was bitten [bitecount] times!" + user << "\The [src] was bitten [bitecount] time\s!" else - user << "\blue \The [src] was bitten multiple times!" + user << "\The [src] was bitten multiple times!" /obj/item/weapon/reagent_containers/food/snacks/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/storage)) @@ -119,32 +119,32 @@ // Eating with forks if(istype(W,/obj/item/weapon/material/kitchen/utensil)) var/obj/item/weapon/material/kitchen/utensil/U = W + if(U.scoop_food) + if(!U.reagents) + U.create_reagents(5) - if(!U.reagents) - U.create_reagents(5) + if (U.reagents.total_volume > 0) + user << "You already have something on your [U]." + return - if (U.reagents.total_volume > 0) - user << "\red You already have something on your [U]." + user.visible_message( \ + "\The [user] scoops up some [src] with \the [U]!", \ + "You scoop up some [src] with \the [U]!" \ + ) + + src.bitecount++ + U.overlays.Cut() + U.loaded = "[src]" + var/image/I = new(U.icon, "loadedfood") + I.color = src.filling_color + U.overlays += I + + reagents.trans_to_obj(U, min(reagents.total_volume,5)) + + if (reagents.total_volume <= 0) + qdel(src) return - user.visible_message( \ - "[user] scoops up some [src] with \the [U]!", \ - "\blue You scoop up some [src] with \the [U]!" \ - ) - - src.bitecount++ - U.overlays.Cut() - U.loaded = "[src]" - var/image/I = new(U.icon, "loadedfood") - I.color = src.filling_color - U.overlays += I - - reagents.trans_to_obj(U, min(reagents.total_volume,5)) - - if (reagents.total_volume <= 0) - qdel(src) - return - if (is_sliceable()) //these are used to allow hiding edge items in food that is not on a table/tray var/can_slice_here = isturf(src.loc) && ((locate(/obj/structure/table) in src.loc) || (locate(/obj/machinery/optable) in src.loc) || (locate(/obj/item/weapon/tray) in src.loc)) @@ -154,7 +154,7 @@ if (W.w_class >= src.w_class || is_robot_module(W)) return - user << "\red You slip [W] inside [src]." + user << "You slip \the [W] inside \the [src]." user.remove_from_mob(W) W.dropped(user) add_fingerprint(user) @@ -163,15 +163,15 @@ if (has_edge(W)) if (!can_slice_here) - user << "\red You cannot slice [src] here! You need a table or at least a tray to do it." + user << "You cannot slice \the [src] here! You need a table or at least a tray to do it." return var/slices_lost = 0 if (W.w_class > 3) - user.visible_message("\blue [user] crudely slices \the [src] with [W]!", "\blue You crudely slice \the [src] with your [W]!") + user.visible_message("\The [user] crudely slices \the [src] with [W]!", "You crudely slice \the [src] with your [W]!") slices_lost = rand(1,min(1,round(slices_num/2))) else - user.visible_message("\blue [user] slices \the [src]!", "\blue You slice \the [src]!") + user.visible_message("\The [user] slices \the [src]!", "You slice \the [src]!") var/reagents_per_slice = reagents.total_volume/slices_num for(var/i=1 to (slices_num-slices_lost)) @@ -474,7 +474,7 @@ ..() new/obj/effect/decal/cleanable/egg_smudge(src.loc) src.reagents.splash(hit_atom, reagents.total_volume) - src.visible_message("\red [src.name] has been squashed.","\red You hear a smack.") + src.visible_message("\The [src] has been squashed!","You hear a smack.") qdel(src) /obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -483,10 +483,10 @@ var/clr = C.colourName if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) - usr << "\blue The egg refuses to take on this color!" + usr << "The egg refuses to take on this color!" return - usr << "\blue You color \the [src] [clr]" + usr << "You color \the [src] [clr]" icon_state = "egg-[clr]" else ..() @@ -1114,7 +1114,7 @@ bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 On_Consume() if(prob(unpopped)) //lol ...what's the point? - usr << "\red You bite down on an un-popped kernel!" + usr << "You bite down on an un-popped kernel!" unpopped = max(0, unpopped-1) ..() @@ -2674,7 +2674,7 @@ if( open && pizza ) user.put_in_hands( pizza ) - user << "\red You take the [src.pizza] out of the [src]." + user << "You take \the [src.pizza] out of \the [src]." src.pizza = null update_icon() return @@ -2688,7 +2688,7 @@ boxes -= box user.put_in_hands( box ) - user << "\red You remove the topmost [src] from your hand." + user << "You remove the topmost [src] from your hand." box.update_icon() update_icon() return @@ -2727,11 +2727,11 @@ box.update_icon() update_icon() - user << "\red You put the [box] ontop of the [src]!" + user << "You put \the [box] ontop of \the [src]!" else - user << "\red The stack is too high!" + user << "The stack is too high!" else - user << "\red Close the [box] first!" + user << "Close \the [box] first!" return @@ -2744,9 +2744,9 @@ update_icon() - user << "\red You put the [I] in the [src]!" + user << "You put \the [I] in \the [src]!" else - user << "\red You try to push the [I] through the lid but it doesn't work!" + user << "You try to push \the [I] through the lid but it doesn't work!" return if( istype(I, /obj/item/weapon/pen/) ) diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index cb6b6d5ece3..4b9a33a3ae3 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -28,9 +28,9 @@ emergency_shuttle.departed = 1 if (emergency_shuttle.evac) - priority_announcement.Announce("The Emergency Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at [boss_name].") + priority_announcement.Announce("The Emergency Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at [dock_name].") else - priority_announcement.Announce("The Crew Transfer Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at [boss_name].") + priority_announcement.Announce("The Crew Transfer Shuttle has left the station. Estimate [round(emergency_shuttle.estimate_arrival_time()/60,1)] minutes until the shuttle docks at [dock_name].") /datum/shuttle/ferry/emergency/can_launch(var/user) if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) @@ -185,7 +185,7 @@ else if (!shuttle.location) shuttle_status = "Standing-by at [station_name]." else - shuttle_status = "Standing-by at [boss_name]." + shuttle_status = "Standing-by at [dock_name]." if(WAIT_LAUNCH, FORCE_LAUNCH) shuttle_status = "Shuttle has recieved command and will depart shortly." if(WAIT_ARRIVE) diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm new file mode 100644 index 00000000000..d81d73e6bf3 --- /dev/null +++ b/code/unit_tests/map_tests.dm @@ -0,0 +1,109 @@ +/* + * + * Map Unit Tests. + * Zone checks / APC / Scrubber / Vent. + * + * + */ + +#define FAILURE 0 +#define SUCCESS 1 + + +datum/unit_test/apc_area_test + name = "MAP: Area Test APC / Scrubbers / Vents Z level 1" + +datum/unit_test/apc_area_test/start_test() + var/list/bad_areas = list() + var/area_test_count = 0 + var/list/exempt_areas = typesof(/area/space, \ + /area/syndicate_station, \ + /area/skipjack_station, \ + /area/solar, \ + /area/shuttle, \ + /area/holodeck, \ + /area/supply/station \ + ) + + var/list/exempt_from_atmos = typesof( /area/maintenance, \ + /area/storage, \ + /area/engineering/atmos/storage, \ + /area/rnd/test_area, \ + /area/construction, \ + /area/server + ) + + var/list/exempt_from_apc = typesof( /area/construction, \ + /area/medical/genetics + ) + + for(var/area/A in world) + if(A.z == 1 && !(A.type in exempt_areas)) + area_test_count++ + var/area_good = 1 + var/bad_msg = "[ascii_red]--------------- [A.name]([A.type])" + + + if(isnull(A.apc) && !(A.type in exempt_from_apc)) + log_unit_test("[bad_msg] lacks an APC.[ascii_reset]") + area_good = 0 + + if(!A.air_scrub_info.len && !(A.type in exempt_from_atmos)) + log_unit_test("[bad_msg] lacks an Air scrubber.[ascii_reset]") + area_good = 0 + + if(!A.air_vent_info.len && !(A.type in exempt_from_atmos)) + log_unit_test("[bad_msg] lacks an Air vent.[ascii_reset]") + area_good = 0 + + if(!area_good) + bad_areas.Add(A) + + if(bad_areas.len) + fail("\[[bad_areas.len]/[area_test_count]\]Some areas lacked APCs, Air Scrubbers, or Air vents.") + else + pass("All \[[area_test_count]\] areas contained APCs, Air scrubbers, and Air vents.") + + return 1 + +//======================================================================================= + +datum/unit_test/wire_test + name = "MAP: Cable Test Z level 1" + +datum/unit_test/wire_test/start_test() + var/wire_test_count = 0 + var/bad_tests = 0 + var/turf/T = null + var/obj/structure/cable/C = null + var/list/cable_turfs = list() + var/list/dirs_checked = list() + + for(C in world) + T = null + + T = get_turf(C) + if(T && T.z == 1) + cable_turfs |= get_turf(C) + + for(T in cable_turfs) + var/bad_msg = "[ascii_red]--------------- [T.name] \[[T.x] / [T.y] / [T.z]\]" + dirs_checked.Cut() + for(C in T) + wire_test_count++ + var/combined_dir = "[C.d1]-[C.d2]" + if(combined_dir in dirs_checked) + bad_tests++ + log_unit_test("[bad_msg] Contains multiple wires with same direction on top of each other.") + dirs_checked.Add(combined_dir) + + if(bad_tests) + fail("\[[bad_tests] / [wire_test_count]\] Some turfs had overlapping wires going the same direction.") + else + pass("All \[[wire_test_count]\] wires had no overlapping cables going the same direction.") + + return 1 + + +#undef SUCCESS +#undef FAILURE diff --git a/code/world.dm b/code/world.dm index d2edb5672ae..57006ec5b4c 100644 --- a/code/world.dm +++ b/code/world.dm @@ -25,10 +25,10 @@ var/global/datum/global_init/init = new () qdel(src) //we're done /datum/global_init/init_observers() - return + return FALSE /datum/global_init/destroy_observers() - return + return FALSE /world mob = /mob/new_player diff --git a/html/changelog.html b/html/changelog.html index a0dea4fdb91..dafb342cc85 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,16 @@ -->
+

13 January 2016

+

Datraen updated:

+ +

Techhead updated:

+ +

08 January 2016

Chinsky updated: