diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 547c81a2f75..8e66a34ed57 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -22,11 +22,14 @@ var/obj/screen/action_button/button = null var/button_icon = 'icons/obj/action_buttons/actions.dmi' var/button_icon_state = "default" + /// The icon to use for the background icon state. Defaults to button_icon if unset. + var/background_icon = 'icons/obj/action_buttons/actions.dmi' var/background_icon_state = "bg_default" var/mob/living/owner /datum/action/New(var/Target) target = Target + background_icon ||= button_icon /datum/action/Destroy() if(owner) diff --git a/code/_onclick/hud/screen/screen_action_button.dm b/code/_onclick/hud/screen/screen_action_button.dm index d8e2ff27532..8e86f334d04 100644 --- a/code/_onclick/hud/screen/screen_action_button.dm +++ b/code/_onclick/hud/screen/screen_action_button.dm @@ -16,7 +16,7 @@ /obj/screen/action_button/on_update_icon() if(!action) return - icon = action.button_icon + icon = action.background_icon icon_state = action.background_icon_state cut_overlays() diff --git a/code/game/objects/random/random_multi.dm b/code/game/objects/random/random_multi.dm index aef5ffd5e15..11ad1cd96df 100644 --- a/code/game/objects/random/random_multi.dm +++ b/code/game/objects/random/random_multi.dm @@ -10,6 +10,10 @@ var/id // Group id var/weight // Probability weight for this spawn point +/obj/random_multi/modify_mapped_vars(map_hash) + . = ..() + ADJUST_TAG_VAR(id, map_hash) + /obj/random_multi/Initialize() . = ..() weight = max(1, round(weight)) diff --git a/code/game/objects/random/subtypes/multi.dm b/code/game/objects/random/subtypes/multi.dm index d54cb0b0f02..34cd5d7077e 100644 --- a/code/game/objects/random/subtypes/multi.dm +++ b/code/game/objects/random/subtypes/multi.dm @@ -1,16 +1,22 @@ -/hook/roundstart/proc/generate_multi_spawn_items() +/hook/roundstart/proc/roundstart_multi_spawn() + generate_multi_spawn_items() + return TRUE + +/proc/generate_multi_spawn_items() for(var/id in multi_point_spawns) var/list/spawn_points = multi_point_spawns[id] var/obj/random_multi/rm = pickweight(spawn_points) rm.generate_items() - for(var/entry in spawn_points) - qdel(entry) - return 1 + QDEL_LIST(spawn_points) + LAZYCLEARLIST(multi_point_spawns) /obj/random_multi/single_item var/item_path // Item type to spawn + var/spawn_nothing_chance = 0 /// Chance to spawn nothing. /obj/random_multi/single_item/generate_items() + if(prob(spawn_nothing_chance)) + return new item_path(loc) /obj/random_multi/single_item/captains_spare_id diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 565a799ddee..de33de72669 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -98,6 +98,7 @@ abstract_type = /obj/structure/sign parts_type = /obj/item/sign parts_amount = 1 + material = /decl/material/solid/organic/plastic /obj/structure/sign/Initialize(ml, _mat, _reinf_mat) . = ..() diff --git a/code/modules/atmospherics/_atmos_setup.dm b/code/modules/atmospherics/_atmos_setup.dm index 7184a9768ec..894e628e062 100644 --- a/code/modules/atmospherics/_atmos_setup.dm +++ b/code/modules/atmospherics/_atmos_setup.dm @@ -14,7 +14,8 @@ var/global/list/pipe_colors = list( "yellow" = PIPE_COLOR_YELLOW, "black" = PIPE_COLOR_BLACK, "orange" = PIPE_COLOR_ORANGE, - "white" = PIPE_COLOR_WHITE) + "white" = PIPE_COLOR_WHITE, + "dark gray" = COLOR_DARK_GRAY) /proc/pipe_color_lookup(var/color) for(var/C in pipe_colors) diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 359222663f1..163c056747e 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -36,7 +36,8 @@ W.write("real_name", pref.real_name) W.write("name_is_always_random", pref.be_random_name) var/decl/spawnpoint/spawnpoint = GET_DECL(pref.spawnpoint) - W.write("spawnpoint", spawnpoint.uid) + if(spawnpoint) + W.write("spawnpoint", spawnpoint.uid) /datum/category_item/player_setup_item/physical/basic/sanitize_character() diff --git a/code/modules/fabrication/designs/replicator/designs_food.dm b/code/modules/fabrication/designs/replicator/designs_food.dm index 9dafa8b26ba..41aee799b2b 100644 --- a/code/modules/fabrication/designs/replicator/designs_food.dm +++ b/code/modules/fabrication/designs/replicator/designs_food.dm @@ -2,6 +2,28 @@ fabricator_types = list(FABRICATOR_CLASS_FOOD) path = /obj/item/chems/food/tofurkey +// Remove matter from plates from the recipe, since we don't print food with plates. +/datum/fabricator_recipe/food/get_resources() + . = ..() + var/obj/item/chems/food/food_result = path + if(!ispath(food_result, /obj/item/chems/food)) + return // why?? why would this not be food?? + var/plate_path = initial(food_result.plate) + if(ispath(plate_path)) + var/list/plate_matter = atom_info_repository.get_matter_for(plate_path) + for(var/key in plate_matter) + resources[key] -= (plate_matter[key] * FABRICATOR_EXTRA_COST_FACTOR) + if(resources[key] <= 0) + resources -= key + +// Print the resulting food without a plate. +/datum/fabricator_recipe/food/build(turf/location, datum/fabricator_build_order/order) + // TODO: On dev, we can just spawn it with skip_plate = TRUE instead. Without that we need a workaround. + . = ..() + for(var/obj/item/chems/food/food in .) + if(istype(food.plate)) + QDEL_NULL(food.plate) + /datum/fabricator_recipe/food/soylentviridians path = /obj/item/chems/food/soylenviridians diff --git a/code/modules/fabrication/fabricator_food.dm b/code/modules/fabrication/fabricator_food.dm index b275ddc8f4c..6b269bcc1af 100644 --- a/code/modules/fabrication/fabricator_food.dm +++ b/code/modules/fabrication/fabricator_food.dm @@ -7,6 +7,7 @@ base_icon_state = "replicator" base_storage_capacity_mult = 5 has_recycler = FALSE + base_type = /obj/machinery/fabricator/replicator /obj/machinery/fabricator/replicator/hear_talk(var/mob/M, var/text, var/verb, var/decl/language/speaking) if(speaking && !speaking.machine_understands) diff --git a/code/modules/maps/_map_template.dm b/code/modules/maps/_map_template.dm index dec09a14977..5df971a8d5e 100644 --- a/code/modules/maps/_map_template.dm +++ b/code/modules/maps/_map_template.dm @@ -237,6 +237,7 @@ if(!QDELETED(mark)) qdel(mark) subtemplates_to_spawn = null + generate_multi_spawn_items() /datum/map_template/proc/extend_bounds_if_needed(var/list/existing_bounds, var/list/new_bounds) var/list/bounds_to_combine = existing_bounds diff --git a/code/modules/maps/helper_landmarks.dm b/code/modules/maps/helper_landmarks.dm index e8c4a5b7547..90fdd2e8ed7 100644 --- a/code/modules/maps/helper_landmarks.dm +++ b/code/modules/maps/helper_landmarks.dm @@ -135,6 +135,9 @@ INITIALIZE_IMMEDIATE(/obj/abstract/landmark/map_load_mark) . = ..() if(!prob(probability)) return // Do nothing. + var/turf/our_turf = get_turf(src) + if(ispath(type_to_find, /turf) && istype(our_turf, type_to_find) && try_set_variable(our_turf)) + return INITIALIZE_HINT_QDEL for(var/atom/candidate_atom in get_turf(src)) if(!istype(candidate_atom, type_to_find)) continue @@ -169,6 +172,10 @@ INITIALIZE_IMMEDIATE(/obj/abstract/landmark/map_load_mark) . = ..() if(!prob(probability)) return // Do nothing. + // turf is not in turf contents, oops + var/turf/our_turf = get_turf(src) + if(ispath(type_to_find, /turf) && istype(our_turf, type_to_find) && try_call_proc(our_turf)) + return INITIALIZE_HINT_QDEL // we don't use locate in case try_call_proc returns false on our first attempt for(var/atom/candidate_atom in get_turf(src)) if(!istype(candidate_atom, type_to_find)) @@ -189,7 +196,7 @@ INITIALIZE_IMMEDIATE(/obj/abstract/landmark/map_load_mark) /obj/abstract/landmark/proc_caller/floor_burner type_to_find = /turf/simulated/floor - proc_to_call = /turf/simulated/floor/proc/burn_tile + proc_to_call = TYPE_PROC_REF(/turf/simulated/floor, burn_tile) arguments_to_pass = null /// Used to tell pipe leak unit tests that a leak is intentional. Placed over the pipe that leaks, not the tile missing a pipe. diff --git a/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm b/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm index 7b7245cb0dd..085c93bbec4 100644 --- a/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm +++ b/code/modules/maps/template_types/random_exoplanet/planet_types/volcanic.dm @@ -99,8 +99,7 @@ /datum/level_data/planetoid/exoplanet/underground ) possible_themes = list( - /datum/exoplanet_theme/mountains = 100, - /datum/exoplanet_theme = 90, + /datum/exoplanet_theme/mountains = 190, /datum/exoplanet_theme/robotic_guardians = 10 ) diff --git a/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm b/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm index aa5e3bd1242..8eb2764c4c1 100644 --- a/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm +++ b/code/modules/maps/template_types/random_exoplanet/random_exoplanet.dm @@ -11,8 +11,7 @@ /datum/level_data/planetoid/exoplanet, ) possible_themes = list( - /datum/exoplanet_theme = 30, - /datum/exoplanet_theme/mountains = 100, + /datum/exoplanet_theme/mountains = 130, /datum/exoplanet_theme/radiation_bombing = 10, /datum/exoplanet_theme/ruined_city = 5, /datum/exoplanet_theme/robotic_guardians = 10 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a6bdc760a8f..76d1b92b33d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -403,7 +403,7 @@ default behaviour is: switch_from_dead_to_living_mob_list() timeofdeath = 0 - stat = CONSCIOUS + set_stat(CONSCIOUS) update_icon() BITSET(hud_updateflag, HEALTH_HUD) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm index 9563d47d807..f3c92813e3b 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_remote_control.dm @@ -36,7 +36,7 @@ add_language(/decl/language/machine, 1) default_language = controlling_ai.default_language - stat = CONSCIOUS + set_stat(CONSCIOUS) if(user.mind) user.mind.transfer_to(src) else diff --git a/code/modules/modular_computers/networking/machinery/relay.dm b/code/modules/modular_computers/networking/machinery/relay.dm index 4710d86c3e1..5283cc7294f 100644 --- a/code/modules/modular_computers/networking/machinery/relay.dm +++ b/code/modules/modular_computers/networking/machinery/relay.dm @@ -31,4 +31,5 @@ name = "long-ranged network relay" icon = 'icons/obj/machines/tcomms/relay.dmi' icon_state = "relay" - network_device_type = /datum/extension/network_device/broadcaster/relay/long_range + network_device_type = /datum/extension/network_device/broadcaster/relay/long_range + base_type = /obj/machinery/network/relay/long_range diff --git a/code/modules/organs/internal/brain_computer.dm b/code/modules/organs/internal/brain_computer.dm index 3d298b04b30..78689d8f059 100644 --- a/code/modules/organs/internal/brain_computer.dm +++ b/code/modules/organs/internal/brain_computer.dm @@ -11,6 +11,7 @@ /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE, /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_TRACE ) + bodytype = /decl/bodytype/prosthetic/basic_human can_use_brain_interface = FALSE var/searching = FALSE var/brain_name @@ -23,7 +24,6 @@ /obj/item/organ/internal/brain/robotic/Initialize() . = ..() - set_bodytype(/decl/bodytype/prosthetic/basic_human) update_icon() brain_name = "[pick(list("ADA","DOS","GNU","MAC","WIN"))]-[random_id(type,1000,9999)]" SetName("[name] ([brain_name])") diff --git a/code/modules/overmap/overmap_shuttle.dm b/code/modules/overmap/overmap_shuttle.dm index 153ed401c14..40a1add39dc 100644 --- a/code/modules/overmap/overmap_shuttle.dm +++ b/code/modules/overmap/overmap_shuttle.dm @@ -24,13 +24,13 @@ fuel_ports += fuel_port_in_area /datum/shuttle/autodock/overmap/fuel_check() - if(!src.try_consume_fuel()) //insufficient fuel - for(var/area/A in shuttle_area) - for(var/mob/living/M in A) - M.show_message(SPAN_WARNING("You hear the shuttle engines sputter... perhaps it doesn't have enough fuel?"), AUDIBLE_MESSAGE, + if(!try_consume_fuel()) //insufficient fuel + for(var/mob/hearer in global.living_mob_list_ + global.ghost_mob_list) + if(is_type_in_list(get_area(hearer), shuttle_area)) + hearer.show_message(SPAN_WARNING("You hear the shuttle engines sputter... perhaps it doesn't have enough fuel?"), AUDIBLE_MESSAGE, SPAN_WARNING("The shuttle shakes but fails to take off."), VISIBLE_MESSAGE) - return 0 //failure! - return 1 //sucess, continue with launch + return FALSE //failure + return TRUE //sucess, continue with launch /datum/shuttle/autodock/overmap/proc/can_go() if(!next_location) diff --git a/code/modules/reagents/chems/chems_ethanol.dm b/code/modules/reagents/chems/chems_ethanol.dm index c4373e38936..024ade8ea30 100644 --- a/code/modules/reagents/chems/chems_ethanol.dm +++ b/code/modules/reagents/chems/chems_ethanol.dm @@ -25,6 +25,7 @@ ) bypass_chilling_products_for_root_type = /decl/material/liquid/ethanol affect_blood_on_ingest = FALSE // prevents automatic toxins/inebriation as though injected + affect_blood_on_inhale = FALSE var/nutriment_factor = 0 var/hydration_factor = 0 @@ -43,6 +44,12 @@ M.adjustToxLoss(removed * 2 * alcohol_toxicity) M.add_chemical_effect(CE_ALCOHOL_TOXIC, alcohol_toxicity) +/decl/material/liquid/ethanol/affect_inhale(mob/living/M, removed, datum/reagents/holder) + if(M.HasTrait(/decl/trait/metabolically_inert)) + return + ..() + affect_ingest(M, removed, holder) // a bit of a hack, but it avoids code duplication + /decl/material/liquid/ethanol/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder) ..() diff --git a/code/unit_tests/machine_tests.dm b/code/unit_tests/machine_tests.dm index fc1da183105..bcb10b27b2f 100644 --- a/code/unit_tests/machine_tests.dm +++ b/code/unit_tests/machine_tests.dm @@ -66,3 +66,23 @@ else pass("All machines had valid construction states.") return 1 + +/datum/unit_test/machine_circuit_matches_basetype + name = "MACHINE: All mapped machines with a circuit for their exact type will have a matching basetype." + +/datum/unit_test/machine_circuit_matches_basetype/start_test() + var/failed = list() + for(var/obj/machinery/machine in SSmachines.machinery) + if(failed[machine.type]) + continue + var/exact_circuit = get_circuit_by_build_path(machine.type) + var/base_circuit = machine.base_type && get_circuit_by_build_path(machine.base_type) + if(exact_circuit && base_circuit && (exact_circuit != base_circuit) && (machine.base_type != machine.type)) + failed[machine.type] = TRUE + log_bad("[machine.type] exactly matches [exact_circuit] but its base type is [machine.base_type], which has [base_circuit].") + + if(length(failed)) + fail("One or more machines had an invaild basetype.") + else + pass("All machines had valid basetypes.") + return 1 diff --git a/mods/content/psionics/system/psionics/mob/mob.dm b/mods/content/psionics/system/psionics/mob/mob.dm index 771c88d55b6..47548ea0fcd 100644 --- a/mods/content/psionics/system/psionics/mob/mob.dm +++ b/mods/content/psionics/system/psionics/mob/mob.dm @@ -7,9 +7,6 @@ return /mob/living/set_psi_rank(var/faculty, var/rank, var/take_larger, var/defer_update, var/temporary) - if(!get_target_zone()) // Can't target a zone, so you can't really invoke psionics. - to_chat(src, SPAN_NOTICE("You feel something strange brush against your mind... but your brain is not able to grasp it.")) - return var/datum/ability_handler/psionics/psi = get_ability_handler(/datum/ability_handler/psionics) var/current_rank = psi?.get_rank(faculty) if(!current_rank && !rank) diff --git a/nano/css/layout_default.css b/nano/css/layout_default.css index c9762874dec..3a7d875cfd5 100644 --- a/nano/css/layout_default.css +++ b/nano/css/layout_default.css @@ -1,6 +1,5 @@ body { background: #121212 url(uiBackground.png) 50% 0 repeat; - box-shadow: 0px 0px 5px 5px #000; } #uiWrapper { diff --git a/scripts/server.sh b/scripts/server.sh index d585b64ad21..b65b6b33d16 100755 --- a/scripts/server.sh +++ b/scripts/server.sh @@ -12,6 +12,7 @@ cd $SERVERDIR cleanup() { # $1: server pid + cd $SERVERDIR rm server_running [[ $1 != "" ]] && kill -s SIGTERM $1 } @@ -60,7 +61,9 @@ while [[ ! -e stopserver ]]; do if [[ "$GITDIR" != "." ]]; then cp "$GITDIR/$DME.dmb" . cp "$GITDIR/$DME.rsc" . - cp -r "$GITDIR/nano" . + cp -r "$GITDIR/nano" . # Necessary for NanoUI + cp -r "$GITDIR/maps" . # Necessary for runtime submap loading + cp -r "$GITDIR/mods" . # Also necessary for runtime submap loading. TODO: a better solution [[ ! -e btime.so && -e "$GITDIR/btime.so" ]] && cp "$GITDIR/btime.so" . [[ ! -e .git/logs ]] && mkdir -p .git/logs cp "$GITDIR/.git/HEAD" ./.git/HEAD