This commit is contained in:
r4d6
2020-01-26 20:58:37 -05:00
47 changed files with 431 additions and 273 deletions

View File

@@ -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.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.

View File

@@ -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"

View File

@@ -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, "<span class='notice'>You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.</span>")
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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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")

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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,"<span class='warning'>The <b>dominator</b> can be spawned only on territory controlled by your gang!</span>")
return FALSE

View File

@@ -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, "<span class='warning'>[src] blinks red as you try to insert the cell!</span>")
return
if(!user.transferItemToLoc(W,src))

View File

@@ -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)

View File

@@ -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

View File

@@ -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, "<span class='notice'>[src] blinks red as you try to insert [G].</span>")
return 1

View File

@@ -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))

View File

@@ -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)

View File

@@ -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'
icon = 'icons/rooms/Lavaland/Mining.dmi'

View File

@@ -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, "<span class='warning'>[A] is unsuitable for tagging.</span>")
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, "<span class='notice'>You tagged [territory] for your gang!</span>")

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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].<br>"
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 += "<h1>AREAS WITH MULTIPLE APCS:</h1>"
for(var/areatype in areas_with_multiple_APCs)
dat += "[areatype]<br>"
if(sub_areas_APC[areatype])
dat += "&nbsp;&nbsp;SUB-AREAS:<br>&nbsp;&nbsp;"
dat += jointext(sub_areas_APC[areatype], "<br>&nbsp;&nbsp;")
CHECK_TICK
if(areas_without_air_alarm.len)
dat += "<h1>AREAS WITHOUT AN AIR ALARM:</h1>"
for(var/areatype in areas_without_air_alarm)
dat += "[areatype]<br>"
if(sub_areas_air_alarm[areatype])
dat += "&nbsp;&nbsp;SUB-AREAS:<br>&nbsp;&nbsp;"
dat += jointext(sub_areas_air_alarm[areatype], "<br>&nbsp;&nbsp;")
CHECK_TICK
if(areas_without_RC.len)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 ..()

View File

@@ -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

View File

@@ -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."

View File

@@ -170,7 +170,7 @@ Difficulty: Medium
to_chat(user, "<span class='warning'>The staff is still recharging!</span>")
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, "<span class='warning'>Something is preventing you from using the staff here.</span>")

View File

@@ -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))

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)