Merge branch 'master' into upstream-merge-32757

This commit is contained in:
LetterJay
2017-11-15 13:01:55 -06:00
committed by GitHub
80 changed files with 911 additions and 720 deletions
+93
View File
@@ -0,0 +1,93 @@
#define BP_MAX_ROOM_SIZE 300
// Gets an atmos isolated contained space
// Returns an associative list of turf|dirs pairs
// The dirs are connected turfs in the same space
// break_if_found is a typecache of turf types to return false if found
/proc/detect_room(turf/origin, list/break_if_found)
if(origin.blocks_air)
return list(origin)
. = list()
var/list/checked_turfs = list()
var/list/found_turfs = list(origin)
while(found_turfs.len)
var/turf/sourceT = found_turfs[1]
if(break_if_found[sourceT.type])
return FALSE
found_turfs.Cut(1, 2)
var/dir_flags = checked_turfs[sourceT]
for(var/dir in GLOB.alldirs)
if(dir_flags & dir) // This means we've checked this dir before, probably from the other turf
continue
var/turf/checkT = get_step(sourceT, dir)
if(!checkT)
continue
checked_turfs[sourceT] |= dir
checked_turfs[checkT] |= turn(dir, 180)
.[sourceT] |= dir
.[checkT] |= turn(dir, 180)
var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE)
if(!cardinal_cache["[dir]"] || checkT.blocks_air || !CANATMOSPASS(sourceT, checkT))
continue
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
/proc/create_area(mob/creator)
var/static/blacklisted_turfs = typecacheof(/turf/open/space)
var/static/blacklisted_areas = typecacheof(/area/space)
var/list/turfs = detect_room(get_turf(creator), blacklisted_turfs)
if(!turfs)
to_chat(creator, "<span class='warning'>The new area must be completely airtight.</span>")
return
if(turfs.len > BP_MAX_ROOM_SIZE)
to_chat(creator, "<span class='warning'>The room you're in is too big. It is [((turfs.len / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed.</span>")
return
// This will fuck up shuttles that use the base area type but we need to fix those anyway
var/list/areas = list("New Area" = /area, "New Shuttle Area" = /area/shuttle/custom)
for(var/i in 1 to turfs.len)
var/area/place = get_area(turfs[i])
if(blacklisted_areas[place.type])
continue
areas[place.name] = place
var/area_choice = input(creator, "Choose an area to expand or make a new area.", "Area Expansion") as null|anything in areas
area_choice = areas[area_choice]
if(!area_choice)
to_chat(creator, "<span class='warning'>No choice selected. The area remains undefined.</span>")
return
var/area/newA
var/area/oldA = get_area(get_turf(creator))
if(!isarea(area_choice))
var/str = trim(stripped_input(creator,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN))
if(!str || !length(str)) //cancel
return
if(length(str) > 50)
to_chat(creator, "<span class='warning'>The given name is too long. The area remains undefined.</span>")
return
newA = new area_choice
newA.setup(str)
newA.set_dynamic_lighting()
newA.has_gravity = oldA.has_gravity
else
newA = area_choice
for(var/i in 1 to turfs.len)
var/turf/thing = turfs[i]
var/area/old_area = thing.loc
newA.contents += thing
thing.change_area(old_area, newA)
var/list/related_areas = oldA.related
for(var/i in 1 to related_areas.len)
var/area/place = related_areas[i]
var/list/firedoors = place.firedoors
if(!LAZYLEN(firedoors))
continue
for(var/k in 1 to firedoors.len)
var/obj/machinery/door/firedoor/FD = firedoors[k]
FD.CalculateAffectingAreas()
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
#undef BP_MAX_ROOM_SIZE
+1
View File
@@ -13,6 +13,7 @@ GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**. Excludes
GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless
GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob
GLOBAL_LIST_EMPTY(living_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player
GLOBAL_LIST_EMPTY(drones_list)
GLOBAL_LIST_EMPTY(dead_mob_list) //all dead mobs, including clientless. Excludes /mob/dead/new_player
GLOBAL_LIST_EMPTY(joined_player_list) //all clients that have joined the game at round-start or as a latejoin.
GLOBAL_LIST_EMPTY(silicon_mobs) //all silicon mobs
+2 -1
View File
@@ -36,4 +36,5 @@ GLOBAL_LIST_EMPTY(wire_name_directory)
GLOBAL_LIST_EMPTY(ai_status_displays)
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
+11 -12
View File
@@ -138,36 +138,35 @@
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
if(emagged)
return
if(locked)
Topic("aiEnable=4", list("aiEnable"="4"), 1)// 1 meaning no window (consistency!)
bolt_raise(usr)
else
Topic("aiDisable=4", list("aiDisable"="4"), 1)
bolt_drop(usr)
/obj/machinery/door/airlock/AIAltClick() // Eletrifies doors.
if(emagged)
return
if(!secondsElectrified)
// permanent shock
Topic("aiEnable=6", list("aiEnable"="6"), 1) // 1 meaning no window (consistency!)
shock_perm(usr)
else
// disable/6 is not in Topic; disable/5 disables both temporary and permenant shock
Topic("aiDisable=5", list("aiDisable"="5"), 1)
shock_restore(usr)
/obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors!
if(emagged)
return
if(density)
Topic("aiEnable=7", list("aiEnable"="7"), 1) // 1 meaning no window (consistency!)
else
Topic("aiDisable=7", list("aiDisable"="7"), 1)
user_toggle_open(usr)
/obj/machinery/door/airlock/AICtrlShiftClick() // Sets/Unsets Emergency Access Override
if(emagged)
return
if(!emergency)
Topic("aiEnable=11", list("aiEnable"="11"), 1) // 1 meaning no window (consistency!)
emergency_on(usr)
else
Topic("aiDisable=11", list("aiDisable"="11"), 1)
emergency_off(usr)
/* APC */
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
+3
View File
@@ -55,6 +55,9 @@
to_chat(src, "[prefix]<a href=\"[CONFIG_GET(string/githuburl)]/commit/[pc]\">[copytext(pc, 1, min(length(pc), 7))]</a>")
else
to_chat(src, "Revision unknown")
if(SERVER_TOOLS_PRESENT)
to_chat(src, "Server tools version: [SERVER_TOOLS_VERSION]")
to_chat(src, "Server tools API version: [SERVER_TOOLS_API_VERSION]")
to_chat(src, "<b>Current Informational Settings:</b>")
to_chat(src, "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]")
to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]")
+22 -1
View File
@@ -21,4 +21,25 @@
mid_sounds = list('sound/machines/generator/generator_mid1.ogg'=1, 'sound/machines/generator/generator_mid2.ogg'=1, 'sound/machines/generator/generator_mid3.ogg'=1)
mid_length = 4
end_sound = 'sound/machines/generator/generator_end.ogg'
volume = 40
volume = 40
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/deep_fryer
start_sound = 'sound/machines/fryer/deep_fryer_immerse.ogg' //my immersions
start_length = 10
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
mid_length = 2
end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg'
volume = 25
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/microwave
start_sound = 'sound/machines/microwave/microwave-start.ogg'
start_length = 10
mid_sounds = list('sound/machines/microwave/microwave-mid1.ogg'=10, 'sound/machines/microwave/microwave-mid2.ogg'=1)
mid_length = 10
end_sound = 'sound/machines/microwave/microwave-end.ogg'
volume = 90
+53 -29
View File
@@ -58,6 +58,8 @@
flags_1 = CAN_BE_DIRTY_1
var/list/firedoors
var/list/cameras
var/list/firealarms
var/firedoors_last_closed_on = 0
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
@@ -102,7 +104,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
uid = ++global_uid
related = list(src)
map_name = name // Save the initial (the name set in the map) name of the area.
if(requires_power)
luminosity = 0
else
@@ -154,27 +156,28 @@ GLOBAL_LIST_EMPTY(teleportlocs)
if (state != poweralm)
poweralm = state
if(istype(source)) //Only report power alarms on the z-level where the source is located.
var/list/cameras = list()
for (var/obj/machinery/camera/C in src)
cameras += C
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
if (state == 1)
aiPlayer.cancelAlarm("Power", src, source)
else
aiPlayer.triggerAlarm("Power", src, cameras, source)
for(var/obj/machinery/computer/station_alert/a in GLOB.machines)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
if(state == 1)
a.cancelAlarm("Power", src, source)
else
a.triggerAlarm("Power", src, cameras, source)
for(var/mob/living/simple_animal/drone/D in GLOB.mob_list)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
if(state == 1)
D.cancelAlarm("Power", src, source)
else
D.triggerAlarm("Power", src, cameras, source)
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
if(state == 1)
p.cancelAlarm("Power", src, source)
else
@@ -185,26 +188,35 @@ GLOBAL_LIST_EMPTY(teleportlocs)
if (danger_level==2)
var/list/cameras = list()
for(var/area/RA in related)
for(var/obj/machinery/camera/C in RA)
for (var/item in RA.cameras)
var/obj/machinery/camera/C = item
cameras += C
for(var/mob/living/silicon/aiPlayer in GLOB.player_list)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.triggerAlarm("Atmosphere", src, cameras, source)
for(var/obj/machinery/computer/station_alert/a in GLOB.machines)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.triggerAlarm("Atmosphere", src, cameras, source)
for(var/mob/living/simple_animal/drone/D in GLOB.mob_list)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.triggerAlarm("Atmosphere", src, cameras, source)
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.triggerAlarm("Atmosphere", src, cameras, source)
else if (src.atmosalm == 2)
for(var/mob/living/silicon/aiPlayer in GLOB.player_list)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.cancelAlarm("Atmosphere", src, source)
for(var/obj/machinery/computer/station_alert/a in GLOB.machines)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.cancelAlarm("Atmosphere", src, source)
for(var/mob/living/simple_animal/drone/D in GLOB.mob_list)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.cancelAlarm("Atmosphere", src, source)
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Atmosphere", src, source)
src.atmosalm = danger_level
@@ -239,18 +251,24 @@ GLOBAL_LIST_EMPTY(teleportlocs)
if (!( RA.fire ))
RA.set_fire_alarm_effect()
RA.ModifyFiredoors(FALSE)
for(var/obj/machinery/firealarm/F in RA)
for(var/item in RA.firealarms)
var/obj/machinery/firealarm/F = item
F.update_icon()
for (var/obj/machinery/camera/C in RA)
for (var/item in RA.cameras)
var/obj/machinery/camera/C = item
cameras += C
for (var/obj/machinery/computer/station_alert/a in GLOB.machines)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.triggerAlarm("Fire", src, cameras, source)
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.triggerAlarm("Fire", src, cameras, source)
for (var/mob/living/simple_animal/drone/D in GLOB.mob_list)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.triggerAlarm("Fire", src, cameras, source)
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.triggerAlarm("Fire", src, cameras, source)
START_PROCESSING(SSobj, src)
@@ -262,16 +280,21 @@ GLOBAL_LIST_EMPTY(teleportlocs)
RA.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
RA.updateicon()
RA.ModifyFiredoors(TRUE)
for(var/obj/machinery/firealarm/F in RA)
for(var/item in RA.firealarms)
var/obj/machinery/firealarm/F = item
F.update_icon()
for (var/mob/living/silicon/aiPlayer in GLOB.player_list)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.cancelAlarm("Fire", src, source)
for (var/obj/machinery/computer/station_alert/a in GLOB.machines)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.cancelAlarm("Fire", src, source)
for (var/mob/living/simple_animal/drone/D in GLOB.mob_list)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.cancelAlarm("Fire", src, source)
for(var/datum/computer_file/program/alarm_monitor/p in GLOB.alarmdisplay)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Fire", src, source)
STOP_PROCESSING(SSobj, src)
@@ -299,7 +322,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
//Lockdown airlocks
for(var/obj/machinery/door/DOOR in RA)
close_and_lock_door(DOOR)
for (var/obj/machinery/camera/C in RA)
for (var/item in RA.cameras)
var/obj/machinery/camera/C = item
cameras += C
for (var/mob/living/silicon/SILICON in GLOB.player_list)
+3
View File
@@ -43,6 +43,9 @@
name = "Hyperspace"
desc = "Weeeeee"
/area/shuttle/custom
name = "Custom player shuttle"
/area/shuttle/arrival
name = "Arrival Shuttle"
+2 -5
View File
@@ -62,7 +62,7 @@
/atom/movable/Move(atom/newloc, direct = 0)
if(!loc || !newloc)
return 0
return FALSE
var/atom/oldloc = loc
if(loc != newloc)
@@ -113,7 +113,7 @@
last_move = direct
setDir(direct)
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
. = 0
return FALSE
//Called after a successful Move(). By this point, we've already moved
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
@@ -325,9 +325,6 @@
SSspacedrift.processing[src] = src
return 1
/atom/movable/proc/checkpass(passflag)
return pass_flags&passflag
/atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum)
set waitfor = 0
SendSignal(COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
+2 -2
View File
@@ -84,14 +84,14 @@ GLOBAL_LIST_EMPTY(blob_nodes)
if(!T || !(T.z in GLOB.station_z_levels))
continue
if(L in GLOB.overminds || L.checkpass(PASSBLOB))
if(L in GLOB.overminds || (L.pass_flags & PASSBLOB))
continue
var/area/Ablob = get_area(T)
if(!Ablob.blob_allowed)
continue
if(!("blob" in L.faction))
playsound(L, 'sound/effects/splat.ogg', 50, 1)
L.death()
+2 -2
View File
@@ -67,7 +67,7 @@
return atmosblock
/obj/structure/blob/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSBLOB))
if(istype(mover) && (mover.pass_flags & PASSBLOB))
return 1
return 0
@@ -78,7 +78,7 @@
. = 0
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSBLOB)
. = . || (mover.pass_flags & PASSBLOB)
/obj/structure/blob/update_icon() //Updates color based on overmind color if we have an overmind.
if(overmind)
+22 -19
View File
@@ -122,15 +122,7 @@
to_chat(user, "<span class='notice'>You remove the screws from [src]'s front panel.</span>")
update_icon()
return
if(NUKESTATE_UNSCREWED)
if(istype(I, /obj/item/crowbar))
to_chat(user, "<span class='notice'>You start removing [src]'s front panel...</span>")
playsound(loc, I.usesound, 100, 1)
if(do_after(user,30*I.toolspeed,target=src))
to_chat(user, "<span class='notice'>You remove [src]'s front panel.</span>")
deconstruction_state = NUKESTATE_PANEL_REMOVED
update_icon()
return
if(NUKESTATE_PANEL_REMOVED)
if(istype(I, /obj/item/weldingtool))
var/obj/item/weldingtool/welder = I
@@ -142,16 +134,6 @@
deconstruction_state = NUKESTATE_WELDED
update_icon()
return
if(NUKESTATE_WELDED)
if(istype(I, /obj/item/crowbar))
to_chat(user, "<span class='notice'>You start prying off [src]'s inner plate...</span>")
playsound(loc, I.usesound, 100, 1)
if(do_after(user,50*I.toolspeed,target=src))
to_chat(user, "<span class='notice'>You pry off [src]'s inner plate. You can see the core's green glow!</span>")
deconstruction_state = NUKESTATE_CORE_EXPOSED
update_icon()
START_PROCESSING(SSobj, core)
return
if(NUKESTATE_CORE_EXPOSED)
if(istype(I, /obj/item/nuke_core_container))
var/obj/item/nuke_core_container/core_box = I
@@ -182,6 +164,27 @@
return
. = ..()
/obj/machinery/nuclearbomb/crowbar_act(mob/user, obj/item/tool)
. = FALSE
switch(deconstruction_state)
if(NUKESTATE_UNSCREWED)
to_chat(user, "<span class='notice'>You start removing [src]'s front panel...</span>")
playsound(loc, tool.usesound, 100, 1)
if(do_after(user, 30 * tool.toolspeed, target = src))
to_chat(user, "<span class='notice'>You remove [src]'s front panel.</span>")
deconstruction_state = NUKESTATE_PANEL_REMOVED
update_icon()
return TRUE
if(NUKESTATE_WELDED)
to_chat(user, "<span class='notice'>You start prying off [src]'s inner plate...</span>")
playsound(loc, tool.usesound, 100, 1)
if(do_after(user, 50 * tool.toolspeed, target = src))
to_chat(user, "<span class='notice'>You pry off [src]'s inner plate. You can see the core's green glow!</span>")
deconstruction_state = NUKESTATE_CORE_EXPOSED
update_icon()
START_PROCESSING(SSobj, core)
return TRUE
/obj/machinery/nuclearbomb/proc/get_nuke_state()
if(exploding)
return NUKE_ON_EXPLODING
+20 -3
View File
@@ -26,6 +26,7 @@
var/invuln = null
var/obj/item/device/camera_bug/bug = null
var/obj/structure/camera_assembly/assembly = null
var/area/myarea = null
//OTHER
@@ -47,6 +48,9 @@
assembly.state = 4
GLOB.cameranet.cameras += src
GLOB.cameranet.addCamera(src)
if (isturf(loc))
myarea = get_area(src)
LAZYADD(myarea.cameras, src)
proximity_monitor = new(src, 1)
if(mapload && (z in GLOB.station_z_levels) && prob(3) && !start_active)
@@ -54,6 +58,8 @@
/obj/machinery/camera/Destroy()
toggle_cam(null, 0) //kick anyone viewing out
if(isarea(myarea))
LAZYREMOVE(myarea.cameras, src)
if(assembly)
qdel(assembly)
assembly = null
@@ -64,7 +70,6 @@
bug = null
GLOB.cameranet.removeCamera(src) //Will handle removal from the camera network and the chunks, so we don't need to worry about that
GLOB.cameranet.cameras -= src
GLOB.cameranet.removeCamera(src)
return ..()
/obj/machinery/camera/emp_act(severity)
@@ -119,6 +124,11 @@
return
user.electrocute_act(10, src)
/obj/machinery/camera/singularity_pull(S, current_size)
if (status && current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects and the camera is still active, turn off the camera as it gets ripped off the wall.
toggle_cam(null, 0)
..()
/obj/machinery/camera/attackby(obj/item/W, mob/living/user, params)
var/msg = "<span class='notice'>You attach [W] into the assembly's inner circuits.</span>"
var/msg2 = "<span class='notice'>[src] already has that upgrade!</span>"
@@ -268,9 +278,16 @@
status = !status
if(can_use())
GLOB.cameranet.addCamera(src)
if (isturf(loc))
myarea = get_area(src)
LAZYADD(myarea.cameras, src)
else
myarea = null
else
set_light(0)
GLOB.cameranet.removeCamera(src)
if (isarea(myarea))
LAZYREMOVE(myarea.cameras, src)
GLOB.cameranet.updateChunk(x, y, z)
var/change_msg = "deactivates"
if(status)
@@ -298,12 +315,12 @@
/obj/machinery/camera/proc/triggerCameraAlarm()
alarm_on = TRUE
for(var/mob/living/silicon/S in GLOB.mob_list)
for(var/mob/living/silicon/S in GLOB.silicon_mobs)
S.triggerAlarm("Camera", get_area(src), list(src), src)
/obj/machinery/camera/proc/cancelCameraAlarm()
alarm_on = FALSE
for(var/mob/living/silicon/S in GLOB.mob_list)
for(var/mob/living/silicon/S in GLOB.silicon_mobs)
S.cancelAlarm("Camera", get_area(src), src)
/obj/machinery/camera/proc/can_use()
+54 -52
View File
@@ -45,14 +45,6 @@
anchored = TRUE
state = 2
return
else if(istype(W, /obj/item/wrench))
playsound(src.loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You unattach the assembly from its place.</span>")
new /obj/item/wallframe/camera(get_turf(src))
qdel(src)
return
if(2)
// State 2
if(istype(W, /obj/item/stack/cable_coil))
@@ -73,40 +65,6 @@
anchored = TRUE
return
if(3)
// State 3
if(istype(W, /obj/item/screwdriver))
playsound(src.loc, W.usesound, 50, 1)
var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")
if(!input)
to_chat(user, "<span class='warning'>No input found, please hang up and try your call again!</span>")
return
var/list/tempnetwork = splittext(input, ",")
if(tempnetwork.len < 1)
to_chat(user, "<span class='warning'>No network found, please hang up and try your call again!</span>")
return
state = 4
var/obj/machinery/camera/C = new(src.loc)
forceMove(C)
C.assembly = src
C.setDir(src.dir)
C.network = tempnetwork
var/area/A = get_area(src)
C.c_tag = "[A.name] ([rand(1, 999)])"
else if(istype(W, /obj/item/wirecutters))
new/obj/item/stack/cable_coil(get_turf(src), 2)
playsound(src.loc, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You cut the wires from the circuits.</span>")
state = 2
return
// Upgrades!
if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
if(!user.transferItemToLoc(W, src))
@@ -115,18 +73,62 @@
upgrades += W
return
// Taking out upgrades
else if(istype(W, /obj/item/crowbar) && upgrades.len)
var/obj/U = locate(/obj) in upgrades
if(U)
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
playsound(src.loc, W.usesound, 50, 1)
U.forceMove(drop_location())
upgrades -= U
return
return ..()
/obj/structure/camera_assembly/crowbar_act(mob/user, obj/item/tool)
if(!upgrades.len)
return FALSE
var/obj/U = locate(/obj) in upgrades
if(U)
to_chat(user, "<span class='notice'>You unattach an upgrade from the assembly.</span>")
playsound(src, tool.usesound, 50, 1)
U.forceMove(drop_location())
upgrades -= U
return TRUE
/obj/structure/camera_assembly/screwdriver_act(mob/user, obj/item/tool)
if(state != 3)
return FALSE
playsound(src, tool.usesound, 50, 1)
var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")
if(!input)
to_chat(user, "<span class='warning'>No input found, please hang up and try your call again!</span>")
return
var/list/tempnetwork = splittext(input, ",")
if(tempnetwork.len < 1)
to_chat(user, "<span class='warning'>No network found, please hang up and try your call again!</span>")
return
state = 4
var/obj/machinery/camera/C = new(src.loc)
forceMove(C)
C.assembly = src
C.setDir(src.dir)
C.network = tempnetwork
var/area/A = get_area(src)
C.c_tag = "[A.name] ([rand(1, 999)])"
return TRUE
/obj/structure/camera_assembly/wirecutter_act(mob/user, obj/item/tool)
if(state != 3)
return FALSE
new /obj/item/stack/cable_coil(get_turf(src), 2)
playsound(src, tool.usesound, 50, 1)
to_chat(user, "<span class='notice'>You cut the wires from the circuits.</span>")
state = 2
return TRUE
/obj/structure/camera_assembly/wrench_act(mob/user, obj/item/tool)
if(state != 1)
return FALSE
playsound(src, tool.usesound, 50, 1)
to_chat(user, "<span class='notice'>You unattach the assembly from its place.</span>")
new /obj/item/wallframe/camera(get_turf(src))
qdel(src)
return TRUE
/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user)
if(!WT.remove_fuel(0, user))
return 0
+2 -6
View File
@@ -258,16 +258,12 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
AI.switchCamera(C)
/mob/living/carbon/human/Move()
var/old_z = src.z
. = ..()
if (src.w_uniform)
var/old_z = src.z
. = ..()
if (old_z != src.z)
GLOB.crewmonitor.queueUpdate(old_z)
GLOB.crewmonitor.queueUpdate(src.z)
else
return ..()
/datum/crewmonitor/proc/queueUpdate(z)
addtimer(CALLBACK(src, .proc/update, z), 5, TIMER_UNIQUE)
+86 -84
View File
@@ -1,85 +1,87 @@
/obj/machinery/computer/station_alert
name = "station alert console"
desc = "Used to access the station's automated alert system."
icon_screen = "alert:0"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/stationalert
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/station_alert
name = "station alert console"
desc = "Used to access the station's automated alert system."
icon_screen = "alert:0"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/stationalert
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/station_alert/Initialize()
. = ..()
GLOB.alert_consoles += src
/obj/machinery/computer/station_alert/Destroy()
GLOB.alert_consoles -= src
return ..()
/obj/machinery/computer/station_alert/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "station_alert", name, 300, 500, master_ui, state)
ui.open()
/obj/machinery/computer/station_alert/ui_data(mob/user)
var/list/data = list()
data["alarms"] = list()
for(var/class in alarms)
data["alarms"][class] = list()
for(var/area in alarms[class])
data["alarms"][class] += area
return data
/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source)
if(source.z != z)
return
if(stat & (BROKEN))
return
var/list/L = alarms[class]
for(var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if (!(source in sources))
sources += source
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
if(O && islist(O))
CL = O
if (CL.len == 1)
C = CL[1]
else if(O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C ? C : O), list(source))
return 1
/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin)
if(stat & (BROKEN))
return
var/list/L = alarms[class]
var/cleared = 0
for (var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if (origin in srcs)
srcs -= origin
if (srcs.len == 0)
cleared = 1
L -= I
return !cleared
/obj/machinery/computer/station_alert/process()
..()
/obj/machinery/computer/station_alert/update_icon()
..()
if(stat & (NOPOWER|BROKEN))
return
var/active_alarms = FALSE
for(var/cat in alarms)
var/list/L = alarms[cat]
if(L.len)
active_alarms = TRUE
if(active_alarms)
add_overlay("alert:2")
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "station_alert", name, 300, 500, master_ui, state)
ui.open()
/obj/machinery/computer/station_alert/ui_data(mob/user)
. = list()
.["alarms"] = list()
for(var/class in alarms)
.["alarms"][class] = list()
for(var/area in alarms[class])
.["alarms"][class] += area
/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source)
if(source.z != z)
return
if(stat & (BROKEN))
return
var/list/L = alarms[class]
for(var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/sources = alarm[3]
if (!(source in sources))
sources += source
return 1
var/obj/machinery/camera/C = null
var/list/CL = null
if(O && islist(O))
CL = O
if (CL.len == 1)
C = CL[1]
else if(O && istype(O, /obj/machinery/camera))
C = O
L[A.name] = list(A, (C ? C : O), list(source))
return 1
/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin)
if(stat & (BROKEN))
return
var/list/L = alarms[class]
var/cleared = 0
for (var/I in L)
if (I == A.name)
var/list/alarm = L[I]
var/list/srcs = alarm[3]
if (origin in srcs)
srcs -= origin
if (srcs.len == 0)
cleared = 1
L -= I
return !cleared
/obj/machinery/computer/station_alert/update_icon()
..()
if(stat & (NOPOWER|BROKEN))
return
var/active_alarms = FALSE
for(var/cat in alarms)
var/list/L = alarms[cat]
if(L.len)
active_alarms = TRUE
if(active_alarms)
add_overlay("alert:2")
+102 -59
View File
@@ -1371,6 +1371,8 @@
power["backup_timeleft"] = src.secondsBackupPowerLost
data["power"] = power
data["density"] = density
data["welded"] = welded
data["shock"] = secondsElectrified == 0 ? 2 : 0
data["shock_timeleft"] = secondsElectrified
data["id_scanner"] = !aiDisabledIdScanner
@@ -1398,7 +1400,7 @@
/obj/machinery/door/airlock/ui_act(action, params)
if(..())
return
if(!(issilicon(usr) && src.canAIControl(usr)) || IsAdminGhost(usr))
if(!user_allowed(usr))
return
switch(action)
if("disrupt-main")
@@ -1416,26 +1418,13 @@
to_chat(usr, "Backup power is already offline.")
. = TRUE
if("shock-restore")
if(wires.is_cut(WIRE_SHOCK))
to_chat(usr, text("Can't un-electrify the airlock - The electrification wire is cut."))
else if(isElectrified())
set_electrified(0)
shock_restore(usr)
. = TRUE
if("shock-temp")
if(wires.is_cut(WIRE_SHOCK))
to_chat(usr, text("The electrification wire has been cut"))
else
shockedby += "\[[time_stamp()]\][usr](ckey:[usr.ckey])"
add_logs(usr, src, "electrified")
set_electrified(AI_ELECTRIFY_DOOR_TIME)
shock_temp(usr)
. = TRUE
if("shock-perm")
if(wires.is_cut(WIRE_SHOCK))
to_chat(usr, text("The electrification wire has been cut"))
else
shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
add_logs(usr, src, "electrified")
set_electrified(ELECTRIFIED_PERMANENT)
shock_perm(usr)
. = TRUE
if("idscan-on")
if(wires.is_cut(WIRE_IDSCAN))
@@ -1454,39 +1443,20 @@
aiDisabledIdScanner = TRUE
. = TRUE
if("emergency-on")
if (!src.emergency)
emergency = TRUE
update_icon()
else
to_chat(usr, text("Emergency access is already enabled!"))
emergency_on(usr)
. = TRUE
if("emergency-off")
if (emergency)
emergency = FALSE
update_icon()
else
to_chat(usr, text("Emergency access is already disabled!"))
emergency_off(usr)
. = TRUE
if("bolt-raise")
if(wires.is_cut(WIRE_BOLTS))
to_chat(usr, text("The door bolt drop wire is cut - you can't raise the door bolts"))
else if(!src.locked)
to_chat(usr, text("The door bolts are already up"))
else
if(src.hasPower())
unbolt()
else
to_chat(usr, text("Cannot raise door bolts due to power failure"))
bolt_raise(usr)
. = TRUE
if("bolt-drop")
if(wires.is_cut(WIRE_BOLTS))
to_chat(usr, "You can't drop the door bolts - The door bolt dropping wire has been cut.")
else
bolt()
bolt_drop(usr)
. = TRUE
if("light-on")
if(wires.is_cut(WIRE_LIGHT))
to_chat(usr, text("Control to door bolt lights has been severed.</a>"))
to_chat(usr, "Control to door bolt lights has been severed.")
else if (!src.lights)
lights = TRUE
update_icon()
@@ -1495,58 +1465,131 @@
. = TRUE
if("light-off")
if(wires.is_cut(WIRE_LIGHT))
to_chat(usr, text("Control to door bolt lights has been severed.</a>"))
to_chat(usr, "Control to door bolt lights has been severed.")
else if (lights)
lights = FALSE
update_icon()
else
to_chat(usr, text("Door bolt lights are already disabled!"))
to_chat(usr, "Door bolt lights are already disabled!")
. = TRUE
if("safe-on")
if(wires.is_cut(WIRE_SAFETY))
to_chat(usr, text("Control to door sensors is disabled."))
to_chat(usr, "Control to door sensors is disabled.")
else if (!src.safe)
safe = TRUE
else
to_chat(usr, text("Firmware reports safeties already in place."))
to_chat(usr, "Firmware reports safeties already in place.")
. = TRUE
if("safe-off")
if(wires.is_cut(WIRE_SAFETY))
to_chat(usr, text("Control to door sensors is disabled."))
to_chat(usr, "Control to door sensors is disabled.")
else if (safe)
safe = FALSE
else
to_chat(usr, text("Firmware reports safeties already overriden."))
to_chat(usr, "Firmware reports safeties already overriden.")
. = TRUE
if("speed-on")
if(wires.is_cut(WIRE_TIMING))
to_chat(usr, text("Control to door timing circuitry has been severed."))
to_chat(usr, "Control to door timing circuitry has been severed.")
else if (!src.normalspeed)
normalspeed = 1
else
to_chat(usr, text("Door timing circuitry currently operating normally."))
to_chat(usr,"Door timing circuitry currently operating normally.")
. = TRUE
if("speed-off")
if(wires.is_cut(WIRE_TIMING))
to_chat(usr, text("Control to door timing circuitry has been severed."))
to_chat(usr, "Control to door timing circuitry has been severed.")
else if (normalspeed)
normalspeed = 0
else
to_chat(usr, text("Door timing circuitry already accelerated."))
to_chat(usr, "Door timing circuitry already accelerated.")
. = TRUE
if("open-close")
if(welded)
to_chat(usr, text("The airlock has been welded shut!"))
else if(locked)
to_chat(usr, text("The door bolts are down!"))
else if(!density)
close()
else
open()
user_toggle_open(usr)
. = TRUE
/obj/machinery/door/airlock/proc/user_allowed(mob/user)
return (issilicon(user) && canAIControl(user)) || IsAdminGhost(user)
/obj/machinery/door/airlock/proc/shock_restore(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_SHOCK))
to_chat(user, "Can't un-electrify the airlock - The electrification wire is cut.")
else if(isElectrified())
set_electrified(0)
/obj/machinery/door/airlock/proc/shock_temp(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_SHOCK))
to_chat(user, "The electrification wire has been cut")
else
shockedby += "\[[time_stamp()]\][user](ckey:[user.ckey])"
add_logs(user, src, "electrified")
set_electrified(AI_ELECTRIFY_DOOR_TIME)
/obj/machinery/door/airlock/proc/shock_perm(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_SHOCK))
to_chat(user, "The electrification wire has been cut")
else
shockedby += text("\[[time_stamp()]\][user](ckey:[user.ckey])")
add_logs(user, src, "electrified")
set_electrified(ELECTRIFIED_PERMANENT)
/obj/machinery/door/airlock/proc/emergency_on(mob/user)
if(!user_allowed(user))
return
if (!emergency)
emergency = TRUE
update_icon()
else
to_chat(user, "Emergency access is already enabled!")
/obj/machinery/door/airlock/proc/emergency_off(mob/user)
if(!user_allowed(user))
return
if (emergency)
emergency = FALSE
update_icon()
else
to_chat(user, "Emergency access is already disabled!")
/obj/machinery/door/airlock/proc/bolt_raise(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_BOLTS))
to_chat(user, "The door bolt drop wire is cut - you can't raise the door bolts")
else if(!src.locked)
to_chat(user, "The door bolts are already up")
else
if(src.hasPower())
unbolt()
else
to_chat(user, "Cannot raise door bolts due to power failure")
/obj/machinery/door/airlock/proc/bolt_drop(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_BOLTS))
to_chat(user, "You can't drop the door bolts - The door bolt dropping wire has been cut.")
else
bolt()
/obj/machinery/door/airlock/proc/user_toggle_open(mob/user)
if(!user_allowed(user))
return
if(welded)
to_chat(user, text("The airlock has been welded shut!"))
else if(locked)
to_chat(user, text("The door bolts are down!"))
else if(!density)
close()
else
open()
#undef AIRLOCK_CLOSED
#undef AIRLOCK_CLOSING
+1 -1
View File
@@ -103,7 +103,7 @@
move_update_air(T)
/obj/machinery/door/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return !opacity
return !density
+2 -2
View File
@@ -212,7 +212,7 @@
CanAtmosPass = ATMOS_PASS_PROC
/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
return !density
@@ -220,7 +220,7 @@
return 1
/obj/machinery/door/firedoor/border_only/CheckExit(atom/movable/mover as mob|obj, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(get_dir(loc, target) == dir)
return !density
+2 -2
View File
@@ -90,7 +90,7 @@
return
/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
return !density
@@ -118,7 +118,7 @@
return !density || (dir != to_dir) || (check_access(ID) && hasPower())
/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(get_dir(loc, target) == dir)
return !density
+19 -9
View File
@@ -1,3 +1,5 @@
#define FIREALARM_COOLDOWN 67 // Chosen fairly arbitrarily, it is the length of the audio in FireAlarm.ogg. The actual track length is 7 seconds 8ms but but the audio stops at 6s 700ms
/obj/item/electronics/firealarm
name = "fire alarm electronics"
desc = "A fire alarm circuit. Can handle heat levels up to 40 degrees celsius."
@@ -25,7 +27,8 @@
var/detecting = 1
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
resistance_flags = FIRE_PROOF
var/last_alarm = 0
var/area/myarea = null
/obj/machinery/firealarm/New(loc, dir, building)
..()
@@ -37,6 +40,12 @@
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
update_icon()
myarea = get_area(src)
LAZYADD(myarea.firealarms, src)
/obj/machinery/firealarm/Destroy()
LAZYREMOVE(myarea.firealarms, src)
return ..()
/obj/machinery/firealarm/power_change()
..()
@@ -87,29 +96,24 @@
playsound(src, "sparks", 50, 1)
/obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume)
if(!emagged && detecting && !stat && (temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT))
if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && (last_alarm+FIREALARM_COOLDOWN < world.time) && !emagged && detecting && !stat)
alarm()
..()
/obj/machinery/firealarm/proc/alarm()
if(!is_operational())
if(!is_operational() && (last_alarm+FIREALARM_COOLDOWN < world.time))
return
last_alarm = world.time
var/area/A = get_area(src)
A.firealert(src)
playsound(src.loc, 'goon/sound/machinery/FireAlarm.ogg', 75)
/obj/machinery/firealarm/proc/alarm_in(time)
addtimer(CALLBACK(src, .proc/alarm), time)
/obj/machinery/firealarm/proc/reset()
if(!is_operational())
return
var/area/A = get_area(src)
A.firereset(src)
/obj/machinery/firealarm/proc/reset_in(time)
addtimer(CALLBACK(src, .proc/reset), time)
/obj/machinery/firealarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
@@ -248,8 +252,14 @@
if(prob(33))
alarm()
/obj/machinery/firealarm/singularity_pull(S, current_size)
if (current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects, the fire alarm experiences integrity failure
deconstruct()
..()
/obj/machinery/firealarm/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1) && buildstage != 0) //can't break the electronics if there isn't any inside.
LAZYREMOVE(myarea.firealarms, src)
stat |= BROKEN
update_icon()
+1 -1
View File
@@ -434,7 +434,7 @@
gen_secondary.use_stored_power(drain_amount*0.5)
/obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return prob(20)
else
if(istype(mover, /obj/item/projectile))
+133 -133
View File
@@ -1,133 +1,133 @@
////////////////////////////////////////
//Singularity beacon
////////////////////////////////////////
/obj/machinery/power/singularity_beacon
name = "ominous beacon"
desc = "This looks suspicious..."
icon = 'icons/obj/singularity.dmi'
icon_state = "beacon"
anchored = FALSE
density = TRUE
layer = BELOW_MOB_LAYER //so people can't hide it and it's REALLY OBVIOUS
stat = 0
verb_say = "states"
var/cooldown = 0
var/active = 0
var/icontype = "beacon"
/obj/machinery/power/singularity_beacon/proc/Activate(mob/user = null)
if(surplus() < 1500)
if(user)
to_chat(user, "<span class='notice'>The connected wire doesn't have enough current.</span>")
return
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.z == z)
singulo.target = src
icon_state = "[icontype]1"
active = 1
if(user)
to_chat(user, "<span class='notice'>You activate the beacon.</span>")
/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user = null)
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.target == src)
singulo.target = null
icon_state = "[icontype]0"
active = 0
if(user)
to_chat(user, "<span class='notice'>You deactivate the beacon.</span>")
/obj/machinery/power/singularity_beacon/attack_ai(mob/user)
return
/obj/machinery/power/singularity_beacon/attack_hand(mob/user)
if(anchored)
return active ? Deactivate(user) : Activate(user)
else
to_chat(user, "<span class='warning'>You need to screw the beacon to the floor first!</span>")
return
/obj/machinery/power/singularity_beacon/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
if(active)
to_chat(user, "<span class='warning'>You need to deactivate the beacon first!</span>")
return
if(anchored)
anchored = FALSE
to_chat(user, "<span class='notice'>You unscrew the beacon from the floor.</span>")
disconnect_from_network()
return
else
if(!connect_to_network())
to_chat(user, "<span class='warning'>This device must be placed over an exposed, powered cable node!</span>")
return
anchored = TRUE
to_chat(user, "<span class='notice'>You screw the beacon to the floor and attach the cable.</span>")
return
else
return ..()
/obj/machinery/power/singularity_beacon/Destroy()
if(active)
Deactivate()
return ..()
//stealth direct power usage
/obj/machinery/power/singularity_beacon/process()
if(!active)
return
if(surplus() > 1500)
add_load(1500)
if(cooldown <= world.time)
cooldown = world.time + 100
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.z == z)
say("The [singulo] is now [get_dist(src,singulo)] standard lengths away to the [dir2text(get_dir(src,singulo))]")
else
Deactivate()
say("Insufficient charge detected - powering down")
/obj/machinery/power/singularity_beacon/syndicate
icontype = "beaconsynd"
icon_state = "beaconsynd0"
// SINGULO BEACON SPAWNER
/obj/item/device/sbeacondrop
name = "suspicious beacon"
icon = 'icons/obj/radio.dmi'
icon_state = "beacon"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
desc = "A label on it reads: <i>Warning: Activating this device will send a special beacon to your location</i>."
origin_tech = "bluespace=6;syndicate=5"
w_class = WEIGHT_CLASS_SMALL
var/droptype = /obj/machinery/power/singularity_beacon/syndicate
/obj/item/device/sbeacondrop/attack_self(mob/user)
if(user)
to_chat(user, "<span class='notice'>Locked In.</span>")
new droptype( user.loc )
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
qdel(src)
return
/obj/item/device/sbeacondrop/bomb
desc = "A label on it reads: <i>Warning: Activating this device will send a high-ordinance explosive to your location</i>."
droptype = /obj/machinery/syndicatebomb
origin_tech = "bluespace=5;syndicate=5"
/obj/item/device/sbeacondrop/powersink
desc = "A label on it reads: <i>Warning: Activating this device will send a power draining device to your location</i>."
droptype = /obj/item/device/powersink
origin_tech = "bluespace=4;syndicate=5"
////////////////////////////////////////
//Singularity beacon
////////////////////////////////////////
/obj/machinery/power/singularity_beacon
name = "ominous beacon"
desc = "This looks suspicious..."
icon = 'icons/obj/singularity.dmi'
icon_state = "beacon"
anchored = FALSE
density = TRUE
layer = BELOW_MOB_LAYER //so people can't hide it and it's REALLY OBVIOUS
stat = 0
verb_say = "states"
var/cooldown = 0
var/active = 0
var/icontype = "beacon"
/obj/machinery/power/singularity_beacon/proc/Activate(mob/user = null)
if(surplus() < 1500)
if(user)
to_chat(user, "<span class='notice'>The connected wire doesn't have enough current.</span>")
return
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.z == z)
singulo.target = src
icon_state = "[icontype]1"
active = 1
if(user)
to_chat(user, "<span class='notice'>You activate the beacon.</span>")
/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user = null)
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.target == src)
singulo.target = null
icon_state = "[icontype]0"
active = 0
if(user)
to_chat(user, "<span class='notice'>You deactivate the beacon.</span>")
/obj/machinery/power/singularity_beacon/attack_ai(mob/user)
return
/obj/machinery/power/singularity_beacon/attack_hand(mob/user)
if(anchored)
return active ? Deactivate(user) : Activate(user)
else
to_chat(user, "<span class='warning'>You need to screw the beacon to the floor first!</span>")
return
/obj/machinery/power/singularity_beacon/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
if(active)
to_chat(user, "<span class='warning'>You need to deactivate the beacon first!</span>")
return
if(anchored)
anchored = FALSE
to_chat(user, "<span class='notice'>You unscrew the beacon from the floor.</span>")
disconnect_from_network()
return
else
if(!connect_to_network())
to_chat(user, "<span class='warning'>This device must be placed over an exposed, powered cable node!</span>")
return
anchored = TRUE
to_chat(user, "<span class='notice'>You screw the beacon to the floor and attach the cable.</span>")
return
else
return ..()
/obj/machinery/power/singularity_beacon/Destroy()
if(active)
Deactivate()
return ..()
//stealth direct power usage
/obj/machinery/power/singularity_beacon/process()
if(!active)
return
if(surplus() > 1500)
add_load(1500)
if(cooldown <= world.time)
cooldown = world.time + 80
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.z == z)
say("[singulo] is now [get_dist(src,singulo)] standard lengths away to the [dir2text(get_dir(src,singulo))]")
else
Deactivate()
say("Insufficient charge detected - powering down")
/obj/machinery/power/singularity_beacon/syndicate
icontype = "beaconsynd"
icon_state = "beaconsynd0"
// SINGULO BEACON SPAWNER
/obj/item/device/sbeacondrop
name = "suspicious beacon"
icon = 'icons/obj/radio.dmi'
icon_state = "beacon"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
desc = "A label on it reads: <i>Warning: Activating this device will send a special beacon to your location</i>."
origin_tech = "bluespace=6;syndicate=5"
w_class = WEIGHT_CLASS_SMALL
var/droptype = /obj/machinery/power/singularity_beacon/syndicate
/obj/item/device/sbeacondrop/attack_self(mob/user)
if(user)
to_chat(user, "<span class='notice'>Locked In.</span>")
new droptype( user.loc )
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
qdel(src)
return
/obj/item/device/sbeacondrop/bomb
desc = "A label on it reads: <i>Warning: Activating this device will send a high-ordinance explosive to your location</i>."
droptype = /obj/machinery/syndicatebomb
origin_tech = "bluespace=5;syndicate=5"
/obj/item/device/sbeacondrop/powersink
desc = "A label on it reads: <i>Warning: Activating this device will send a power draining device to your location</i>."
droptype = /obj/item/device/powersink
origin_tech = "bluespace=4;syndicate=5"
@@ -295,7 +295,7 @@
Item.extinguish()
/obj/structure/foamedmetal/resin/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE
. = ..()
+2 -2
View File
@@ -58,8 +58,8 @@
delay = delay - myseed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
obj_integrity = myseed.endurance
max_integrity = myseed.endurance
if(myseed.get_gene(/datum/plant_gene/trait/glow))
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
if(G)
set_light(G.glow_range(myseed), G.glow_power(myseed), G.glow_color)
setDir(CalcDir())
var/base_icon_state = initial(icon_state)
+6 -151
View File
@@ -3,16 +3,6 @@
#define AREA_SPACE 2
#define AREA_SPECIAL 3
#define BORDER_ERROR 0
#define BORDER_NONE 1
#define BORDER_BETWEEN 2
#define BORDER_2NDTILE 3
#define BORDER_SPACE 4
#define ROOM_ERR_LOLWAT 0
#define ROOM_ERR_SPACE 1
#define ROOM_ERR_TOOLARGE 2
/obj/item/areaeditor
name = "area modification item"
icon = 'icons/obj/items_and_weapons.dmi'
@@ -22,16 +12,15 @@
/obj/item/areaeditor/attack_self(mob/user)
add_fingerprint(user)
var/text = "<BODY><HTML><head><title>[src]</title></head> \
. = "<BODY><HTML><head><title>[src]</title></head> \
<h2>[station_name()] [src.name]</h2> \
<small>[fluffnotice]</small><hr>"
switch(get_area_type())
if(AREA_SPACE)
text += "<p>According to the [src.name], you are now in an unclaimed territory.</p> \
<p><a href='?src=[REF(src)];create_area=1'>Mark this place as new area.</a></p>"
. += "<p>According to the [src.name], you are now in an unclaimed territory.</p>"
if(AREA_SPECIAL)
text += "<p>This place is not noted on the [src.name].</p>"
return text
. += "<p>This place is not noted on the [src.name].</p>"
. += "<p><a href='?src=[REF(src)];create_area=1'>Create or modify an existing area</a></p>"
/obj/item/areaeditor/Topic(href, href_list)
@@ -41,8 +30,7 @@
usr << browse(null, "window=blueprints")
return
if(href_list["create_area"])
if(get_area_type()==AREA_SPACE)
create_area(usr)
create_area(usr)
updateUsrDialog()
//Station blueprints!!!
@@ -69,7 +57,7 @@
var/area/A = get_area()
if(get_area_type() == AREA_STATION)
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
. += "<p>You may <a href='?src=[REF(src)];edit_area=1'>make an amendment</a> to the drawing.</p>"
. += "<p><a href='?src=[REF(src)];edit_area=1'>Change area name</a></p>"
. += "<p><a href='?src=[REF(src)];view_legend=1'>View wire colour legend</a></p>"
if(!viewing)
. += "<p><a href='?src=[REF(src)];view_blueprints=1'>View structural data</a></p>"
@@ -186,63 +174,6 @@
return message
return ""
/proc/create_area(mob/living/creator)
var/res = detect_room(get_turf(creator))
if(!islist(res))
switch(res)
if(ROOM_ERR_SPACE)
to_chat(creator, "<span class='warning'>The new area must be completely airtight.</span>")
return
if(ROOM_ERR_TOOLARGE)
to_chat(creator, "<span class='warning'>The new area is too large.</span>")
return
else
to_chat(creator, "<span class='warning'>Error! Please notify administration.</span>")
return
var/list/turfs = res
var/str = trim(stripped_input(creator,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN))
if(!str || !length(str)) //cancel
return
if(length(str) > 50)
to_chat(creator, "<span class='warning'>The given name is too long. The area remains undefined.</span>")
return
var/area/old = get_area(get_turf(creator))
var/old_gravity = old.has_gravity
var/area/A
for(var/key in turfs)
if(key == str)
A = turfs[key]
if(turfs[key])
turfs -= turfs[key]
turfs -= key
if(A)
A.set_dynamic_lighting()
for (var/turf/T in turfs)
var/area/old_area = T.loc
A.contents += T
T.change_area(old_area, T)
else
A = new
A.setup(str)
A.set_dynamic_lighting()
for (var/turf/T in turfs)
var/area/old_area = T.loc
A.contents += T
T.change_area(old_area, T)
A.has_gravity = old_gravity
for(var/area/RA in old.related)
if(RA.firedoors)
for(var/D in RA.firedoors)
var/obj/machinery/door/firedoor/FD = D
FD.CalculateAffectingAreas()
to_chat(creator, "<span class='notice'>You have created a new area, named [str]. It is now weather proof, and constructing an APC will allow it to be powered.</span>")
return 1
/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area()
var/prevname = "[A.name]"
@@ -280,82 +211,6 @@
M.name = replacetext(M.name,oldtitle,title)
//TODO: much much more. Unnamed airlocks, cameras, etc.
/turf/proc/check_tile_is_border()
return BORDER_NONE
/turf/open/space/check_tile_is_border()
return BORDER_SPACE
/turf/closed/check_tile_is_border()
return BORDER_2NDTILE
/turf/open/check_tile_is_border()
for(var/atom/movable/AM in src)
if(!CANATMOSPASS(AM, src))
return BORDER_2NDTILE
return BORDER_NONE
/turf/closed/mineral/check_tile_is_border()
return BORDER_NONE
/proc/detect_room(turf/first)
var/list/turf/found = new
var/list/turf/pending = list(first)
var/list/border = list()
while(pending.len)
if (found.len+pending.len > 300)
return ROOM_ERR_TOOLARGE
var/turf/T = pending[1] //why byond havent list::pop()?
pending -= T
for (var/dir in GLOB.cardinals)
var/skip = 0
for (var/obj/structure/window/W in T)
if(dir == W.dir || (W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST)))
skip = 1
break
if (skip)
continue
for(var/obj/machinery/door/window/D in T)
if(dir == D.dir)
skip = 1
break
if (skip)
continue
var/turf/NT = get_step(T,dir)
if (!isturf(NT) || (NT in found) || (NT in pending))
continue
switch(NT.check_tile_is_border())
if(BORDER_NONE)
pending+=NT
if(BORDER_BETWEEN)
var/area/A = NT.loc
if(!found[A.name])
found[A.name] = NT.loc
if(BORDER_2NDTILE)
border[NT] += dir
if(BORDER_SPACE)
return ROOM_ERR_SPACE
found+=T
for(var/V in border) //lazy but works
var/turf/F = V
for(var/direction in GLOB.cardinals)
if(direction == border[F])
continue //don't want to grab turfs from outside the border
var/turf/U = get_step(F, direction)
if((U in border) || (U in found))
continue
if(U.check_tile_is_border() == BORDER_2NDTILE)
found += U
found |= F
return found
//Blueprint Subtypes
/obj/item/areaeditor/blueprints/cyborg
@@ -95,7 +95,7 @@
return ..()
/obj/structure/projected_forcefield/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
return !density
@@ -11,7 +11,6 @@
var/frequency = 1459 //common chat
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
var/canhear_range = 3 // the range which mobs can hear this radio from
var/obj/item/device/radio/patch_link = null
var/list/secure_radio_connections
var/prison_radio = 0
var/b_stat = 0
@@ -82,7 +81,6 @@
qdel(wires)
wires = null
remove_radio_all(src) //Just to be sure
patch_link = null
keyslot = null
return ..()
+2 -2
View File
@@ -287,7 +287,7 @@
return TRUE
/obj/structure/girder/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGRILLE))
if(istype(mover) && (mover.pass_flags & PASSGRILLE))
return prob(girderpasschance)
else
if(istype(mover, /obj/item/projectile))
@@ -299,7 +299,7 @@
. = !density
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSGRILLE)
. = . || (mover.pass_flags & PASSGRILLE)
/obj/structure/girder/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
+20 -2
View File
@@ -21,6 +21,24 @@
. = ..()
AddComponent(/datum/component/rad_insulation, RAD_NO_INSULATION)
/obj/structure/grille/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
update_icon()
/obj/structure/grille/update_icon()
if(QDELETED(src))
return
var/ratio = obj_integrity / max_integrity
ratio = Ceiling(ratio*4) * 25
if(smooth)
queue_smooth(src)
if(ratio > 50)
return
icon_state = "grille50_[rand(0,3)]"
/obj/structure/grille/examine(mob/user)
..()
if(anchored)
@@ -100,7 +118,7 @@
/obj/structure/grille/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGRILLE))
if(istype(mover) && (mover.pass_flags & PASSGRILLE))
return TRUE
else
if(istype(mover, /obj/item/projectile) && density)
@@ -112,7 +130,7 @@
. = !density
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSGRILLE)
. = . || (mover.pass_flags & PASSGRILLE)
/obj/structure/grille/attackby(obj/item/W, mob/user, params)
user.changeNext_move(CLICK_CD_MELEE)
+2 -2
View File
@@ -323,7 +323,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
icon_state = "morguet"
/obj/structure/tray/m_tray/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
if(istype(mover) && (mover.pass_flags & PASSTABLE))
return 1
if(locate(/obj/structure/table) in get_turf(mover))
return 1
@@ -334,4 +334,4 @@ GLOBAL_LIST_EMPTY(crematoriums)
. = !density
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSTABLE)
. = . || (mover.pass_flags & PASSTABLE)
+1 -1
View File
@@ -64,7 +64,7 @@
return 1 //diseases, stings, etc can pass
/obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T)
if(istype(A) && A.checkpass(PASSGLASS))
if(istype(A) && (A.pass_flags & PASSGLASS))
return prob(60)
var/obj/structure/bed/B = A
+4 -4
View File
@@ -74,7 +74,7 @@
..()
/obj/structure/table/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
if(istype(mover) && (mover.pass_flags & PASSTABLE))
return 1
if(mover.throwing)
return 1
@@ -87,7 +87,7 @@
. = !density
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSTABLE)
. = . || (mover.pass_flags & PASSTABLE)
/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob)
pushed_mob.forceMove(src.loc)
@@ -423,7 +423,7 @@
/obj/structure/rack/CanPass(atom/movable/mover, turf/target)
if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!|
return 1
if(istype(mover) && mover.checkpass(PASSTABLE))
if(istype(mover) && (mover.pass_flags & PASSTABLE))
return 1
else
return 0
@@ -432,7 +432,7 @@
. = !density
if(ismovableatom(caller))
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSTABLE)
. = . || (mover.pass_flags & PASSTABLE)
/obj/structure/rack/MouseDrop_T(obj/O, mob/user)
if ((!( istype(O, /obj/item) ) || user.get_active_held_item() != O))
@@ -14,7 +14,7 @@
var/enter_delay = 0
/obj/structure/transit_tube/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
return !density
@@ -55,7 +55,7 @@
icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
return !density
@@ -78,7 +78,7 @@
return 1
/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(get_dir(loc, target) == dir)
return !density
+2 -2
View File
@@ -120,7 +120,7 @@
..(FULLTILE_WINDOW_DIR)
/obj/structure/window/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSGLASS))
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return 1
if(dir == FULLTILE_WINDOW_DIR)
return 0 //full tile window, you can't move into it!
@@ -139,7 +139,7 @@
return 1
/obj/structure/window/CheckExit(atom/movable/O as mob|obj, target)
if(istype(O) && O.checkpass(PASSGLASS))
if(istype(O) && (O.pass_flags & PASSGLASS))
return 1
if(get_dir(O.loc, target) == dir)
return 0
+1 -1
View File
@@ -16,7 +16,7 @@
return FALSE
/turf/closed/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSCLOSEDTURF))
if(istype(mover) && (mover.pass_flags & PASSCLOSEDTURF))
return TRUE
else
..()
+5
View File
@@ -772,6 +772,11 @@
winheight = min(winheight, 690)
usr << browse(dat, "window=players;size=375x[winheight]")
/datum/admins/proc/create_or_modify_area()
set category = "Debug"
set name = "Create or modify area"
create_area(usr)
//
//
//ALL DONE
+2 -1
View File
@@ -157,7 +157,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug())
/client/proc/view_runtimes,
/client/proc/pump_random_event,
/client/proc/cmd_display_init_log,
/client/proc/cmd_display_overlay_log
/client/proc/cmd_display_overlay_log,
/datum/admins/proc/create_or_modify_area
)
GLOBAL_PROTECT(admin_verbs_possess)
GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release))
@@ -97,9 +97,8 @@
/turf/open/proc/update_visuals()
var/list/new_overlay_types = tile_graphic()
var/list/atmos_overlay_types = src.atmos_overlay_types // Cache for free performance
<<<<<<< HEAD
=======
#if DM_VERSION >= 513
#warning 512 is stable now for sure, remove the old code
#endif
@@ -115,7 +114,6 @@
else
vars["vis_contents"] += new_overlay_types
#else
>>>>>>> 5941e80... 511 client fix and a config to make the version warning a popup (#32757)
if (atmos_overlay_types)
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
cut_overlay(overlay)
@@ -125,6 +123,7 @@
add_overlay(new_overlay_types - atmos_overlay_types) //don't add overlays that already exist
else
add_overlay(new_overlay_types)
#endif
UNSETEMPTY(new_overlay_types)
src.atmos_overlay_types = new_overlay_types
-1
View File
@@ -21,7 +21,6 @@
/////////
var/datum/preferences/prefs = null
var/move_delay = 1
var/moving = null
var/area = null
@@ -8,7 +8,7 @@
icon_state = "meat"
dried_type = /obj/item/reagent_containers/food/snacks/sosjerky/healthy
bitesize = 3
list_reagents = list("nutriment" = 3)
list_reagents = list("nutriment" = 3, "cooking_oil" = 2) //Meat has fats that a food processor can process into cooking oil
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/plain
slice_path = /obj/item/reagent_containers/food/snacks/meat/rawcutlet/plain
slices_num = 3
@@ -170,7 +170,7 @@
name = "bear meat"
desc = "A very manly slab of meat."
icon_state = "bearmeat"
list_reagents = list("nutriment" = 12, "morphine" = 5, "vitamin" = 2)
list_reagents = list("nutriment" = 12, "morphine" = 5, "vitamin" = 2, "cooking_oil" = 6)
filling_color = "#FFB6C1"
cooked_type = /obj/item/reagent_containers/food/snacks/meat/steak/bear
slice_path = /obj/item/reagent_containers/food/snacks/meat/rawcutlet/bear
@@ -205,7 +205,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/goliath
name = "goliath meat"
desc = "A slab of goliath meat. It's not very edible now, but it cooks great in lava."
list_reagents = list("nutriment" = 3, "toxin" = 5)
list_reagents = list("nutriment" = 3, "toxin" = 5, "cooking_oil" = 3)
icon_state = "goliathmeat"
tastes = list("meat" = 1)
foodtype = RAW | MEAT | TOXIC
@@ -218,7 +218,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/meatwheat
name = "meatwheat clump"
desc = "This doesn't look like meat, but your standards aren't <i>that</i> high to begin with."
list_reagents = list("nutriment" = 3, "vitamin" = 2, "blood" = 5)
list_reagents = list("nutriment" = 3, "vitamin" = 2, "blood" = 5, "cooking_oil" = 1)
filling_color = rgb(150, 0, 0)
icon_state = "meatwheat_clump"
bitesize = 4
@@ -228,7 +228,7 @@
/obj/item/reagent_containers/food/snacks/meat/slab/gorilla
name = "gorilla meat"
desc = "Much meatier than monkey meat."
list_reagents = list("nutriment" = 5, "vitamin" = 1)
list_reagents = list("nutriment" = 5, "vitamin" = 1, "cooking_oil" = 5) //Plenty of fat!
/obj/item/reagent_containers/food/snacks/meat/rawbacon
name = "raw piece of bacon"
@@ -236,7 +236,7 @@
icon_state = "bacon"
cooked_type = /obj/item/reagent_containers/food/snacks/meat/bacon
bitesize = 2
list_reagents = list("nutriment" = 1)
list_reagents = list("nutriment" = 1, "cooking_oil" = 3)
filling_color = "#B22222"
tastes = list("bacon" = 1)
foodtype = RAW | MEAT
@@ -246,7 +246,7 @@
desc = "A delicious piece of bacon."
icon_state = "baconcooked"
list_reagents = list("nutriment" = 2)
bonus_reagents = list("nutriment" = 1, "vitamin" = 1)
bonus_reagents = list("nutriment" = 1, "vitamin" = 1, "cooking_oil" = 2)
filling_color = "#854817"
tastes = list("bacon" = 1)
foodtype = MEAT
@@ -185,36 +185,39 @@
icon_state = ""
bitesize = 2
/obj/item/reagent_containers/food/snacks/deepfryholder/proc/fry(obj/item/frying, datum/reagents/reagents, cook_time = 30)
if(istype(frying, /obj/item/reagent_containers/))
var/obj/item/reagent_containers/food = frying
food.reagents.trans_to(src, food.reagents.total_volume)
icon = frying.icon
overlays = frying.overlays
icon_state = frying.icon_state
desc = frying.desc
w_class = frying.w_class
reagents.trans_to(src, 2*(cook_time/15))
/obj/item/reagent_containers/food/snacks/deepfryholder/Initialize(mapload, obj/item/fried)
. = ..()
name = fried.name //We'll determine the other stuff when it's actually removed
icon = fried.icon
overlays = fried.copy_overlays()
icon_state = fried.icon_state
desc = fried.desc
if(istype(fried, /obj/item/reagent_containers/food/snacks))
fried.reagents.trans_to(src, fried.reagents.total_volume)
qdel(fried)
else
fried.forceMove(src)
/obj/item/reagent_containers/food/snacks/deepfryholder/proc/fry(cook_time = 30)
switch(cook_time)
if(0 to 15)
add_atom_colour(rgb(166,103,54), FIXED_COLOUR_PRIORITY)
name = "lightly-fried [frying.name]"
name = "lightly-fried [name]"
desc = "[desc] It's been lightly fried in a deep fryer."
if(16 to 49)
add_atom_colour(rgb(103,63,24), FIXED_COLOUR_PRIORITY)
name = "fried [frying.name]"
name = "fried [name]"
desc = "[desc] It's been fried, increasing its tastiness value by [rand(1, 75)]%."
if(50 to 59)
add_atom_colour(rgb(63,23,4), FIXED_COLOUR_PRIORITY)
name = "deep-fried [frying.name]"
name = "deep-fried [name]"
desc = "[desc] Deep-fried to perfection."
if(60 to INFINITY)
add_atom_colour(rgb(33,19,9), FIXED_COLOUR_PRIORITY)
name = "the physical manifestation of the very concept of fried foods"
desc = "A heavily fried...something. Who can tell anymore?"
desc = "A heavily-fried...something. Who can tell anymore?"
filling_color = color
foodtype |= FRIED
if(istype(frying, /obj/item/reagent_containers/food/snacks/))
qdel(frying)
else
frying.forceMove(src)
/obj/item/reagent_containers/food/snacks/butteredtoast
name = "buttered toast"
@@ -1,11 +1,25 @@
/*
April 3rd, 2014 marks the day this machine changed the face of the kitchen on NTStation13
God bless America.
insert ascii eagle on american flag background here
___----------___
_-- ----__
- ---_
-___ ____---_ --_
__---_ .-_-- _ O _- -
- -_- --- -
- __---------___ -
- _---- -
- -_ _
` _- _
_ _-_ _-_ _
_- ____ -_ - --
- _-__ _ __--- ------- -
_- _- -_-- -_-- _
-_- _
_- _
-
*/
// April 3rd, 2014 marks the day this machine changed the face of the kitchen on NTStation13
// God bless America.
/obj/machinery/deepfryer
name = "deep fryer"
desc = "Deep fried <i>everything</i>."
@@ -16,8 +30,12 @@ insert ascii eagle on american flag background here
use_power = IDLE_POWER_USE
idle_power_usage = 5
container_type = OPENCONTAINER_1
var/obj/item/frying = null //What's being fried RIGHT NOW?
var/obj/item/reagent_containers/food/snacks/deepfryholder/frying //What's being fried RIGHT NOW?
var/cook_time = 0
var/oil_use = 0.05 //How much cooking oil is used per tick
var/fry_speed = 1 //How quickly we fry food
var/frying_fried //If the object has been fried; used for messages
var/frying_burnt //If the object has been burnt
var/static/list/deepfry_blacklisted_items = typecacheof(list(
/obj/item/screwdriver,
/obj/item/crowbar,
@@ -26,16 +44,27 @@ insert ascii eagle on american flag background here
/obj/item/device/multitool,
/obj/item/weldingtool,
/obj/item/reagent_containers/glass,
/obj/item/reagent_containers/syringe,
/obj/item/reagent_containers/food/condiment,
/obj/item/storage/part_replacer))
var/datum/looping_sound/deep_fryer/fry_loop
/obj/machinery/deepfryer/Initialize()
. = ..()
create_reagents(50)
reagents.add_reagent("nutriment", 25)
reagents.add_reagent("cooking_oil", 25)
component_parts = list()
component_parts += new /obj/item/circuitboard/machine/deep_fryer(null)
component_parts += new /obj/item/stock_parts/micro_laser(null)
RefreshParts()
fry_loop = new(list(src), FALSE)
/obj/machinery/deepfryer/RefreshParts()
var/oil_efficiency
for(var/obj/item/stock_parts/micro_laser/M in component_parts)
oil_efficiency += M.rating
oil_use = initial(oil_use) - (oil_efficiency * 0.0095)
fry_speed = oil_efficiency
/obj/machinery/deepfryer/examine()
..()
@@ -43,8 +72,16 @@ insert ascii eagle on american flag background here
to_chat(usr, "You can make out \a [frying] in the oil.")
/obj/machinery/deepfryer/attackby(obj/item/I, mob/user)
if(!reagents.total_volume)
to_chat(user, "There's nothing to fry with in [src]!")
if(istype(I, /obj/item/reagent_containers/pill))
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>There's nothing to dissolve [I] in!</span>")
return
user.visible_message("<span class='notice'>[user] drops [I] into [src].</span>", "<span class='notice'>You dissolve [I] in [src].</span>")
I.reagents.trans_to(src, I.reagents.total_volume)
qdel(I)
return
if(!reagents.has_reagent("cooking_oil"))
to_chat(user, "<span class='warning'>[src] has no cooking oil to fry with!</span>")
return
if(istype(I, /obj/item/reagent_containers/food/snacks/deepfryholder))
to_chat(user, "<span class='userdanger'>Your cooking skills are not up to the legendary Doublefry technique.</span>")
@@ -60,20 +97,26 @@ insert ascii eagle on american flag background here
. = ..()
else if(!frying && user.transferItemToLoc(I, src))
to_chat(user, "<span class='notice'>You put [I] into [src].</span>")
frying = I
frying = new/obj/item/reagent_containers/food/snacks/deepfryholder(src, I)
icon_state = "fryer_on"
fry_loop.start()
/obj/machinery/deepfryer/process()
..()
if(!reagents.total_volume)
var/datum/reagent/consumable/cooking_oil/C = reagents.has_reagent("cooking_oil")
if(!C)
return
reagents.chem_temp = C.fry_temperature
if(frying)
cook_time++
if(cook_time == 30)
reagents.trans_to(frying, oil_use, multiplier = fry_speed * 3) //Fried foods gain more of the reagent thanks to space magic
cook_time += fry_speed
if(cook_time >= 30 && !frying_fried)
frying_fried = TRUE //frying... frying... fried
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
visible_message("[src] dings!")
else if (cook_time == 60)
visible_message("[src] emits an acrid smell!")
audible_message("<span class='notice'>[src] dings!</span>")
else if (cook_time >= 60 && !frying_burnt)
frying_burnt = TRUE
visible_message("<span class='warning'>[src] emits an acrid smell!</span>")
/obj/machinery/deepfryer/attack_ai(mob/user)
@@ -83,13 +126,14 @@ insert ascii eagle on american flag background here
if(frying)
if(frying.loc == src)
to_chat(user, "<span class='notice'>You eject [frying] from [src].</span>")
var/obj/item/reagent_containers/food/snacks/deepfryholder/S = new(drop_location())
S.fry(frying, reagents, cook_time)
frying.fry(cook_time)
icon_state = "fryer_off"
if(user.Adjacent(src))
user.put_in_hands(S)
user.put_in_hands(frying)
frying = null
cook_time = 0
frying_fried = FALSE
frying_burnt = FALSE
fry_loop.stop()
return
else if(user.pulling && user.a_intent == "grab" && iscarbon(user.pulling) && reagents.total_volume)
if(user.grab_state < GRAB_AGGRESSIVE)
@@ -98,7 +142,7 @@ insert ascii eagle on american flag background here
var/mob/living/carbon/C = user.pulling
user.visible_message("<span class = 'danger'>[user] dunks [C]'s face in [src]!</span>")
reagents.reaction(C, TOUCH)
C.adjustFireLoss(reagents.total_volume)
C.apply_damage(min(30, reagents.total_volume), BURN, "head")
reagents.remove_any((reagents.total_volume/2))
C.Knockdown(60)
user.changeNext_move(CLICK_CD_MELEE)
@@ -15,6 +15,7 @@
var/broken = 0 // ={0,1,2} How broken is it???
var/max_n_of_items = 10 // whatever fat fuck made this a global var needs to look at themselves in the mirror sometime
var/efficiency = 0
var/datum/looping_sound/microwave/soundloop
//Microwaving doesn't use recipes, instead it calls the microwave_act of the objects. For food, this creates something based on the food's cooked_type
@@ -25,6 +26,7 @@
/obj/machinery/microwave/Initialize()
. = ..()
create_reagents(100)
soundloop = new(list(src), FALSE)
/obj/machinery/microwave/RefreshParts()
var/E
@@ -266,6 +268,7 @@
/obj/machinery/microwave/proc/start()
visible_message("The microwave turns on.", "<span class='italics'>You hear a microwave humming.</span>")
soundloop.start()
operating = TRUE
icon_state = "mw1"
updateUsrDialog()
@@ -276,7 +279,7 @@
updateUsrDialog()
/obj/machinery/microwave/proc/stop()
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
soundloop.stop()
abort()
/obj/machinery/microwave/proc/dispose()
+1 -1
View File
@@ -15,7 +15,7 @@
icon_dead = "soybean-dead"
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/soya/koi)
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05, "cooking_oil" = 0.03) //Vegetable oil!
/obj/item/reagent_containers/food/snacks/grown/soybeans
seed = /obj/item/seeds/soya
+1 -1
View File
@@ -118,7 +118,7 @@
density = TRUE
/obj/structure/bonfire/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSTABLE))
if(istype(mover) && (mover.pass_flags & PASSTABLE))
return TRUE
if(mover.throwing)
return TRUE
@@ -56,8 +56,6 @@
nutrition -= HUNGER_FACTOR/10
if(m_intent == MOVE_INTENT_RUN)
nutrition -= HUNGER_FACTOR/10
if((disabilities & FAT) && m_intent == MOVE_INTENT_RUN && bodytemperature <= 360)
bodytemperature += 2
/mob/living/carbon/Moved(oldLoc, Dir)
. = ..()
@@ -56,8 +56,8 @@
FP.update_icon()
update_inv_shoes()
//End bloody footprints
S.step_action()
/mob/living/carbon/human/Moved()
. = ..()
if(buckled_mobs && buckled_mobs.len && riding_datum)
@@ -55,9 +55,6 @@
var/datum/species/golem/G = V
if(!initial(G.random_eligible))
random_golem_types -= G
to_chat(world, "Excluding golem type [initial(G.id)]")
else
to_chat(world, "Allowing golem type [initial(G.id)]")
var/datum/species/golem/golem_type = pick(random_golem_types)
var/mob/living/carbon/human/H = C
H.set_species(golem_type)
@@ -128,10 +128,10 @@
/datum/species/jelly/slime/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
if(ishuman(C))
slime_split = new
/*slime_split = new
slime_split.Grant(C)
swap_body = new
swap_body.Grant(C)
swap_body.Grant(C)*/
if(!bodies || !bodies.len)
bodies = list(C)
@@ -145,10 +145,10 @@
bodies = old_species.bodies
/datum/species/jelly/slime/spec_life(mob/living/carbon/human/H)
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
/*if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
if(prob(5))
to_chat(H, "<span class='notice'>You feel very bloated!</span>")
else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
to_chat(H, "<span class='notice'>You feel very bloated!</span>")*/
if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
H.blood_volume += 3
H.nutrition -= 2.5
-1
View File
@@ -471,7 +471,6 @@
s_active.close(src)
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
makeTrail(newloc, T, old_direction)
/mob/living/movement_delay(ignorewalk = 0)
@@ -80,7 +80,7 @@
/mob/living/simple_animal/drone/Initialize()
. = ..()
GLOB.drones_list += src
access_card = new /obj/item/card/id(src)
var/datum/job/captain/C = new /datum/job/captain
access_card.access = C.get_access()
@@ -124,6 +124,7 @@
holder.icon_state = "hudstat"
/mob/living/simple_animal/drone/Destroy()
GLOB.drones_list -= src
qdel(access_card) //Otherwise it ends up on the floor!
return ..()
-3
View File
@@ -395,7 +395,6 @@
pulling = null
grab_state = 0
update_pull_hud_icon()
if(isliving(ex_pulled))
var/mob/living/L = ex_pulled
L.update_canmove()// mob gets up if it was lyng down in a chokehold
@@ -676,8 +675,6 @@
/mob/proc/canface()
if(!canmove)
return 0
if(client.moving)
return 0
if(world.time < client.move_delay)
return 0
if(stat==2)
+9 -14
View File
@@ -1,8 +1,8 @@
/mob/CanPass(atom/movable/mover, turf/target)
if((mover.pass_flags & PASSMOB))
return TRUE
if(istype(mover, /obj/item/projectile) || mover.throwing)
return (!density || lying)
if(mover.checkpass(PASSMOB))
return TRUE
if(buckled == mover)
return TRUE
if(ismob(mover))
@@ -112,6 +112,7 @@
#define MOVEMENT_DELAY_BUFFER 0.75
#define MOVEMENT_DELAY_BUFFER_DELTA 1.25
/client/Move(n, direct)
if(world.time < move_delay)
return FALSE
@@ -129,15 +130,13 @@
if(mob.stat == DEAD)
mob.ghostize()
return FALSE
if(moving)
return FALSE
if(mob.force_moving)
return FALSE
if(isliving(mob))
var/mob/living/L = mob
if(L.incorporeal_move) //Move though walls
Process_Incorpmove(direct)
return FALSE
var/mob/living/L = mob //Already checked for isliving earlier
if(L.incorporeal_move) //Move though walls
Process_Incorpmove(direct)
return FALSE
if(mob.remote_control) //we're controlling something, our movement is relayed to it
return mob.remote_control.relaymove(mob, direct)
@@ -162,7 +161,6 @@
return FALSE
//We are now going to move
moving = 1
var/delay = mob.movement_delay()
if (old_move_delay + (delay*MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time)
move_delay = old_move_delay + delay
@@ -181,8 +179,7 @@
else
. = ..()
moving = 0
if(mob && .)
if(.) // If mob is null here, we deserve the runtime
if(mob.throwing)
mob.throwing.finalize(FALSE)
@@ -190,8 +187,6 @@
for(var/obj/O in mob.user_movement_hooks)
O.intercept_user_move(direct, mob, n, oldloc)
return .
/mob/Moved(oldLoc, dir, Forced = FALSE)
. = ..()
for(var/obj/O in contents)
+1 -1
View File
@@ -78,7 +78,7 @@
var/move_bias = pick(GLOB.alldirs)
for(var/i in 0 to move_amount)
var/move_dir = pick(GLOB.alldirs + move_bias) //ensures large-ball teslas don't just sit around
if(target && prob(60))
if(target && prob(10))
move_dir = get_dir(src,target)
var/turf/T = get_step(src, move_dir)
if(can_move(T))
+1 -1
View File
@@ -405,7 +405,7 @@
/obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it.
..()
if(isliving(AM) && (AM.density || AM == original) && !checkpass(PASSMOB))
if(isliving(AM) && (AM.density || AM == original) && !(src.pass_flags & PASSMOB))
Collide(AM)
/obj/item/projectile/Destroy()
@@ -83,6 +83,50 @@
M.satiety += 30
. = ..()
/datum/reagent/consumable/cooking_oil
name = "Cooking Oil"
id = "cooking_oil"
description = "A variety of cooking oil derived from fat or plants. Used in food preparation and frying."
color = "#EADD6B" //RGB: 234, 221, 107 (based off of canola oil)
taste_mult = 0.8
taste_description = "oil"
nutriment_factor = 7 * REAGENTS_METABOLISM //Not very healthy on its own
metabolization_rate = 10 * REAGENTS_METABOLISM
var/fry_temperature = 450 //Around ~350 F (117 C) which deep fryers operate around in the real world
var/boiling //Used in mob life to determine if the oil kills, and only on touch application
/datum/reagent/consumable/cooking_oil/reaction_obj(obj/O, reac_volume)
if(holder && holder.chem_temp >= fry_temperature)
if(isitem(O))
O.loc.visible_message("<span class='warning'>[O] rapidly fries as it's splashed with hot oil! Somehow.</span>")
var/obj/item/reagent_containers/food/snacks/deepfryholder/F = new(O.drop_location())
F.fry(O, volume)
/datum/reagent/consumable/cooking_oil/reaction_mob(mob/living/M, method = TOUCH, reac_volume, show_message = 1, touch_protection = 0)
if(!istype(M))
return
if(holder && holder.chem_temp >= fry_temperature)
boiling = TRUE
if(method == VAPOR || method == TOUCH) //Directly coats the mob, and doesn't go into their bloodstream
if(boiling)
M.visible_message("<span class='warning'>The boiling oil sizzles as it covers [M]!</span>", \
"<span class='userdanger'>You're covered in boiling oil!</span>")
M.emote("scream")
playsound(M, 'sound/machines/fryer/deep_fryer_emerge.ogg', 25, TRUE)
var/oil_damage = (holder.chem_temp / fry_temperature) * 0.33 //Damage taken per unit
M.adjustFireLoss(min(35, oil_damage * reac_volume)) //Damage caps at 35
else
..()
return TRUE
/datum/reagent/consumable/cooking_oil/reaction_turf(turf/open/T, reac_volume)
if(!istype(T))
return
if(reac_volume >= 5)
T.MakeSlippery(min_wet_time = 10, wet_time_to_add = reac_volume * 1.5)
T.name = "deep-fried [initial(T.name)]"
T.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
/datum/reagent/consumable/sugar
name = "Sugar"
id = "sugar"
@@ -164,19 +164,11 @@
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/medicine/clonexadone/on_mob_life(mob/living/M)
switch(M.bodytemperature) // Low temperatures are required to take effect.
if(0 to 100) // At extreme temperatures (upgraded cryo) the effect is greatly increased.
M.status_flags &= ~DISFIGURED
M.adjustCloneLoss(-7, 0)
. = 1
if(100 to 225) // At lower temperatures (cryo) the full effect is boosted
M.status_flags &= ~DISFIGURED
M.adjustCloneLoss(-3, 0)
. = 1
if(225 to T0C)
M.status_flags &= ~DISFIGURED
M.adjustCloneLoss(-2, 0)
. = 1
if(M.bodytemperature < T0C)
M.adjustCloneLoss(0.00006 * (M.bodytemperature ** 2) - 6, 0)
M.status_flags &= ~DISFIGURED
. = 1
metabolization_rate = REAGENTS_METABOLISM * (0.000015 * (M.bodytemperature ** 2) + 0.75)
..()
/datum/reagent/medicine/rezadone
+9 -1
View File
@@ -181,4 +181,12 @@
icon_state = "virus_food"
anchored = TRUE
density = FALSE
reagent_id = "virusfood"
reagent_id = "virusfood"
/obj/structure/reagent_dispensers/cooking_oil
name = "vat of cooking oil"
desc = "A huge metal vat with a tap on the front. Filled with cooking oil for use in frying food."
icon_state = "vat"
anchored = TRUE
reagent_id = "cooking_oil"