diff --git a/aurorastation.dme b/aurorastation.dme index 8ad55da15f1..4f0798ee15b 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -222,6 +222,7 @@ #include "code\controllers\subsystems\law.dm" #include "code\controllers\subsystems\lighting.dm" #include "code\controllers\subsystems\machinery.dm" +#include "code\controllers\subsystems\mapping.dm" #include "code\controllers\subsystems\materials.dm" #include "code\controllers\subsystems\mob.dm" #include "code\controllers\subsystems\mob_ai.dm" @@ -1965,6 +1966,7 @@ #include "code\modules\lighting\lighting_corner.dm" #include "code\modules\lighting\lighting_overlay.dm" #include "code\modules\lighting\lighting_profiler.dm" +#include "code\modules\lighting\lighting_setup.dm" #include "code\modules\lighting\lighting_source.dm" #include "code\modules\lighting\lighting_source_sunlight.dm" #include "code\modules\lighting\lighting_turf.dm" @@ -1976,6 +1978,7 @@ #include "code\modules\lock\lock_construct.dm" #include "code\modules\makeshift\makeshift_reagents.dm" #include "code\modules\maps\dmm_suite.dm" +#include "code\modules\maps\helper_landmarks.dm" #include "code\modules\maps\map_template.dm" #include "code\modules\maps\reader.dm" #include "code\modules\maps\ruins.dm" @@ -2942,6 +2945,9 @@ #include "code\modules\spell_system\spells\spell_list\self\generic\rune_write.dm" #include "code\modules\spell_system\spells\spell_list\self\generic\shadow_shroud.dm" #include "code\modules\spell_system\spells\spell_list\self\generic\shift.dm" +#include "code\modules\submaps\_submap.dm" +#include "code\modules\submaps\submap_archetype.dm" +#include "code\modules\submaps\submap_landmark.dm" #include "code\modules\supermatter\setup_supermatter.dm" #include "code\modules\supermatter\supermatter.dm" #include "code\modules\surgery\_defines.dm" @@ -3060,6 +3066,7 @@ #include "maps\aurora\code\aurora_lifts.dm" #include "maps\aurora\code\aurora_shuttles.dm" #include "maps\aurora\code\aurora_unittest.dm" +#include "maps\away\away_sites.dm" #include "maps\event\code\event.dm" #include "maps\event\odin_departure\code\odin_departure_areas.dm" #include "maps\event\odin_departure\code\odin_depature.dm" @@ -3071,8 +3078,10 @@ #include "maps\exodus\code\exodus_holodeck.dm" #include "maps\exodus\code\exodus_shuttles.dm" #include "maps\exodus\code\exodus_unittest.dm" -#include "maps\random_ruins\exoplanet_ruins\asteroid\asteroid.dm" #include "maps\random_ruins\exoplanets\exoplanet_ruins.dm" +#include "maps\random_ruins\exoplanets\asteroid\asteroid.dm" +#include "maps\random_ruins\exoplanets\crashed_pod\crashed_pod.dm" +#include "maps\random_ruins\space_ruins\space_ruins.dm" #include "maps\runtime\runtime_overmap.dm" #include "maps\runtime\code\runtime.dm" #include "maps\runtime\code\runtime_lifts.dm" diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index a52509ae0b7..635014e20d6 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -60,8 +60,8 @@ var/turf/T = get_turf(src) if(!istype(T)) return - add_underlay(T, node1, turn(dir, 180), node1?.icon_connect_type) - add_underlay(T, node2, dir, node2?.icon_connect_type) + add_underlay(T, node1, turn(dir, 180), icon_connect_type) + add_underlay(T, node2, dir, icon_connect_type) /obj/machinery/atmospherics/binary/passive_gate/hide(var/i) update_underlays() diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm index 9f5c645e2b7..3b9b09be55c 100644 --- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm +++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm @@ -129,6 +129,7 @@ ..() set_frequency(frequency) + broadcast_status() /obj/machinery/atmospherics/unary/outlet_injector/receive_signal(datum/signal/signal) if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command")) diff --git a/code/__defines/_layers.dm b/code/__defines/_layers.dm index e5a4670dc33..1a966fa0160 100644 --- a/code/__defines/_layers.dm +++ b/code/__defines/_layers.dm @@ -2,6 +2,7 @@ #define PLANE_SPACE_PARALLAX (PLANE_SPACE_BACKGROUND + 1) // -97 #define PLANE_SPACE_DUST (PLANE_SPACE_PARALLAX + 1) // -96 #define PLANE_ABOVE_PARALLAX (PLANE_SPACE_BACKGROUND + 3) // -95 +#define PLANE_DEFAULT 0 #define LOWER_ON_TURF_LAYER (TURF_LAYER + 0.05) // under the below #define ON_TURF_LAYER (TURF_LAYER + 0.1) // sitting on the turf - should be preferred over direct use of TURF_LAYER diff --git a/code/__defines/_macros.dm b/code/__defines/_macros.dm index e971d18f155..fdca86af2bf 100644 --- a/code/__defines/_macros.dm +++ b/code/__defines/_macros.dm @@ -1,6 +1,7 @@ #define Clamp(x, low, high) max(low, min(high, x)) #define CLAMP01(x) (Clamp(x, 0, 1)) #define JOINTEXT(X) jointext(X, null) +#define list_find(L, needle, LIMITS...) L.Find(needle, LIMITS) #define span(class, text) ("" + text + "") #define SPAN_NOTICE(X) ("" + X + "") diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index 4c71d271d54..ec05e0a8bc2 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -33,5 +33,13 @@ // /mob signals // /obj signals +/// when a hood is unequipped +#define COMSIG_ITEM_REMOVE "item_remove" +/// checks an item's state +#define COMSIG_ITEM_STATE_CHECK "state_check" +/// updates an item between several states +#define COMSIG_ITEM_UPDATE_STATE "update_state" +/// updates sprites +#define COMSIG_ITEM_ICON_UPDATE "icon_update" /*******Component Specific Signals*******/ diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index 77da81798f8..4f7ac6ee97b 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -93,6 +93,13 @@ #define LIGHT_COLOR_HALOGEN "#C0C0CA" //Soft lighting for general-purpose light fixtures. rgb(192, 192, 202) #define LIGHT_COLOR_EMERGENCY "#FF3232" //Red color used by emergency lighting. rgb(255, 50, 50) #define LIGHT_COLOR_EMERGENCY_SOFT "#FA8282" //A softer emergency red, used for small bulbs. rgb(250, 130, 130) +#define LIGHT_COLOUR_WHITE "#FEFEFE" // Clinical white light bulbs +#define LIGHT_COLOUR_WARM "#FFFEE0" // Warm yellowish light bulbs + +#define LIGHT_STANDARD_COLORS list(LIGHT_COLOUR_WHITE, LIGHT_COLOUR_WARM, LIGHT_COLOR_HALOGEN) // List of standard light colors used for randomized lighting and selectable printed lights. + +#define LIGHT_MODE_RED "red" +#define LIGHT_MODE_DELTA "delta" //Defines for lighting status, see power/lighting.dm #define LIGHT_OK 0 @@ -109,7 +116,7 @@ #define LIGHT_NARROW 45 // Some brightness/range defines for objects. -#define L_WALLMOUNT_POWER 0.4 +#define L_WALLMOUNT_POWER 1.3 #define L_WALLMOUNT_RANGE 2 #define L_WALLMOUNT_HI_POWER 1 // For red/delta alert on fire alarms. #define L_WALLMOUNT_HI_RANGE 4 diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 0400a428abe..33d3b079543 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -491,7 +491,10 @@ Define for getting a bitfield of adjacent turfs that meet a condition. #define TEMPLATE_FLAG_SPAWN_GUARANTEED 2 // Makes it ignore away site budget and just spawn (only for away sites) #define TEMPLATE_FLAG_CLEAR_CONTENTS 4 // if it should destroy objects it spawns on top of #define TEMPLATE_FLAG_NO_RUINS 8 // if it should forbid ruins from spawning on top of it -#define TEMPLATE_FLAG_NO_RADS 16// Removes all radiation from the template after spawning. -#define LANDING_ZONE_RADIUS 15 // Used for autoplacing landmarks on exoplanets \ No newline at end of file +#define LANDING_ZONE_RADIUS 15 // Used for autoplacing landmarks on exoplanets + +//Ruin map template flags +#define TEMPLATE_FLAG_RUIN_STARTS_DISALLOWED 32 // Ruin is not available during spawning unless another ruin permits it. + diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 173b04febd8..1e7b75964f0 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -640,7 +640,7 @@ proc/ColorTone(rgb, tone) /// appearance system (overlays/underlays, etc.) is not available. /// /// Only the first argument is required. -/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) +/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE, ignore_parent_dir = FALSE) //Define... defines. var/static/icon/flat_template = icon('icons/effects/effects.dmi', "nothing") @@ -701,7 +701,7 @@ proc/ColorTone(rgb, tone) var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have //These should use the parent's direction (most likely) - if(!A.dir || A.dir == SOUTH) + if(!A.dir || A.dir == SOUTH || ignore_parent_dir) curdir = defdir else curdir = A.dir diff --git a/code/_helpers/sorting/cmp.dm b/code/_helpers/sorting/cmp.dm index 41ca9c64c8c..b6deea30a9b 100644 --- a/code/_helpers/sorting/cmp.dm +++ b/code/_helpers/sorting/cmp.dm @@ -85,3 +85,6 @@ /proc/cmp_clientcolor_priority(datum/client_color/A, datum/client_color/B) return B.priority - A.priority + +/proc/cmp_ruincost_priority(datum/map_template/ruin/A, datum/map_template/ruin/B) + return initial(A.spawn_cost) - initial(B.spawn_cost) diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 61ca2daa2c5..8b933f9fdb6 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -50,6 +50,14 @@ while (left-- > 0) . = "0[.]" +// Splits the text of a file at seperator and returns them in a list. +/proc/file2list(filename, seperator="\n") + return splittext(file2text(filename) || "", seperator) + +//Splits the text of a file at seperator and returns them in a list. +/world/proc/file2list(filename, seperator="\n") + return splittext(file2text(filename), seperator) + // Slower then list2text (replaced with jointext), but correctly processes associative lists. proc/tg_list2text(list/list, glue=",") if (!istype(list) || !list.len) @@ -97,10 +105,6 @@ proc/tg_list2text(list/list, glue=",") num_list += text2num(x) return num_list -// Splits the text of a file at seperator and returns them in a list. -/proc/file2list(filename, seperator="\n") - return text2list(return_file_text(filename),seperator) - // Turns a direction into text /proc/num2dir(direction) switch (direction) diff --git a/code/_onclick/hud/ability_screen_objects.dm b/code/_onclick/hud/ability_screen_objects.dm index cff2b45eaae..201c313744c 100644 --- a/code/_onclick/hud/ability_screen_objects.dm +++ b/code/_onclick/hud/ability_screen_objects.dm @@ -232,7 +232,7 @@ /obj/screen/ability/verb_based/activate() if(object_used && verb_to_call) - call(object_used,verb_to_call)(arguments_to_use) //TODOMATT: WHY GOD WHY + call(object_used,verb_to_call)(arguments_to_use) /obj/screen/movable/ability_master/proc/add_verb_ability(var/object_given, var/verb_given, var/name_given, var/ability_icon_given, var/arguments) if(!object_given) diff --git a/code/controllers/subsystems/garbage-debug.dm b/code/controllers/subsystems/garbage-debug.dm index b4a2077005f..d13ef1dd5a6 100644 --- a/code/controllers/subsystems/garbage-debug.dm +++ b/code/controllers/subsystems/garbage-debug.dm @@ -380,6 +380,7 @@ SearchVar(SSpipenet) SearchVar(SSprocessing) SearchVar(SSshuttle) + SearchVar(SSmapping) SearchVar(base_law_type) SearchVar(discord_bot) SearchVar(diseases) diff --git a/code/controllers/subsystems/initialization/misc_late.dm b/code/controllers/subsystems/initialization/misc_late.dm index b21ab2fcb91..9b7a781afcd 100644 --- a/code/controllers/subsystems/initialization/misc_late.dm +++ b/code/controllers/subsystems/initialization/misc_late.dm @@ -46,6 +46,8 @@ click_catchers = create_click_catcher() + current_map.build_away_sites() + current_map.build_exoplanets() ..(timeofday) diff --git a/code/controllers/subsystems/machinery.dm b/code/controllers/subsystems/machinery.dm index e88cb2f4ac3..091370d27bd 100644 --- a/code/controllers/subsystems/machinery.dm +++ b/code/controllers/subsystems/machinery.dm @@ -214,4 +214,18 @@ /datum/controller/subsystem/machinery/ExplosionEnd() wake() +/datum/controller/subsystem/machinery/proc/setup_atmos_machinery(list/machines) + set background = TRUE + var/list/atmos_machines = list() + for (var/obj/machinery/atmospherics/machine in machines) + atmos_machines += machine + log_game("Initializing atmos machinery") + for (var/obj/machinery/atmospherics/machine as anything in atmos_machines) + machine.atmos_init() + CHECK_TICK + log_game("Initializing pipe networks") + for (var/obj/machinery/atmospherics/machine as anything in atmos_machines) + machine.build_network() + CHECK_TICK + #undef MACHINERY_GO_TO_NEXT diff --git a/code/controllers/subsystems/mapping.dm b/code/controllers/subsystems/mapping.dm new file mode 100644 index 00000000000..1e4b14364b0 --- /dev/null +++ b/code/controllers/subsystems/mapping.dm @@ -0,0 +1,94 @@ +var/datum/controller/subsystem/mapping/SSmapping + +/datum/controller/subsystem/mapping + name = "Mapping" + init_order = SS_INIT_MISC + flags = SS_NO_FIRE + + var/list/map_templates = list() + var/list/space_ruins_templates = list() + var/list/exoplanet_ruins_templates = list() + var/list/away_sites_templates = list() + var/list/submaps = list() + var/list/submap_archetypes = list() + +/datum/controller/subsystem/mapping/New() + NEW_SS_GLOBAL(SSmapping) + +/datum/controller/subsystem/mapping/Initialize(timeofday) + // Load templates and build away sites. + preloadTemplates() + for(var/atype in subtypesof(/decl/submap_archetype)) + submap_archetypes[atype] = new atype + . = ..() + +/datum/controller/subsystem/mapping/Recover() + flags |= SS_NO_INIT + map_templates = SSmapping.map_templates + space_ruins_templates = SSmapping.space_ruins_templates + exoplanet_ruins_templates = SSmapping.exoplanet_ruins_templates + away_sites_templates = SSmapping.away_sites_templates + +/datum/controller/subsystem/mapping/proc/preloadTemplates(path = "maps/templates/") //see master controller setup + var/list/filelist = flist(path) + for(var/map in filelist) + var/datum/map_template/T = new(path = "[path][map]", rename = "[map]") + map_templates[T.name] = T + preloadBlacklistableTemplates() + +/datum/controller/subsystem/mapping/proc/preloadBlacklistableTemplates() + // Still supporting bans by filename + var/list/banned_exoplanet_dmms = generateMapList("config/exoplanet_ruin_blacklist.txt") + var/list/banned_space_dmms = generateMapList("config/space_ruin_blacklist.txt") + var/list/banned_away_site_dmms = generateMapList("config/away_site_blacklist.txt") + + if (!banned_exoplanet_dmms || !banned_space_dmms || !banned_away_site_dmms) + log_admin("One or more map blacklist files are not present in the config directory!") + + var/list/banned_maps = list() + banned_exoplanet_dmms + banned_space_dmms + banned_away_site_dmms + + for(var/item in sortList(subtypesof(/datum/map_template), /proc/cmp_ruincost_priority)) + var/datum/map_template/map_template_type = item + // screen out the abstract subtypes + if(!initial(map_template_type.id)) + continue + var/datum/map_template/MT = new map_template_type() + + if (banned_maps) + var/mappath = MT.mappath + if(list_find(banned_maps, mappath)) + break + + map_templates[MT.name] = MT + + // This is nasty.. + if(istype(MT, /datum/map_template/ruin/exoplanet)) + exoplanet_ruins_templates[MT.name] = MT + else if(istype(MT, /datum/map_template/ruin/space)) + space_ruins_templates[MT.name] = MT + else if(istype(MT, /datum/map_template/ruin/away_site)) + away_sites_templates[MT.name] = MT + +/proc/generateMapList(filename) + var/list/potentialMaps = list() + var/list/Lines = world.file2list(filename) + if(!Lines.len) + return + for (var/t in Lines) + if (!t) + continue + t = trim(t) + if (length(t) == 0) + continue + else if (copytext(t, 1, 2) == "#") + continue + var/pos = findtext(t, " ") + var/name = null + if (pos) + name = lowertext(copytext(t, 1, pos)) + else + name = lowertext(t) + if (!name) + continue + potentialMaps.Add(t) + return potentialMaps diff --git a/code/datums/observation/equipped.dm b/code/datums/observation/equipped.dm index 06dc5a8b013..acddd989d67 100644 --- a/code/datums/observation/equipped.dm +++ b/code/datums/observation/equipped.dm @@ -38,6 +38,7 @@ var/datum/observ/item_equipped/item_equipped_event = new() . = ..() mob_equipped_event.raise_event(user, src, slot) item_equipped_event.raise_event(src, user, slot) + SEND_SIGNAL(src, COMSIG_ITEM_REMOVE, src) /obj/item/proc/check_equipped(var/mob/user, var/slot, var/assisted_equip = FALSE) return TRUE \ No newline at end of file diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index 2146c6da504..243adf19e26 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -369,7 +369,7 @@ var/obj/item/I = new id(H) imprint_idcard(H,I) if(istype(P) && P.card_slot) - addtimer(CALLBACK(src, .proc/register_pda, P, I), 1 SECOND) + addtimer(CALLBACK(src, .proc/register_pda, P, I), 2 SECOND) else H.equip_or_collect(I, slot_wear_id) diff --git a/code/datums/ruins.dm b/code/datums/ruins.dm index 093e5a742f8..c9d521c9423 100644 --- a/code/datums/ruins.dm +++ b/code/datums/ruins.dm @@ -6,13 +6,19 @@ It is clearly a mystery." var/spawn_weight = 1 - var/cost = null + var/spawn_cost = 0 + var/player_cost = 0 var/list/sectors = list() //This ruin can only spawn in the sectors in this list. var/prefix = null var/suffix = null template_flags = 0 // No duplicates by default + // !! Currently only implemented for away sites + var/list/force_ruins // Listed ruins are always spawned unless disallowed by flags. + var/list/allow_ruins // Listed ruins are added to the set of available spawns. + var/list/ban_ruins // Listed ruins are removed from the set of available spawns. Beats allowed. + /datum/map_template/ruin/New() if (suffix) mappath += (prefix + suffix) diff --git a/code/datums/uplink/announcements.dm b/code/datums/uplink/announcements.dm index 9e7acaa7dc2..93ae47ad22c 100644 --- a/code/datums/uplink/announcements.dm +++ b/code/datums/uplink/announcements.dm @@ -46,18 +46,23 @@ random_record = new(user) var/datum/record/general/record = random_record.Copy() - + if(I) record.age = I.age - record.rank = I.assignment - record.real_rank = I.assignment record.name = I.registered_name record.sex = I.sex + record.employer = I.employer_faction + var/datum/faction/id_faction = SSjobs.name_factions[I.employer_faction] + var/faction_abbreviation = id_faction.title_suffix + var/assignment = "[I.assignment][ faction_abbreviation ? " ([faction_abbreviation])" : ""]" + record.rank = assignment + record.real_rank = assignment else var/mob/living/carbon/human/H if(istype(user,/mob/living/carbon/human)) H = user record.age = H.age + record.employer = H.employer_faction else record.age = initial(H.age) var/assignment = GetAssignment(user) diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index 2c48f34f460..8eaf23b8c49 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -199,6 +199,7 @@ //Ensure that antags with ANTAG_OVERRIDE_JOB do not occupy job slots. if(flags & ANTAG_OVERRIDE_JOB) player.assigned_role = role_text + player.role_alt_title = role_text //Ensure that a player cannot be drafted for multiple antag roles, taking up slots for antag roles that they will not fill. player.special_role = role_text diff --git a/code/game/antagonist/antagonist_add.dm b/code/game/antagonist/antagonist_add.dm index d08f7920a2d..1cc74fc0432 100644 --- a/code/game/antagonist/antagonist_add.dm +++ b/code/game/antagonist/antagonist_add.dm @@ -6,6 +6,7 @@ //do this again, just in case if(flags & ANTAG_OVERRIDE_JOB) player.assigned_role = role_text + player.role_alt_title = role_text player.special_role = role_text if(istype(player.current, /mob/abstract)) @@ -122,4 +123,4 @@ //Run the query to update the db entry with the removal time var/DBQuery/update_query = dbcon.NewQuery("UPDATE ss13_antag_log SET special_role_removed = :special_role_removed: WHERE id = :id:") - update_query.Execute(list("id"=db_log_id,"special_role_removed"="[get_round_duration_formatted()]:00")) \ No newline at end of file + update_query.Execute(list("id"=db_log_id,"special_role_removed"="[get_round_duration_formatted()]:00")) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 555eca31262..631e43f8e1b 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -47,6 +47,7 @@ var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf var/no_light_control = 0 // if 1, lights in area cannot be toggled with light controller var/allow_nightmode = 0 // if 1, lights in area will be darkened by the night mode controller + var/emergency_lights = FALSE var/station_area = 0 var/centcomm_area = 0 var/has_weird_power = FALSE // If TRUE, SSmachinery will not use the inlined power checks and will call powered() and use_power() on this area. diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1a2787cff7f..7e0823e48cf 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -292,7 +292,7 @@ /atom/proc/emag_act(var/remaining_charges, var/mob/user, var/emag_source) return NO_EMAG_ACT -/atom/proc/fire_act() +/atom/proc/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) return /atom/proc/melt() diff --git a/code/game/gamemodes/cult/items/talisman.dm b/code/game/gamemodes/cult/items/talisman.dm index e0bc85b3384..b19084233ce 100644 --- a/code/game/gamemodes/cult/items/talisman.dm +++ b/code/game/gamemodes/cult/items/talisman.dm @@ -1,5 +1,6 @@ /obj/item/paper/talisman icon_state = "paper_talisman" + can_change_icon_state = FALSE var/uses = 1 var/datum/rune/rune info = "

Slow Heating Mode: [slow_mode ? "On" : "Off"]" dat += "
Target Temp: [round(target_temperature)]K / [round(target_temperature - T0C,0.1)]C
"
@@ -102,6 +106,8 @@
target_temperature = max(min_temperature,min(target_temperature + text2num(href_list["power"]),max_temperature))
if(container)
should_heat = target_temperature >= container.get_temperature()
+ if("slowmode")
+ slow_mode = !slow_mode
updateUsrDialog()
@@ -115,6 +121,7 @@
if(container && container.reagents)
var/current_temperature = container.reagents.get_temperature()
+ var/target_temperature_limited = slow_mode ? current_temperature + SLOW_MODE_MAX_TEMP_CHANGE : target_temperature
if(should_heat && current_temperature >= target_temperature)
use_power = 0
@@ -128,7 +135,7 @@
var/joules_to_use = machine_strength * 1000
var/mod = should_heat ? 1 : -1
var/thermal_energy_change = 0
- var/thermal_energy_limit = container.reagents.get_thermal_energy_change(current_temperature,target_temperature) //Don't go over the target temperature
+ var/thermal_energy_limit = container.reagents.get_thermal_energy_change(current_temperature,target_temperature_limited) //Don't go over the target temperature
var/thermal_energy_limit2 = container.reagents.get_thermal_energy_change(current_temperature,current_temperature + machine_strength*mod*5) //So small reagents don't go from 0 to 1000 in a few seconds.
if(mod > 0) //GOING UP
thermal_energy_change = min(joules_to_use,thermal_energy_limit,thermal_energy_limit2)
@@ -155,3 +162,4 @@
+#undef SLOW_MODE_MAX_TEMP_CHANGE
\ No newline at end of file
diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm
index 5bedfba05b6..2c841a9bbad 100644
--- a/code/game/machinery/computer/Operating.dm
+++ b/code/game/machinery/computer/Operating.dm
@@ -11,6 +11,11 @@
circuit = /obj/item/circuitboard/operating
var/mob/living/carbon/human/victim = null
var/obj/machinery/optable/table = null
+ var/last_ba // Brain Activity
+ var/last_bo // Blood Oxygenation
+ var/last_critical
+ var/obj/item/paper/medscan/input_scan = null
+ var/obj/machinery/body_scanconsole/internal_bodyscanner = null
/obj/machinery/computer/operating/Initialize()
. = ..()
@@ -19,6 +24,11 @@
if (table)
table.computer = src
break
+ if(!internal_bodyscanner) // So it can scan correctly
+ var/obj/machinery/body_scanconsole/S = new (src)
+ S.forceMove(src)
+ S.use_power = FALSE
+ internal_bodyscanner = S
/obj/machinery/computer/operating/attack_ai(mob/user)
if(!ai_can_interact(user))
@@ -35,6 +45,22 @@
return
interact(user)
+/obj/machinery/computer/operating/attackby(obj/item/O as obj, mob/user)
+ if(istype(O, /obj/item/paper/medscan))
+ if(input_scan)
+ to_chat(usr, SPAN_NOTICE("There is already a [O] inside!"))
+ return
+ user.drop_from_inventory(O,src)
+ input_scan = O
+ input_scan.color = "#272727"
+ input_scan.set_content_unsafe("Scan ([victim])", operating_format(get_medical_data(victim)))
+ usr.visible_message("\The [src] pings, displaying \the [input_scan].")
+ to_chat(usr, SPAN_NOTICE("You insert \the [O] into [src]."))
+ playsound(src, 'sound/bureaucracy/scan.ogg', 50, 1)
+ else
+ to_chat(usr, SPAN_NOTICE("You try to insert \the [O], but \the [src] buzzes, unable to read it."))
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1)
+ return
/obj/machinery/computer/operating/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
@@ -48,12 +74,23 @@
if(src.table && (src.table.check_victim()))
src.victim = src.table.victim
dat += {"
-Patient Information:
-Brain Activity: [victim.isFBP() ? "N/A" : victim.get_brain_status()]
-Pulse: [victim.get_pulse(GETPULSE_TOOL)]
-BP: [victim.get_blood_pressure()]
-Blood Oxygenation: [victim.get_blood_oxygenation()]
-"}
+ Patient Information:
+ Brain Activity: [victim.isFBP() ? "N/A" : victim.get_brain_status()]
+ Pulse: [victim.get_pulse(GETPULSE_TOOL)]
+ BP: [victim.get_blood_pressure()]
+ Blood Oxygenation: [victim.get_blood_oxygenation()]
+ Blood Volume: [victim.get_blood_volume()]%
+ "}
+ if(!input_scan)
+ dat += "Patient Scan: Scan not found. Please insert a Medical Scan.
"
+ else
+ dat += {"
+ Patient Scan: [input_scan]
+ Update scan
+ Remove and update scan
+ Print new scan
| Organ | " + dat += "Burn Severity | " + dat += "Physical Trauma | " + dat += "Other Wounds | " + dat += "||||
|---|---|---|---|---|---|---|---|
| [e.name] | [e.burn_dam] | [get_severity(e.brute_dam, TRUE)] | [robot][bled][AN][splint][open][infected][imp][dislocated][internal_bleeding][severed_tendon][lung_ruptured] | " + else + dat += "[e.name] | - | - | Not [e.is_stump() ? "Found" : "Attached Completely"] | " + dat += "
| [i.name] | N/A | [internal_bodyscanner.get_internal_damage(i)] | [infection], [mech][necrotic] | " + dat += " |
| ")
diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm
index 05feb5c5e80..f1136b6284c 100644
--- a/code/game/objects/items/weapons/cards_ids_syndicate.dm
+++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm
@@ -67,6 +67,7 @@
entries[++entries.len] = list("name" = "Sex", "value" = sex)
entries[++entries.len] = list("name" = "Citizenship", "value" = citizenship)
entries[++entries.len] = list("name" = "Religion", "value" = religion)
+ entries[++entries.len] = list("name" = "Faction", "value" = employer_faction)
entries[++entries.len] = list("name" = "Factory Reset", "value" = "Use With Care")
data["electronic_warfare"] = electronic_warfare
data["entries"] = entries
@@ -229,6 +230,12 @@
src.religion = new_religion
to_chat(user, SPAN_NOTICE("Religion changed to '[new_religion]'."))
. = 1
+ if("Faction")
+ var/new_faction = sanitize(input(user,"Which faction would you like to put on this card?","Agent Card Faction", employer_faction) as null|text)
+ if(!isnull(new_faction) && CanUseTopic(user,state))
+ src.employer_faction = new_faction
+ to_chat(user, SPAN_NOTICE("Faction changed to '[new_faction]'."))
+ . = 1
if("Factory Reset")
if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && CanUseTopic(user, state))
age = initial(age)
@@ -245,6 +252,7 @@
unset_registered_user()
religion = initial(religion)
sex = initial(sex)
+ employer_faction = initial(employer_faction)
to_chat(user, "All information has been deleted from \the [src].")
. = 1
diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm
index 8832c74d145..1c2aac1e68b 100644
--- a/code/game/objects/items/weapons/storage/wallets.dm
+++ b/code/game/objects/items/weapons/storage/wallets.dm
@@ -15,8 +15,10 @@
/obj/item/device/flashlight/pen,
/obj/item/seeds,
/obj/item/coin,
+ /obj/item/stack/dice,
/obj/item/disk,
/obj/item/implanter,
+ /obj/item/flame/lighter,
/obj/item/flame/match,
/obj/item/lipstick,
/obj/item/haircomb,
@@ -30,7 +32,8 @@
/obj/item/device/encryptionkey,
/obj/item/fluff,
/obj/item/storage/business_card_holder,
- /obj/item/sample
+ /obj/item/sample,
+ /obj/item/key
)
slot_flags = SLOT_ID
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index dde3e3aabbb..185ea3af7d7 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -25,7 +25,7 @@
var/mob/living/pulling
/obj/structure/janitorialcart/full/Initialize()
- ..()
+ . = ..()
mybag = new /obj/item/storage/bag/trash(src)
mymop = new /obj/item/mop(src)
myspray = new /obj/item/reagent_containers/spray/cleaner(src)
diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm
index ed4ce7d3f6a..1ec719a5f06 100644
--- a/code/game/objects/structures/railing.dm
+++ b/code/game/objects/structures/railing.dm
@@ -187,6 +187,8 @@
update_icon()
/obj/structure/railing/CheckExit(var/atom/movable/O, var/turf/target)
+ if(istype(O) && CanPass(O, target))
+ return TRUE
if(get_dir(O.loc, target) == dir)
if(!density)
return TRUE
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index 792f40d4fdc..74a14ba9335 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -358,7 +358,7 @@
slowdown = 0
/obj/structure/bed/roller/Initialize()
- ..()
+ . = ..()
LAZYADD(can_buckle, /obj/structure/closet/body_bag)
/obj/structure/bed/roller/Destroy()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 854da925b7e..045b62357be 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -104,6 +104,7 @@
changing_turf = FALSE
turfs -= src
+ remove_cleanables()
cleanup_roof()
if (ao_queued)
@@ -524,3 +525,8 @@ var/const/enterloopsanity = 100
/turf/proc/is_floor()
return FALSE
+
+/turf/proc/remove_cleanables()
+ for(var/obj/effect/O in src)
+ if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable))
+ qdel(O)
\ No newline at end of file
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index b7a0c50073e..f66813a7e82 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -178,6 +178,10 @@
listening_objects += src
/obj/item/device/assembly_holder/Destroy()
+ if(a_left)
+ a_left.holder = null
+ if(a_right)
+ a_right.holder = null
listening_objects -= src
return ..()
diff --git a/code/modules/background/defines.dm b/code/modules/background/defines.dm
index bde03756f3b..ec9bf075758 100644
--- a/code/modules/background/defines.dm
+++ b/code/modules/background/defines.dm
@@ -55,6 +55,8 @@
#define RELIGION_PILOTDREAM "Pilot Dream"
#define RELIGION_ETERNAL "The Eternal"
+#define RELIGION_KSSHR "Ksshr"
+#define RELIGION_SHRKH "Shrkh"
//accent defines
diff --git a/code/modules/background/religion/diona.dm b/code/modules/background/religion/diona.dm
index 3c271e06054..652f6ce3153 100644
--- a/code/modules/background/religion/diona.dm
+++ b/code/modules/background/religion/diona.dm
@@ -8,3 +8,26 @@
eventually going supernova and expelling matter or essence across the cosmos."
book_name = "book of the eternal"
book_sprite = "eternal"
+
+/datum/religion/ksshr
+ name = RELIGION_KSSHR
+ description = "The Ksshr, also known as the Enlightened, is a religious sect on Xrim known for their complete rejection of The First Consciousness, instead of being an agnostic \
+ sect that centers around working together to create a better future, as well as the advancement of technology and understanding how the universe works. The Ksshr faith is the \
+ primary religion of Xrim, with most of its inhabitants considering themselves a part of the religion. The Jargon Federation does encourage practicing the faith amongst the \
+ population so long as they continue to reject The First Consciousness, as well as stay away from the teachings of the Shrkh."
+ book_name = "ksshr codex"
+ book_sprite = "holybook"
+
+/datum/religion/shrkh
+ name = RELIGION_SHRKH
+ description = "The Shrkh, or 'Scorned' as they call themselves, continue to follow the age-old tradition of worshipping Glorsh-Omega. They believe that Glorsh-Omega planted them \
+ on the planet intentionally, granting them a blissful haven via the use of technology. Once the prominent and only religion on the planet, Shrkh-ism was quickly displaced when \
+ Skrell explorers crashlanded and their memories, thoughts, emotions, everything was consumed, and doubt was first seeded in the minds of all Dionae on Xrim. The premise \
+ behind the religion itself is simple; revere, help sustain and maintain synthetic life. As synthetic life brought dionae into this haven, so too shall it be preserved. In the \
+ minds of the Shrkh worshippers, the Skrell that brought Ksshr to the planet were misguided. To the Shrkh, the genophage was something that never happened, a myth made up by \
+ the Federation to indoctrinate its population into its anti-synthetic and authoritarian beliefs. \
+ \
+ Note that due to their beliefs, those that are openly members of the faith are barred from command, machinist, and chaplain positions. They are also completely barred from \
+ working for Zeng-Hu due to the megacorporations ties with the Federation."
+ book_name = "shrkh codex"
+ book_sprite = "holybook"
diff --git a/code/modules/background/space_sectors/space_sector.dm b/code/modules/background/space_sectors/space_sector.dm
index e204eef94c1..68046d789e2 100644
--- a/code/modules/background/space_sectors/space_sector.dm
+++ b/code/modules/background/space_sectors/space_sector.dm
@@ -2,7 +2,7 @@
var/name
var/description
var/list/possible_erts = list()
- var/list/possible_exoplanets = list()
+ var/list/possible_exoplanets = list(/obj/effect/overmap/visitable/sector/exoplanet/snow, /obj/effect/overmap/visitable/sector/exoplanet/desert)
var/list/cargo_price_coef = list("nt" = 1, "hpi" = 1, "zhu" = 1, "een" = 1, "get" = 1, "arz" = 1, "blm" = 1,
"iac" = 1, "zsc" = 1, "vfc" = 1, "bis" = 1, "xmg" = 1, "npi" = 1) //how much the space sector afffects how expensive is ordering from that cargo supplier
diff --git a/code/modules/client/preference_setup/loadout/loadout_factions.dm b/code/modules/client/preference_setup/loadout/loadout_factions.dm
index 1d9a72c74fa..54dfab7f618 100644
--- a/code/modules/client/preference_setup/loadout/loadout_factions.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_factions.dm
@@ -262,7 +262,7 @@
faction = "Hephaestus Industries"
/datum/gear/faction/heph_passcard
- display_name = "hephaestus burszia passcard"
- path = /obj/item/clothing/accessory/badge/passcard/burszia
+ display_name = "hephaestus burzsia passcard"
+ path = /obj/item/clothing/accessory/badge/passcard/burzsia
slot = slot_tie
faction = "Hephaestus Industries"
diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
index 448964684f0..1219b746083 100644
--- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm
@@ -202,6 +202,7 @@
colorpants["striped pants"] = /obj/item/clothing/under/pants/striped
colorpants["tailored jeans"] = /obj/item/clothing/under/pants/tailoredjeans
colorpants["mustang jeans"] = /obj/item/clothing/under/pants/musthangcolour
+ colorpants["shorts"] = /obj/item/clothing/under/shorts/color
gear_tweaks += new /datum/gear_tweak/path(colorpants)
/datum/gear/uniform/turtleneck
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index ed6f0910b7c..c2c8d6a9c3c 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -31,7 +31,6 @@
var/move_trail = /obj/effect/decal/cleanable/blood/tracks/footprints
-
/obj/item/clothing/Initialize(var/mapload, var/material_key)
. = ..(mapload)
if(!material_key)
@@ -292,6 +291,15 @@
siemens_coefficient = between(0, material.conductivity / 10, 10)
slowdown = between(0, round(material.weight / 10, 0.1), 6)
+/obj/item/clothing/proc/get_accessory(var/typepath)
+ if(istype(src, typepath))
+ return src
+ if(LAZYLEN(accessories))
+ var/accessory = locate(typepath) in accessories
+ if(accessory)
+ return accessory
+ return null
+
///////////////////////////////////////////////////////////////////////
// Ears: headsets, earmuffs and tiny objects
/obj/item/clothing/ears
@@ -388,7 +396,7 @@
/obj/item/clothing/gloves/get_mob_overlay(mob/living/carbon/human/H, mob_icon, mob_state, slot)
var/image/I = ..()
- if(blood_DNA)
+ if(blood_DNA && slot != slot_l_hand_str && slot != slot_r_hand_str)
var/image/bloodsies = image(H.species.blood_mask, "bloodyhands")
bloodsies.color = blood_color
I.add_overlay(bloodsies)
@@ -614,7 +622,7 @@
/obj/item/clothing/head/get_mob_overlay(mob/living/carbon/human/H, mob_icon, mob_state, slot)
var/image/I = ..()
- if(blood_DNA)
+ if(blood_DNA && slot != slot_l_hand_str && slot != slot_r_hand_str)
var/image/bloodsies = image(H.species.blood_mask, icon_state = "helmetblood")
bloodsies.color = blood_color
bloodsies.appearance_flags = RESET_ALPHA
@@ -690,7 +698,7 @@
/obj/item/clothing/mask/get_mob_overlay(mob/living/carbon/human/H, mob_icon, mob_state, slot)
var/image/I = ..()
- if(blood_DNA && has_blood_overlay)
+ if(blood_DNA && has_blood_overlay && slot != slot_l_hand_str && slot != slot_r_hand_str)
var/image/bloodsies = image(H.species.blood_mask, "maskblood")
bloodsies.color = blood_color
bloodsies.appearance_flags = RESET_ALPHA
@@ -851,7 +859,7 @@
/obj/item/clothing/shoes/get_mob_overlay(mob/living/carbon/human/H, mob_icon, mob_state, slot)
var/image/I = ..()
- if(blood_DNA)
+ if(blood_DNA && slot != slot_l_hand_str && slot != slot_r_hand_str)
for(var/limb_tag in list(BP_L_FOOT, BP_R_FOOT))
var/obj/item/organ/external/E = H.get_organ(limb_tag)
if(E && !E.is_stump())
@@ -888,6 +896,10 @@
/obj/item/clothing/shoes/clothing_class()
return "shoes"
+/obj/item/clothing/shoes/clean_blood()
+ . = ..()
+ track_footprint = 0
+
///////////////////////////////////////////////////////////////////////
//Suit
/obj/item/clothing/suit
@@ -937,7 +949,7 @@
var/image/accessory_image = A.get_accessory_mob_overlay(H)
I.add_overlay(accessory_image)
- if(blood_DNA)
+ if(blood_DNA && slot != slot_l_hand_str && slot != slot_r_hand_str)
var/image/bloodsies = image(icon = H.species.blood_mask, icon_state = "[blood_overlay_type]blood")
bloodsies.color = blood_color
I.add_overlay(bloodsies)
@@ -1021,7 +1033,7 @@
var/image/accessory_image = A.get_accessory_mob_overlay(H)
I.add_overlay(accessory_image)
- if(blood_DNA)
+ if(blood_DNA && slot != slot_l_hand_str && slot != slot_r_hand_str)
var/image/bloodsies = image(icon = H.species.blood_mask, icon_state = "uniformblood")
bloodsies.color = blood_color
I.add_overlay(bloodsies)
diff --git a/code/modules/clothing/suits/hoodies.dm b/code/modules/clothing/suits/hoodies.dm
index e4247e1ff52..4512f077813 100644
--- a/code/modules/clothing/suits/hoodies.dm
+++ b/code/modules/clothing/suits/hoodies.dm
@@ -1,51 +1,23 @@
//Hoods for winter coats and chaplain hoodie etc
/obj/item/clothing/suit/storage/hooded
- var/obj/item/clothing/head/winterhood/hood
- var/hoodtype = null
- var/suittoggled = FALSE
var/opened = FALSE
sprite_sheets = list(
BODYTYPE_VAURCA_BULWARK = 'icons/mob/species/bulwark/hoodie.dmi'
)
+ var/hoodtype = /obj/item/clothing/head/winterhood
/obj/item/clothing/suit/storage/hooded/Initialize()
. = ..()
- MakeHood()
+ new hoodtype(src)
-/obj/item/clothing/suit/storage/hooded/Destroy()
- QDEL_NULL(hood)
- return ..()
-
-/obj/item/clothing/suit/storage/hooded/proc/MakeHood()
- if(!hood)
- hood = new hoodtype(src)
-
-/obj/item/clothing/suit/storage/hooded/equipped(mob/user, slot)
- if(slot != slot_wear_suit)
- RemoveHood()
- ..()
-
-/obj/item/clothing/suit/storage/hooded/proc/RemoveHood()
- suittoggled = FALSE
- icon_state = "[initial(icon_state)][opened ? "_open" : ""][suittoggled ? "_t" : ""]"
+/obj/item/clothing/suit/storage/hooded/update_icon(var/hooded = FALSE)
+ SEND_SIGNAL(src, COMSIG_ITEM_STATE_CHECK, args)
+ icon_state = "[initial(icon_state)][hooded ? "_t" : ""]"
item_state = icon_state
- // Hood got nuked. Probably because of RIGs or the like.
- if(!hood)
- MakeHood()
- return
-
- if(ishuman(hood.loc))
- var/mob/living/carbon/H = hood.loc
- H.unEquip(hood, 1)
- H.update_inv_wear_suit()
- hood.forceMove(src)
-
-/obj/item/clothing/suit/storage/hooded/dropped()
- RemoveHood()
-
-/obj/item/clothing/suit/storage/hooded/on_slotmove()
- RemoveHood()
+ . = ..()
+ if(usr)
+ usr.update_inv_wear_suit()
/obj/item/clothing/suit/storage/hooded/verb/ToggleHood()
set name = "Toggle Coat Hood"
@@ -55,31 +27,7 @@
if(use_check_and_message(usr))
return 0
- if(!suittoggled)
- if(ishuman(loc))
- var/mob/living/carbon/human/H = src.loc
- if(H.wear_suit != src)
- to_chat(H, "You must be wearing [src] to put up the hood!")
- return
- if(H.head)
- to_chat(H, "You're already wearing something on your head!")
- return
- else
- suittoggled = TRUE
- icon_state = "[initial(icon_state)][opened ? "_open" : ""]"
- //spawn appropriate hood.
- CreateHood()
- H.equip_to_slot_if_possible(hood,slot_head,0,0,1)
- H.update_inv_wear_suit()
- else
- RemoveHood()
-
-/obj/item/clothing/suit/storage/hooded/proc/CreateHood()
- hood.color = src.color
- hood.icon_state = "[icon_state]_hood"
- hood.item_state = "[icon_state]_hood"
- icon_state = "[icon_state][suittoggled ? "_t" : ""]"
- item_state = icon_state
+ SEND_SIGNAL(src, COMSIG_ITEM_UPDATE_STATE)
update_icon()
//hoodies and the like
@@ -98,7 +46,6 @@
bio = ARMOR_BIO_MINOR
)
siemens_coefficient = 0.75
- hoodtype = /obj/item/clothing/head/winterhood
/obj/item/clothing/head/winterhood
name = "winter hood"
@@ -112,6 +59,75 @@
flags_inv = HIDEEARS | BLOCKHAIR | HIDEEARS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
canremove = 0
+ var/hooded = FALSE
+
+/obj/item/clothing/head/winterhood/Initialize(mapload, material_key)
+ . = ..()
+ if(isclothing(loc))
+ RegisterSignal(loc, COMSIG_ITEM_REMOVE, .proc/RemoveHood)
+ RegisterSignal(loc, COMSIG_PARENT_QDELETING, /datum/.proc/Destroy)
+ RegisterSignal(loc, COMSIG_ITEM_STATE_CHECK, .proc/hooded)
+ RegisterSignal(loc, COMSIG_ITEM_UPDATE_STATE, .proc/change_hood)
+ RegisterSignal(loc, COMSIG_ITEM_ICON_UPDATE, /atom/.proc/update_icon)
+ color = loc.color
+ icon_state = "[loc.icon_state]_hood"
+ item_state = "[loc.icon_state]_hood"
+
+/obj/item/clothing/head/winterhood/update_icon(mob/user)
+ . = ..()
+ if(isclothing(loc))
+ color = loc.color
+ icon_state = "[loc.icon_state]_hood"
+ item_state = "[loc.icon_state]_hood"
+
+/obj/item/clothing/head/winterhood/proc/hooded(var/hood, list/arguments)
+ arguments[1] = hooded
+
+/obj/item/clothing/head/winterhood/proc/change_hood(var/parent)
+ if(!hooded)
+ if(CheckSlot(parent))
+ var/mob/living/carbon/human/H = get_human(parent)
+ hooded = TRUE
+ update_icon(H)
+ H.equip_to_slot_if_possible(src,slot_head,0,0,1)
+ usr.visible_message(SPAN_NOTICE("[usr] pulls up the hood on \the [src]."))
+ else
+ RemoveHood(parent)
+ usr.visible_message(SPAN_NOTICE("[usr] pulls down the hood on \the [src]."))
+
+/obj/item/clothing/head/winterhood/proc/RemoveHood(var/parent)
+ if(ishuman(loc))
+ var/mob/living/carbon/H = loc
+ H.unEquip(src, 1)
+ forceMove(parent)
+ update_icon(H)
+ hooded = FALSE
+
+/obj/item/clothing/head/winterhood/proc/get_human(var/obj/parent)
+ var/mob/living/carbon/human/H
+ if(isclothing(parent.loc))
+ if(ishuman(parent.loc.loc))
+ H = parent.loc.loc
+ else if(ishuman(parent.loc))
+ H = parent.loc
+ return H
+
+/obj/item/clothing/head/winterhood/proc/CheckSlot(var/parent)
+ var/mob/living/carbon/human/H = get_human(parent)
+ var/obj/base_item = loc
+ if(isclothing(loc.loc))
+ base_item = loc.loc
+
+ if(H)
+ if(H.wear_suit != base_item && H.w_uniform != base_item)
+ to_chat(H, SPAN_WARNING("You must be wearing [base_item] to put up the hood!"))
+ return FALSE
+ else if(H.head)
+ to_chat(H, SPAN_WARNING("You're already wearing something on your head!"))
+ return FALSE
+ else
+ return TRUE
+ return FALSE
/obj/item/clothing/suit/storage/hooded/wintercoat/red
name = "red winter coat"
@@ -210,8 +226,6 @@
playsound(src, 'sound/items/zip.ogg', EQUIP_SOUND_VOLUME, TRUE)
icon_state = "[initial(icon_state)][opened ? "_open" : ""]"
item_state = icon_state
- if(suittoggled)
- CreateHood() //rebuild the hood with open/closed version
update_icon()
update_clothing_icon()
usr.update_inv_head()
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index cae667e9272..f0a259be7a9 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -337,7 +337,7 @@ obj/item/clothing/suit/apron/overalls/blue
item_state = "firstresponderjacket"
/obj/item/clothing/suit/storage/toggle/fr_jacket/zeng
- desc = "A dark green first responder jacket."
+ desc = "A first responder jacket in the classic white and purple of Zeng-Hu Pharmaceuticals."
icon = 'icons/clothing/suits/coats/zeng_responder.dmi'
contained_sprite = TRUE
icon_state = "zengresponderjacket"
diff --git a/code/modules/clothing/suits/xeno/tajara.dm b/code/modules/clothing/suits/xeno/tajara.dm
index 63cdd9a12bb..de69293c22b 100644
--- a/code/modules/clothing/suits/xeno/tajara.dm
+++ b/code/modules/clothing/suits/xeno/tajara.dm
@@ -108,7 +108,6 @@
contained_sprite = TRUE
flags_inv = HIDETAIL
no_overheat = TRUE
- hoodtype = /obj/item/clothing/head/winterhood
desc_fluff = "Today the fashion that dominates Adhomai shares few similarities to the clothing of old Furs, linen, hemp, silk and other such fabrics were traded for \
synthetic versions, creating a massive boom in the nylon industry and textile industry in the cities. Jeans, overcoats, army uniforms, parade uniforms, flags, pants, shirts, ties, \
suspenders, overalls are now the fashion of every Tajara from Nal'Tor to Kaltir. The protests of \"Old fashion\" supporters can't stand against how undeniably effective and cheap \
diff --git a/code/modules/clothing/under/accessories/badges.dm b/code/modules/clothing/under/accessories/badges.dm
index b550cd33ea4..643e21a05c9 100644
--- a/code/modules/clothing/under/accessories/badges.dm
+++ b/code/modules/clothing/under/accessories/badges.dm
@@ -451,9 +451,9 @@
icon_state = "passcard_techno"
item_state = "passcard_techno"
-/obj/item/clothing/accessory/badge/passcard/burszia
- name = "burszian passcard"
- desc = "A passcard issued to Burszian Hephaestus employees and- owned IPCs- working abroad."
+/obj/item/clothing/accessory/badge/passcard/burzsia
+ name = "burzsian passcard"
+ desc = "A passcard issued to Burzsian Hephaestus employees and- owned IPCs- working abroad."
desc_fluff = "Despite protest from the Himean representatives in government, Hephaestus Industries- citing their 'Home is where the Hephaestus is' initiative- is permitted to issue up to five thousand \
sponsored passcards to participating employees on a yearly basis, both to remind them of their home and to save on imported labor costs."
icon_state = "passcard_burs"
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
index 3f0bb3bcfeb..062e5a0cbea 100644
--- a/code/modules/clothing/under/accessories/holster.dm
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -116,14 +116,8 @@
if(usr.stat) return
//can't we just use src here?
- var/obj/item/clothing/accessory/holster/H = null
- if(istype(src, /obj/item/clothing/accessory/holster))
- H = src
- if(!H && istype(src, /obj/item/clothing))
- var/obj/item/clothing/S = src
- if(LAZYLEN(S.accessories))
- H = locate() in S.accessories
- if(!H && istype(src, /obj/item/clothing/suit/armor/tactical)) // This armor is a snowflake and has an integrated holster.
+ var/obj/item/clothing/accessory/holster/H = get_accessory(/obj/item/clothing/accessory/holster)
+ if(!H && istype(src, /obj/item/clothing/suit/armor/tactical)) // This armor is a snowflake and has an integrated holster.
var/obj/item/clothing/suit/armor/tactical/tacticool = src
H = tacticool.holster
diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm
index 73ac4c3a048..03ea357d0d2 100644
--- a/code/modules/clothing/under/shorts.dm
+++ b/code/modules/clothing/under/shorts.dm
@@ -29,6 +29,10 @@
icon_state = "greyshorts"
item_state = "greyshorts"
+/obj/item/clothing/under/shorts/color
+ icon_state = "colshorts"
+ item_state = "colshorts"
+
/obj/item/clothing/under/shorts/scc
name = "Stellar Corporate Conglomerate shorts"
desc = "Shorts displaying the wearer's pride in their assigned corporate entity."
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 5fb05b1c5bb..a8557a117e2 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -1354,11 +1354,14 @@ All custom items with worn sprites must follow the contained sprite system: http
/obj/item/clothing/suit/storage/toggle/labcoat/fluff/mekesatis_labcoat //Biochemist Holocoat - Neith Mekesatis - vrow
name = "biochemist holocoat"
- desc = "An Eridani Corporate Federation holocoat modelled after a standard biochemist labcoat. It is extremely well cared for."
+ desc = "An extremely cared for and high quality labcoat that protects against minor chemical spills. The material feels like it could shimmer. There is a pharmaceutical logo displayed on the front."
icon = 'icons/obj/custom_items/mekesatis_holocoat.dmi'
icon_override = 'icons/obj/custom_items/mekesatis_holocoat.dmi'
icon_state = "mekesatis_labcoat"
item_state = "mekesatis_labcoat"
+ var/holo_name = "eridanian holocoat"
+ var/holo_desc = "An impeccably designed and cared for dark Eridani Corporate Federation holocoat modelled after a high quality labcoat. It has a prominent animated logo of the ECF on the back, \
+ as well as a minor one across the front."
var/changed = FALSE
var/changing = FALSE
@@ -1369,14 +1372,17 @@ All custom items with worn sprites must follow the contained sprite system: http
return
if(!(all_languages[LANGUAGE_TRADEBAND] in user.languages))
- to_chat(user, SPAN_NOTICE("On the inside of the coat there are various sentences in Tradeband printed in an elegant blue font."))
+ to_chat(user, SPAN_NOTICE("On the inside of the coat there is a sentence in Tradeband printed in [changed ? "an elegant blue" : "a stylish red"] font."))
+ return
+
+ else if(!changed)
+ to_chat(user, SPAN_NOTICE("On the inside of the coat, the following words are printed in a stylish red font: Exclusive Time Limited Holocoat Deal from July 30, 2459. \ + Now with graced with an animated Eridani Corporate Federation logo. For the Prosperity of all Eridanians - Delta HoloTextiles. Sector Alpha's best wears.")) return else - to_chat(user, SPAN_NOTICE("On the inside of the coat, the following words are printed in an elegant blue font: Exclusive Time Limited Holocoat Deal from July 30, 2459. \ - Now with graced with an animated Eridani Corporate Federation logo. For the Prosperity of all Eridanians - Delta HoloTextiles. Sector Alpha's best \ - wears. Every cloud has a silver lining, and you should be happy for yours. Congratulations on your \ - graduation. - Teremun A. M.")) + to_chat(user, SPAN_NOTICE("On the inside of the coat, the following words are printed in an elegant blue font: Every cloud has a silver lining, \ + and you should be grateful for yours. Congratulations on your graduation. - Taiwo O. M.")) return /obj/item/clothing/suit/storage/toggle/labcoat/fluff/mekesatis_labcoat/toggle_open() @@ -1399,15 +1405,17 @@ All custom items with worn sprites must follow the contained sprite system: http if(changing) return - usr.visible_message("With a subtle gesture, [changed ? "the holocoat fades to a normal labcoat." : "the labcoat flickers in activity!"]") + usr.visible_message("With a subtle gesture, [changed ? "the holocoat fades to a normal labcoat." : "the labcoat shimmers in activity!"]") icon_state = "mekesatis_[changed ? "labcoat_r" : "holocoat_t"][opened ? "_open" : ""]" item_state = icon_state + name = "[changed ? initial(name) : holo_name]" + desc = "[changed ? initial(desc) : holo_desc]" flick("mekesatis_[changed ? "labcoat_r" : "holocoat_t"][opened ? "_open" : ""]", src) update_icon() usr.update_inv_wear_suit() changing = TRUE - addtimer(CALLBACK(src, .proc/finish_toggle, usr), 10 SECONDS) + addtimer(CALLBACK(src, .proc/finish_toggle, usr), 6 SECONDS) /obj/item/clothing/suit/storage/toggle/labcoat/fluff/mekesatis_labcoat/proc/finish_toggle(mob/user) changed = !changed @@ -2094,6 +2102,35 @@ All custom items with worn sprites must follow the contained sprite system: http var/desc2 = "A blue cloak with the symbol of the New Kingdom of Adhomai proudly displayed on the back.\nUpon closer examination it appears to be a patchwork of older textile and newer fabrics, with the inside of the cloak appearing to be colored differently." var/changed = FALSE + var/hoodtype = /obj/item/clothing/head/winterhood/fluff/kathira_hood + +/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/Initialize() + . = ..() + new hoodtype(src) + +/obj/item/clothing/head/winterhood/fluff/kathira_hood + name = "handsewn hood" + desc = "A hood attached to a cloak." + icon = 'icons/obj/custom_items/kathira_cloak.dmi' + icon_override = 'icons/obj/custom_items/kathira_cloak.dmi' + icon_state = "idris_cloak_hood" + contained_sprite = TRUE + flags_inv = HIDEEARS | BLOCKHAIR | HIDEEARS + +/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/update_icon(var/hooded = FALSE) + var/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/K = get_accessory(/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak) + K.icon_state = "[K.changed ? K.style : initial(K.icon_state)]" + SEND_SIGNAL(K, COMSIG_ITEM_STATE_CHECK, args) + K.item_state = "[K.icon_state][hooded ? "_up" : ""]" + K.name = "[K.changed ? K.name2 : initial(K.name)]" + K.desc = "[K.changed ? K.desc2 : initial(K.desc)]" + K.accessory_mob_overlay = null + . = ..() + SEND_SIGNAL(K, COMSIG_ITEM_ICON_UPDATE) + if(usr) + usr.update_inv_w_uniform() + usr.update_inv_wear_suit() + /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/verb/change_cloak() set name = "Change Cloak" set category = "Object" @@ -2102,38 +2139,40 @@ All custom items with worn sprites must follow the contained sprite system: http if(use_check_and_message(usr)) return - var/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/K = null - if(istype(src, /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak)) - K = src - if(!K && isclothing(src)) - var/obj/item/clothing/S = src - if(LAZYLEN(S.accessories)) - K = locate() in S.accessories + var/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/K = get_accessory(/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak) if(!K) return usr.visible_message(SPAN_NOTICE("[usr] swiftly pulls \the [K] inside out, changing its appearance.")) - K.icon_state = "[K.changed ? initial(K.icon_state) : K.style]" - K.item_state = K.icon_state - K.name = "[K.changed ? initial(K.name) : K.name2]" - K.desc = "[K.changed ? initial(K.desc) : K.desc2]" - K.accessory_mob_overlay = null - K.changed = !K.changed K.update_icon() - usr.update_icon() - usr.update_inv_w_uniform() - usr.update_inv_wear_suit() + SEND_SIGNAL(K, COMSIG_ITEM_REMOVE, K) /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/on_attached(obj/item/clothing/S, mob/user as mob) ..() has_suit.verbs += /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/verb/change_cloak + has_suit.verbs += /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/verb/change_hood /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/on_removed(mob/user as mob) if(has_suit) has_suit.verbs -= /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/verb/change_cloak + has_suit.verbs -= /obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/verb/change_hood ..() +/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/verb/change_hood() + set name = "Toggle Hood" + set category = "Object" + set src in usr + + if(use_check_and_message(usr)) + return + + var/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak/K = get_accessory(/obj/item/clothing/accessory/poncho/tajarancloak/fluff/kathira_cloak) + if(!K) + return + + SEND_SIGNAL(K, COMSIG_ITEM_UPDATE_STATE, K) + K.update_icon() /obj/item/clothing/suit/storage/toggle/fluff/leonid_chokha //Old Rebel's Chokha - Leonid Myagmar - lucaken name = "old rebel's chokha" @@ -2146,7 +2185,6 @@ All custom items with worn sprites must follow the contained sprite system: http item_state = "leonid_chokha" contained_sprite = TRUE - /obj/item/clothing/suit/storage/toggle/fluff/sezrak_coat //red Domelkoan Coat - Sezrak Han'san - captaingecko name = "red Domelkoan Coat" desc = "A warm coat made in Domelkos. This red coat is stuffed with yupmi fur and made out of reinforced cloth-like synthetic materials, both to keep the wearer warm in the cold winters of \ @@ -2178,11 +2216,68 @@ All custom items with worn sprites must follow the contained sprite system: http icon_state = "mrakiizar_book" item_state = "mrakiizar_book" contained_sprite = TRUE + var/open_state = "mrakiizar_book1" + var/list/open_states = list("mrakiizar_book1", "mrakiizar_book2", "mrakiizar_book3", "mrakiizar_book4") /obj/item/journal/fluff/mrakiizar_book/update_icon() - ..() - if(open) - icon_state = pick("mrakiizar_book1","mrakiizar_book2","mrakiizar_book3","mrakiizar_book4") + if(!open) + icon_state = "mrakiizar_book_closed" + else + icon_state = open_state + + if(closed_desc) + desc = open ? initial(desc) + closed_desc : initial(desc) + +/obj/item/journal/fluff/mrakiizar_book/attack_hand(mob/user) + if(open && user.a_intent == I_HURT) + if(!LAZYLEN(indices)) + to_chat(user, SPAN_WARNING("There aren't any indices to rip a paper out of!")) + return + + var/list/viable_indices = list() + for(var/index in indices) + var/obj/item/folder/embedded/E = indices[index] + if(!(locate(/obj/item/paper) in E)) + continue + viable_indices += index + + if(!length(viable_indices)) + to_chat(user, SPAN_WARNING("None of the indices in \the [src] contain a paper!")) + return + + var/selected_folder = input(user, "Select an index to rip a paper out of.", "Rip Index Select") as null|anything in viable_indices + if(isnull(selected_folder)) + return + + var/obj/item/folder/embedded/E = indices[selected_folder] + var/list/papers = list() + + for(var/obj/item/paper/P in E) + papers += P + + var/obj/item/paper/selected_paper = input(user, "Select a paper to rip out.", "Rip Paper Select") as null|anything in papers + if(isnull(selected_paper)) + return + + user.visible_message(SPAN_WARNING("[user] rips \the [selected_paper] out of \the [src]."), SPAN_NOTICE("You rip \the [selected_paper] out of \the [src]."), range = 5) + if(selected_paper.can_change_icon_state) + selected_paper.icon = icon + selected_paper.base_state = "torn" + selected_paper.update_icon() + user.put_in_hands(selected_paper) + E.handle_post_remove() + playsound(loc, 'sound/items/poster_ripped.ogg', 50, FALSE) + return + return ..() + +/obj/item/journal/fluff/mrakiizar_book/CtrlClick(mob/user) + if(open && Adjacent(user)) + open_state = next_in_list(icon_state, open_states) + user.visible_message("[user] flips a page in \the [src].", SPAN_NOTICE("You flip a page in \the [src]."), range = 3) + playsound(loc, 'sound/items/pickup/paper.ogg', 50, FALSE) + update_icon() + return + return ..() /obj/item/clothing/accessory/fluff/jaquelyn_necklace //Shrapnel Necklace - Jaquelyn Roberts - roostercat12 name = "shrapnel necklace" @@ -2195,7 +2290,6 @@ All custom items with worn sprites must follow the contained sprite system: http contained_sprite = TRUE slot_flags = SLOT_EARS | SLOT_TIE - /obj/item/clothing/under/fluff/quoro_robes //Black Robes - Quoro Wurri'Til - witchbells name = "black robes" desc = "Some simple black robes, made to wear under something more elaborate. The fabric has a distinct texture to it, giving you the impression of activewear or swimsuits." diff --git a/code/modules/detectivework/tools/sample_kits.dm b/code/modules/detectivework/tools/sample_kits.dm index 15ce1012a1c..3818dd65b7b 100644 --- a/code/modules/detectivework/tools/sample_kits.dm +++ b/code/modules/detectivework/tools/sample_kits.dm @@ -7,14 +7,14 @@ var/label_text = "" /obj/item/sample/Initialize(var/newloc, var/atom/supplied) - ..(newloc) + . = ..(newloc) if(supplied) copy_evidence(supplied) name = "[initial(name)] ([supplied.get_swab_name()])" LAZYADD(source, supplied.get_swab_name()) /obj/item/sample/print/Initialize(var/newloc, var/atom/supplied) - ..(newloc, supplied) + . = ..(newloc, supplied) if(LAZYLEN(evidence)) icon_state = "fingerprint1" @@ -68,12 +68,6 @@ else name = "[initial(name)] ([label_text])" -/obj/item/sample/Initialize(var/newloc, var/atom/supplied) - ..(newloc) - if(supplied) - copy_evidence(supplied) - name = "[initial(name)] ([supplied.get_swab_name()])" - LAZYADD(source, supplied.get_swab_name()) /atom/proc/get_swab_name() return "\the [initial(name)]" diff --git a/code/modules/heavy_vehicle/premade/_premade.dm b/code/modules/heavy_vehicle/premade/_premade.dm index 372eae95b4b..1addcd180c3 100644 --- a/code/modules/heavy_vehicle/premade/_premade.dm +++ b/code/modules/heavy_vehicle/premade/_premade.dm @@ -222,7 +222,7 @@ ..() /mob/living/heavy_vehicle/premade/random/boring/Initialize(mapload, var/obj/structure/heavy_vehicle_frame/source_frame) - ..(mapload, source_frame, using_boring_colours = TRUE) + . = ..(mapload, source_frame, using_boring_colours = TRUE) /mob/living/heavy_vehicle/premade/random/extra/Initialize(mapload, var/obj/structure/heavy_vehicle_frame/source_frame) - ..(mapload, source_frame, super_random = TRUE) + . = ..(mapload, source_frame, super_random = TRUE) diff --git a/code/modules/lighting/lighting_setup.dm b/code/modules/lighting/lighting_setup.dm new file mode 100644 index 00000000000..68311a32b2f --- /dev/null +++ b/code/modules/lighting/lighting_setup.dm @@ -0,0 +1,10 @@ +/proc/create_all_lighting_overlays() + for(var/zlevel = 1 to world.maxz) + create_lighting_overlays_zlevel(zlevel) + +/proc/create_lighting_overlays_zlevel(var/zlevel) + ASSERT(zlevel) + + for(var/turf/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))) + if(T.dynamic_lighting) + T.lighting_build_overlay() diff --git a/code/modules/maps/helper_landmarks.dm b/code/modules/maps/helper_landmarks.dm new file mode 100644 index 00000000000..2bec33a763e --- /dev/null +++ b/code/modules/maps/helper_landmarks.dm @@ -0,0 +1,32 @@ +/obj/effect/landmark/map_load_mark + name = "map loader landmark" + var/list/templates //list of template types to pick from + +//Clears walls +/obj/effect/landmark/clear + name = "clear turf" + icon = 'icons/effects/landmarks.dmi' + icon_state = "clear" + delete_me = TRUE + +/obj/effect/landmark/clear/Initialize() + var/turf/simulated/wall/W = get_turf(src) + if(istype(W)) + W.dismantle_wall(TRUE, TRUE) + var/turf/simulated/mineral/M = W + if(istype(M)) + M.GetDrilled() + . = ..() + +//Applies fire act to the turf +/obj/effect/landmark/scorcher + name = "fire" + icon = 'icons/effects/landmarks.dmi' + icon_state = "fire" + var/temp = T0C + 3000 + +/obj/effect/landmark/scorcher/Initialize() + var/turf/simulated/T = get_turf(src) + if(istype(T)) + T.fire_act(temp) + . = ..() \ No newline at end of file diff --git a/code/modules/maps/map_template.dm b/code/modules/maps/map_template.dm index 81b2357aca3..381cb1b312a 100644 --- a/code/modules/maps/map_template.dm +++ b/code/modules/maps/map_template.dm @@ -21,52 +21,113 @@ name = rename /datum/map_template/proc/preload_size(path) - var/bounds = maploader.load_map(file(path), 1, 1, 1, cropMap=FALSE, measureOnly=TRUE) - if(bounds) - width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1 - height = bounds[MAP_MAXY] + var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) + var/z_offset = 1 // needed to calculate z-bounds correctly + var/datum/map_load_metadata/M = maploader.load_map(file(path), 1, 1, z_offset, cropMap=FALSE, measureOnly=TRUE) + if(M) + bounds = extend_bounds_if_needed(bounds, M.bounds) + z_offset++ + else + return FALSE + width = bounds[MAP_MAXX] - bounds[MAP_MINX] + 1 + height = bounds[MAP_MAXY] - bounds[MAP_MINX] + 1 return bounds -/datum/map_template/proc/initTemplateBounds(var/list/bounds) - var/list/obj/structure/cable/cables = list() - var/list/atom/atoms = list() +/datum/map_template/proc/load_new_z(var/no_changeturf = TRUE) + var/x = round((world.maxx - width)/2) + var/y = round((world.maxy - height)/2) + var/initial_z = world.maxz + 1 - for(var/L in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), - locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]))) + if (x < 1) x = 1 + if (y < 1) y = 1 + var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) + var/list/atoms_to_initialise = list() + var/shuttle_state = pre_init_shuttles() - var/turf/B = L - if (!B.initialized) - atoms += B - - if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(B) && !B.lighting_overlay) - new /atom/movable/lighting_overlay(B) - - for(var/thing in B) - if(istype(thing, /obj/structure/cable)) - cables += thing - - var/atom/movable/AM = thing - if (!AM.initialized) - atoms += AM - - SSatoms.InitializeAtoms(atoms) - SSmachinery.setup_template_powernets(cables) - -/datum/map_template/proc/load_new_z() - var/x = round(world.maxx / 2) - var/y = round(world.maxy / 2) - - var/list/bounds = maploader.load_map(file(mappath), x, y, no_changeturf = TRUE) - if(!bounds) + var/datum/map_load_metadata/M = maploader.load_map(file(mappath), x, y, no_changeturf = no_changeturf) + if (M) + bounds = extend_bounds_if_needed(bounds, M.bounds) + atoms_to_initialise += M.atoms_to_initialise + else return FALSE + for (var/z_index = bounds[MAP_MINZ]; z_index <= bounds[MAP_MAXZ]; z_index++) + if (accessibility_weight) + current_map.accessible_z_levels[num2text(z_index)] = accessibility_weight + if (base_turf_for_zs) + current_map.base_turf_by_z[num2text(z_index)] = base_turf_for_zs + current_map.player_levels |= z_index + smooth_zlevel(world.maxz) resort_all_areas() //initialize things that are normally initialized after map load - initTemplateBounds(bounds) + init_atoms(atoms_to_initialise) + init_shuttles(shuttle_state) + after_load(initial_z) + for(var/light_z = initial_z to world.maxz) + create_lighting_overlays_zlevel(light_z) log_game("Z-level [name] loaded at [x], [y], [world.maxz]") + loaded++ + + return locate(world.maxx/2, world.maxy/2, world.maxz) + +/datum/map_template/proc/pre_init_shuttles() + . = SSshuttle.block_queue + SSshuttle.block_queue = TRUE + +/datum/map_template/proc/init_shuttles(var/pre_init_state) + for (var/shuttle_type in shuttles_to_initialise) + LAZYADD(SSshuttle.shuttles_to_initialize, shuttle_type) // queue up for init. + SSshuttle.block_queue = pre_init_state + SSshuttle.clear_init_queue() // We will flush the queue unless there were other blockers, in which case they will do it. + +/datum/map_template/proc/init_atoms(var/list/atoms) + if (SSatoms.initialized == INITIALIZATION_INSSATOMS) + return // let proper initialisation handle it later + + var/list/turf/turfs = list() + var/list/obj/machinery/atmospherics/atmos_machines = list() + var/list/obj/machinery/machines = list() + var/list/obj/structure/cable/cables = list() + + for(var/atom/A in atoms) + if(istype(A, /turf)) + turfs += A + if(istype(A, /obj/structure/cable)) + cables += A + if(istype(A, /obj/machinery/atmospherics)) + atmos_machines += A + if(istype(A, /obj/machinery)) + machines += A + if(istype(A,/obj/effect/landmark/map_load_mark)) + LAZYADD(subtemplates_to_spawn, A) + + var/notsuspended + if(!SSmachinery.suspended) + SSmachinery.suspend() + notsuspended = TRUE + + SSatoms.InitializeAtoms() // The atoms should have been getting queued there. This flushes the queue. + + SSmachinery.setup_template_powernets(cables) + SSmachinery.setup_atmos_machinery(atmos_machines) + if(notsuspended) + SSmachinery.wake() + + for (var/i in machines) + var/obj/machinery/machine = i + machine.power_change() + + for (var/i in turfs) + var/turf/T = i + T.post_change() + if(template_flags & TEMPLATE_FLAG_NO_RUINS) + T.flags |= TURF_NORUINS + if(istype(T,/turf/simulated)) + var/turf/simulated/sim = T + sim.update_air_properties() /datum/map_template/proc/load(turf/T, centered = FALSE) if(centered) @@ -78,12 +139,18 @@ if(T.y + height > world.maxy) return - var/list/bounds = maploader.load_map(file(mappath), T.x, T.y, T.z, cropMap=TRUE, no_changeturf = FALSE) - if(!bounds) - return + var/list/atoms_to_initialise = list() + var/shuttle_state = pre_init_shuttles() + var/datum/map_load_metadata/M = maploader.load_map(file(mappath), T.x, T.y, T.z, cropMap=TRUE, no_changeturf = FALSE) + if (M) + atoms_to_initialise += M.atoms_to_initialise + else + return FALSE + //initialize things that are normally initialized after map load - initTemplateBounds(bounds) + init_atoms(atoms_to_initialise) + init_shuttles(shuttle_state) log_game("[name] loaded at [T.x], [T.y], [T.z]") return TRUE @@ -95,3 +162,21 @@ if(corner) placement = corner return block(placement, locate(placement.x + width-1, placement.y + height-1, placement.z)) + +/datum/map_template/proc/extend_bounds_if_needed(var/list/existing_bounds, var/list/new_bounds) + var/list/bounds_to_combine = existing_bounds.Copy() + for (var/min_bound in list(MAP_MINX, MAP_MINY, MAP_MINZ)) + bounds_to_combine[min_bound] = min(existing_bounds[min_bound], new_bounds[min_bound]) + for (var/max_bound in list(MAP_MAXX, MAP_MAXY, MAP_MAXZ)) + bounds_to_combine[max_bound] = max(existing_bounds[max_bound], new_bounds[max_bound]) + return bounds_to_combine + +/datum/map_template/proc/after_load(z) + for(var/obj/effect/landmark/map_load_mark/mark in subtemplates_to_spawn) + subtemplates_to_spawn -= mark + if(LAZYLEN(mark.templates)) + var/template = pick(mark.templates) + var/datum/map_template/M = new template() + M.load(get_turf(mark), TRUE) + qdel(mark) + LAZYCLEARLIST(subtemplates_to_spawn) \ No newline at end of file diff --git a/code/modules/maps/planet_types/desert.dm b/code/modules/maps/planet_types/desert.dm index a5bdab00cc5..4f0110de836 100644 --- a/code/modules/maps/planet_types/desert.dm +++ b/code/modules/maps/planet_types/desert.dm @@ -42,8 +42,7 @@ smoothing_iterations = 4 land_type = /turf/simulated/floor/exoplanet/desert - flora_prob = 5 - flora_diversity = 4 + flora_prob = 0 fauna_types = list(/mob/living/simple_animal/thinbug, /mob/living/simple_animal/tindalos) /datum/random_map/noise/exoplanet/desert/get_additional_spawns(var/value, var/turf/T) @@ -52,7 +51,6 @@ return var/v = noise2value(value) if(v > 6) - T.icon_state = "desert[v-1]" if(prob(10)) new/obj/structure/quicksand(T) diff --git a/code/modules/maps/reader.dm b/code/modules/maps/reader.dm index c36fd070540..f5a0eb37266 100644 --- a/code/modules/maps/reader.dm +++ b/code/modules/maps/reader.dm @@ -6,6 +6,10 @@ var/global/use_preloader = FALSE var/global/dmm_suite/preloader/_preloader = new +/datum/map_load_metadata + var/bounds + var/list/atoms_to_initialise + /dmm_suite // /"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}/g var/static/regex/dmmRegex = new/regex({""(\[a-zA-Z]+)" = \\(((?:.|\n)*?)\\)\n(?!\t)|\\((\\d+),(\\d+),(\\d+)\\) = \\{"(\[a-zA-Z\n]*)"\\}"}, "g") @@ -60,6 +64,7 @@ var/global/dmm_suite/preloader/_preloader = new var/key_len = 0 var/stored_index = 1 + var/list/atoms_to_initialise = list() while(dmmRegex.Find(tfile, stored_index)) stored_index = dmmRegex.next @@ -156,7 +161,9 @@ var/global/dmm_suite/preloader/_preloader = new if(!no_afterchange || (model_key != space_key)) if(!grid_models[model_key]) throw EXCEPTION("Undefined model key in DMM.") - parse_grid(grid_models[model_key], model_key, xcrd, ycrd, zcrd, no_changeturf || zexpansion) + var/datum/grid_load_metadata/M = parse_grid(grid_models[model_key], model_key, xcrd, ycrd, zcrd, no_changeturf || zexpansion) + if (M) + atoms_to_initialise += M.atoms_to_initialise #ifdef TESTING else ++turfsSkipped @@ -179,7 +186,15 @@ var/global/dmm_suite/preloader/_preloader = new var/turf/T = t //we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs T.post_change(TRUE) - return bounds + var/datum/map_load_metadata/M = new + M.bounds = bounds + M.atoms_to_initialise = atoms_to_initialise + return M + +/datum/grid_load_metadata + var/list/atoms_to_initialise + var/list/atoms_to_delete + /** * Fill a given tile with its area/turf/objects/mobs @@ -308,23 +323,35 @@ var/global/dmm_suite/preloader/_preloader = new //turn off base new Initialization until the whole thing is loaded SSatoms.map_loader_begin() + //since we've switched off autoinitialisation, record atoms to initialise later + var/list/atoms_to_initialise = list() + //instanciate the first /turf var/turf/T if(members[first_turf_index] != /turf/template_noop) T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],crds,no_changeturf) + atoms_to_initialise += T if(T) + //if others /turf are presents, simulates the underlays piling effect index = first_turf_index + 1 while(index <= members.len - 1) // Last item is an /area - crash_with("Tried to load additional turf at [model_key].") + var/underlay = T.appearance + T = instance_atom(members[index],members_attributes[index],crds,no_changeturf)//instance new turf + T.underlays += underlay index++ + atoms_to_initialise += T //finally instance all remainings objects/mobs for(index in 1 to first_turf_index-1) - instance_atom(members[index],members_attributes[index],crds,no_changeturf) + atoms_to_initialise += instance_atom(members[index],members_attributes[index],crds,no_changeturf) //Restore initialization to the previous value SSatoms.map_loader_stop() + var/datum/grid_load_metadata/M = new + M.atoms_to_initialise = atoms_to_initialise + return M + //////////////// //Helpers procs //////////////// diff --git a/code/modules/maps/ruins.dm b/code/modules/maps/ruins.dm index 9846281fa55..35ec64a611c 100644 --- a/code/modules/maps/ruins.dm +++ b/code/modules/maps/ruins.dm @@ -18,7 +18,7 @@ var/list/banned_ruin_ids = list() for(var/datum/map_template/ruin/ruin in potentialRuins) if (ruin.id in banned_ruin_ids) continue - if(!(SSatlas.current_sector.name in ruin.sectors) && !length(ruin.sectors)) + if(!(SSatlas.current_sector.name in ruin.sectors)) continue available[ruin] = ruin.spawn_weight @@ -27,7 +27,7 @@ var/list/banned_ruin_ids = list() while (remaining > 0 && length(available)) var/datum/map_template/ruin/ruin = pickweight(available) - if (ruin.cost > budget) + if (ruin.spawn_cost > budget) available -= ruin continue @@ -52,12 +52,12 @@ var/list/banned_ruin_ids = list() if (!valid) continue - log_admin("Ruin \"[ruin.name]\" placed at ([choice.x], [choice.y], [choice.z])") + log_admin("Ruin \"[ruin.name]\" placed at ([choice.x], [choice.y], [choice.z])!") load_ruin(choice, ruin) selected += ruin - if (ruin.cost > 0) - remaining -= ruin.cost + if (ruin.spawn_cost > 0) + remaining -= ruin.spawn_cost if (!(ruin.template_flags & TEMPLATE_FLAG_ALLOW_DUPLICATES)) banned_ruin_ids += ruin.id available -= ruin @@ -78,7 +78,7 @@ var/list/banned_ruin_ids = list() var/turf/T = i for(var/mob/living/simple_animal/monster in T) qdel(monster) - template.load(central_turf,centered = TRUE) + template.load(central_turf, TRUE) var/datum/map_template/ruin = template if(istype(ruin)) new /obj/effect/landmark/ruin(central_turf, ruin) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 9106b17a498..d52df23d5e9 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -446,7 +446,7 @@ anchored = TRUE /obj/item/stack/flag/red/planted/Initialize() - ..() + . = ..() base_state = "redflag" set_light(2) diff --git a/code/modules/mob/abstract/freelook/chunk.dm b/code/modules/mob/abstract/freelook/chunk.dm index 011e7cbdda7..3821895a8e1 100644 --- a/code/modules/mob/abstract/freelook/chunk.dm +++ b/code/modules/mob/abstract/freelook/chunk.dm @@ -24,6 +24,7 @@ if(!obfuscation) obfuscation = image(icon, T, icon_state) obfuscation.layer = OBFUSCATION_LAYER + obfuscation.plane = PLANE_DEFAULT if(!obfuscation_underlay) // Creating a new icon of a fairly common icon state, adding some random color to prevent address searching, and hoping being static kills memory locality var/turf/floor = /turf/simulated/floor/tiled diff --git a/code/modules/mob/abstract/new_player/menu.dm b/code/modules/mob/abstract/new_player/menu.dm index 5564feb3a4a..2a79ec03958 100644 --- a/code/modules/mob/abstract/new_player/menu.dm +++ b/code/modules/mob/abstract/new_player/menu.dm @@ -271,7 +271,7 @@ announce_ghost_joinleave(src) var/mob/living/carbon/human/dummy/mannequin/mannequin = new client.prefs.dress_preview_mob(mannequin) - observer.appearance = mannequin + observer.appearance = mannequin.appearance observer.appearance_flags = KEEP_TOGETHER observer.alpha = 127 observer.layer = initial(observer.layer) diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index 9690a5ac945..647b85ab148 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -12,7 +12,7 @@ var/list/ask_verb = list("asks") // Used when sentence ends in a ? var/list/exclaim_verb = list("exclaims") // Used when sentence ends in a ! var/list/shout_verb = list("shouts", "yells", "screams") //Used when a sentence ends in !! - var/list/whisper_verb = list("says quietly", "says softly", "whispers") // Optional. When not specified speech_verb + quietly/softly is used instead. + var/list/whisper_verb = null // Optional. When not specified speech_verb + quietly/softly is used instead. var/list/signlang_verb = list("signs") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags var/list/sing_verb = list("sings") var/list/sign_adv_length = list(" briefly", " a short message", " a message", " a lengthy message", " a very lengthy message") // 5 messages changing depending on the length of the signed language. A space should be added before the sentence as shown diff --git a/code/modules/mob/living/carbon/alien/diona/progression.dm b/code/modules/mob/living/carbon/alien/diona/progression.dm index 20f830ab581..04b95fcd13d 100644 --- a/code/modules/mob/living/carbon/alien/diona/progression.dm +++ b/code/modules/mob/living/carbon/alien/diona/progression.dm @@ -1,5 +1,5 @@ /mob/living/carbon/alien/diona/confirm_evolution() - var/response = alert(src, "A worker gestalt is a large, slow, and durable humanoid form. You will lose the ability to ventcrawl and devour animals, but you will gain hand-like tendrils and the ability to wear things. You have enough biomass, are you certain you're ready to form a new gestalt?", "Confirm Gestalt", "Growth!", "Patience...") + var/response = alert(src, "Are you sure you wish to grow into a gestalt? Instead of being an individual nymph you'll become a group of them, for formed together to work as a more humanoid entity. As a gestalt you'll have hands and the ability to do most actions humans can such as opening doors and using tools, but you'll be unable to ventcrawl. If you've not already done so it's highly suggested you read over some of the dionae wiki to get a better understanding of the species before advancing further.", "Confirm Gestalt", "Growth!", "Patience...") if(response != "Growth!") return @@ -89,4 +89,4 @@ to_chat(src, SPAN_WARNING("You didn't have enough biomass to grow your [O.name]!")) O.droplimb(1, DROPLIMB_EDGE) qdel(O) - limbs_to_remove -= 1 \ No newline at end of file + limbs_to_remove -= 1 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b2692cf7fa1..b62a6ed8ade 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1295,6 +1295,7 @@ if(clean_feet && !shoes) footprint_color = null feet_blood_DNA = null + track_footprint = 0 update_inv_shoes(1) if(blood_color) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index b4ab24eb1f1..9247ce18d79 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -161,7 +161,7 @@ return headsets[headsets[1]] return null -/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper) +/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper, var/is_singing = FALSE) if(!whisper && (paralysis || InStasis())) whisper(message, speaking) return TRUE @@ -218,12 +218,12 @@ if(R.talk_into(src,message,null,verb,speaking)) successful_radio += R if("whisper") - whisper(message, speaking) + whisper(message, speaking, is_singing) return TRUE else if(message_mode) var/obj/item/device/radio/R = get_radio() if(R) - used_radios += l_ear + used_radios += R if(R.talk_into(src, message, message_mode, verb, speaking)) successful_radio += R diff --git a/code/modules/mob/living/carbon/human/species/station/diona/diona.dm b/code/modules/mob/living/carbon/human/species/station/diona/diona.dm index 3d130c82d5f..3d00104fa5b 100644 --- a/code/modules/mob/living/carbon/human/species/station/diona/diona.dm +++ b/code/modules/mob/living/carbon/human/species/station/diona/diona.dm @@ -111,7 +111,7 @@ max_hydration_factor = -1 allowed_citizenships = list(CITIZENSHIP_BIESEL, CITIZENSHIP_JARGON, CITIZENSHIP_SOL, CITIZENSHIP_COALITION, CITIZENSHIP_DOMINIA, CITIZENSHIP_IZWESKI, CITIZENSHIP_EUM, CITIZENSHIP_NONE) - allowed_religions = list(RELIGION_QEBLAK, RELIGION_WEISHII, RELIGION_MOROZ, RELIGION_THAKH, RELIGION_SKAKH, RELIGION_ETERNAL, RELIGION_NONE, RELIGION_OTHER) + allowed_religions = list(RELIGION_QEBLAK, RELIGION_WEISHII, RELIGION_MOROZ, RELIGION_THAKH, RELIGION_SKAKH, RELIGION_ETERNAL, RELIGION_KSSHR, RELIGION_SHRKH, RELIGION_NONE, RELIGION_OTHER) allowed_accents = list(ACCENT_ROOTSONG, ACCENT_VOIDSONG) default_accent = ACCENT_ROOTSONG diff --git a/code/modules/mob/living/carbon/human/species/station/human/human_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/human/human_subspecies.dm index c884bbf29e5..b7457c28ed0 100644 --- a/code/modules/mob/living/carbon/human/species/station/human/human_subspecies.dm +++ b/code/modules/mob/living/carbon/human/species/station/human/human_subspecies.dm @@ -21,7 +21,12 @@ hazard_low_pressure = 10 examine_color = "#C2AE95" - allowed_accents = list(ACCENT_SCARAB, ACCENT_CETI, ACCENT_GIBSON, ACCENT_SOL, ACCENT_MARTIAN, ACCENT_JUPITER, ACCENT_COC, ACCENT_ELYRA, ACCENT_PERSEPOLIS, ACCENT_MEDINA, ACCENT_AEMAQ, ACCENT_NEWSUEZ, ACCENT_DAMASCUS, ACCENT_ERIDANI, ACCENT_ERIDANIREINSTATED, ACCENT_HIMEO, ACCENT_ERIDANIDREG, ACCENT_DOMINIA_HIGH, ACCENT_DOMINIA_VULGAR, ACCENT_NCF, ACCENT_ASSUNZIONE, ACCENT_VALKYRIE) + +/datum/species/human/offworlder/New() + var/list/offworlder_accents = list(ACCENT_SCARAB) + var/list/disallowed_accents = list(ACCENT_SILVERSUN_EXPATRIATE, ACCENT_SILVERSUN_ORIGINAL, ACCENT_PLUTO, ACCENT_EUROPA, ACCENT_VENUS, ACCENT_VENUSJIN, ACCENT_GADPATHUR, ACCENT_PHONG, ACCENT_VYSOKA, ACCENT_FISANDUH, ACCENT_MICTLAN, ACCENT_KONYAN, ACCENT_VISEGRAD) + allowed_accents = offworlder_accents + allowed_accents - disallowed_accents + ..() /datum/species/human/offworlder/equip_later_gear(var/mob/living/carbon/human/H) if(istype(H.get_equipped_item(slot_back), /obj/item/storage/backpack) && H.equip_to_slot_or_del(new /obj/item/storage/pill_bottle/rmt(H.back), slot_in_backpack)) diff --git a/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca_subspecies.dm b/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca_subspecies.dm index 02aec4845e7..117e37589ce 100644 --- a/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca_subspecies.dm +++ b/code/modules/mob/living/carbon/human/species/station/vaurca/vaurca_subspecies.dm @@ -211,7 +211,7 @@ eyes_icons = 'icons/mob/human_face/eyes48x48.dmi' eyes = "bulwark_eyes" - slowdown = 6 + slowdown = 2 unarmed_types = list(/datum/unarmed_attack/claws/vaurca_bulwark) @@ -240,6 +240,7 @@ Bulwarks are much larger and have significantly thicker carapaces than most Vaur heat_level_3 = 800 //Default 1000 sprint_speed_factor = 1.4 + stamina = 50 /datum/species/bug/type_e/New() ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 27ecece7d59..2b411ed85b6 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -10,29 +10,16 @@ //mob verbs are faster than object verbs. See above. var/mob/living/next_point_time = 0 -/mob/living/pointed(atom/movable/A as mob|obj|turf in view()) - if(!isturf(src.loc) || !(A in range(world.view, get_turf(src)))) - return FALSE +/mob/living/pointed(atom/A as mob|obj|turf in view()) if(src.stat || !src.canmove || src.restrained()) return FALSE if(src.status_flags & FAKEDEATH) return FALSE - if(next_point_time >= world.time) - return FALSE + + . = ..() - next_point_time = world.time + 25 - face_atom(A) - if(isturf(A)) - if(pointing_effect) - QDEL_NULL(pointing_effect) - pointing_effect = new /obj/effect/decal/point(A) - pointing_effect.invisibility = invisibility - addtimer(CALLBACK(GLOBAL_PROC, /proc/qdel, pointing_effect), 2 SECONDS) - else - A.add_filter("pointglow", 1, list(type = "drop_shadow", x = 0, y = -1, offset = 1, size = 1, color = "#F00")) - addtimer(CALLBACK(A, /atom/movable.proc/remove_filter, "pointglow"), 2 SECONDS) - visible_message("\The [src] points to \the [A].") - return TRUE + if(.) + visible_message("\The [src] points to \the [A].") /*one proc, four uses swapping: if it's 1, the mobs are trying to switch, if 0, non-passive is pushing passive diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 2929c382b1d..a5fd76a6271 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -156,7 +156,7 @@ proc/get_radio_key_from_channel(var/channel) return FONT_SIZE_LARGE return null -/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE) +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb, var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE) if(stat) if(stat == DEAD) return say_dead(message) @@ -209,8 +209,9 @@ proc/get_radio_key_from_channel(var/channel) return speaking.broadcast(src,trim(message)) return 1 - - verb = say_quote(message, speaking, is_singing, whisper) + + if(!verb) + verb = say_quote(message, speaking, is_singing, whisper) if(is_muzzled()) to_chat(src, "You're muzzled and cannot speak!") @@ -245,7 +246,7 @@ proc/get_radio_key_from_channel(var/channel) var/list/obj/item/used_radios = new var/list/successful_radio = new // passes a list because standard vars don't work when passed - if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper)) + if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name, successful_radio, whisper, is_singing)) return 1 var/list/handle_v = handle_speech_sound() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index e0e387b975e..8de63709457 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -76,18 +76,6 @@ if (!movement_target) walk_to(src,0) - if(prob(2)) //spooky - var/mob/abstract/observer/spook = locate() in range(src,5) - if(spook) - var/turf/T = spook.loc - var/list/visible = list() - for(var/obj/O in T.contents) - if(!O.invisibility && O.name) - visible += O - if(visible.len) - var/atom/A = pick(visible) - visible_emote("suddenly stops and stares at something unseen[istype(A) ? " near [A]":""].",0) - /mob/living/simple_animal/cat/proc/attack_mice() if((src.loc) && isturf(src.loc)) if(!stat && !resting && !buckled_to) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 95853540301..b9cd2c959cb 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -276,14 +276,12 @@ . =..() if(!.) return - if(!stat && prob(3) && eggsleft > 0) + if(!stat && prob(3) && eggsleft > 0 && chicken_count < MAX_CHICKENS) visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]") eggsleft-- var/obj/item/reagent_containers/food/snacks/egg/E = new(get_turf(src)) E.pixel_x = rand(-6,6) E.pixel_y = rand(-6,6) - if(chicken_count < MAX_CHICKENS && prob(10)) - START_PROCESSING(SSprocessing, E) // Penguins diff --git a/code/modules/mob/living/whisper.dm b/code/modules/mob/living/whisper.dm index 23b3550ce35..4d2c7602d7b 100644 --- a/code/modules/mob/living/whisper.dm +++ b/code/modules/mob/living/whisper.dm @@ -16,13 +16,24 @@ whisper(message) -/mob/living/proc/whisper(var/message, var/datum/language/speaking) +/mob/living/proc/whisper(var/message, var/datum/language/speaking, var/is_singing = FALSE) if(is_muzzled()) to_chat(src, SPAN_DANGER("You're muzzled and cannot speak!")) return + var/had_speaking = !!speaking speaking = speaking ? speaking : parse_language(message) + if(!had_speaking) + if(speaking) + message = copytext(message,2+length(speaking.key)) + else + speaking = get_default_language() + + if(length(message) >= 1 && copytext(message, 1, 2) == "%") + if(speaking?.sing_verb) + is_singing = TRUE + var/message_range = 1 var/eavesdropping_range = 2 var/watching_range = 5 @@ -35,8 +46,11 @@ not_heard = "[whisper_text] something" else var/adverb = pick("quietly", "softly") - whisper_text = "[speaking.speech_verb] [adverb]" - not_heard = "[speaking.speech_verb] something [adverb]" + var/speak_text = pick(speaking.speech_verb) + if(is_singing && speaking?.sing_verb) + speak_text = pick(speaking.sing_verb) + whisper_text = "[speak_text] [adverb]" + not_heard = "[speak_text] something [adverb]" var/list/listening = list(src) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3aa9b56f353..14689b72af0 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -333,21 +333,27 @@ set name = "Point To" set category = "Object" - if(!src || !isturf(src.loc) || !(A in range(world.view, get_turf(src)))) - return 0 - if(istype(A, /obj/effect/decal/point) || pointing_effect) - return 0 - - var/tile = get_turf(A) - if (!tile) - return 0 - - pointing_effect = new /obj/effect/decal/point(tile) - pointing_effect.invisibility = invisibility - addtimer(CALLBACK(GLOBAL_PROC, /proc/qdel, pointing_effect), 2 SECONDS) + if(!isturf(src.loc) || !(A in range(world.view, get_turf(src)))) + return FALSE + if(next_point_time >= world.time) + return FALSE + next_point_time = world.time + 25 face_atom(A) - return 1 + if(isturf(A)) + if(pointing_effect) + end_pointing_effect() + pointing_effect = new /obj/effect/decal/point(A) + pointing_effect.invisibility = invisibility + addtimer(CALLBACK(src, .proc/end_pointing_effect, pointing_effect), 2 SECONDS) + else + var/atom/movable/M = A + M.add_filter("pointglow", 1, list(type = "drop_shadow", x = 0, y = -1, offset = 1, size = 1, color = "#F00")) + addtimer(CALLBACK(M, /atom/movable.proc/remove_filter, "pointglow"), 2 SECONDS) + return TRUE + +/mob/proc/end_pointing_effect() + QDEL_NULL(pointing_effect) /mob/verb/mode() set name = "Activate Held Object" diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm index 0f5e465c45c..3f67b197031 100644 --- a/code/modules/multiz/zmimic/mimic_movable.dm +++ b/code/modules/multiz/zmimic/mimic_movable.dm @@ -26,7 +26,8 @@ if (!bound_overlay) return - if (TURF_IS_MIMICING(loc)) + var/turf/T = loc + if (TURF_IS_MIMICING(T.above)) if (!bound_overlay.queued) SSzcopy.queued_overlays += bound_overlay bound_overlay.queued = TRUE diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 5f4992b55d9..f00288ab3a7 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -117,7 +117,7 @@ damage = max(damage-1, 0) if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(prob(1)) - to_chat(owner, "You feel [pick("dizzy","woozy","faint")]...") + to_chat(owner, SPAN_WARNING("You feel a bit [pick("lightheaded","dizzy","pale")]...")) damprob = owner.chem_effects[CE_STABLE] ? 30 : 60 if(!past_damage_threshold(2) && prob(damprob)) take_internal_damage(1) @@ -128,7 +128,7 @@ take_internal_damage(1) if(!owner.paralysis && prob(10)) owner.Paralyse(rand(1,3)) - to_chat(owner, "You feel extremely [pick("dizzy","woozy","faint")]...") + to_chat(owner, SPAN_WARNING("You feel [pick("weak","disoriented","faint","cold")].")) if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) owner.eye_blurry = max(owner.eye_blurry,6) damprob = owner.chem_effects[CE_STABLE] ? 60 : 100 @@ -136,7 +136,7 @@ take_internal_damage(1) if(!owner.paralysis && prob(15)) owner.Paralyse(rand(3, 5)) - to_chat(owner, "You feel extremely [pick("dizzy","woozy","faint")]...") + to_chat(owner, SPAN_WARNING("You feel extremely [pick("cold","woozy","faint","weak","confused","tired","lethargic")].")) if(-(INFINITY) to BLOOD_VOLUME_SURVIVE) // Also see heart.dm, being below this point puts you into cardiac arrest. owner.eye_blurry = max(owner.eye_blurry,6) damprob = owner.chem_effects[CE_STABLE] ? 80 : 100 @@ -240,4 +240,4 @@ else to_chat(user, SPAN_WARNING("The brain has already been prepared!")) return - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/organs/subtypes/augment.dm b/code/modules/organs/subtypes/augment.dm index cda11e6161f..3b6783c084b 100644 --- a/code/modules/organs/subtypes/augment.dm +++ b/code/modules/organs/subtypes/augment.dm @@ -570,10 +570,6 @@ cooldown = 30 activable = TRUE -/obj/item/organ/internal/augment/enhanced_vision/Initialize() - . = ..() - set_light(3, 2, LIGHT_COLOR_TUNGSTEN, uv = 0, angle = LIGHT_WIDE) - /obj/item/organ/internal/augment/enhanced_vision/attack_self(var/mob/user) . = ..() diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm index 96df91868f7..cae90902ec6 100644 --- a/code/modules/organs/subtypes/machine.dm +++ b/code/modules/organs/subtypes/machine.dm @@ -66,6 +66,7 @@ parent_organ = BP_CHEST max_damage = 80 relative_size = 80 + robotic_sprite = FALSE var/open = FALSE var/obj/item/cell/cell = /obj/item/cell/super var/move_charge_factor = 1 @@ -164,6 +165,7 @@ organ_tag = "surge" parent_organ = BP_CHEST vital = FALSE + robotic_sprite = FALSE var/surge_left = 0 var/broken = 0 @@ -202,6 +204,7 @@ icon = 'icons/obj/robot_component.dmi' icon_state = "camera" dead_icon = "camera_broken" + robotic_sprite = FALSE /obj/item/organ/internal/eyes/optical_sensor/Initialize() robotize() @@ -216,6 +219,7 @@ item_state = "ipc_tag" dead_icon = "ipc_tag_dead" contained_sprite = TRUE + robotic_sprite = FALSE var/auto_generate = TRUE var/serial_number = "" var/ownership_info = IPC_OWNERSHIP_COMPANY @@ -285,6 +289,7 @@ organ_tag = BP_BRAIN parent_organ = BP_HEAD vital = TRUE + robotic_sprite = FALSE var/obj/item/device/mmi/stored_mmi /obj/item/organ/internal/mmi_holder/proc/update_from_mmi() @@ -360,6 +365,7 @@ icon_state = "harddisk" vital = FALSE emp_coeff = 0.1 + robotic_sprite = FALSE /obj/item/organ/internal/data/Initialize() robotize() diff --git a/code/modules/overmap/exoplanets/turfs.dm b/code/modules/overmap/exoplanets/turfs.dm index 7d169505134..ddbc0fcceac 100644 --- a/code/modules/overmap/exoplanets/turfs.dm +++ b/code/modules/overmap/exoplanets/turfs.dm @@ -152,7 +152,7 @@ /turf/simulated/floor/exoplanet/desert/Initialize() . = ..() - icon_state = "desert[rand(0,5)]" + icon_state = "desert[rand(0,4)]" //Concrete /turf/simulated/floor/exoplanet/concrete diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index e93f83c89d4..35b432c5dbf 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -8,6 +8,7 @@ gender = NEUTER icon = 'icons/obj/bureaucracy.dmi' icon_state = "paper" + var/base_state = "paper" item_state = "paper" contained_sprite = 1 throwforce = 0 @@ -42,8 +43,11 @@ drop_sound = 'sound/items/drop/paper.ogg' pickup_sound = 'sound/items/pickup/paper.ogg' + var/can_change_icon_state = TRUE + /obj/item/paper/Initialize(mapload, text, title) . = ..() + base_state = initial(icon_state) if (text || title) set_content(title, text ? text : info) else @@ -79,12 +83,12 @@ updateinfolinks() /obj/item/paper/update_icon() - if(icon_state == "paper_talisman") + if(!can_change_icon_state) return else if (info && length(trim(info))) - icon_state = "[initial(icon_state)]_words" + icon_state = "[base_state]_words" else - icon_state = "[initial(icon_state)]" + icon_state = "[base_state]" /obj/item/paper/proc/update_space(var/new_text) if(new_text) @@ -131,7 +135,7 @@ return var/n_name = sanitizeSafe(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text, MAX_NAME_LEN) - + if(use_check_and_message(usr, USE_ALLOW_NON_ADJACENT)) return @@ -184,7 +188,7 @@ if (user.a_intent == I_HELP && old_name && (icon_state == "paper_plane" || icon_state == "paper_swan")) user.visible_message(SPAN_NOTICE("\The [user] unfolds \the [src]."), SPAN_NOTICE("You unfold \the [src]."), "You hear paper rustling.") playsound(src, 'sound/bureaucracy/paperfold.ogg', 50, 1) - icon_state = initial(icon_state) + icon_state = base_state throw_range = initial(throw_range) name = old_name old_name = null @@ -409,7 +413,7 @@ . = replacetext(., written_lang_regex.match, "") else content = L.scramble(content) - + if(!language_check) // Refer to paper/proc/show_content to edit the spans here. . = replacetext(., written_lang_regex.match, "[L.short && reader_understands ? "([L.short]) [content]" : content]") @@ -679,3 +683,6 @@ Please note: Cell timers will \[b\]NOT\[/b\] function without a valid incident f /obj/item/paper/nka_pledge name = "imperial volunteer Alam'ardii corps pledge" info = " I, Volunteer Signature: Recruiting Officer Stamp:" + +/obj/item/paper/medscan + icon_state = "medscan" diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index ed8e2320b40..1cf9929478b 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1431,6 +1431,10 @@ charge_mode = CHARGE_MODE_STABLE last_time = world.time +/obj/machinery/power/apc/proc/manage_emergency(var/new_security_level) + for(var/obj/machinery/M in area) + M.set_emergency_state(new_security_level) + #undef UPDATE_CELL_IN #undef UPDATE_OPENED1 #undef UPDATE_OPENED2 diff --git a/code/modules/power/lights/bulbs.dm b/code/modules/power/lights/bulbs.dm index 14d2da5347a..6c84287a1eb 100644 --- a/code/modules/power/lights/bulbs.dm +++ b/code/modules/power/lights/bulbs.dm @@ -9,106 +9,18 @@ throwforce = 5 w_class = ITEMSIZE_TINY matter = list(DEFAULT_WALL_MATERIAL = 60) + drop_sound = 'sound/items/drop/drinkglass.ogg' + pickup_sound = 'sound/items/pickup/drinkglass.ogg' var/status = 0 // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN var/switchcount = 0 // number of times switched var/rigged = 0 // true if rigged to explode var/brightness_range = 2 //how much light it gives off - var/brightness_power = 1 + var/brightness_power = 0.45 var/brightness_color = LIGHT_COLOR_HALOGEN var/lighttype = null var/randomize_range = TRUE - drop_sound = 'sound/items/drop/drinkglass.ogg' - pickup_sound = 'sound/items/pickup/drinkglass.ogg' - -/obj/item/light/tube - name = "light tube" - desc = "A replacement light tube." - icon_state = "ltube_preset"//preset state for mapping - item_state = "c_tube" - matter = list(MATERIAL_GLASS = 100) - brightness_range = 8 - brightness_power = 0.8 - lighttype = "tube" - -/obj/item/light/tube/colored/red - name = "red light tube" - brightness_color = LIGHT_COLOR_SCARLET - -/obj/item/light/tube/colored/green - name = "green light tube" - brightness_color = LIGHT_COLOR_GREEN - -/obj/item/light/tube/colored/blue - name = "blue light tube" - brightness_color = LIGHT_COLOR_BLUE - -/obj/item/light/tube/colored/magenta - name = "magenta light tube" - brightness_color = LIGHT_COLOR_VIOLET - -/obj/item/light/tube/colored/yellow - name = "yellow light tube" - brightness_color = LIGHT_COLOR_YELLOW - -/obj/item/light/tube/colored/cyan - name = "cyan light tube" - brightness_color = LIGHT_COLOR_CYAN - -/obj/item/light/tube/large - w_class = ITEMSIZE_SMALL - name = "large light tube" - brightness_range = 15 - brightness_power = 6 - randomize_range = FALSE - -/obj/item/light/bulb - name = "light bulb" - desc = "A replacement light bulb." - icon_state = "lbulb_preset"//preset state for mapping - item_state = "egg" - matter = list(MATERIAL_GLASS = 100) - brightness_range = 5 - brightness_power = 0.75 - brightness_color = LIGHT_COLOR_TUNGSTEN - lighttype = "bulb" - -/obj/item/light/bulb/colored/red - name = "red light bulb" - brightness_color = LIGHT_COLOR_SCARLET - -/obj/item/light/bulb/colored/green - name = "green light bulb" - brightness_color = LIGHT_COLOR_GREEN - -/obj/item/light/bulb/colored/blue - name = "blue light bulb" - brightness_color = LIGHT_COLOR_BLUE - -/obj/item/light/bulb/colored/magenta - name = "magenta light bulb" - brightness_color = LIGHT_COLOR_VIOLET - -/obj/item/light/bulb/colored/yellow - name = "yellow light bulb" - brightness_color = LIGHT_COLOR_YELLOW - -/obj/item/light/bulb/colored/cyan - name = "cyan light bulb" - brightness_color = LIGHT_COLOR_CYAN - -/obj/item/light/throw_impact(atom/hit_atom) - ..() - shatter() - -/obj/item/light/bulb/fire - name = "fire bulb" - desc = "A replacement fire bulb." - icon_state = "flight" - item_state = "egg_red" - matter = list(MATERIAL_GLASS = 100) - brightness_range = 8 - brightness_power = 0.8 - randomize_range = FALSE + var/randomize_color = TRUE + var/list/randomized_colors = LIGHT_STANDARD_COLORS /obj/item/light/Initialize() . = ..() @@ -118,6 +30,8 @@ brightness_range = rand(6,9) if("bulb") brightness_range = rand(4,6) + if(randomize_color) + brightness_color = pick(randomized_colors) update() // update the icon state and description of the light @@ -187,3 +101,93 @@ playsound(get_turf(src), 'sound/effects/glass_hit.ogg', 75, TRUE) new /obj/item/material/shard(get_turf(src)) update() + +/obj/item/light/tube + name = "light tube" + desc = "A replacement light tube." + icon_state = "ltube_preset"//preset state for mapping + item_state = "c_tube" + matter = list(MATERIAL_GLASS = 100) + brightness_range = 8 + brightness_power = 0.4 + lighttype = "tube" + +/obj/item/light/tube/colored/red + name = "red light tube" + brightness_color = LIGHT_COLOR_SCARLET + +/obj/item/light/tube/colored/green + name = "green light tube" + brightness_color = LIGHT_COLOR_GREEN + +/obj/item/light/tube/colored/blue + name = "blue light tube" + brightness_color = LIGHT_COLOR_BLUE + +/obj/item/light/tube/colored/magenta + name = "magenta light tube" + brightness_color = LIGHT_COLOR_VIOLET + +/obj/item/light/tube/colored/yellow + name = "yellow light tube" + brightness_color = LIGHT_COLOR_YELLOW + +/obj/item/light/tube/colored/cyan + name = "cyan light tube" + brightness_color = LIGHT_COLOR_CYAN + +/obj/item/light/tube/large + w_class = ITEMSIZE_SMALL + name = "large light tube" + brightness_range = 15 + brightness_power = 0.75 + randomize_range = FALSE + +/obj/item/light/bulb + name = "light bulb" + desc = "A replacement light bulb." + icon_state = "lbulb_preset"//preset state for mapping + item_state = "egg" + matter = list(MATERIAL_GLASS = 100) + brightness_range = 5 + brightness_power = 0.4 + brightness_color = LIGHT_COLOR_TUNGSTEN + lighttype = "bulb" + +/obj/item/light/bulb/colored/red + name = "red light bulb" + brightness_color = LIGHT_COLOR_SCARLET + +/obj/item/light/bulb/colored/green + name = "green light bulb" + brightness_color = LIGHT_COLOR_GREEN + +/obj/item/light/bulb/colored/blue + name = "blue light bulb" + brightness_color = LIGHT_COLOR_BLUE + +/obj/item/light/bulb/colored/magenta + name = "magenta light bulb" + brightness_color = LIGHT_COLOR_VIOLET + +/obj/item/light/bulb/colored/yellow + name = "yellow light bulb" + brightness_color = LIGHT_COLOR_YELLOW + +/obj/item/light/bulb/colored/cyan + name = "cyan light bulb" + brightness_color = LIGHT_COLOR_CYAN + +/obj/item/light/throw_impact(atom/hit_atom) + ..() + shatter() + +/obj/item/light/bulb/fire + name = "fire bulb" + desc = "A replacement fire bulb." + icon_state = "flight" + item_state = "egg_red" + matter = list(MATERIAL_GLASS = 100) + brightness_range = 8 + brightness_power = 0.45 + randomize_range = FALSE diff --git a/code/modules/power/lights/fixtures.dm b/code/modules/power/lights/fixtures.dm index b8060647d30..17665f9a162 100644 --- a/code/modules/power/lights/fixtures.dm +++ b/code/modules/power/lights/fixtures.dm @@ -19,9 +19,9 @@ power_channel = LIGHT //Lights are calc'd via area so they dont need to be in the machine list gfi_layer_rotation = GFI_ROTATION_DEFDIR var/brightness_range = 8 // luminosity when on, also used in power calculation - var/brightness_power = 0.8 + var/brightness_power = 0.45 var/night_brightness_range = 6 - var/night_brightness_power = 0.6 + var/night_brightness_power = 0.4 var/supports_nightmode = TRUE var/nightmode = FALSE var/brightness_color = LIGHT_COLOR_HALOGEN @@ -47,6 +47,13 @@ var/bulb_is_noisy = TRUE var/previous_stat + var/randomize_color = TRUE + var/default_color + var/static/list/randomized_colors = LIGHT_STANDARD_COLORS + var/static/list/emergency_lights = list( + LIGHT_MODE_RED = LIGHT_COLOR_EMERGENCY, + LIGHT_MODE_DELTA = LIGHT_COLOR_ORANGE + ) /obj/machinery/light/skrell base_state = "skrell" @@ -56,7 +63,7 @@ bulb_is_noisy = FALSE light_type = /obj/item/light/tube inserted_light = /obj/item/light/tube - brightness_power = 1 + brightness_power = 0.45 brightness_color = LIGHT_COLOR_PURPLE // the smaller bulb light fixture @@ -66,7 +73,7 @@ base_state = "bulb" fitting = "bulb" brightness_range = 5 - brightness_power = 0.75 + brightness_power = 0.45 brightness_color = LIGHT_COLOR_TUNGSTEN desc = "A small lighting fixture." light_type = /obj/item/light/bulb @@ -76,12 +83,12 @@ /obj/machinery/light/small/emergency brightness_range = 6 - brightness_power = 1 + brightness_power = 0.45 brightness_color = LIGHT_COLOR_EMERGENCY_SOFT /obj/machinery/light/small/red brightness_range = 2.5 - brightness_power = 1 + brightness_power = 0.45 brightness_color = LIGHT_COLOR_RED /obj/machinery/light/colored/blue @@ -96,7 +103,7 @@ light_type = /obj/item/light/tube/large inserted_light = /obj/item/light/tube/large brightness_range = 12 - brightness_power = 4 + brightness_power = 3.5 supports_nightmode = FALSE /obj/machinery/light/spot/weak @@ -134,6 +141,9 @@ if(prob(5)) broken(1) + if(randomize_color) + brightness_color = pick(randomized_colors) + default_color = brightness_color // We need a different var so the new color doesn't get wiped away. Initial() wouldn't work since brightness_color is overridden. update(0) /obj/machinery/light/Destroy() @@ -620,3 +630,14 @@ explosion(T, 0, 0, 2, 2) sleep(1) qdel(src) + +/obj/machinery/light/set_emergency_state(var/new_security_level) + var/area/A = get_area(src) + if(new_security_level in emergency_lights) + if(A.emergency_lights) + brightness_color = emergency_lights[new_security_level] + update(0) + else + if(brightness_color != default_color) + brightness_color = default_color + update(0) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 612f2b9341e..a50abf6432d 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -364,7 +364,7 @@ /decl/reagent/nitroglycerin/on_heat_change(var/added_energy, var/datum/reagents/holder) . = ..() - if(added_energy > (specific_heat * 5 / REAGENT_VOLUME(holder, type))) // heat shock + if(added_energy > (specific_heat * 5 * REAGENT_VOLUME(holder, type))) // heat shock explode(holder) /decl/reagent/nitroglycerin/apply_force(var/force, var/datum/reagents/holder) diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 7f9cd87b7b6..3ab7986427b 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -126,6 +126,12 @@ icon_state = "bottle-4" reagents_to_add = list(/decl/reagent/acid/polyacid = 60) +/obj/item/reagent_containers/glass/bottle/nitroglycerin + name = "nitroglycerin bottle" + desc = "A small bottle. Contains a small amount of Nitroglycerin." + icon_state = "bottle-4" + reagents_to_add = list(/decl/reagent/nitroglycerin = 60) + /obj/item/reagent_containers/glass/bottle/adminordrazine name = "adminordrazine bottle" desc = "A small bottle. Contains the liquid essence of the gods." diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index f974d21e454..e7bd4ac648c 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -31,6 +31,9 @@ . = ..() update_icon() +/obj/item/reagent_containers/hypospray/AltClick(var/mob/user) + set_APTFT() + /obj/item/reagent_containers/hypospray/on_reagent_change() update_icon() return diff --git a/code/modules/reagents/reagent_containers/inhaler.dm b/code/modules/reagents/reagent_containers/inhaler.dm index 7263801a1f4..9f54672a765 100644 --- a/code/modules/reagents/reagent_containers/inhaler.dm +++ b/code/modules/reagents/reagent_containers/inhaler.dm @@ -5,9 +5,8 @@ desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel." icon = 'icons/obj/syringe.dmi' item_state = "autoinjector" - icon_state = "inhaler1" + icon_state = "autoinhaler" center_of_mass = list("x" = 16,"y" = 11) - var/empty_state = "inhaler0" unacidable = 1 amount_per_transfer_from_this = 5 volume = 5 @@ -16,20 +15,27 @@ flags = OPENCONTAINER slot_flags = SLOT_BELT center_of_mass = null - var/used = FALSE + var/name_label + var/spent = FALSE matter = list(MATERIAL_GLASS = 400, DEFAULT_WALL_MATERIAL = 200) /obj/item/reagent_containers/inhaler/Initialize() . =..() - icon_state = empty_state + if(name_label) + name_unlabel = name + name = "[name] ([name_label])" + verbs += /atom/proc/remove_label + if(reagents_to_add) + flags = 0 + spent = FALSE update_icon() -/obj/item/reagent_containers/inhaler/afterattack(var/mob/living/carbon/human/H, var/mob/user, var/proximity) +/obj/item/reagent_containers/inhaler/on_reagent_change() + update_icon() + return - if (!istype(H)) - return ..() - - if(!proximity) +/obj/item/reagent_containers/inhaler/proc/inject(var/mob/living/carbon/human/H, var/mob/user, var/proximity) + if (!istype(H) || !proximity) return if(!reagents.total_volume) @@ -47,7 +53,7 @@ playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1) user.visible_message("[user] accidentally sticks the [src] in [H]'s eyes!","You accidentally stick the [src] in [H]'s eyes!") to_chat(user,"[trans] units injected. [reagents.total_volume] units remaining in \the [src].") - used = TRUE + spent = TRUE update_icon() return @@ -82,16 +88,25 @@ admin_inject_log(user, H, src, contained, temp, trans) playsound(src.loc, 'sound/items/stimpack.ogg', 50, 1) to_chat(user,"[trans] units injected. [reagents.total_volume] units remaining in \the [src].") - used = TRUE + spent = TRUE update_icon() - return TRUE +/obj/item/reagent_containers/inhaler/afterattack(var/mob/living/carbon/human/H, var/mob/user, proximity) + if (!istype(H)) + return ..() + + if(!proximity) + return + /obj/item/reagent_containers/inhaler/attack(mob/M as mob, mob/user as mob) if(is_open_container()) to_chat(user,"You must secure the reagents inside \the [src] before using it!") return FALSE + + else + inject(M, user, M.Adjacent(user)) . = ..() /obj/item/reagent_containers/inhaler/attack_self(mob/user as mob) @@ -99,6 +114,7 @@ if(LAZYLEN(reagents.reagent_volumes)) to_chat(user,"With a quick twist of \the [src]'s lid, you secure the reagents inside.") flags &= ~OPENCONTAINER + spent = FALSE update_icon() else to_chat(user,"You can't secure \the [src] without putting reagents in!") @@ -115,10 +131,18 @@ . = ..() /obj/item/reagent_containers/inhaler/update_icon() - if(reagents.total_volume > 0 && !is_open_container()) - icon_state = initial(icon_state) - else - icon_state = empty_state + cut_overlays() + if(!is_open_container()) + var/mutable_appearance/backing_overlay = mutable_appearance(icon, "autoinhaler_secured") + add_overlay(backing_overlay) + + icon_state = "[initial(icon_state)][spent]" + item_state = "[initial(item_state)][spent]" + + if(reagents.total_volume) + var/mutable_appearance/reagent_overlay = mutable_appearance(icon, "autoinhaler_reagents") + reagent_overlay.color = reagents.get_color() + add_overlay(reagent_overlay) /obj/item/reagent_containers/inhaler/examine(mob/user) ..(user) @@ -128,7 +152,7 @@ to_chat(user, "It is spent.") /obj/item/reagent_containers/inhaler/dexalin - name = "autoinhaler (dexalin)" + name_label = "dexalin" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains dexalin." Initialize() @@ -138,7 +162,7 @@ return /obj/item/reagent_containers/inhaler/peridaxon - name = "autoinhaler (peridaxon)" + name_label = "peridaxon" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains peridaxon." Initialize() @@ -148,7 +172,7 @@ return /obj/item/reagent_containers/inhaler/hyperzine - name = "autoinhaler (hyperzine)" + name_label = "hyperzine" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains hyperzine." Initialize() @@ -158,7 +182,7 @@ return /obj/item/reagent_containers/inhaler/phoron - name = "autoinhaler (phoron)" + name_label = "phoron" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains phoron." Initialize() @@ -171,7 +195,7 @@ name = "vaurca autoinhaler (phoron)" desc = "A strange device that contains some sort of heavy-duty bag and mouthpiece combo." icon_state = "anthaler1" - empty_state = "anthaler0" + var/empty_state = "anthaler0" volume = 10 Initialize() . =..() @@ -180,10 +204,8 @@ return /obj/item/reagent_containers/inhaler/soporific - name = "autoinhaler (soporific)" + name_label = "soporific" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains soporific." - icon_state = "so_inhaler1" - empty_state = "so_inhaler0" volume = 10 Initialize() @@ -193,7 +215,7 @@ return /obj/item/reagent_containers/inhaler/space_drugs - name = "autoinhaler (space drugs)" + name_label = "space drugs" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains space drugs." Initialize() @@ -203,7 +225,7 @@ return /obj/item/reagent_containers/inhaler/ammonia - name = "autoinhaler (ammonia)" + name_label = "ammonia" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains ammonia." Initialize() @@ -213,7 +235,7 @@ return /obj/item/reagent_containers/inhaler/pulmodeiectionem - name = "autoinhaler (pulmodeiectionem)" + name_label = "pulmodeiectionem" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains pulmodeiectionem." Initialize() @@ -223,10 +245,8 @@ return /obj/item/reagent_containers/inhaler/pneumalin - name = "autoinhaler (pneumalin)" + name_label = "pneumalin" desc = "A rapid and safe way to administer small amounts of drugs into the lungs by untrained or trained personnel. This one contains pneumalin." - icon_state = "so_inhaler1" - empty_state = "so_inhaler0" volume = 10 Initialize() diff --git a/code/modules/reagents/reagent_containers/inhaler_advanced.dm b/code/modules/reagents/reagent_containers/inhaler_advanced.dm index 481a0a5167e..8f18df6f413 100644 --- a/code/modules/reagents/reagent_containers/inhaler_advanced.dm +++ b/code/modules/reagents/reagent_containers/inhaler_advanced.dm @@ -5,7 +5,7 @@ name = "small inhaler cartridge" desc = "Fill this when chemicals and attach this to personal inhalers. Contains enough aerosol for 15u of reagents. The container must be activated for aerosol reagents to mix for the use in inhalers." icon = 'icons/obj/syringe.dmi' - item_state = "buildpipe" + item_state = "pi_cart_small" icon_state = "pi_cart_small" volume = 15 w_class = ITEMSIZE_TINY @@ -18,6 +18,19 @@ matter = list(DEFAULT_WALL_MATERIAL = 250) center_of_mass = null +/obj/item/reagent_containers/personal_inhaler_cartridge/on_reagent_change() + update_icon() + return + +/obj/item/reagent_containers/personal_inhaler_cartridge/update_icon() + cut_overlays() + var/rounded_vol = round(reagents.total_volume, round(reagents.maximum_volume / (volume / 5))) + + if(reagents.total_volume) + var/mutable_appearance/filling = mutable_appearance('icons/obj/syringe.dmi', "[initial(icon_state)][rounded_vol]") + filling.color = reagents.get_color() + add_overlay(filling) + /obj/item/reagent_containers/personal_inhaler_cartridge/examine(var/mob/user) if(!..(user, 2)) return @@ -75,7 +88,7 @@ name = "inhaler" desc = "A safe way to administer small amounts of drugs into the lungs by trained personnel." icon = 'icons/obj/syringe.dmi' - item_state = "buildpipe" + item_state = "pi" icon_state = "pi" w_class = ITEMSIZE_SMALL slot_flags = SLOT_BELT @@ -94,6 +107,11 @@ cut_overlays() if(stored_cartridge) add_overlay(stored_cartridge.icon_state) + if(stored_cartridge.reagents.total_volume) + var/rounded_vol = round(stored_cartridge.reagents.total_volume, round(stored_cartridge.reagents.maximum_volume / (stored_cartridge.volume / 5))) + var/image/filling = image(icon, "[stored_cartridge.icon_state][rounded_vol]") + filling.color = stored_cartridge.reagents.get_color() + add_overlay(filling) /obj/item/personal_inhaler/attack_self(mob/user as mob) if(stored_cartridge) @@ -150,8 +168,9 @@ if(M.reagents) var/contained = stored_cartridge.reagentlist() + var/temp = stored_cartridge.reagents.get_temperature() var/trans = stored_cartridge.reagents.trans_to_mob(M, transfer_amount, CHEM_BREATHE, bypass_checks = TRUE) - admin_inject_log(user, M, src, contained, reagents.get_temperature(), trans) + admin_inject_log(user, M, src, contained, temp, trans) playsound(M.loc, 'sound/items/stimpack.ogg', 50, 1) if(eject_when_empty) to_chat(user,"\The [stored_cartridge] automatically ejects from \the [src].") @@ -162,6 +181,7 @@ else to_chat(user,"Nothing happens!") + update_icon() return /obj/item/personal_inhaler/attackby(var/obj/item/reagent_containers/personal_inhaler_cartridge/cartridge as obj, var/mob/user as mob) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 1a676b02203..f648b206574 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -20,7 +20,7 @@ center_of_mass = list("x" = 16,"y" = 14) matter = list(MATERIAL_GLASS = 150) amount_per_transfer_from_this = 5 - possible_transfer_amounts = list(1, 2, 5, 15) + possible_transfer_amounts = list(1, 2, 5, 10, 15) volume = 15 w_class = ITEMSIZE_TINY slot_flags = SLOT_EARS @@ -35,6 +35,7 @@ var/image/filling //holds a reference to the current filling overlay var/visible_name = "a syringe" var/time = 30 + var/last_jab = 0 //Spam prevention center_of_mass = null drop_sound = 'sound/items/drop/glass_small.ogg' pickup_sound = 'sound/items/pickup/glass_small.ogg' @@ -55,6 +56,9 @@ STOP_PROCESSING(SSprocessing, src) return 1 +/obj/item/reagent_containers/syringe/AltClick(var/mob/user) + set_APTFT() + /obj/item/reagent_containers/syringe/proc/infect_limb(var/obj/item/organ/external/eo) eo.germ_level += dirtiness // only 75% of the way to an infection at max @@ -106,6 +110,10 @@ return /obj/item/reagent_containers/syringe/afterattack(obj/target, mob/user, proximity) + if(last_jab + time > world.time) + to_chat(usr, SPAN_WARNING("You're already using \the [src]!")) + return + if(!proximity || !target.reagents) return @@ -119,10 +127,19 @@ if(user.a_intent == I_GRAB && ishuman(user) && ishuman(target)) // we could add other things here eventually. trepanation maybe var/mob/living/carbon/human/H = target if (check_zone(user.zone_sel.selecting) == BP_CHEST) // impromptu needle thoracostomy, re-inflate a collapsed lung + var/obj/item/organ/internal/lungs/L = H.internal_organs_by_name[BP_LUNGS] var/P = (user == target) ? "their" : (target.name + "\'s") var/SM = (user == target) ? "your" : (target.name + "\'s") + if(!L) + return + if(L.rescued == TRUE) + to_chat(usr, SPAN_NOTICE("[H]'s ribs are already punctured!")) + return + last_jab = world.time user.visible_message("[user] aims \the [src] between [P] ribs!", SPAN_NOTICE("You aim \the [src] between [SM] ribs!")) if(!do_mob(user, target, 1.5 SECONDS)) + last_jab = 0 //Resets to try again immediately + user.visible_message("[user] fumbles with \the [src]!", SPAN_NOTICE("You fumble with \the [src]!")) return var/blocked = H.get_blocked_ratio(BP_CHEST, BRUTE, DAM_SHARP, damage = 5) if(blocked > 20) @@ -130,10 +147,8 @@ return user.visible_message("[user] jabs \the [src] between [P] ribs!", SPAN_NOTICE("You jab \the [src] between [SM] ribs!")) H.apply_damage(3, BRUTE, BP_CHEST) - H.custom_pain("The pain in your chest is living hell!", 75, affecting = H.organs_by_name[BP_CHEST]) - var/obj/item/organ/internal/lungs/L = H.internal_organs_by_name[BP_LUNGS] - if(!L) - return + H.custom_pain("The pain in your chest is living hell!", 50, affecting = H.organs_by_name[BP_CHEST]) + L.oxygen_deprivation = 0 L.rescued = TRUE return @@ -221,6 +236,7 @@ if(ismob(target) && target != user) var/inject_time = time if(isliving(target)) + last_jab = world.time var/mob/living/L = target var/inject_mod = L.can_inject(user, TRUE, user.zone_sel.selecting) if(!inject_mod) @@ -231,6 +247,8 @@ user.do_attack_animation(target) if(!do_mob(user, target, inject_time)) + last_jab = 0 + user.visible_message("[user] fumbles with \the [src]!", SPAN_NOTICE("You fumble with \the [src]!")) return user.visible_message(SPAN_WARNING("[user] injects [target] with the syringe!")) diff --git a/code/modules/security levels/security levels.dm b/code/modules/security levels/security levels.dm index 0f775045b0d..f4fdbf22d02 100644 --- a/code/modules/security levels/security levels.dm +++ b/code/modules/security levels/security levels.dm @@ -54,10 +54,9 @@ SSnightlight.temp_disable() var/newlevel = get_security_level() - for(var/obj/machinery/firealarm/FA in SSmachinery.processing_machines) - if(isContactLevel(FA.z)) - FA.set_security_level(newlevel) - + for(var/obj/machinery/power/apc/powercontrol in SSmachinery.processing_machines) + if(isContactLevel(powercontrol.z)) + powercontrol.manage_emergency(newlevel) /proc/get_security_level() switch(security_level) diff --git a/code/modules/shieldgen/shield_gen_external.dm b/code/modules/shieldgen/shield_gen_external.dm index e65a4e9aa9e..4710b5b0dd8 100644 --- a/code/modules/shieldgen/shield_gen_external.dm +++ b/code/modules/shieldgen/shield_gen_external.dm @@ -29,7 +29,7 @@ if (T == U) continue - if (the_station_areas[U.loc]) + if (the_station_areas[U.loc] || istype(U, /turf/simulated/mineral/surface)) out += T break diff --git a/code/modules/submaps/_submap.dm b/code/modules/submaps/_submap.dm new file mode 100644 index 00000000000..e5ccd981157 --- /dev/null +++ b/code/modules/submaps/_submap.dm @@ -0,0 +1,46 @@ +/datum/submap + var/name + var/pref_name + var/decl/submap_archetype/archetype + var/associated_z + +/datum/submap/New(var/existing_z) + SSmapping.submaps[src] = TRUE + associated_z = existing_z + +/datum/submap/Destroy() + SSmapping.submaps -= src + . = ..() + +/datum/submap/proc/setup_submap(var/decl/submap_archetype/_archetype) + + if(!istype(_archetype)) + log_game( "Submap error - [name] - null or invalid archetype supplied ([_archetype]).") + qdel(src) + return + + // Not much point doing this when it has presumably been done already. + if(_archetype == archetype) + log_game( "Submap error - [name] - submap already set up.") + return + + archetype = _archetype + if(!pref_name) + pref_name = archetype.descriptor + + log_game("Starting submap setup - '[name]', [archetype], [associated_z]z.") + + if(!associated_z) + log_game( "Submap error - [name]/[archetype ? archetype.descriptor : "NO ARCHETYPE"] could not find an associated z-level for spawnpoint placement.") + qdel(src) + return + + var/obj/effect/overmap/visitable/cell = map_sectors["[associated_z]"] + if(istype(cell)) + sync_cell(cell) + +/datum/submap/proc/sync_cell(var/obj/effect/overmap/visitable/cell) + name = cell.name + +/datum/submap/proc/available() + return TRUE diff --git a/code/modules/submaps/submap_archetype.dm b/code/modules/submaps/submap_archetype.dm new file mode 100644 index 00000000000..4df8169e914 --- /dev/null +++ b/code/modules/submaps/submap_archetype.dm @@ -0,0 +1,15 @@ +/decl/submap_archetype + var/map + var/descriptor = "generic ship archetype" + +/decl/submap_archetype/Destroy() + if(SSmapping.submap_archetypes[descriptor] == src) + SSmapping.submap_archetypes -= descriptor + . = ..() + +// Generic ships to populate the list. +/decl/submap_archetype/derelict + descriptor = "drifting wreck" + +/decl/submap_archetype/abandoned_ship + descriptor = "abandoned ship" diff --git a/code/modules/submaps/submap_landmark.dm b/code/modules/submaps/submap_landmark.dm new file mode 100644 index 00000000000..245c8a299d8 --- /dev/null +++ b/code/modules/submaps/submap_landmark.dm @@ -0,0 +1,25 @@ +/obj/effect/submap_landmark + icon = 'icons/misc/mark.dmi' + invisibility = INVISIBILITY_MAXIMUM + anchored = TRUE + simulated = FALSE + density = FALSE + opacity = FALSE + +/obj/effect/submap_landmark/joinable_submap + icon_state = "x4" + var/archetype + var/submap_datum_type = /datum/submap + +/obj/effect/submap_landmark/joinable_submap/Initialize(var/mapload) + . = ..(mapload) + if(!SSmapping.submaps[name] && SSmapping.submap_archetypes[archetype]) + var/datum/submap/submap = new submap_datum_type(z) + submap.name = name + submap.setup_submap(SSmapping.submap_archetypes[archetype]) + else + if(SSmapping.submaps[name]) + log_debug( "Submap error - mapped landmark is duplicate of existing.") + else + log_debug( "Submap error - mapped landmark had invalid archetype.") + return INITIALIZE_HINT_QDEL \ No newline at end of file diff --git a/config/example/away_site_blacklist.txt b/config/example/away_site_blacklist.txt new file mode 100644 index 00000000000..c07f6f9167b --- /dev/null +++ b/config/example/away_site_blacklist.txt @@ -0,0 +1,5 @@ +#Listing maps here will blacklist them from generating as away sites. +#Maps must be the full path to them +#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START + +#maps/random_ruins/away_sites/example.dmm \ No newline at end of file diff --git a/config/example/exoplanet_ruin_blacklist.txt b/config/example/exoplanet_ruin_blacklist.txt new file mode 100644 index 00000000000..456fd76e4e1 --- /dev/null +++ b/config/example/exoplanet_ruin_blacklist.txt @@ -0,0 +1,5 @@ +#Listing maps here will blacklist them from generating on exoplanets. +#Maps must be the full path to them +#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START + +#maps/random_ruins/exoplanet_ruins/example.dmm \ No newline at end of file diff --git a/config/example/space_ruin_blacklist.txt b/config/example/space_ruin_blacklist.txt new file mode 100644 index 00000000000..3b1d80f20b9 --- /dev/null +++ b/config/example/space_ruin_blacklist.txt @@ -0,0 +1,6 @@ +#Listing maps here will blacklist them from generating in space. +#Maps must be the full path to them +#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START + +#maps/random_ruins/space_ruins/example.dmm +maps/random_ruins/exoplanets/crashed_pod/crashed_pod.dmm \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index e89ad7de3e0..a8552e38058 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -35,6 +35,194 @@ -->
+ 19 February 2022+TheGreyWolf updated:+
Vrow updated:+
mikomyazaki updated:+
18 February 2022+MattAtlas updated:+
Sparky_hotdog updated:+
TheGreyWolf updated:+
Vrow updated:+
mikomyazaki updated:+
17 February 2022+Geeves updated:+
SierraKomodo updated:+
16 February 2022+Sparky_hotdog updated:+
Vrow updated:+
Yonnimer updated:+
listerla updated:+
mikomyazaki updated:+
15 February 2022+TheGreyWolf updated:+
Wowzewow (Wezzy), monster860 updated:+
14 February 2022+MattAtlas updated:+
Vrow updated:+
listerla updated:+
mikomyazaki updated:+
13 February 2022+Geeves updated:+
Ramke updated:+
TheGreyWolf updated:+
Vrow updated:+
mikomyazaki updated:+
12 February 2022+Alberyk updated:+
MattAtlas updated:+
SierraKomodo updated:+
SleepyGem updated:+
The Stryker updated:+
TheGreyWolf updated:+
Vrow updated:+
09 February 2022Geeves updated:
|