diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index cc1b474c49..4304af77f3 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -184,7 +184,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define BODY_ZONE_PRECISE_R_FOOT "r_foot" //We will round to this value in damage calculations. -#define DAMAGE_PRECISION 0.1 +#define DAMAGE_PRECISION 0.01 //items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25) #define TOTAL_MASS_TINY_ITEM 1.25 @@ -202,4 +202,4 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting. #define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting. #define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default. -#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs. \ No newline at end of file +#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs. diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 3034876e36..6b70eb1e0f 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -1,6 +1,7 @@ //config files #define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) #define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) +#define CONFIG_GET_ENTRY(X) global.config.GetEntryDatum(/datum/config_entry/##X) #define CONFIG_MAPS_FILE "maps.txt" diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index 4b52187e13..3b1496bae0 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -1,5 +1,81 @@ #define BP_MAX_ROOM_SIZE 300 +//Repopulates sortedAreas list +/proc/repopulate_sorted_areas() + GLOB.sortedAreas = list() + + for(var/area/A in world) + GLOB.sortedAreas.Add(A) + + sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) + +/area/proc/addSorted() + GLOB.sortedAreas.Add(src) + sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) + +//Takes: Area type as a text string from a variable. +//Returns: Instance for the area in the world. +/proc/get_area_instance_from_text(areatext) + if(istext(areatext)) + areatext = text2path(areatext) + return GLOB.areas_by_type[areatext] + +//Takes: Area type as text string or as typepath OR an instance of the area. +//Returns: A list of all areas of that type in the world. +/proc/get_areas(areatype, subtypes=TRUE) + if(istext(areatype)) + areatype = text2path(areatype) + else if(isarea(areatype)) + var/area/areatemp = areatype + areatype = areatemp.type + else if(!ispath(areatype)) + return null + + var/list/areas = list() + if(subtypes) + var/list/cache = typecacheof(areatype) + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(cache[A.type]) + areas += V + else + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(A.type == areatype) + areas += V + return areas + +//Takes: Area type as text string or as typepath OR an instance of the area. +//Returns: A list of all turfs in areas of that type of that type in the world. +/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE) + if(istext(areatype)) + areatype = text2path(areatype) + else if(isarea(areatype)) + var/area/areatemp = areatype + areatype = areatemp.type + else if(!ispath(areatype)) + return null + + var/list/turfs = list() + if(subtypes) + var/list/cache = typecacheof(areatype) + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(!cache[A.type]) + continue + for(var/turf/T in A) + if(target_z == 0 || target_z == T.z) + turfs += T + else + for(var/V in GLOB.sortedAreas) + var/area/A = V + if(A.type != areatype) + continue + for(var/turf/T in A) + if(target_z == 0 || target_z == T.z) + turfs += T + return turfs + // Gets an atmos isolated contained space // Returns an associative list of turf|dirs pairs // The dirs are connected turfs in the same space @@ -103,4 +179,60 @@ to_chat(creator, "You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.") return TRUE + +/** + * Returns the base area the target is located in if there is one. + * Alternatively, returns the area as is. + */ +/proc/get_base_area(atom/target) + var/area/A = get_area(target) + if(A?.base_area) + return A.base_area + return A + +/** + * Returns either null, or a list containing every sub area associated with our base area. + * If include_base is TRUE, the base area will also be added to the return list. + */ +/proc/get_sub_areas(atom/target, include_base = TRUE) + var/area/A = get_area(target) + if(!A) + return + . = list() + if(A.base_area) + A = A.base_area + if(include_base) + . += A + if(A.sub_areas) + . += A.sub_areas + +/** + * Proc used for purposes similar to get_areas_turfs(), but aimed to include associated areas. + * Only accepts area instances and paths for the first arg, no text strings. + * Returns a list of all turfs found in the sub areas (including the base's if include_base is TRUE) + * and located in a z level matching target_z, or anywhere if target_z is 0 + */ + +/proc/get_sub_areas_turfs(area/A, target_z = 0, include_base = TRUE) + var/list/contents = get_sub_areas_contents(A, include_base) + . = list() + for(var/turf/T in contents) + if(target_z == 0 || target_z == T.z) + . += T +/** + * Simple proc that returns a sum of all contents from every sub area, + * Think of the above but for all contents, not just turfs, and without target z. + */ + +/proc/get_sub_areas_contents(area/A, include_base = TRUE) + if(ispath(A)) + A = GLOB.areas_by_type[A] + if(!A) + return + if(A.base_area) + A = A.base_area + . = list(A.contents) + for(var/i in A.sub_areas) + . += A.sub_areas[i].contents + #undef BP_MAX_ROOM_SIZE diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index ca4b913369..59bf210853 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -8,8 +8,8 @@ #define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) #define CULT_POLL_WAIT 2400 -/proc/get_area_name(atom/X, format_text = FALSE) - var/area/A = isarea(X) ? X : get_area(X) +/proc/get_area_name(atom/X, format_text = FALSE, get_base_area = FALSE) + var/area/A = get_base_area ? get_base_area(X) : get_area(X) if(!A) return null return format_text ? format_text(A.name) : A.name diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index e916b2532a..8b86ce691d 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -566,82 +566,6 @@ Turf and target are separate in case you want to teleport some distance from a t else return 0 -//Repopulates sortedAreas list -/proc/repopulate_sorted_areas() - GLOB.sortedAreas = list() - - for(var/area/A in world) - GLOB.sortedAreas.Add(A) - - sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) - -/area/proc/addSorted() - GLOB.sortedAreas.Add(src) - sortTim(GLOB.sortedAreas, /proc/cmp_name_asc) - -//Takes: Area type as a text string from a variable. -//Returns: Instance for the area in the world. -/proc/get_area_instance_from_text(areatext) - if(istext(areatext)) - areatext = text2path(areatext) - return GLOB.areas_by_type[areatext] - -//Takes: Area type as text string or as typepath OR an instance of the area. -//Returns: A list of all areas of that type in the world. -/proc/get_areas(areatype, subtypes=TRUE) - if(istext(areatype)) - areatype = text2path(areatype) - else if(isarea(areatype)) - var/area/areatemp = areatype - areatype = areatemp.type - else if(!ispath(areatype)) - return null - - var/list/areas = list() - if(subtypes) - var/list/cache = typecacheof(areatype) - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(cache[A.type]) - areas += V - else - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(A.type == areatype) - areas += V - return areas - -//Takes: Area type as text string or as typepath OR an instance of the area. -//Returns: A list of all turfs in areas of that type of that type in the world. -/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE) - if(istext(areatype)) - areatype = text2path(areatype) - else if(isarea(areatype)) - var/area/areatemp = areatype - areatype = areatemp.type - else if(!ispath(areatype)) - return null - - var/list/turfs = list() - if(subtypes) - var/list/cache = typecacheof(areatype) - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(!cache[A.type]) - continue - for(var/turf/T in A) - if(target_z == 0 || target_z == T.z) - turfs += T - else - for(var/V in GLOB.sortedAreas) - var/area/A = V - if(A.type != areatype) - continue - for(var/turf/T in A) - if(target_z == 0 || target_z == T.z) - turfs += T - return turfs - /proc/get_cardinal_dir(atom/A, atom/B) var/dx = abs(B.x - A.x) var/dy = abs(B.y - A.y) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 4ce0ccf361..ad1f869057 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -193,6 +193,13 @@ stat("[name]:", statclick) /datum/controller/configuration/proc/Get(entry_type) + var/datum/config_entry/E = GetEntryDatum(entry_type) + if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") + log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") + return + return E.config_entry_value + +/datum/controller/configuration/proc/GetEntryDatum(entry_type) var/datum/config_entry/E = entry_type var/entry_is_abstract = initial(E.abstract_type) == entry_type if(entry_is_abstract) @@ -200,10 +207,7 @@ E = entries_by_type[entry_type] if(!E) CRASH("Missing config entry for [entry_type]!") - if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") - log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") - return - return E.config_entry_value + return E /datum/controller/configuration/proc/Set(entry_type, new_val) var/datum/config_entry/E = entry_type diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 6efc9eab12..a3bc47ac91 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -249,6 +249,18 @@ /datum/config_entry/number/movedelay/walk_delay +/datum/config_entry/number/movedelay/sprint_speed_increase + config_entry_value = 1 + +/datum/config_entry/number/movedelay/sprint_buffer_max + config_entry_value = 42 + +/datum/config_entry/number/movedelay/sprint_stamina_cost + config_entry_value = 0.7 + +/datum/config_entry/number/movedelay/sprint_buffer_regen_per_ds + config_entry_value = 0.3 + /////////////////////////////////////////////////Outdated move delay /datum/config_entry/number/outdated_movedelay deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index 2f0405af2e..63e4f4f092 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -229,7 +229,7 @@ UnregisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER) mastermind = null if(cleanup) - var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M) + var/obj/effect/vr_clean_master/cleanbot = locate() in get_base_area(M) if(cleanbot) LAZYOR(cleanbot.corpse_party, M) qdel(src) diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index 230a074bb1..71a5bcb99e 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -94,7 +94,7 @@ STI KALY - blind var/area/thearea = pick(theareas) var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) + for(var/turf/T in thearea) if(T.z != affected_mob.z) continue if(T.name == "space") diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index a3b666dcc6..01b9facbb8 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -50,7 +50,10 @@ stage = STARTUP_STAGE var/list/affectareas = list() for(var/V in get_areas(area_type)) - affectareas += V + var/area/A = V + affectareas |= A + if(A.sub_areas) + affectareas |= A.sub_areas for(var/V in protected_areas) affectareas -= get_areas(V) for(var/V in affectareas) diff --git a/code/datums/wires/airalarm.dm b/code/datums/wires/airalarm.dm index 6eb4dc04db..0c4715e27e 100644 --- a/code/datums/wires/airalarm.dm +++ b/code/datums/wires/airalarm.dm @@ -46,7 +46,7 @@ A.mode = 1 // AALARM_MODE_SCRUB A.apply_mode() if(WIRE_ALARM) // Clear alarms. - var/area/AA = get_area(A) + var/area/AA = get_base_area(A) if(AA.atmosalert(0, holder)) A.post_alert(0) A.update_icon() @@ -68,7 +68,7 @@ A.mode = 3 // AALARM_MODE_PANIC A.apply_mode() if(WIRE_ALARM) // Post alarm. - var/area/AA = get_area(A) + var/area/AA = get_base_area(A) if(AA.atmosalert(2, holder)) A.post_alert(2) A.update_icon() \ No newline at end of file diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 2d256aad27..99b8165306 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -63,6 +63,15 @@ var/xenobiology_compatible = FALSE //Can the Xenobio management console transverse this area by default? var/list/canSmoothWithAreas //typecache to limit the areas that atoms in this area can smooth with +/** + * These two vars allow for multiple unique areas to be linked to a master area + * and share some functionalities such as APC powernet nodes, fire alarms etc, without sacrificing + * their own flags, statuses, variables and more snowflakes. + * Friendly reminder: no map edited areas. + */ + var/list/area/sub_areas //list of typepaths of the areas you wish to link here, will be replaced with a list of references on mapload. + var/area/base_area //The area we wish to use in place of src for certain actions such as APC area linking. + var/nightshift_public_area = NIGHTSHIFT_AREA_NONE //considered a public area for nightshift /*Adding a wizard area teleport list because motherfucking lag -- Urist*/ @@ -123,10 +132,35 @@ GLOBAL_LIST_EMPTY(teleportlocs) reg_in_areas_in_z() + //so far I'm only implementing it on mapped unique areas, it's easier this way. + if(unique && sub_areas) + if(type in sub_areas) + WARNING("\"[src]\" typepath found inside its own sub-areas list, please make sure it doesn't share its parent type initial sub-areas value.") + sub_areas = null + else + var/paths = sub_areas.Copy() + sub_areas = null + for(var/type in paths) + var/area/A = GLOB.areas_by_type[type] + if(!A) //By chance an area not loaded in the current world, no warning report. + continue + if(A == src) + WARNING("\"[src]\" area a attempted to link with itself.") + continue + if(A.base_area) + WARNING("[src] attempted to link with [A] while the latter is already linked to another area ([A.base_area]).") + continue + LAZYADD(sub_areas, A) + A.base_area = src + else if(LAZYLEN(sub_areas)) + WARNING("sub-areas are currently not supported for non-unique areas such as [src].") + sub_areas = null + return INITIALIZE_HINT_LATELOAD /area/LateInitialize() - power_change() // all machines set to current power level, also updates icon + if(!base_area) //we don't want to run it twice. + power_change() // all machines set to current power level, also updates icon /area/proc/reg_in_areas_in_z() if(contents.len) @@ -149,6 +183,19 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/Destroy() if(GLOB.areas_by_type[type] == src) GLOB.areas_by_type[type] = null + if(base_area) + LAZYREMOVE(base_area, src) + base_area = null + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + A.base_area = null + sub_areas -= A + if(A.requires_power) + A.power_light = FALSE + A.power_equip = FALSE + A.power_environ = FALSE + INVOKE_ASYNC(A, .proc/power_change) STOP_PROCESSING(SSobj, src) return ..() @@ -214,9 +261,12 @@ GLOBAL_LIST_EMPTY(teleportlocs) var/datum/computer_file/program/alarm_monitor/p = item p.cancelAlarm("Atmosphere", src, source) - src.atmosalm = danger_level - return 1 - return 0 + atmosalm = danger_level + for(var/i in sub_areas) + var/area/A = i + A.atmosalm = danger_level + return TRUE + return FALSE /area/proc/ModifyFiredoors(opening) if(firedoors) @@ -241,11 +291,8 @@ GLOBAL_LIST_EMPTY(teleportlocs) return if (!fire) - set_fire_alarm_effect() + set_fire_alarm_effects(TRUE) ModifyFiredoors(FALSE) - for(var/item in firealarms) - var/obj/machinery/firealarm/F = item - F.update_icon() for (var/item in GLOB.alert_consoles) var/obj/machinery/computer/station_alert/a = item @@ -264,11 +311,8 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/proc/firereset(obj/source) if (fire) - unset_fire_alarm_effects() + set_fire_alarm_effects(FALSE) ModifyFiredoors(TRUE) - for(var/item in firealarms) - var/obj/machinery/firealarm/F = item - F.update_icon() for (var/item in GLOB.silicon_mobs) var/mob/living/silicon/aiPlayer = item @@ -300,9 +344,9 @@ GLOBAL_LIST_EMPTY(teleportlocs) return //Trigger alarm effect - set_fire_alarm_effect() + set_fire_alarm_effects(TRUE) //Lockdown airlocks - for(var/obj/machinery/door/DOOR in src) + for(var/obj/machinery/door/DOOR in get_sub_areas_contents(src)) close_and_lock_door(DOOR) for (var/i in GLOB.silicon_mobs) @@ -311,23 +355,20 @@ GLOBAL_LIST_EMPTY(teleportlocs) //Cancel silicon alert after 1 minute addtimer(CALLBACK(SILICON, /mob/living/silicon.proc/cancelAlarm,"Burglar",src,trigger), 600) -/area/proc/set_fire_alarm_effect() - fire = TRUE +/area/proc/set_fire_alarm_effects(boolean) + fire = boolean + for(var/i in sub_areas) + var/area/A = i + A.fire = boolean mouse_opacity = MOUSE_OPACITY_TRANSPARENT for(var/alarm in firealarms) var/obj/machinery/firealarm/F = alarm F.update_fire_light(fire) - for(var/obj/machinery/light/L in src) + F.update_icon() + for(var/obj/machinery/light/L in get_sub_areas_contents(src)) L.update() -/area/proc/unset_fire_alarm_effects() - fire = FALSE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - for(var/alarm in firealarms) - var/obj/machinery/firealarm/F = alarm - F.update_fire_light(fire) - for(var/obj/machinery/light/L in src) - L.update() +/area/proc/updateicon() /** * Update the icon state of the area * @@ -380,26 +421,35 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/proc/power_change() for(var/obj/machinery/M in src) // for each machine in the area M.power_change() // reverify power status (to update icons etc.) + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + A.power_light = power_light + A.power_equip = power_equip + A.power_environ = power_environ + INVOKE_ASYNC(A, .proc/power_change) update_icon() /area/proc/usage(chan) - var/used = 0 switch(chan) if(LIGHT) - used += used_light + . += used_light if(EQUIP) - used += used_equip + . += used_equip if(ENVIRON) - used += used_environ + . += used_environ if(TOTAL) - used += used_light + used_equip + used_environ + . += used_light + used_equip + used_environ if(STATIC_EQUIP) - used += static_equip + . += static_equip if(STATIC_LIGHT) - used += static_light + . += static_light if(STATIC_ENVIRON) - used += static_environ - return used + . += static_environ + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + . += A.usage(chan) /area/proc/addStaticPower(value, powerchannel) switch(powerchannel) @@ -414,6 +464,10 @@ GLOBAL_LIST_EMPTY(teleportlocs) used_equip = 0 used_light = 0 used_environ = 0 + if(sub_areas) + for(var/i in sub_areas) + var/area/A = i + A.clear_usage() /area/proc/use_power(amount, chan) diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index d010da465e..b296ba7273 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -12,7 +12,7 @@ var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai) for(var/area/A in world) - if( !A.requires_power || A.always_unpowered ) + if( !A.requires_power || A.always_unpowered || A.base_area) continue var/skip = 0 @@ -61,8 +61,9 @@ S.output_attempt = 1 S.update_icon() S.power_change() + for(var/area/A in world) - if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival)) + if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival) && !A.always_unpowered && !A.base_area) A.power_light = TRUE A.power_equip = TRUE A.power_environ = TRUE diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm index 8c1272dcbd..db060a6539 100644 --- a/code/game/gamemodes/gangs/dominator.dm +++ b/code/game/gamemodes/gangs/dominator.dm @@ -101,7 +101,7 @@ playsound(loc, 'sound/items/timer.ogg', 10, 0) if(!warned && (time_remaining < 180)) warned = TRUE - var/area/domloc = get_area(loc) + var/area/domloc = get_base_area(loc) gang.message_gangtools("Less than 3 minutes remains in hostile takeover. Defend your dominator at [domloc.map_name]!") for(var/G in GLOB.gangs) var/datum/team/gang/tempgang = G @@ -179,7 +179,7 @@ if((tempgang.domination_time != NOT_DOMINATING) || !tempgang.dom_attempts || !in_range(src, user) || !isturf(loc)) return 0 - var/area/A = get_area(loc) + var/area/A = get_base_area(loc) var/locname = A.map_name gang = tempgang diff --git a/code/game/gamemodes/gangs/gang_decals.dm b/code/game/gamemodes/gangs/gang_decals.dm index 6e5cb58891..7aaed769d9 100644 --- a/code/game/gamemodes/gangs/gang_decals.dm +++ b/code/game/gamemodes/gangs/gang_decals.dm @@ -19,7 +19,7 @@ return INITIALIZE_HINT_QDEL gang = G var/newcolor = G.color - var/area/territory = get_area(src) + var/area/territory = get_base_area(src) icon_state = G.name G.new_territories |= list(territory.type = territory.name) //If this isn't tagged by a specific gangster there's no bonus income. @@ -27,7 +27,7 @@ /obj/effect/decal/cleanable/crayon/gang/Destroy() if(gang) - var/area/territory = get_area(src) + var/area/territory = get_base_area(src) gang.territories -= territory.type gang.new_territories -= territory.type gang.lost_territories |= list(territory.type = territory.name) diff --git a/code/game/gamemodes/gangs/gang_items.dm b/code/game/gamemodes/gangs/gang_items.dm index 2e9ca4dcc0..688af3beea 100644 --- a/code/game/gamemodes/gangs/gang_items.dm +++ b/code/game/gamemodes/gangs/gang_items.dm @@ -401,7 +401,7 @@ datum/gang_item/equipment/gangsheild return "This device requires a 5x5 area clear of walls to FUNCTION. (Estimated Takeover Time: [round(gang.determine_domination_time()/60,0.1)] minutes)" /datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) - var/area/userarea = get_area(user) + var/area/userarea = get_base_area(user) if(!(userarea.type in gang.territories|gang.new_territories)) to_chat(user,"The dominator can be spawned only on territory controlled by your gang!") return FALSE diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index fc6cac785a..991577e123 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -46,7 +46,7 @@ var/area/a = loc.loc // Gets our locations location, like a dream within a dream if(!isarea(a)) return - if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! + if(!a.powered(EQUIP)) // There's no APC in this area, don't try to cheat power! to_chat(user, "[src] blinks red as you try to insert the cell!") return if(!user.transferItemToLoc(W,src)) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index f5bf8c8a1b..cb133978b2 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -44,7 +44,7 @@ /obj/machinery/door/firedoor/proc/CalculateAffectingAreas() remove_from_areas() - affecting_areas = get_adjacent_open_areas(src) | get_area(src) + affecting_areas = get_adjacent_open_areas(src) | get_base_area(src) for(var/I in affecting_areas) var/area/A = I LAZYADD(A.firedoors, src) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 1ef3fc0a74..0e2363cb6a 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -44,7 +44,7 @@ pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 update_icon() - myarea = get_area(src) + myarea = get_base_area(src) LAZYADD(myarea.firealarms, src) /obj/machinery/firealarm/Destroy() @@ -124,7 +124,7 @@ if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time)) return last_alarm = world.time - var/area/A = get_area(src) + var/area/A = get_base_area(src) A.firealert(src) playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75) if(user) @@ -133,7 +133,7 @@ /obj/machinery/firealarm/proc/reset(mob/user) if(!is_operational()) return - var/area/A = get_area(src) + var/area/A = get_base_area(src) A.firereset(src) if(user) log_game("[user] reset a fire alarm at [COORD(src)]") @@ -142,7 +142,7 @@ if(buildstage != 2) return ..() add_fingerprint(user) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(A.fire) reset(user) else @@ -322,7 +322,7 @@ /obj/machinery/firealarm/partyalarm/reset() if (stat & (NOPOWER|BROKEN)) return - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (!A || !A.party) return A.party = FALSE @@ -331,7 +331,7 @@ /obj/machinery/firealarm/partyalarm/alarm() if (stat & (NOPOWER|BROKEN)) return - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (!A || A.party || A.name == "Space") return A.party = TRUE diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 2211397f3e..f777c893f8 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -70,7 +70,7 @@ //Checks to make sure he's not in space doing it, and that the area got proper power. var/area/a = get_area(src) - if(!isarea(a) || a.power_equip == 0) + if(!a || !a.powered(EQUIP)) to_chat(user, "[src] blinks red as you try to insert [G].") return 1 diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index fdb620cc67..5a907804ce 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -283,7 +283,7 @@ /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge() if(equip_ready) //disabled return - var/area/A = get_area(chassis) + var/area/A = get_base_area(chassis) var/pow_chan = get_power_channel(A) if(pow_chan) return 1000 //making magic @@ -328,7 +328,7 @@ occupant_message("No powercell detected.") return if(cur_charge < chassis.cell.maxcharge) - var/area/A = get_area(chassis) + var/area/A = get_base_area(chassis) if(A) var/pow_chan for(var/c in list(EQUIP,ENVIRON,LIGHT)) diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index aabf9acafa..38a1a6089e 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -126,7 +126,7 @@ T.PlaceOnTop(/turf/open/floor/plating/foam, flags = CHANGETURF_INHERIT_AIR) for(var/direction in GLOB.cardinals) var/turf/cardinal_turf = get_step(T, direction) - if(get_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf! + if(get_base_area(cardinal_turf) != get_area(T)) //We're at an area boundary, so let's block off this turf! new/obj/structure/foamedmetal(T) break flick("[icon_state]-disolve", src) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 8f09827bd2..3d63f4a553 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -456,7 +456,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) if(!SSmapping.station_room_templates[t]) log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list") templates -= t - template_name = pickweight(templates) + template_name = pickweightAllowZero(templates) if(!template_name) GLOB.stationroom_landmarks -= src qdel(src) @@ -485,4 +485,4 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) // Landmark for the mining station /obj/effect/landmark/stationroom/lavaland/station templates = list("Public Mining Base" = 3) - icon = 'icons/rooms/Lavaland/Mining.dmi' \ No newline at end of file + icon = 'icons/rooms/Lavaland/Mining.dmi' diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 143354b496..cb77a58769 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -427,7 +427,7 @@ /obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target) // Check area validity. // Reject space, player-created areas, and non-station z-levels. - var/area/A = get_area(target) + var/area/A = get_base_area(target) if(!A || (!is_station_level(A.z)) || !A.valid_territory) to_chat(user, "[A] is unsuitable for tagging.") return FALSE @@ -461,7 +461,7 @@ qdel(old_marking) var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) - var/area/territory = get_area(target) + var/area/territory = get_base_area(target) new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) // Heres the gang tag. to_chat(user, "You tagged [territory] for your gang!") diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 5b9a764925..fcd1f80a4f 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -52,7 +52,7 @@ var/area/A = get_area(src) if(!A.blob_allowed) return FALSE - if(!A.power_equip) + if(!A.powered(EQUIP)) return FALSE if(!SSmapping.level_trait(T.z,ZTRAIT_STATION)) return FALSE diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 053512a256..b72a4b816e 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -305,7 +305,7 @@ /datum/barsign/meow_mix name = "Meow Mix" - icon = "meow_mix" + icon = "Meow Mix" desc = "No, we don't serve catnip, officer!" /datum/barsign/hiddensigns diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 8c25a2ca5c..70533df0ad 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -80,7 +80,7 @@ /obj/structure/displaycase/proc/trigger_alarm() //Activate Anti-theft if(alert) - var/area/alarmed = get_area(src) + var/area/alarmed = get_base_area(src) alarmed.burglaralert(src) playsound(src, 'sound/effects/alert.ogg', 50, 1) diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index 7cda24d98b..b62c17832a 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -222,18 +222,23 @@ /obj/effect/vr_clean_master/Initialize() . = ..() - vr_area = get_area(src) - addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES) + vr_area = get_base_area(src) + if(!vr_area) + return INITIALIZE_HINT_QDEL + addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES, TIMER_LOOP) /obj/effect/vr_clean_master/proc/clean_up() - if (vr_area) - for (var/obj/item/ammo_casing/casing in vr_area) - qdel(casing) - for(var/obj/effect/decal/cleanable/C in vr_area) - qdel(C) - for (var/A in corpse_party) - var/mob/M = A - if(M && M.stat == DEAD && get_area(M) == vr_area) - qdel(M) - corpse_party -= M - addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES) + if (!vr_area) + qdel(src) + return + var/list/contents = get_sub_areas_contents(src) + for (var/obj/item/ammo_casing/casing in contents) + qdel(casing) + for(var/obj/effect/decal/cleanable/C in contents) + qdel(C) + for (var/A in corpse_party) + var/mob/M = A + if(!QDELETED(M) && (M in contents) && M.stat == DEAD) + qdel(M) + corpse_party -= M + addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index f08112939a..ad2eeb7289 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -541,7 +541,9 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) var/list/areas_all = list() var/list/areas_with_APC = list() var/list/areas_with_multiple_APCs = list() + var/list/sub_areas_APC = list() var/list/areas_with_air_alarm = list() + var/list/sub_areas_air_alarm = list() var/list/areas_with_RC = list() var/list/areas_with_light = list() var/list/areas_with_LS = list() @@ -578,6 +580,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) if(!A) dat += "Skipped over [APC] in invalid location, [APC.loc]." continue + LAZYSET(sub_areas_APC, A.type, get_sub_areas(A, FALSE)) if(!(A.type in areas_with_APC)) areas_with_APC.Add(A.type) else if(A.type in areas_all) @@ -585,10 +588,11 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) CHECK_TICK for(var/obj/machinery/airalarm/AA in GLOB.machines) - var/area/A = get_area(AA) + var/area/A = get_base_area(AA) if(!A) //Make sure the target isn't inside an object, which results in runtimes. dat += "Skipped over [AA] in invalid location, [AA.loc].
" continue + LAZYSET(sub_areas_air_alarm, A.type, get_sub_areas(A, FALSE)) if(!(A.type in areas_with_air_alarm)) areas_with_air_alarm.Add(A.type) CHECK_TICK @@ -638,8 +642,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) areas_with_camera.Add(A.type) CHECK_TICK - var/list/areas_without_APC = areas_all - areas_with_APC - var/list/areas_without_air_alarm = areas_all - areas_with_air_alarm + var/list/areas_without_APC = areas_all - (areas_with_APC + flatten_list(sub_areas_APC)) + var/list/areas_without_air_alarm = areas_all - (areas_with_air_alarm + flatten_list(sub_areas_air_alarm)) var/list/areas_without_RC = areas_all - areas_with_RC var/list/areas_without_light = areas_all - areas_with_light var/list/areas_without_LS = areas_all - areas_with_LS @@ -656,12 +660,18 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) dat += "

AREAS WITH MULTIPLE APCS:

" for(var/areatype in areas_with_multiple_APCs) dat += "[areatype]
" + if(sub_areas_APC[areatype]) + dat += "  SUB-AREAS:
  " + dat += jointext(sub_areas_APC[areatype], "
  ") CHECK_TICK if(areas_without_air_alarm.len) dat += "

AREAS WITHOUT AN AIR ALARM:

" for(var/areatype in areas_without_air_alarm) dat += "[areatype]
" + if(sub_areas_air_alarm[areatype]) + dat += "  SUB-AREAS:
  " + dat += jointext(sub_areas_air_alarm[areatype], "
  ") CHECK_TICK if(areas_without_RC.len) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index e49368016b..95063aadf6 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -207,7 +207,7 @@ pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0 if(name == initial(name)) - name = "[get_area_name(src)] Air Alarm" + name = "[get_area_name(src, get_base_area = TRUE)] Air Alarm" power_change() set_frequency(frequency) @@ -250,7 +250,7 @@ "danger_level" = danger_level, ) - var/area/A = get_area(src) + var/area/A = get_base_area(src) data["atmos_alarm"] = A.atmosalm data["fire_alarm"] = A.fire @@ -386,7 +386,7 @@ send_signal(device_id, list("checks" = text2num(params["val"])^2), usr) . = TRUE if("set_external_pressure", "set_internal_pressure") - var/area/A = get_area(src) + var/area/A = get_base_area(src) var/target = input("New target pressure:", name, A.air_vent_info[device_id][(action == "set_external_pressure" ? "external" : "internal")]) as num|null if(!isnull(target) && !..()) send_signal(device_id, list("[action]" = target), usr) @@ -420,12 +420,12 @@ apply_mode() . = TRUE if("alarm") - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(A.atmosalert(2, src)) post_alert(2) . = TRUE if("reset") - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(A.atmosalert(0, src)) post_alert(0) . = TRUE @@ -456,7 +456,7 @@ return 0 /obj/machinery/airalarm/proc/refresh_all() - var/area/A = get_area(src) + var/area/A = get_base_area(src) for(var/id_tag in A.air_vent_names) var/list/I = A.air_vent_info[id_tag] if(I && I["timestamp"] + AALARM_REPORT_TIMEOUT / 2 > world.time) @@ -507,7 +507,7 @@ return "Flood" /obj/machinery/airalarm/proc/apply_mode() - var/area/A = get_area(src) + var/area/A = get_base_area(src) switch(mode) if(AALARM_MODE_SCRUBBING) for(var/device_id in A.air_scrub_names) @@ -645,7 +645,7 @@ icon_state = "alarm1" var/overlay_state = AALARM_OVERLAY_OFF - var/area/A = get_area(src) + var/area/A = get_base_area(src) switch(max(danger_level, A.atmosalm)) if(0) add_overlay(AALARM_OVERLAY_GREEN) @@ -715,7 +715,7 @@ return var/datum/signal/alert_signal = new(list( - "zone" = get_area_name(src), + "zone" = get_area_name(src, get_base_area = TRUE), "type" = "Atmospheric" )) if(alert_level==2) @@ -728,7 +728,7 @@ frequency.post_signal(src, alert_signal, range = -1) /obj/machinery/airalarm/proc/apply_danger_level() - var/area/A = get_area(src) + var/area/A = get_base_area(src) var/new_area_danger_level = 0 for(var/obj/machinery/airalarm/AA in A) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 3cbf1b4d0e..f2f2329661 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -38,7 +38,7 @@ id_tag = assign_uid_vents() /obj/machinery/atmospherics/components/unary/vent_pump/Destroy() - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (A) A.air_vent_names -= id_tag A.air_vent_info -= id_tag @@ -155,7 +155,7 @@ "sigtype" = "status" )) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(!A.air_vent_names[id_tag]) name = "\improper [A.name] vent pump #[A.air_vent_names.len + 1]" A.air_vent_names[id_tag] = name diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 22cd9d7fca..10eac9c717 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -39,7 +39,7 @@ filter_types += gas_id2path(f) /obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy() - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (A) A.air_scrub_names -= id_tag A.air_scrub_info -= id_tag @@ -112,7 +112,7 @@ "sigtype" = "status" )) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(!A.air_scrub_names[id_tag]) name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]" A.air_scrub_names[id_tag] = name diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index bd4e716357..8ceef76a06 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -7,8 +7,6 @@ #define AMMO_DROP_LIFETIME 300 #define CTF_REQUIRED_PLAYERS 4 - - /obj/item/twohanded/ctf name = "banner" icon = 'icons/obj/items_and_weapons.dmi' @@ -210,7 +208,6 @@ toggle_all_ctf(user) return - people_who_want_to_play |= user.ckey var/num = people_who_want_to_play.len var/remaining = CTF_REQUIRED_PLAYERS - num @@ -438,9 +435,9 @@ . = FALSE if(istype(target, /obj/structure/barricade/security/ctf)) . = TRUE - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/shielded/ctf)) + if(isliving(target)) + var/mob/living/H = target + if((RED_TEAM in H.faction) || (BLUE_TEAM in H.faction)) . = TRUE // RED TEAM GUNS diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 33b9dffaf0..e83f67f796 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -30,6 +30,9 @@ /mob/living/carbon/monkey/handle_mutations_and_radiation() if(radiation) + if(radiation > RAD_MOB_MUTATE && prob((radiation - RAD_MOB_MUTATE) / 25)) + gorillize() + return if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB)) if(!IsKnockdown()) emote("collapse") @@ -41,10 +44,6 @@ randmutb() emote("gasp") domutcheck() - - if(radiation > RAD_MOB_MUTATE * 2 && prob(50)) - gorillize() - return if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB)) vomit(10, TRUE) return ..() diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 15a04235cc..1147042c8c 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -53,11 +53,11 @@ if(NONE) return FALSE if(POWER_REQ_ALL) - return !T || !A || ((!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) if(POWER_REQ_CLOCKCULT) for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, SIGIL_ACCESS_RANGE)) return FALSE - return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) /mob/living/silicon/ai/updatehealth() if(status_flags & GODMODE) @@ -100,7 +100,7 @@ sleep(50) var/turf/T = get_turf(src) var/area/AIarea = get_area(src) - if(AIarea && AIarea.power_equip) + if(AIarea && AIarea.powered(EQUIP)) if(!isspaceturf(T)) ai_restore_power() return @@ -120,7 +120,7 @@ var/PRP //like ERP with the code, at least this stuff is no more 4x sametext for (PRP=1, PRP<=4, PRP++) T = get_turf(src) - AIarea = get_area(src) + AIarea = get_base_area(src) if(AIarea) for (var/obj/machinery/power/apc/APC in AIarea) if (!(APC.stat & BROKEN)) @@ -134,7 +134,7 @@ to_chat(src, "Lost connection with the APC!") aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC return - if(AIarea.power_equip) + if(AIarea.powered(EQUIP)) if(!isspaceturf(T)) ai_restore_power() return diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 71465f23f9..65ee6a69f2 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -479,31 +479,33 @@ Difficulty: Very Hard NewTerrainTables = /obj/structure/table/abductor /obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method) - if(..()) - var/area/A = get_area(src) - if(!A.outdoors && !(A in affected_targets)) - for(var/atom/Stuff in A) - if(isturf(Stuff)) - var/turf/T = Stuff - if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors) - var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR) - if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE)) - var/atom/Picked = pick(NewFlora) - new Picked(O) - continue - if(iswallturf(T) && NewTerrainWalls) - T.ChangeTurf(NewTerrainWalls) - continue - if(istype(Stuff, /obj/structure/chair) && NewTerrainChairs) - var/obj/structure/chair/Original = Stuff - var/obj/structure/chair/C = new NewTerrainChairs(Original.loc) - C.setDir(Original.dir) - qdel(Stuff) - continue - if(istype(Stuff, /obj/structure/table) && NewTerrainTables) - new NewTerrainTables(Stuff.loc) - continue - affected_targets += A + . = ..() + if(!.) + return + for(var/i in get_sub_areas(src)) + var/area/A = i + if(A.outdoors || (A in affected_targets)) + continue + affected_targets += A + for(var/stuff in A) + var/atom/target = stuff + if(isturf(target)) + var/turf/T = target + if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors) + var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR) + if(NewFlora.len && prob(florachance) && !is_blocked_turf(O, TRUE)) + var/atom/Picked = pick(NewFlora) + new Picked(O) + else if(iswallturf(T) && NewTerrainWalls) + T.ChangeTurf(NewTerrainWalls) + else if(NewTerrainChairs && istype(target, /obj/structure/chair)) + var/obj/structure/chair/Original = target + var/obj/structure/chair/C = new NewTerrainChairs(Original.loc) + C.setDir(Original.dir) + qdel(target) + else if(NewTerrainTables && istype(target, /obj/structure/table)) + new NewTerrainTables(target.loc) + qdel(target) /obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with observer_desc = "This crystal generates a projectile when activated." diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 49b56d0950..43ce940d57 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -170,7 +170,7 @@ Difficulty: Medium to_chat(user, "The staff is still recharging!") return - var/area/user_area = get_area(user) + var/area/user_area = get_base_area(user) var/turf/user_turf = get_turf(user) if(!user_area || !user_turf || (user_area.type in excluded_areas)) to_chat(user, "Something is preventing you from using the staff here.") diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index b7cbcdb9d8..78294e988d 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -56,6 +56,8 @@ integrity_failure = 50 var/damage_deflection = 10 resistance_flags = FIRE_PROOF + armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) + req_access = list(ACCESS_ENGINE_EQUIP) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON var/lon_range = 1.5 @@ -148,12 +150,40 @@ if(terminal) terminal.connect_to_network() -/obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0) - if (!req_access) - req_access = list(ACCESS_ENGINE_EQUIP) - if (!armor) - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) - ..() +/obj/machinery/power/apc/Initialize(mapload, ndir, building = FALSE) + . = ..() + var/area/A = get_base_area(src) + if(!building) + has_electronics = APC_ELECTRONICS_SECURED + // is starting with a power cell installed, create it and set its charge level + if(cell_type) + cell = new cell_type + cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value) + + //if area isn't specified use current + if(areastring) + area = get_area_instance_from_text(areastring) + if(!area) + area = A + stack_trace("Bad areastring path for [src], [src.areastring]") + else if(isarea(A) && !areastring) + area = A + if(auto_name) + name = "\improper [A.name] APC" + update_icon() + + make_terminal() + update_nightshift_auth_requirement() + + else + area = A + opened = APC_COVER_OPENED + operating = FALSE + name = "\improper [A.name] APC" + stat |= MAINT + update_icon() + addtimer(CALLBACK(src, .proc/update), 5) + GLOB.apcs_list += src wires = new /datum/wires/apc(src) @@ -164,9 +194,6 @@ src.tdir = dir // to fix Vars bug setDir(SOUTH) - if(auto_name) - name = "\improper [get_area(src)] APC" - switch(tdir) if(NORTH) pixel_y = 23 @@ -176,14 +203,6 @@ pixel_x = 24 if(WEST) pixel_x = -25 - if (building) - area = get_area(src) - opened = APC_COVER_OPENED - operating = FALSE - name = "[area.name] APC" - stat |= MAINT - src.update_icon() - addtimer(CALLBACK(src, .proc/update), 5) /obj/machinery/power/apc/Destroy() GLOB.apcs_list -= src @@ -217,33 +236,6 @@ terminal.setDir(tdir) terminal.master = src -/obj/machinery/power/apc/Initialize(mapload) - . = ..() - if(!mapload) - return - has_electronics = APC_ELECTRONICS_SECURED - // is starting with a power cell installed, create it and set its charge level - if(cell_type) - cell = new cell_type - cell.charge = start_charge * cell.maxcharge / 100 // (convert percentage to actual value) - - var/area/A = src.loc.loc - - //if area isn't specified use current - if(areastring) - src.area = get_area_instance_from_text(areastring) - if(!src.area) - src.area = A - stack_trace("Bad areastring path for [src], [src.areastring]") - else if(isarea(A) && src.areastring == null) - src.area = A - update_icon() - - make_terminal() - update_nightshift_auth_requirement() - - addtimer(CALLBACK(src, .proc/update), 5) - /obj/machinery/power/apc/examine(mob/user) . = ..() if(stat & BROKEN) @@ -1432,7 +1424,7 @@ return for(var/A in GLOB.ai_list) var/mob/living/silicon/ai/I = A - if(get_area(I) == area) + if(get_base_area(I) == area) return failure_timer = max(failure_timer, round(duration)) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 903f63e22c..5343256c8e 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -294,7 +294,7 @@ cut_overlays() switch(status) // set icon_states if(LIGHT_OK) - var/area/A = get_area(src) + var/area/A = get_base_area(src) if(emergency_mode || (A && A.fire)) icon_state = "[base_state]_emergency" else @@ -323,7 +323,7 @@ var/CO = bulb_colour if(color) CO = color - var/area/A = get_area(src) + var/area/A = get_base_area(src) if (A && A.fire) CO = bulb_emergency_colour else if (nightshift_enabled) diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index d2d3d60066..fba526edbd 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -382,6 +382,7 @@ return null /area/proc/get_apc() + var/target = base_area ? base_area : src for(var/obj/machinery/power/apc/APC in GLOB.apcs_list) - if(APC.area == src) + if(APC.area == target) return APC \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index ecd906f2a9..1495ff61ba 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -374,14 +374,18 @@ desc = "Decreases the cooldown of a kinetic accelerator. Not rated for minebot use." modifier = 2.5 minebot_upgrade = FALSE + var/decreased /obj/item/borg/upgrade/modkit/cooldown/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user) . = ..() if(.) - KA.overheat_time -= modifier + var/old = KA.overheat_time + KA.overheat_time = max(0, KA.overheat_time - modifier) + decreased = old - KA.overheat_time + /obj/item/borg/upgrade/modkit/cooldown/uninstall(obj/item/gun/energy/kinetic_accelerator/KA) - KA.overheat_time += modifier + KA.overheat_time += decreased ..() /obj/item/borg/upgrade/modkit/cooldown/minebot diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm index 0e8bf1e11f..af37a70232 100644 --- a/code/modules/research/xenobiology/crossbreeding/consuming.dm +++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm @@ -212,7 +212,7 @@ Consuming extracts: taste = "sugar and starlight" /obj/item/slime_cookie/bluespace/do_effect(mob/living/M, mob/user) - var/list/L = get_area_turfs(get_area(get_turf(M))) + var/list/L = get_sub_areas_turfs(get_area(M)) var/turf/target while (L.len && !target) var/I = rand(1, L.len) diff --git a/html/changelogs/AutoChangeLog-pr-10466.yml b/html/changelogs/AutoChangeLog-pr-10466.yml new file mode 100644 index 0000000000..ac9d94a677 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10466.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - balance: "monkies gorrilize easier now" diff --git a/html/changelogs/AutoChangeLog-pr-10717.yml b/html/changelogs/AutoChangeLog-pr-10717.yml new file mode 100644 index 0000000000..fd9fea8d52 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10717.yml @@ -0,0 +1,4 @@ +author: "Putnam3145" +delete-after: True +changes: + - bugfix: "Meow Mix bar sign works" diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi index fe60cf6c0d..aad3e78590 100644 Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm index 0b6903c9fe..bd43d96ba4 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm @@ -12,8 +12,11 @@ /mob/living/carbon/human/movement_delay() . = 0 - if(!resting && m_intent == MOVE_INTENT_RUN && !sprinting) - . += 1 + if(!resting && m_intent == MOVE_INTENT_RUN && sprinting) + var/static/datum/config_entry/number/movedelay/sprint_speed_increase/SSI + if(!SSI) + SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase) + . -= SSI.config_entry_value if(wrongdirmovedelay) . += 1 . += ..() diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm index 513a80cae0..0caf548196 100644 --- a/modular_citadel/code/modules/mob/living/living.dm +++ b/modular_citadel/code/modules/mob/living/living.dm @@ -17,6 +17,12 @@ var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer. //---End +/mob/living/update_config_movespeed() + . = ..() + sprint_buffer_max = CONFIG_GET(number/movedelay/sprint_buffer_max) + sprint_buffer_regen_ds = CONFIG_GET(number/movedelay/sprint_buffer_regen_per_ds) + sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost) + /mob/living/movement_delay(ignorewalk = 0) . = ..() if(resting)