# Conflicts:
#	code/modules/mob/living/silicon/robot/robot_modules/station.dm
#	code/modules/vore/eating/bellymodes_vr.dm
#	vorestation.dme
This commit is contained in:
Repede
2018-02-28 22:06:46 -05:00
175 changed files with 3659 additions and 3308 deletions

View File

@@ -5,7 +5,7 @@ sudo: false
env:
global:
- BYOND_MAJOR="512"
- BYOND_MINOR="1403"
- BYOND_MINOR="1411"
- MACRO_COUNT=4
matrix:
- TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
//
// Pipe Cap - They go on the end
//
/obj/machinery/atmospherics/pipe/cap
name = "pipe endcap"
desc = "An endcap for pipes"
icon = 'icons/atmos/pipes.dmi'
icon_state = ""
level = 2
layer = 2.4 //under wires with their 2.44
volume = 35
dir = SOUTH
initialize_directions = SOUTH
var/obj/machinery/atmospherics/node
/obj/machinery/atmospherics/pipe/cap/init_dir()
initialize_directions = dir
/obj/machinery/atmospherics/pipe/cap/pipeline_expansion()
return list(node)
/obj/machinery/atmospherics/pipe/cap/Destroy()
if(node)
node.disconnect(src)
node = null
. = ..()
/obj/machinery/atmospherics/pipe/cap/disconnect(obj/machinery/atmospherics/reference)
if(reference == node)
if(istype(node, /obj/machinery/atmospherics/pipe))
qdel(parent)
node = null
update_icon()
..()
/obj/machinery/atmospherics/pipe/cap/change_color(var/new_color)
..()
//for updating connected atmos device pipes (i.e. vents, manifolds, etc)
if(node)
node.update_underlays()
/obj/machinery/atmospherics/pipe/cap/update_icon(var/safety = 0)
if(!check_icon_cache())
return
alpha = 255
overlays.Cut()
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap")
/obj/machinery/atmospherics/pipe/cap/atmos_init()
for(var/obj/machinery/atmospherics/target in get_step(src, dir))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node = target
break
var/turf/T = src.loc // hide if turf is not intact
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/cap/can_unwrench()
return 1
/obj/machinery/atmospherics/pipe/cap/visible
level = 2
icon_state = "cap"
/obj/machinery/atmospherics/pipe/cap/visible/scrubbers
name = "scrubbers pipe endcap"
desc = "An endcap for scrubbers pipes"
icon_state = "cap-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/cap/visible/supply
name = "supply pipe endcap"
desc = "An endcap for supply pipes"
icon_state = "cap-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/cap/hidden
level = 1
icon_state = "cap"
alpha = 128
/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers
name = "scrubbers pipe endcap"
desc = "An endcap for scrubbers pipes"
icon_state = "cap-f-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/cap/hidden/supply
name = "supply pipe endcap"
desc = "An endcap for supply pipes"
icon_state = "cap-f-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE

View File

@@ -1,153 +1,155 @@
/obj/machinery/atmospherics/pipe/simple/heat_exchanging
icon = 'icons/atmos/heat.dmi'
icon_state = "intact"
pipe_icon = "hepipe"
color = "#404040"
level = 2
connect_types = CONNECT_TYPE_HE
layer = 2.41
var/initialize_directions_he
var/surface = 2 //surface area in m^2
var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh
minimum_temperature_difference = 20
thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
buckle_lying = 1
// BubbleWrap
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/New()
..()
// BubbleWrap END
color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default.
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/init_dir()
..()
initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init()
normalize_dir()
var/node1_dir
var/node2_dir
for(var/direction in cardinal)
if(direction&initialize_directions_he)
if (!node1_dir)
node1_dir = direction
else if (!node2_dir)
node2_dir = direction
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir))
if(target.initialize_directions_he & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node2_dir))
if(target.initialize_directions_he & get_dir(target,src))
node2 = target
break
if(!node1 && !node2)
qdel(src)
return
update_icon()
return
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process()
if(!parent)
..()
else
var/datum/gas_mixture/pipe_air = return_air()
if(istype(loc, /turf/simulated/))
var/environment_temperature = 0
if(loc:blocks_air)
environment_temperature = loc:temperature
else
var/datum/gas_mixture/environment = loc.return_air()
environment_temperature = environment.temperature
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference)
parent.temperature_interact(loc, volume, thermal_conductivity)
else if(istype(loc, /turf/space/))
parent.radiate_heat_to_space(surface, 1)
if(has_buckled_mobs())
for(var/M in buckled_mobs)
var/mob/living/L = M
var/hc = pipe_air.heat_capacity()
var/avg_temp = (pipe_air.temperature * hc + L.bodytemperature * 3500) / (hc + 3500)
pipe_air.temperature = avg_temp
L.bodytemperature = avg_temp
var/heat_limit = 1000
var/mob/living/carbon/human/H = L
if(istype(H) && H.species)
heat_limit = H.species.heat_level_3
if(pipe_air.temperature > heat_limit + 1)
L.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_TORSO, used_weapon = "Excessive Heat")
//fancy radiation glowing
if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K
if(abs(pipe_air.temperature - icon_temperature) > 10)
icon_temperature = pipe_air.temperature
var/h_r = heat2color_r(icon_temperature)
var/h_g = heat2color_g(icon_temperature)
var/h_b = heat2color_b(icon_temperature)
if(icon_temperature < 2000) //scale up overlay until 2000K
var/scale = (icon_temperature - 500) / 1500
h_r = 64 + (h_r - 64)*scale
h_g = 64 + (h_g - 64)*scale
h_b = 64 + (h_b - 64)*scale
animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING)
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
icon = 'icons/atmos/junction.dmi'
icon_state = "intact"
pipe_icon = "hejunction"
level = 2
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE
minimum_temperature_difference = 300
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/init_dir()
..()
switch ( dir )
if ( SOUTH )
initialize_directions = NORTH
initialize_directions_he = SOUTH
if ( NORTH )
initialize_directions = SOUTH
initialize_directions_he = NORTH
if ( EAST )
initialize_directions = WEST
initialize_directions_he = EAST
if ( WEST )
initialize_directions = EAST
initialize_directions_he = WEST
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init()
for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,initialize_directions_he))
if(target.initialize_directions_he & get_dir(target,src))
node2 = target
break
if(!node1&&!node2)
qdel(src)
return
update_icon()
return
//
// Heat Exchanging Pipes - Behave like simple pipes
//
/obj/machinery/atmospherics/pipe/simple/heat_exchanging
icon = 'icons/atmos/heat.dmi'
icon_state = "intact"
pipe_icon = "hepipe"
color = "#404040"
level = 2
connect_types = CONNECT_TYPE_HE
layer = 2.41
var/initialize_directions_he
var/surface = 2 //surface area in m^2
var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh
minimum_temperature_difference = 20
thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
buckle_lying = 1
// BubbleWrap
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/New()
..()
// BubbleWrap END
color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default.
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/init_dir()
..()
initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init()
normalize_dir()
var/node1_dir
var/node2_dir
for(var/direction in cardinal)
if(direction&initialize_directions_he)
if (!node1_dir)
node1_dir = direction
else if (!node2_dir)
node2_dir = direction
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir))
if(target.initialize_directions_he & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node2_dir))
if(target.initialize_directions_he & get_dir(target,src))
node2 = target
break
if(!node1 && !node2)
qdel(src)
return
update_icon()
return
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process()
if(!parent)
..()
else
var/datum/gas_mixture/pipe_air = return_air()
if(istype(loc, /turf/simulated/))
var/environment_temperature = 0
if(loc:blocks_air)
environment_temperature = loc:temperature
else
var/datum/gas_mixture/environment = loc.return_air()
environment_temperature = environment.temperature
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference)
parent.temperature_interact(loc, volume, thermal_conductivity)
else if(istype(loc, /turf/space/))
parent.radiate_heat_to_space(surface, 1)
if(has_buckled_mobs())
for(var/M in buckled_mobs)
var/mob/living/L = M
var/hc = pipe_air.heat_capacity()
var/avg_temp = (pipe_air.temperature * hc + L.bodytemperature * 3500) / (hc + 3500)
pipe_air.temperature = avg_temp
L.bodytemperature = avg_temp
var/heat_limit = 1000
var/mob/living/carbon/human/H = L
if(istype(H) && H.species)
heat_limit = H.species.heat_level_3
if(pipe_air.temperature > heat_limit + 1)
L.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_TORSO, used_weapon = "Excessive Heat")
//fancy radiation glowing
if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K
if(abs(pipe_air.temperature - icon_temperature) > 10)
icon_temperature = pipe_air.temperature
var/h_r = heat2color_r(icon_temperature)
var/h_g = heat2color_g(icon_temperature)
var/h_b = heat2color_b(icon_temperature)
if(icon_temperature < 2000) //scale up overlay until 2000K
var/scale = (icon_temperature - 500) / 1500
h_r = 64 + (h_r - 64)*scale
h_g = 64 + (h_g - 64)*scale
h_b = 64 + (h_b - 64)*scale
animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING)
//
// Heat Exchange Junction - Interfaces HE pipes to normal pipes
//
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
icon = 'icons/atmos/junction.dmi'
icon_state = "intact"
pipe_icon = "hejunction"
level = 2
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE
minimum_temperature_difference = 300
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/init_dir()
..()
switch ( dir )
if ( SOUTH )
initialize_directions = NORTH
initialize_directions_he = SOUTH
if ( NORTH )
initialize_directions = SOUTH
initialize_directions_he = NORTH
if ( EAST )
initialize_directions = WEST
initialize_directions_he = EAST
if ( WEST )
initialize_directions = EAST
initialize_directions_he = WEST
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init()
for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions))
if(target.initialize_directions & get_dir(target,src))
node1 = target
break
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,initialize_directions_he))
if(target.initialize_directions_he & get_dir(target,src))
node2 = target
break
if(!node1&&!node2)
qdel(src)
return
update_icon()
return

View File

@@ -0,0 +1,244 @@
//
// Manifold Pipes - Three way "T" joints
//
/obj/machinery/atmospherics/pipe/manifold
icon = 'icons/atmos/manifold.dmi'
icon_state = ""
name = "pipe manifold"
desc = "A manifold composed of regular pipes"
volume = ATMOS_DEFAULT_VOLUME_PIPE * 1.5
dir = SOUTH
initialize_directions = EAST|NORTH|WEST
var/obj/machinery/atmospherics/node3
level = 1
layer = 2.4 //under wires with their 2.44
/obj/machinery/atmospherics/pipe/manifold/New()
..()
alpha = 255
icon = null
/obj/machinery/atmospherics/pipe/manifold/init_dir()
switch(dir)
if(NORTH)
initialize_directions = EAST|SOUTH|WEST
if(SOUTH)
initialize_directions = WEST|NORTH|EAST
if(EAST)
initialize_directions = SOUTH|WEST|NORTH
if(WEST)
initialize_directions = NORTH|EAST|SOUTH
/obj/machinery/atmospherics/pipe/manifold/pipeline_expansion()
return list(node1, node2, node3)
/obj/machinery/atmospherics/pipe/manifold/Destroy()
if(node1)
node1.disconnect(src)
node1 = null
if(node2)
node2.disconnect(src)
node2 = null
if(node3)
node3.disconnect(src)
node3 = null
. = ..()
/obj/machinery/atmospherics/pipe/manifold/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/atmospherics/pipe))
qdel(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/atmospherics/pipe))
qdel(parent)
node2 = null
if(reference == node3)
if(istype(node3, /obj/machinery/atmospherics/pipe))
qdel(parent)
node3 = null
update_icon()
..()
/obj/machinery/atmospherics/pipe/manifold/change_color(var/new_color)
..()
//for updating connected atmos device pipes (i.e. vents, manifolds, etc)
if(node1)
node1.update_underlays()
if(node2)
node2.update_underlays()
if(node3)
node3.update_underlays()
/obj/machinery/atmospherics/pipe/manifold/update_icon(var/safety = 0)
if(!check_icon_cache())
return
alpha = 255
overlays.Cut()
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)
underlays.Cut()
var/turf/T = get_turf(src)
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
var/node1_direction = get_dir(src, node1)
var/node2_direction = get_dir(src, node2)
var/node3_direction = get_dir(src, node3)
directions -= dir
directions -= add_underlay(T,node1,node1_direction,icon_connect_type)
directions -= add_underlay(T,node2,node2_direction,icon_connect_type)
directions -= add_underlay(T,node3,node3_direction,icon_connect_type)
for(var/D in directions)
add_underlay(T,,D,icon_connect_type)
/obj/machinery/atmospherics/pipe/manifold/update_underlays()
..()
update_icon()
/obj/machinery/atmospherics/pipe/manifold/atmos_init()
var/connect_directions = (NORTH|SOUTH|EAST|WEST)&(~dir)
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/atmospherics/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
connect_directions &= ~direction
break
if (node1)
break
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/atmospherics/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node2 = target
connect_directions &= ~direction
break
if (node2)
break
for(var/direction in cardinal)
if(direction&connect_directions)
for(var/obj/machinery/atmospherics/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node3 = target
connect_directions &= ~direction
break
if (node3)
break
if(!node1 && !node2 && !node3)
qdel(src)
return
var/turf/T = get_turf(src)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/manifold/visible
icon_state = "map"
level = 2
/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers
name="Scrubbers pipe manifold"
desc = "A manifold composed of scrubbers pipes"
icon_state = "map-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold/visible/supply
name="Air supply pipe manifold"
desc = "A manifold composed of supply pipes"
icon_state = "map-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold/visible/yellow
color = PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/manifold/visible/cyan
color = PIPE_COLOR_CYAN
/obj/machinery/atmospherics/pipe/manifold/visible/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold/visible/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold/visible/red
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold/visible/blue
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold/visible/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold/hidden
icon_state = "map"
level = 1
alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers
name="Scrubbers pipe manifold"
desc = "A manifold composed of scrubbers pipes"
icon_state = "map-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold/hidden/supply
name="Air supply pipe manifold"
desc = "A manifold composed of supply pipes"
icon_state = "map-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold/hidden/yellow
color = PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/manifold/hidden/cyan
color = PIPE_COLOR_CYAN
/obj/machinery/atmospherics/pipe/manifold/hidden/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold/hidden/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold/hidden/red
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold/hidden/blue
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold/hidden/purple
color = PIPE_COLOR_PURPLE

View File

@@ -0,0 +1,247 @@
//
// 4-Way Manifold Pipes - 4 way "cross" junction
//
/obj/machinery/atmospherics/pipe/manifold4w
icon = 'icons/atmos/manifold.dmi'
icon_state = ""
name = "4-way pipe manifold"
desc = "A manifold composed of regular pipes"
volume = ATMOS_DEFAULT_VOLUME_PIPE * 2
dir = SOUTH
initialize_directions = NORTH|SOUTH|EAST|WEST
var/obj/machinery/atmospherics/node3
var/obj/machinery/atmospherics/node4
level = 1
layer = 2.4 //under wires with their 2.44
/obj/machinery/atmospherics/pipe/manifold4w/New()
..()
alpha = 255
icon = null
/obj/machinery/atmospherics/pipe/manifold4w/pipeline_expansion()
return list(node1, node2, node3, node4)
/obj/machinery/atmospherics/pipe/manifold4w/Destroy()
if(node1)
node1.disconnect(src)
node1 = null
if(node2)
node2.disconnect(src)
node2 = null
if(node3)
node3.disconnect(src)
node3 = null
if(node4)
node4.disconnect(src)
node4 = null
. = ..()
/obj/machinery/atmospherics/pipe/manifold4w/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/atmospherics/pipe))
qdel(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/atmospherics/pipe))
qdel(parent)
node2 = null
if(reference == node3)
if(istype(node3, /obj/machinery/atmospherics/pipe))
qdel(parent)
node3 = null
if(reference == node4)
if(istype(node4, /obj/machinery/atmospherics/pipe))
qdel(parent)
node4 = null
update_icon()
..()
/obj/machinery/atmospherics/pipe/manifold4w/change_color(var/new_color)
..()
//for updating connected atmos device pipes (i.e. vents, manifolds, etc)
if(node1)
node1.update_underlays()
if(node2)
node2.update_underlays()
if(node3)
node3.update_underlays()
if(node4)
node4.update_underlays()
/obj/machinery/atmospherics/pipe/manifold4w/update_icon(var/safety = 0)
if(!check_icon_cache())
return
alpha = 255
overlays.Cut()
overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)
overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)
underlays.Cut()
/*
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
directions -= add_underlay(node1)
directions -= add_underlay(node2)
directions -= add_underlay(node3)
directions -= add_underlay(node4)
for(var/D in directions)
add_underlay(,D)
*/
var/turf/T = get_turf(src)
var/list/directions = list(NORTH, SOUTH, EAST, WEST)
var/node1_direction = get_dir(src, node1)
var/node2_direction = get_dir(src, node2)
var/node3_direction = get_dir(src, node3)
var/node4_direction = get_dir(src, node4)
directions -= dir
directions -= add_underlay(T,node1,node1_direction,icon_connect_type)
directions -= add_underlay(T,node2,node2_direction,icon_connect_type)
directions -= add_underlay(T,node3,node3_direction,icon_connect_type)
directions -= add_underlay(T,node4,node4_direction,icon_connect_type)
for(var/D in directions)
add_underlay(T,,D,icon_connect_type)
/obj/machinery/atmospherics/pipe/manifold4w/update_underlays()
..()
update_icon()
/obj/machinery/atmospherics/pipe/manifold4w/atmos_init()
for(var/obj/machinery/atmospherics/target in get_step(src,1))
if(target.initialize_directions & 2)
if (check_connect_types(target,src))
node1 = target
break
for(var/obj/machinery/atmospherics/target in get_step(src,2))
if(target.initialize_directions & 1)
if (check_connect_types(target,src))
node2 = target
break
for(var/obj/machinery/atmospherics/target in get_step(src,4))
if(target.initialize_directions & 8)
if (check_connect_types(target,src))
node3 = target
break
for(var/obj/machinery/atmospherics/target in get_step(src,8))
if(target.initialize_directions & 4)
if (check_connect_types(target,src))
node4 = target
break
if(!node1 && !node2 && !node3 && !node4)
qdel(src)
return
var/turf/T = get_turf(src)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/manifold4w/visible
icon_state = "map_4way"
level = 2
/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers
name="4-way scrubbers pipe manifold"
desc = "A manifold composed of scrubbers pipes"
icon_state = "map_4way-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold4w/visible/supply
name="4-way air supply pipe manifold"
desc = "A manifold composed of supply pipes"
icon_state = "map_4way-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow
color = PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan
color = PIPE_COLOR_CYAN
/obj/machinery/atmospherics/pipe/manifold4w/visible/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold4w/visible/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold4w/visible/red
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold4w/visible/blue
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold4w/visible/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold4w/hidden
icon_state = "map_4way"
level = 1
alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game
/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers
name="4-way scrubbers pipe manifold"
desc = "A manifold composed of scrubbers pipes"
icon_state = "map_4way-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply
name="4-way air supply pipe manifold"
desc = "A manifold composed of supply pipes"
icon_state = "map_4way-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow
color = PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/manifold4w/hidden/cyan
color = PIPE_COLOR_CYAN
/obj/machinery/atmospherics/pipe/manifold4w/hidden/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold4w/hidden/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/manifold4w/hidden/red
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold4w/hidden/blue
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple
color = PIPE_COLOR_PURPLE

View File

@@ -0,0 +1,137 @@
//
// Base type of pipes
//
/obj/machinery/atmospherics/pipe
var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke
var/datum/pipeline/parent
var/volume = 0
layer = 2.4 //under wires with their 2.44
use_power = 0
var/alert_pressure = 80*ONE_ATMOSPHERE
//minimum pressure before check_pressure(...) should be called
can_buckle = 1
buckle_require_restraints = 1
buckle_lying = -1
/obj/machinery/atmospherics/pipe/drain_power()
return -1
/obj/machinery/atmospherics/pipe/New()
if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall))
level = 1
..()
/obj/machinery/atmospherics/pipe/hides_under_flooring()
return level != 2
/obj/machinery/atmospherics/pipe/proc/pipeline_expansion()
return null
/obj/machinery/atmospherics/pipe/proc/check_pressure(pressure)
//Return 1 if parent should continue checking other pipes
//Return null if parent should stop checking other pipes. Recall: qdel(src) will by default return null
return 1
/obj/machinery/atmospherics/pipe/return_air()
if(!parent)
parent = new /datum/pipeline()
parent.build_pipeline(src)
return parent.air
/obj/machinery/atmospherics/pipe/build_network()
if(!parent)
parent = new /datum/pipeline()
parent.build_pipeline(src)
return parent.return_network()
/obj/machinery/atmospherics/pipe/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
if(!parent)
parent = new /datum/pipeline()
parent.build_pipeline(src)
return parent.network_expand(new_network, reference)
/obj/machinery/atmospherics/pipe/return_network(obj/machinery/atmospherics/reference)
if(!parent)
parent = new /datum/pipeline()
parent.build_pipeline(src)
return parent.return_network(reference)
/obj/machinery/atmospherics/pipe/Destroy()
qdel_null(parent)
if(air_temporary)
loc.assume_air(air_temporary)
. = ..()
/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (istype(src, /obj/machinery/atmospherics/pipe/tank))
return ..()
if(istype(W,/obj/item/device/pipe_painter))
return 0
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
if (level==1 && isturf(T) && !T.is_plating())
to_chat(user, "<span class='warning'>You must remove the plating first.</span>")
return 1
if(!can_unwrench())
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>")
add_fingerprint(user)
return 1
playsound(src, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
if (do_after(user, 40 * W.toolspeed))
user.visible_message( \
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
"<span class='notice'>You have unfastened \the [src].</span>", \
"You hear a ratchet.")
new /obj/item/pipe(loc, make_from=src)
for (var/obj/machinery/meter/meter in T)
if (meter.target == src)
new /obj/item/pipe_meter(T)
qdel(meter)
qdel(src)
/obj/machinery/atmospherics/pipe/proc/change_color(var/new_color)
//only pass valid pipe colors please ~otherwise your pipe will turn invisible
if(!pipe_color_check(new_color))
return
pipe_color = new_color
update_icon()
/obj/machinery/atmospherics/pipe/color_cache_name(var/obj/machinery/atmospherics/node)
if(istype(src, /obj/machinery/atmospherics/pipe/tank))
return ..()
if(istype(node, /obj/machinery/atmospherics/pipe/manifold) || istype(node, /obj/machinery/atmospherics/pipe/manifold4w))
if(pipe_color == node.pipe_color)
return node.pipe_color
else
return null
else if(istype(node, /obj/machinery/atmospherics/pipe/simple))
return node.pipe_color
else
return pipe_color
/obj/machinery/atmospherics/pipe/hide(var/i)
if(istype(loc, /turf/simulated))
invisibility = i ? 101 : 0
update_icon()
/obj/machinery/atmospherics/pipe/process()
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
..()
else
. = PROCESS_KILL

View File

@@ -0,0 +1,257 @@
//
// Simple Pipes - Just a tube, maybe bent
//
/obj/machinery/atmospherics/pipe/simple
icon = 'icons/atmos/pipes.dmi'
icon_state = ""
var/pipe_icon = "" //what kind of pipe it is and from which dmi is the icon manager getting its icons, "" for simple pipes, "hepipe" for HE pipes, "hejunction" for HE junctions
name = "pipe"
desc = "A one meter section of regular pipe"
volume = ATMOS_DEFAULT_VOLUME_PIPE
dir = SOUTH
initialize_directions = SOUTH|NORTH
var/minimum_temperature_difference = 300
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
var/maximum_pressure = 70*ONE_ATMOSPHERE
var/fatigue_pressure = 55*ONE_ATMOSPHERE
alert_pressure = 55*ONE_ATMOSPHERE
level = 1
/obj/machinery/atmospherics/pipe/simple/New()
..()
// Pipe colors and icon states are handled by an image cache - so color and icon should
// be null. For mapping purposes color is defined in the object definitions.
icon = null
alpha = 255
/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure)
var/datum/gas_mixture/environment = loc.return_air()
var/pressure_difference = pressure - environment.return_pressure()
if(pressure_difference > maximum_pressure)
burst()
else if(pressure_difference > fatigue_pressure)
//TODO: leak to turf, doing pfshhhhh
if(prob(5))
burst()
else return 1
/obj/machinery/atmospherics/pipe/simple/init_dir()
switch(dir)
if(SOUTH || NORTH)
initialize_directions = SOUTH|NORTH
if(EAST || WEST)
initialize_directions = EAST|WEST
if(NORTHEAST)
initialize_directions = NORTH|EAST
if(NORTHWEST)
initialize_directions = NORTH|WEST
if(SOUTHEAST)
initialize_directions = SOUTH|EAST
if(SOUTHWEST)
initialize_directions = SOUTH|WEST
/obj/machinery/atmospherics/pipe/simple/proc/burst()
src.visible_message("<span class='danger'>\The [src] bursts!</span>");
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
var/datum/effect/effect/system/smoke_spread/smoke = new
smoke.set_up(1,0, src.loc, 0)
smoke.start()
qdel(src)
/obj/machinery/atmospherics/pipe/simple/proc/normalize_dir()
if(dir==3)
set_dir(1)
else if(dir==12)
set_dir(4)
/obj/machinery/atmospherics/pipe/simple/Destroy()
if(node1)
node1.disconnect(src)
node1 = null
if(node2)
node2.disconnect(src)
node1 = null
. = ..()
/obj/machinery/atmospherics/pipe/simple/pipeline_expansion()
return list(node1, node2)
/obj/machinery/atmospherics/pipe/simple/change_color(var/new_color)
..()
//for updating connected atmos device pipes (i.e. vents, manifolds, etc)
if(node1)
node1.update_underlays()
if(node2)
node2.update_underlays()
/obj/machinery/atmospherics/pipe/simple/update_icon(var/safety = 0)
if(!check_icon_cache())
return
alpha = 255
overlays.Cut()
if(node1 && node2)
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]")
else
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]")
/obj/machinery/atmospherics/pipe/simple/update_underlays()
return
/obj/machinery/atmospherics/pipe/simple/atmos_init()
normalize_dir()
var/node1_dir
var/node2_dir
for(var/direction in cardinal)
if(direction&initialize_directions)
if (!node1_dir)
node1_dir = direction
else if (!node2_dir)
node2_dir = direction
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
break
for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node2 = target
break
if(!node1 && !node2)
qdel(src)
return
var/turf/T = loc
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/atmospherics/pipe))
qdel(parent)
node1 = null
if(reference == node2)
if(istype(node2, /obj/machinery/atmospherics/pipe))
qdel(parent)
node2 = null
update_icon()
return null
/obj/machinery/atmospherics/pipe/simple/visible
icon_state = "intact"
level = 2
/obj/machinery/atmospherics/pipe/simple/visible/scrubbers
name = "Scrubbers pipe"
desc = "A one meter section of scrubbers pipe"
icon_state = "intact-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/simple/visible/supply
name = "Air supply pipe"
desc = "A one meter section of supply pipe"
icon_state = "intact-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/simple/visible/yellow
color = PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/simple/visible/cyan
color = PIPE_COLOR_CYAN
/obj/machinery/atmospherics/pipe/simple/visible/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/simple/visible/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/simple/visible/red
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/simple/visible/blue
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/simple/visible/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/simple/hidden
icon_state = "intact"
level = 1
alpha = 128 //set for the benefit of mapping - this is reset to opaque when the pipe is spawned in game
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers
name = "Scrubbers pipe"
desc = "A one meter section of scrubbers pipe"
icon_state = "intact-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
layer = 2.38
icon_connect_type = "-scrubbers"
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/simple/hidden/supply
name = "Air supply pipe"
desc = "A one meter section of supply pipe"
icon_state = "intact-supply"
connect_types = CONNECT_TYPE_SUPPLY
layer = 2.39
icon_connect_type = "-supply"
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/simple/hidden/yellow
color = PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/simple/hidden/cyan
color = PIPE_COLOR_CYAN
/obj/machinery/atmospherics/pipe/simple/hidden/green
color = PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/simple/hidden/black
color = PIPE_COLOR_BLACK
/obj/machinery/atmospherics/pipe/simple/hidden/red
color = PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/simple/hidden/blue
color = PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/simple/hidden/purple
color = PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/simple/insulated
icon = 'icons/obj/atmospherics/red_pipe.dmi'
icon_state = "intact"
minimum_temperature_difference = 10000
thermal_conductivity = 0
maximum_pressure = 1000*ONE_ATMOSPHERE
fatigue_pressure = 900*ONE_ATMOSPHERE
alert_pressure = 900*ONE_ATMOSPHERE
level = 2

View File

@@ -0,0 +1,161 @@
//
// Tanks - These are implemented as pipes with large volume
//
/obj/machinery/atmospherics/pipe/tank
icon = 'icons/atmos/tank_vr.dmi' //VOREStation Edit - New Icons
icon_state = "air_map"
name = "Pressure Tank"
desc = "A large vessel containing pressurized gas."
volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet
var/start_pressure = 75*ONE_ATMOSPHERE //Vorestation edit
level = 1
dir = SOUTH
initialize_directions = SOUTH
density = 1
/obj/machinery/atmospherics/pipe/tank/New()
icon_state = "air"
..()
/obj/machinery/atmospherics/pipe/tank/init_dir()
initialize_directions = dir
/obj/machinery/atmospherics/pipe/tank/Destroy()
if(node1)
node1.disconnect(src)
node1 = null
. = ..()
/obj/machinery/atmospherics/pipe/tank/pipeline_expansion()
return list(node1)
/obj/machinery/atmospherics/pipe/tank/update_underlays()
if(..())
underlays.Cut()
var/turf/T = get_turf(src)
if(!istype(T))
return
add_underlay(T, node1, dir)
/obj/machinery/atmospherics/pipe/tank/hide()
update_underlays()
/obj/machinery/atmospherics/pipe/tank/atmos_init()
var/connect_direction = dir
for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
break
update_underlays()
/obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/atmospherics/pipe))
qdel(parent)
node1 = null
update_underlays()
return null
/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob)
if(istype(W, /obj/item/device/pipe_painter))
return
if(istype(W, /obj/item/device/analyzer) && in_range(user, src))
var/obj/item/device/analyzer/A = W
A.analyze_gases(src, user)
/obj/machinery/atmospherics/pipe/tank/air
name = "Pressure Tank (Air)"
icon_state = "air_map"
/obj/machinery/atmospherics/pipe/tank/air/New()
air_temporary = new
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \
"nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "air"
/obj/machinery/atmospherics/pipe/tank/oxygen
name = "Pressure Tank (Oxygen)"
icon_state = "o2_map"
/obj/machinery/atmospherics/pipe/tank/oxygen/New()
air_temporary = new
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "o2"
/obj/machinery/atmospherics/pipe/tank/nitrogen
name = "Pressure Tank (Nitrogen)"
icon_state = "n2_map"
volume = 40000 //Vorestation edit
/obj/machinery/atmospherics/pipe/tank/nitrogen/New()
air_temporary = new
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "n2"
/obj/machinery/atmospherics/pipe/tank/carbon_dioxide
name = "Pressure Tank (Carbon Dioxide)"
icon_state = "co2_map"
/obj/machinery/atmospherics/pipe/tank/carbon_dioxide/New()
air_temporary = new
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "co2"
/obj/machinery/atmospherics/pipe/tank/phoron
name = "Pressure Tank (Phoron)"
icon_state = "phoron_map"
/obj/machinery/atmospherics/pipe/tank/phoron/New()
air_temporary = new
air_temporary.volume = volume
air_temporary.temperature = T20C
air_temporary.adjust_gas("phoron", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "phoron"
/obj/machinery/atmospherics/pipe/tank/nitrous_oxide
name = "Pressure Tank (Nitrous Oxide)"
icon_state = "n2o_map"
/obj/machinery/atmospherics/pipe/tank/nitrous_oxide/New()
air_temporary = new
air_temporary.volume = volume
air_temporary.temperature = T0C
air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature))
..()
icon_state = "n2o"

View File

@@ -0,0 +1,102 @@
//
// Universal Pipe Adapter - Designed for connecting scrubbers, normal, and supply pipes together.
//
/obj/machinery/atmospherics/pipe/simple/visible/universal
name="Universal pipe adapter"
desc = "An adapter for regular, supply and scrubbers pipes"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER
icon_state = "map_universal"
/obj/machinery/atmospherics/pipe/simple/visible/universal/update_icon(var/safety = 0)
if(!check_icon_cache())
return
alpha = 255
overlays.Cut()
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
underlays.Cut()
if (node1)
universal_underlays(node1)
if(node2)
universal_underlays(node2)
else
var/node1_dir = get_dir(node1,src)
universal_underlays(,node1_dir)
else if (node2)
universal_underlays(node2)
else
universal_underlays(,dir)
universal_underlays(dir, -180)
/obj/machinery/atmospherics/pipe/simple/visible/universal/update_underlays()
..()
update_icon()
/obj/machinery/atmospherics/pipe/simple/hidden/universal
name="Universal pipe adapter"
desc = "An adapter for regular, supply and scrubbers pipes"
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER
icon_state = "map_universal"
/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0)
if(!check_icon_cache())
return
alpha = 255
overlays.Cut()
overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")
underlays.Cut()
if (node1)
universal_underlays(node1)
if(node2)
universal_underlays(node2)
else
var/node2_dir = turn(get_dir(src,node1),-180)
universal_underlays(,node2_dir)
else if (node2)
universal_underlays(node2)
var/node1_dir = turn(get_dir(src,node2),-180)
universal_underlays(,node1_dir)
else
universal_underlays(,dir)
universal_underlays(,turn(dir, -180))
/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_underlays()
..()
update_icon()
/obj/machinery/atmospherics/proc/universal_underlays(var/obj/machinery/atmospherics/node, var/direction)
var/turf/T = loc
if(node)
var/node_dir = get_dir(src,node)
if(node.icon_connect_type == "-supply")
add_underlay_adapter(T, , node_dir, "")
add_underlay_adapter(T, node, node_dir, "-supply")
add_underlay_adapter(T, , node_dir, "-scrubbers")
else if (node.icon_connect_type == "-scrubbers")
add_underlay_adapter(T, , node_dir, "")
add_underlay_adapter(T, , node_dir, "-supply")
add_underlay_adapter(T, node, node_dir, "-scrubbers")
else
add_underlay_adapter(T, node, node_dir, "")
add_underlay_adapter(T, , node_dir, "-supply")
add_underlay_adapter(T, , node_dir, "-scrubbers")
else
add_underlay_adapter(T, , direction, "-supply")
add_underlay_adapter(T, , direction, "-scrubbers")
add_underlay_adapter(T, , direction, "")
/obj/machinery/atmospherics/proc/add_underlay_adapter(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type) //modified from add_underlay, does not make exposed underlays
if(node)
if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
else
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
else
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "retracted" + icon_connect_type)

View File

@@ -0,0 +1,83 @@
//
// Vent Pipe - Unpowered vent
//
/obj/machinery/atmospherics/pipe/vent
icon = 'icons/obj/atmospherics/pipe_vent.dmi'
icon_state = "intact"
name = "Vent"
desc = "A large air vent"
level = 1
volume = 250
dir = SOUTH
initialize_directions = SOUTH
var/build_killswitch = 1
/obj/machinery/atmospherics/pipe/vent/init_dir()
initialize_directions = dir
/obj/machinery/atmospherics/pipe/vent/high_volume
name = "Larger vent"
volume = 1000
/obj/machinery/atmospherics/pipe/vent/process()
if(!parent)
if(build_killswitch <= 0)
. = PROCESS_KILL
else
build_killswitch--
..()
return
else
parent.mingle_with_turf(loc, volume)
/obj/machinery/atmospherics/pipe/vent/Destroy()
if(node1)
node1.disconnect(src)
node1 = null
. = ..()
/obj/machinery/atmospherics/pipe/vent/pipeline_expansion()
return list(node1)
/obj/machinery/atmospherics/pipe/vent/update_icon()
if(node1)
icon_state = "intact"
set_dir(get_dir(src, node1))
else
icon_state = "exposed"
/obj/machinery/atmospherics/pipe/vent/atmos_init()
var/connect_direction = dir
for(var/obj/machinery/atmospherics/target in get_step(src,connect_direction))
if(target.initialize_directions & get_dir(target,src))
if (check_connect_types(target,src))
node1 = target
break
update_icon()
/obj/machinery/atmospherics/pipe/vent/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
if(istype(node1, /obj/machinery/atmospherics/pipe))
qdel(parent)
node1 = null
update_icon()
return null
/obj/machinery/atmospherics/pipe/vent/hide(var/i) //to make the little pipe section invisible, the icon changes.
if(node1)
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]intact"
set_dir(get_dir(src, node1))
else
icon_state = "exposed"

View File

@@ -6,9 +6,9 @@
/turf/simulated/proc/update_graphic(list/graphic_add = null, list/graphic_remove = null)
if(LAZYLEN(graphic_add))
overlays += graphic_add
add_overlay(graphic_add, priority = TRUE)
if(LAZYLEN(graphic_remove))
overlays -= graphic_remove
cut_overlay(graphic_remove, priority = TRUE)
/turf/proc/update_air_properties()
var/block = c_airblock(src)

View File

@@ -21,8 +21,6 @@
#define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD * BREATH_PERCENTAGE * 0.16)
#define HUMAN_HEAT_CAPACITY 280000 //J/K For 80kg person
#define SOUND_MINIMUM_PRESSURE 10
#define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE.
#define MAX_HIGH_PRESSURE_DAMAGE 4 // This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :(
#define LOW_PRESSURE_DAMAGE 2 // The amount of damage someone takes when in a low pressure area. (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value).

56
code/__defines/sound.dm Normal file
View File

@@ -0,0 +1,56 @@
//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on
#define CHANNEL_LOBBYMUSIC 1024
#define CHANNEL_ADMIN 1023
#define CHANNEL_VOX 1022
#define CHANNEL_JUKEBOX 1021
#define CHANNEL_HEARTBEAT 1020 //sound channel for heartbeats
#define CHANNEL_AMBIENCE_FORCED 1019
#define CHANNEL_AMBIENCE 1018
#define CHANNEL_BUZZ 1017
#define CHANNEL_BICYCLE 1016
//THIS SHOULD ALWAYS BE THE LOWEST ONE!
//KEEP IT UPDATED
#define CHANNEL_HIGHEST_AVAILABLE 1015
#define SOUND_MINIMUM_PRESSURE 10
#define FALLOFF_SOUNDS 0.5
//Sound environment defines. Reverb preset for sounds played in an area, see sound datum reference for more.
#define GENERIC 0
#define PADDED_CELL 1
#define ROOM 2
#define BATHROOM 3
#define LIVINGROOM 4
#define STONEROOM 5
#define AUDITORIUM 6
#define CONCERT_HALL 7
#define CAVE 8
#define ARENA 9
#define HANGAR 10
#define CARPETED_HALLWAY 11
#define HALLWAY 12
#define STONE_CORRIDOR 13
#define ALLEY 14
#define FOREST 15
#define CITY 16
#define MOUNTAINS 17
#define QUARRY 18
#define PLAIN 19
#define PARKING_LOT 20
#define SEWER_PIPE 21
#define UNDERWATER 22
#define DRUGGED 23
#define DIZZY 24
#define PSYCHOTIC 25
#define STANDARD_STATION STONEROOM
#define LARGE_ENCLOSED HANGAR
#define SMALL_ENCLOSED BATHROOM
#define TUNNEL_ENCLOSED CAVE
#define LARGE_SOFTFLOOR CARPETED_HALLWAY
#define MEDIUM_SOFTFLOOR LIVINGROOM
#define SMALL_SOFTFLOOR ROOM
#define ASTEROID CAVE
#define SPACE UNDERWATER

View File

@@ -45,6 +45,9 @@
#define LANGUAGE_OCCULT "Occult"
#define LANGUAGE_CHANGELING "Changeling"
#define LANGUAGE_VOX "Vox-Pidgin"
#define LANGUAGE_TERMINUS "Terminus"
#define LANGUAGE_SKRELLIANFAR "High Skrellian"
#define LANGUAGE_MINBUS "Minbus"
// Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.

View File

@@ -803,7 +803,6 @@ proc/GaussRandRound(var/sigma,var/roundto)
var/old_dir1 = T.dir
var/old_icon_state1 = T.icon_state
var/old_icon1 = T.icon
var/old_overlays = T.overlays.Copy()
var/old_underlays = T.underlays.Copy()
var/old_decals = T.decals ? T.decals.Copy() : null
@@ -811,11 +810,9 @@ proc/GaussRandRound(var/sigma,var/roundto)
X.set_dir(old_dir1)
X.icon_state = old_icon_state1
X.icon = old_icon1
X.overlays = old_overlays
X.copy_overlays(T, TRUE)
X.underlays = old_underlays
X.decals = old_decals
if(old_decals)
X.apply_decals()
//Move the air from source to dest
var/turf/simulated/ST = T
@@ -841,14 +838,10 @@ proc/GaussRandRound(var/sigma,var/roundto)
if(shuttlework)
var/turf/simulated/shuttle/SS = T
SS.landed_holder.leave_turf()
else if(turftoleave)
T.ChangeTurf(turftoleave)
T.apply_decals()
else
T.ChangeTurf(get_base_turf_by_area(T))
T.apply_decals()
refined_src -= T
refined_trg -= B

2
code/_macros_vr.dm Normal file
View File

@@ -0,0 +1,2 @@
#define isbelly(A) istype(A, /obj/belly)
#define isstorage(A) istype(A, /obj/item/weapon/storage)

View File

@@ -0,0 +1,41 @@
#define SSBELLIES_PROCESSED 1
#define SSBELLIES_IGNORED 2
//
// Bellies subsystem - Process vore bellies
//
SUBSYSTEM_DEF(bellies)
name = "Bellies"
priority = 5
wait = 1 SECONDS
flags = SS_KEEP_TIMING|SS_NO_INIT
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
var/static/list/belly_list = list()
var/list/currentrun = list()
var/ignored_bellies = 0
/datum/controller/subsystem/bellies/stat_entry()
..("#: [belly_list.len] | P: [ignored_bellies]")
/datum/controller/subsystem/bellies/fire(resumed = 0)
if (!resumed)
ignored_bellies = 0
src.currentrun = belly_list.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
var/times_fired = src.times_fired
while(currentrun.len)
var/obj/belly/B = currentrun[currentrun.len]
currentrun.len--
if(QDELETED(B))
belly_list -= B
else
if(B.process_belly(times_fired,wait) == SSBELLIES_IGNORED)
ignored_bellies++
if (MC_TICK_CHECK)
return

View File

@@ -1,28 +0,0 @@
//
// Floor Decals Initialization Subsystem
// This is part of the giant decal hack that works around a BYOND bug where DreamDaemon will crash if you
// update overlays on turfs too much.
// The master_controller on Polaris used to init decals prior to initializing areas (which initilized turfs)
// Now that we switched to subsystems we still want to do the same thing, so this takes care of it.
//
SUBSYSTEM_DEF(floor_decals)
name = "Floor Decals"
init_order = INIT_ORDER_DECALS
flags = SS_NO_FIRE
/datum/controller/subsystem/floor_decals/Initialize(timeofday)
if(floor_decals_initialized)
return ..()
to_world_log("Initializing Floor Decals")
admin_notice("<span class='danger'>Initializing Floor Decals</span>", R_DEBUG)
var/list/turfs_with_decals = list()
for(var/obj/effect/floor_decal/D in world)
var/T = D.add_to_turf_decals()
if(T) turfs_with_decals |= T
CHECK_TICK
for(var/item in turfs_with_decals)
var/turf/T = item
if(T.decals) T.apply_decals()
CHECK_TICK
floor_decals_initialized = TRUE
return ..()

View File

@@ -11,6 +11,8 @@ SUBSYSTEM_DEF(overlays)
var/list/overlay_icon_state_caches // Cache thing
var/list/overlay_icon_cache // Cache thing
var/global/image/appearance_bro = new() // Temporarily super-global because of BYOND init order dumbness.
/datum/controller/subsystem/overlays/PreInit()
overlay_icon_state_caches = list()
overlay_icon_cache = list()
@@ -90,7 +92,7 @@ SUBSYSTEM_DEF(overlays)
icon_cache[icon] = .
/atom/proc/build_appearance_list(old_overlays)
var/static/image/appearance_bro = new()
// var/static/image/appearance_bro = new() // Moved to be superglobal due to BYOND insane init order stupidness.
var/list/new_overlays = list()
if (!islist(old_overlays))
old_overlays = list(old_overlays)

View File

@@ -152,9 +152,7 @@ SUBSYSTEM_DEF(transcore)
// Send a past-due notification to the medical radio channel.
/datum/controller/subsystem/transcore/proc/notify(var/name)
ASSERT(name)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
a.autosay("[name] is past-due for a mind backup. This will be the only notification.", "TransCore Oversight", "Medical")
qdel(a)
global_announcer.autosay("[name] is past-due for a mind backup. This will be the only notification.", "TransCore Oversight", "Medical")
// Called from mind_record to add itself to the transcore.
/datum/controller/subsystem/transcore/proc/add_backup(var/datum/transhuman/mind_record/MR)
@@ -187,10 +185,8 @@ SUBSYSTEM_DEF(transcore)
// Moves all mind records from the databaes into the disk and shuts down all backup canary processing.
/datum/controller/subsystem/transcore/proc/core_dump(var/obj/item/weapon/disk/transcore/disk)
ASSERT(disk)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
a.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Command")
a.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Medical")
qdel(a)
global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Command")
global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Medical")
disk.stored += backed_up
backed_up.Cut()

View File

@@ -1,22 +1,13 @@
/datum/teleport/proc/try_televore()
var/datum/belly/target_belly
//Destination is a living thing
target_belly = check_belly(destination)
//Destination has a living thing on it
if(!target_belly)
for(var/mob/living/M in get_turf(destination))
if(M.vore_organs.len)
var/I = M.vore_organs[1]
target_belly = M.vore_organs[I]
if(target_belly)
teleatom.forceMove(destination.loc)
//Destination is in a belly
if(isbelly(destination.loc))
var/obj/belly/B = destination.loc
teleatom.forceMove(get_turf(B)) //So we can splash the sound and sparks and everything.
playSpecials(destination,effectout,soundout)
target_belly.internal_contents |= teleatom
playsound(destination, target_belly.vore_sound, 100, 1)
teleatom.forceMove(B)
return 1
//No fun!
return 0
return 0

View File

@@ -116,14 +116,6 @@
containername = "Robolimb blueprints (Bishop)"
access = access_robotics
/datum/supply_packs/robotics/robolimbs/veymed
name = "Vey-Med robolimb blueprints"
contains = list(/obj/item/weapon/disk/limb/veymed)
cost = 70
containertype = /obj/structure/closet/crate/secure/science
containername = "Robolimb blueprints (Vey-Med)"
access = access_robotics
/datum/supply_packs/robotics/mecha_ripley
name = "Circuit Crate (\"Ripley\" APLU)"
contains = list(

View File

@@ -260,26 +260,26 @@ var/list/mob/living/forced_ambiance_list = new
// If we previously were in an area with force-played ambiance, stop it.
if(L in forced_ambiance_list)
L << sound(null, channel = 1)
L << sound(null, channel = CHANNEL_AMBIENCE_FORCED)
forced_ambiance_list -= L
if(!L.client.ambience_playing)
L.client.ambience_playing = 1
L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2)
L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = CHANNEL_AMBIENCE)
if(forced_ambience)
if(forced_ambience.len)
forced_ambiance_list |= L
var/sound/chosen_ambiance = pick(forced_ambience)
if(!istype(chosen_ambiance))
chosen_ambiance = sound(chosen_ambiance, repeat = 1, wait = 0, volume = 25, channel = 1)
chosen_ambiance = sound(chosen_ambiance, repeat = 1, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE_FORCED)
L << chosen_ambiance
else
L << sound(null, channel = 1)
else if(src.ambience.len && prob(35))
if((world.time >= L.client.played + 600))
var/sound = pick(ambience)
L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = 1)
L << sound(sound, repeat = 0, wait = 0, volume = 25, channel = CHANNEL_AMBIENCE)
L.client.played = world.time
/area/proc/gravitychange(var/gravitystate = 0, var/area/A)

View File

@@ -296,3 +296,7 @@
/atom/movable/proc/adjust_scale(new_scale)
icon_scale = new_scale
update_transform()
// Stub for now, override with better things.
/atom/movable/proc/drop_location()
return loc

View File

@@ -12,9 +12,9 @@
var/livingprey = 0
var/objectprey = 0
for(var/I in H.vore_organs)
var/datum/belly/B = H.vore_organs[I]
for(var/C in B.internal_contents)
for(var/belly in H.vore_organs)
var/obj/belly/B = belly
for(var/C in B)
if(ishuman(C))
humanprey++
else if(isliving(C))

View File

@@ -824,7 +824,7 @@ FIRE ALARM
alarms_hidden = TRUE
/obj/machinery/firealarm/update_icon()
overlays.Cut()
cut_overlays()
if(panel_open)
set_light(0)
@@ -847,8 +847,7 @@ FIRE ALARM
if("blue") set_light(l_range = 2, l_power = 0.5, l_color = "#1024A9")
if("red") set_light(l_range = 4, l_power = 2, l_color = "#ff0000")
if("delta") set_light(l_range = 4, l_power = 2, l_color = "#FF6633")
overlays += image('icons/obj/monitors.dmi', "overlay_[seclevel]")
add_overlay("overlay_[seclevel]")
/obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume)
if(detecting)

View File

@@ -225,13 +225,12 @@
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
operating = 0
for (var/obj/thing in contents)
// Todo: unify limbs and internal organs
for (var/obj/item/thing in contents)
// There's a chance that the gibber will fail to destroy some evidence.
if((istype(thing,/obj/item/organ) || istype(thing,/obj/item/organ)) && prob(80))
if(istype(thing,/obj/item/organ) && prob(80))
qdel(thing)
continue
thing.loc = get_turf(thing) // Drop it onto the turf for throwing.
thing.forceMove(get_turf(thing)) // Drop it onto the turf for throwing.
thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt.
update_icon()

View File

@@ -1112,8 +1112,8 @@
/obj/item/toy/plushie/kitten = 2,
/obj/item/toy/plushie/lizard = 2,
/obj/item/toy/plushie/spider = 2,
/obj/item/toy/plushie/farwa = 2)
// /obj/item/weapon/storage/trinketbox = 2 (readding later due to conflict)
/obj/item/toy/plushie/farwa = 2,
/obj/item/weapon/storage/trinketbox = 2)
prices = list(/obj/item/weapon/storage/fancy/heartbox = 15,
/obj/item/toy/bouquet = 10,
/obj/item/toy/bouquet/fake = 3,

View File

@@ -50,6 +50,12 @@
name = "entertainment intercom"
frequency = ENT_FREQ
/obj/item/device/radio/intercom/omni
name = "global announcer"
/obj/item/device/radio/intercom/omni/initialize()
channels = radiochannels.Copy()
return ..()
/obj/item/device/radio/intercom/New()
..()
processing_objects += src

View File

@@ -53,14 +53,13 @@ var/global/list/default_medbay_channels = list(
var/const/FREQ_LISTENING = 1
var/list/internal_channels
/obj/item/device/radio
var/datum/radio_frequency/radio_connection
var/list/datum/radio_frequency/secure_radio_connections = new
proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
/obj/item/device/radio/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
/obj/item/device/radio/New()
..()

View File

@@ -213,8 +213,10 @@
R.add_language(LANGUAGE_UNATHI, 1)
R.add_language(LANGUAGE_SIIK, 1)
R.add_language(LANGUAGE_SKRELLIAN, 1)
R.add_language(LANGUAGE_SKRELLIANFAR, 0)
R.add_language(LANGUAGE_GUTTER, 1)
R.add_language(LANGUAGE_SCHECHI, 1)
R.add_language(LANGUAGE_ROOTLOCAL, 1)
R.add_language(LANGUAGE_TERMINUS, 1)
return 1

View File

@@ -10,7 +10,7 @@
/obj/fiftyspawner/wood/sif
name = "stack of alien wood"
type_to_spawn = /obj/item/stack/tile/sifwood
type_to_spawn = /obj/item/stack/tile/wood/sif
/obj/fiftyspawner/carpet
name = "stack of carpet"

View File

@@ -37,9 +37,6 @@
flags = 0
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
/obj/item/stack/tile/grass/fifty
amount = 50
/*
* Wood
*/
@@ -55,23 +52,11 @@
flags = 0
no_variants = FALSE
/obj/item/stack/tile/sifwood
/obj/item/stack/tile/wood/sif
name = "alien wood tile"
singular_name = "alien wood tile"
desc = "An easy to fit wooden floor tile. It's blue!"
icon_state = "tile-sifwood"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
/obj/item/stack/tile/wood/fifty
amount = 50
/obj/item/stack/tile/sifwood/fifty
amount = 50
/obj/item/stack/tile/wood/cyborg
name = "wood floor tile synthesizer"

View File

@@ -12,10 +12,7 @@
if(H.species.trashcan == 1)
playsound(H.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
user.drop_item()
var/belly = H.vore_selected
var/datum/belly/selected = H.vore_organs[belly]
forceMove(H)
selected.internal_contents |= src
forceMove(H.vore_selected)
to_chat(H, "<span class='notice'>You can taste the flavor of garbage. Wait what?</span>")
return
@@ -24,10 +21,7 @@
if(R.module.type == /obj/item/weapon/robot_module/robot/scrubpup) // You can now feed the trash borg yay.
playsound(R.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
user.drop_item()
var/belly = R.vore_selected
var/datum/belly/selected = R.vore_organs[belly]
forceMove(R)
selected.internal_contents |= src // Too many hoops and obstacles to stick it into the sleeper module.
forceMove(R.vore_selected)
R.visible_message("<span class='warning'>[user] feeds [R] with [src]!</span>")
return
..()

View File

@@ -96,7 +96,8 @@
name = "box of syringes"
desc = "A box full of syringes."
icon_state = "syringe"
starts_with = list(/obj/item/weapon/reagent_containers/syringe = 7)
can_hold = list(/obj/item/weapon/reagent_containers/syringe) //VOREStation Edit
starts_with = list(/obj/item/weapon/reagent_containers/syringe = 20) //VOREStation Edit
/obj/item/weapon/storage/box/syringegun
name = "box of syringe gun cartridges"

View File

@@ -674,7 +674,6 @@
/*
* Trinket Box - READDING SOON
*/
/*
/obj/item/weapon/storage/trinketbox
name = "trinket box"
desc = "A box that can hold small trinkets, such as a ring."
@@ -724,5 +723,4 @@
..()
if(open && contents.len)
var/display_item = contents[1]
to_chat(user, "<span class='notice'>\The [src] contains \the [display_item]!</span>")
*/
to_chat(user, "<span class='notice'>\The [src] contains \the [display_item]!</span>")

View File

@@ -13,9 +13,9 @@
desc = "A small wrapped package."
w_class = ITEMSIZE_NORMAL
var/devastate = 0
var/heavy_impact = 1
var/light_impact = 2
var/devastate = 1
var/heavy_impact = 2
var/light_impact = 4
var/flash_range = 5
var/size = "small" /*Used for the icon, this one will make c-4small_0 for the off state.*/
@@ -24,7 +24,7 @@
item_state = "radio"
desc = "A mysterious package, it's quite heavy."
devastate = 1
heavy_impact = 2
heavy_impact = 3
light_impact = 5
flash_range = 7
size = "large"

View File

@@ -199,3 +199,11 @@
T = get_step_rand(this_mob) || T
if(T)
this_mob.forceMove(T)
//Just overriding this here, no more super medkit so those can be reserved for PoIs and such
/obj/random/firstaid/item_to_spawn()
return pick(prob(4);/obj/item/weapon/storage/firstaid/regular,
prob(3);/obj/item/weapon/storage/firstaid/toxin,
prob(3);/obj/item/weapon/storage/firstaid/o2,
prob(2);/obj/item/weapon/storage/firstaid/adv,
prob(3);/obj/item/weapon/storage/firstaid/fire)

View File

@@ -18,13 +18,6 @@
src.dump_contents()
qdel(src)
/obj/structure/closet/secure_closet/egg/dump_contents()
var/datum/belly/belly = check_belly(src)
if(belly)
for(var/atom/movable/M in src)
belly.internal_contents |= M
return ..()
/obj/structure/closet/secure_closet/egg/unathi
name = "unathi egg"
desc = "Some species of Unathi apparently lay soft-shelled eggs!"

View File

@@ -1,107 +1,50 @@
//Sound environment defines. Reverb preset for sounds played in an area, see sound datum reference for more.
#define GENERIC 0
#define PADDED_CELL 1
#define ROOM 2
#define BATHROOM 3
#define LIVINGROOM 4
#define STONEROOM 5
#define AUDITORIUM 6
#define CONCERT_HALL 7
#define CAVE 8
#define ARENA 9
#define HANGAR 10
#define CARPETED_HALLWAY 11
#define HALLWAY 12
#define STONE_CORRIDOR 13
#define ALLEY 14
#define FOREST 15
#define CITY 16
#define MOUNTAINS 17
#define QUARRY 18
#define PLAIN 19
#define PARKING_LOT 20
#define SEWER_PIPE 21
#define UNDERWATER 22
#define DRUGGED 23
#define DIZZY 24
#define PSYCHOTIC 25
#define STANDARD_STATION STONEROOM
#define LARGE_ENCLOSED HANGAR
#define SMALL_ENCLOSED BATHROOM
#define TUNNEL_ENCLOSED CAVE
#define LARGE_SOFTFLOOR CARPETED_HALLWAY
#define MEDIUM_SOFTFLOOR LIVINGROOM
#define SMALL_SOFTFLOOR ROOM
#define ASTEROID CAVE
#define SPACE UNDERWATER
var/list/shatter_sound = list('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg')
var/list/explosion_sound = list('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg','sound/effects/Explosion3.ogg','sound/effects/Explosion4.ogg','sound/effects/Explosion5.ogg','sound/effects/Explosion6.ogg')
var/list/spark_sound = list('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks5.ogg','sound/effects/sparks6.ogg','sound/effects/sparks7.ogg')
var/list/rustle_sound = list('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg')
var/list/punch_sound = list('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')
var/list/clown_sound = list('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg')
var/list/swing_hit_sound = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')
var/list/hiss_sound = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg')
var/list/fracture_sound = list('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg')
var/list/casing_sound = list ('sound/weapons/casingfall1.ogg','sound/weapons/casingfall2.ogg','sound/weapons/casingfall3.ogg')
var/list/keyboard_sound = list ('sound/effects/keyboard/keyboard1.ogg','sound/effects/keyboard/keyboard2.ogg','sound/effects/keyboard/keyboard3.ogg', 'sound/effects/keyboard/keyboard4.ogg')
var/list/mechstep_sound = list('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg')
var/list/bodyfall_sound = list('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg')
var/list/can_sound = list('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg')
var/list/geiger_sound = list('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg')
var/list/geiger_weak_sound = list('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg')
//var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg')
/proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff, var/is_global, var/frequency)
soundin = get_sfx(soundin) // same sound for everyone
/proc/playsound(atom/source, soundin, vol as num, vary, extrarange as num, falloff, is_global, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, preference = null)
if(isarea(source))
error("[source] is an area and is trying to make the sound: [soundin]")
throw EXCEPTION("playsound(): source is an area")
return
frequency = isnull(frequency) ? get_rand_frequency() : frequency // Same frequency for everybody
var/turf/turf_source = get_turf(source)
//allocate a channel if necessary now so its the same for everyone
channel = channel || open_sound_channel()
// Looping through the player list has the added bonus of working for mobs inside containers
for (var/P in player_list)
var/sound/S = sound(get_sfx(soundin))
var/maxdistance = (world.view + extrarange) * 3
var/list/listeners = player_list
if(!ignore_walls) //these sounds don't carry through walls
listeners = listeners & hearers(maxdistance,turf_source)
for(var/P in listeners)
var/mob/M = P
if(!M || !M.client)
continue
var/turf/T = get_turf(M)
var/distance = get_dist(T, turf_source)
var/distance = get_dist(M, turf_source)
if(distance <= (world.view + extrarange) * 3)
var/turf/T = get_turf(M)
if(distance <= maxdistance)
if(T && T.z == turf_source.z)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global)
M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, is_global, channel, pressure_affected, S)
var/const/FALLOFF_SOUNDS = 0.5
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, channel = 0, pressure_affected = TRUE, sound/S, preference)
if(!client || ear_deaf > 0)
return
if(preference && !client.is_preference_enabled(preference))
return
/mob/proc/playsound_local(var/turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global)
if(!src.client || ear_deaf > 0) return
soundin = get_sfx(soundin)
if(!S)
S = sound(get_sfx(soundin))
var/sound/S = sound(soundin)
S.wait = 0 //No queue
S.channel = 0 //Any channel
S.channel = channel || open_sound_channel()
S.volume = vol
S.environment = -1
if (vary)
if(vary)
if(frequency)
S.frequency = frequency
else
S.frequency = get_rand_frequency()
//sound volume falloff with pressure
var/pressure_factor = 1.0
if(isturf(turf_source))
// 3D sounds, the technology is here!
var/turf/T = get_turf(src)
//sound volume falloff with distance
@@ -109,24 +52,32 @@ var/const/FALLOFF_SOUNDS = 0.5
S.volume -= max(distance - world.view, 0) * 2 //multiplicative falloff to add on top of natural audio falloff.
var/datum/gas_mixture/hearer_env = T.return_air()
var/datum/gas_mixture/source_env = turf_source.return_air()
//Atmosphere affects sound
var/pressure_factor = 1
if(pressure_affected)
var/datum/gas_mixture/hearer_env = T.return_air()
var/datum/gas_mixture/source_env = turf_source.return_air()
if (hearer_env && source_env)
var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure())
if(hearer_env && source_env)
var/pressure = min(hearer_env.return_pressure(), source_env.return_pressure())
if(pressure < ONE_ATMOSPHERE)
pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0)
else //space
pressure_factor = 0
if (pressure < ONE_ATMOSPHERE)
pressure_factor = max((pressure - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 0)
else //in space
pressure_factor = 0
if(distance <= 1)
pressure_factor = max(pressure_factor, 0.15) //touching the source of the sound
if (distance <= 1)
pressure_factor = max(pressure_factor, 0.15) //hearing through contact
S.volume *= pressure_factor
//End Atmosphere affecting sound
S.volume *= pressure_factor
//Don't bother with doing anything below.
if(S.volume <= 0)
return //No sound
if (S.volume <= 0)
return //no volume means no sound
//Apply a sound environment.
if(!is_global)
S.environment = get_sound_env(pressure_factor)
var/dx = turf_source.x - T.x // Hearing from the right/left
S.x = dx
@@ -136,34 +87,27 @@ var/const/FALLOFF_SOUNDS = 0.5
S.y = 1
S.falloff = (falloff ? falloff : FALLOFF_SOUNDS)
if(!is_global)
if(istype(src,/mob/living/))
var/mob/living/M = src
if (M.hallucination)
S.environment = PSYCHOTIC
else if (M.druggy)
S.environment = DRUGGED
else if (M.drowsyness)
S.environment = DIZZY
else if (M.confused)
S.environment = DIZZY
else if (M.sleeping)
S.environment = UNDERWATER
else if (pressure_factor < 0.5)
S.environment = SPACE
else
var/area/A = get_area(src)
S.environment = A.sound_env
else if (pressure_factor < 0.5)
S.environment = SPACE
else
var/area/A = get_area(src)
S.environment = A.sound_env
src << S
/proc/sound_to_playing_players(sound, volume = 100, vary)
sound = get_sfx(sound)
for(var/M in player_list)
if(ismob(M) && !isnewplayer(M))
var/mob/MO = M
MO.playsound_local(get_turf(MO), sound, volume, vary, pressure_affected = FALSE)
/proc/open_sound_channel()
var/static/next_channel = 1 //loop through the available 1024 - (the ones we reserve) channels and pray that its not still being used
. = ++next_channel
if(next_channel > CHANNEL_HIGHEST_AVAILABLE)
next_channel = 1
/mob/proc/stop_sound_channel(chan)
src << sound(null, repeat = 0, wait = 0, channel = chan)
/proc/get_rand_frequency()
return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs.
/client/proc/playtitlemusic()
if(!ticker || !all_lobby_tracks.len || !media) return
if(is_preference_enabled(/datum/client_preference/play_lobby_music))
@@ -171,25 +115,26 @@ var/const/FALLOFF_SOUNDS = 0.5
media.push_music(T.url, world.time, 0.85)
to_chat(src,"<span class='notice'>Lobby music: <b>[T.title]</b> by <b>[T.artist]</b>.</span>")
/proc/get_rand_frequency()
return rand(32000, 55000) //Frequency stuff only works with 45kbps oggs.
/proc/get_sfx(soundin)
if(istext(soundin))
switch(soundin)
if ("shatter") soundin = pick(shatter_sound)
if ("explosion") soundin = pick(explosion_sound)
if ("sparks") soundin = pick(spark_sound)
if ("rustle") soundin = pick(rustle_sound)
if ("punch") soundin = pick(punch_sound)
if ("clownstep") soundin = pick(clown_sound)
if ("swing_hit") soundin = pick(swing_hit_sound)
if ("hiss") soundin = pick(hiss_sound)
if ("pageturn") soundin = pick(page_sound)
if ("fracture") soundin = pick(fracture_sound)
if ("canopen") soundin = pick(can_sound)
if ("mechstep") soundin = pick(mechstep_sound)
//if ("gunshot") soundin = pick(gun_sound)
if("geiger") soundin = pick(geiger_sound)
if("geiger_weak") soundin = pick(geiger_weak_sound)
if ("shatter") soundin = pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg')
if ("explosion") soundin = pick('sound/effects/Explosion1.ogg','sound/effects/Explosion2.ogg','sound/effects/Explosion3.ogg','sound/effects/Explosion4.ogg','sound/effects/Explosion5.ogg','sound/effects/Explosion6.ogg')
if ("sparks") soundin = pick('sound/effects/sparks1.ogg','sound/effects/sparks2.ogg','sound/effects/sparks3.ogg','sound/effects/sparks5.ogg','sound/effects/sparks6.ogg','sound/effects/sparks7.ogg')
if ("rustle") soundin = pick('sound/effects/rustle1.ogg','sound/effects/rustle2.ogg','sound/effects/rustle3.ogg','sound/effects/rustle4.ogg','sound/effects/rustle5.ogg')
if ("punch") soundin = pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')
if ("clownstep") soundin = pick('sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg')
if ("swing_hit") soundin = pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')
if ("hiss") soundin = pick('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
if ("pageturn") soundin = pick('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg')
if ("fracture") soundin = pick('sound/effects/bonebreak1.ogg','sound/effects/bonebreak2.ogg','sound/effects/bonebreak3.ogg','sound/effects/bonebreak4.ogg')
if ("canopen") soundin = pick('sound/effects/can_open1.ogg','sound/effects/can_open2.ogg','sound/effects/can_open3.ogg','sound/effects/can_open4.ogg')
if ("mechstep") soundin = pick('sound/mecha/mechstep1.ogg', 'sound/mecha/mechstep2.ogg')
if ("geiger") soundin = pick('sound/items/geiger1.ogg', 'sound/items/geiger2.ogg', 'sound/items/geiger3.ogg', 'sound/items/geiger4.ogg', 'sound/items/geiger5.ogg')
if ("geiger_weak") soundin = pick('sound/items/geiger_weak1.ogg', 'sound/items/geiger_weak2.ogg', 'sound/items/geiger_weak3.ogg', 'sound/items/geiger_weak4.ogg')
return soundin
//Are these even used?
var/list/casing_sound = list ('sound/weapons/casingfall1.ogg','sound/weapons/casingfall2.ogg','sound/weapons/casingfall3.ogg')
var/list/keyboard_sound = list ('sound/effects/keyboard/keyboard1.ogg','sound/effects/keyboard/keyboard2.ogg','sound/effects/keyboard/keyboard3.ogg', 'sound/effects/keyboard/keyboard4.ogg')
var/list/bodyfall_sound = list('sound/effects/bodyfall1.ogg','sound/effects/bodyfall2.ogg','sound/effects/bodyfall3.ogg','sound/effects/bodyfall4.ogg')

View File

@@ -1,5 +1,10 @@
var/list/flooring_types
/proc/populate_flooring_types()
flooring_types = list()
for (var/flooring_path in typesof(/decl/flooring))
flooring_types["[flooring_path]"] = new flooring_path
/proc/get_flooring_data(var/flooring_path)
if(!flooring_types)
flooring_types = list()
@@ -285,22 +290,12 @@ var/list/flooring_types
'sound/effects/footstep/wood4.ogg',
'sound/effects/footstep/wood5.ogg'))
/decl/flooring/sifwood
/decl/flooring/wood/sif
name = "alien wooden floor"
desc = "Polished alien wood planks."
icon = 'icons/turf/flooring/wood.dmi'
icon_base = "sifwood"
has_damage_range = 6
damage_temperature = T0C+200
descriptor = "planks"
build_type = /obj/item/stack/tile/sifwood
flags = TURF_CAN_BREAK | TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER
footstep_sounds = list("human" = list(
'sound/effects/footstep/wood1.ogg',
'sound/effects/footstep/wood2.ogg',
'sound/effects/footstep/wood3.ogg',
'sound/effects/footstep/wood4.ogg',
'sound/effects/footstep/wood5.ogg'))
build_type = /obj/item/stack/tile/wood/sif
/decl/flooring/reinforced
name = "reinforced floor"

View File

@@ -14,17 +14,29 @@ var/list/floor_decals = list()
if(newcolour) color = newcolour
..(newloc)
// Hack to workaround byond crash bug
/obj/effect/floor_decal/initialize()
if(!floor_decals_initialized || !loc || QDELETED(src))
return
add_to_turf_decals()
var/turf/T = get_turf(src)
if(T) //VOREStation Edit
T.apply_decals()
initialized = TRUE
return INITIALIZE_HINT_QDEL
// This is a separate proc from initialize() to facilitiate its caching and other stuff. Look into it someday.
/obj/effect/floor_decal/proc/add_to_turf_decals()
if(supplied_dir)
set_dir(supplied_dir) // TODO - Why can't this line be done in initialize/New()?
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
var/cache_key = "[alpha]-[color]-[dir]-[icon_state]-[T.layer]"
var/image/I = floor_decals[cache_key]
if(!I)
I = image(icon = icon, icon_state = icon_state, dir = dir)
I.layer = T.layer
I.color = color
I.alpha = alpha
floor_decals[cache_key] = I
LAZYADD(T.decals, I) // Add to its decals list (so it remembers to re-apply after it cuts overlays)
T.add_overlay(I) // Add to its current overlays too.
return T
/obj/effect/floor_decal/reset
name = "reset marker"

View File

@@ -68,11 +68,11 @@
icon_state = "wood"
initial_flooring = /decl/flooring/wood
/turf/simulated/floor/sifwood
/turf/simulated/floor/wood/sif
name = "alien wooden floor"
icon = 'icons/turf/flooring/wood.dmi'
icon_state = "sifwood"
initial_flooring = /decl/flooring/sifwood
initial_flooring = /decl/flooring/wood/sif
/turf/simulated/floor/grass
name = "grass patch"
@@ -230,9 +230,8 @@
oxygen = 0
nitrogen = 0
/turf/simulated/floor/reinforced/n20/New()
..()
sleep(-1)
/turf/simulated/floor/reinforced/n20/initialize()
. = ..()
if(!air) make_air()
air.adjust_gas("sleeping_agent", ATMOSTANK_NITROUSOXIDE)
@@ -412,11 +411,11 @@
. = ..()
/turf/snow/update_icon()
overlays.Cut()
cut_overlays()
for(var/d in crossed_dirs)
var/amt = crossed_dirs[d]
for(var/i in 1 to amt)
overlays += icon(icon, "footprint[i]", text2num(d))
add_overlay(image(icon, "footprint[i]", text2num(d)))
//**** Here ends snow ****

View File

@@ -1,95 +0,0 @@
//
// Initialize floor decals! Woo! This is crazy.
//
var/global/floor_decals_initialized = FALSE
// The Turf Decal Holder
// Since it is unsafe to add overlays to turfs, we hold them here for now.
// Since I want this object to basically not exist, I am modeling it in part after lighting_overlay
/atom/movable/turf_overlay_holder
name = "turf overlay holder"
density = 0
simulated = 0
anchored = 1
layer = TURF_LAYER
icon = null
icon_state = null
mouse_opacity = 0
// auto_init = 0
/atom/movable/turf_overlay_holder/initialize()
// doesn't need special init
initialized = TRUE
return INITIALIZE_HINT_NORMAL
/atom/movable/turf_overlay_holder/New(var/atom/newloc)
..()
verbs.Cut()
var/turf/T = loc
T.overlay_holder = src
/atom/movable/turf_overlay_holder/Destroy()
if(loc)
var/turf/T = loc
if(T.overlay_holder == src)
T.overlay_holder = null
. = ..()
// Variety of overrides so the overlays don't get affected by weird things.
/atom/movable/turf_overlay_holder/ex_act()
return
/atom/movable/turf_overlay_holder/singularity_act()
return
/atom/movable/turf_overlay_holder/singularity_pull()
return
/atom/movable/turf_overlay_holder/forceMove()
return 0 //should never move
/atom/movable/turf_overlay_holder/Move()
return 0
/atom/movable/turf_overlay_holder/throw_at()
return 0
/obj/effect/floor_decal/proc/add_to_turf_decals()
if(src.supplied_dir) src.set_dir(src.supplied_dir)
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
var/cache_key = "[src.alpha]-[src.color]-[src.dir]-[src.icon_state]-[T.layer]"
var/image/I = floor_decals[cache_key]
if(!I)
I = image(icon = src.icon, icon_state = src.icon_state, dir = src.dir)
I.layer = T.layer
I.color = src.color
I.alpha = src.alpha
floor_decals[cache_key] = I
if(!T.decals) T.decals = list()
//world.log << "About to add img:\ref[I] onto decals at turf:\ref[T] ([T.x],[T.y],[T.z]) which has appearance:\ref[T.appearance] and decals.len=[T.decals.len]"
T.decals += I
return T
// qdel(D)
src.loc = null
src.tag = null
// Changes to turf to let us do this
/turf
var/atom/movable/turf_overlay_holder/overlay_holder = null
// After a turf change, destroy the old overlay holder since we will have lost access to it.
/turf/post_change()
var/atom/movable/turf_overlay_holder/TOH = locate(/atom/movable/turf_overlay_holder, src)
if(TOH)
qdel(TOH)
..()
/turf/proc/apply_decals()
if(decals)
if(!overlay_holder)
overlay_holder = new(src)
overlay_holder.overlays = src.decals
else if(overlay_holder)
overlay_holder.overlays.Cut()

View File

@@ -21,16 +21,15 @@
spawn(0)
wet = wet_val
if(wet_overlay)
overlays -= wet_overlay
wet_overlay = null
wet_overlay = image('icons/effects/water.dmi',src,"wet_floor")
overlays += wet_overlay
cut_overlay(wet_overlay)
wet_overlay = image('icons/effects/water.dmi', icon_state = "wet_floor")
add_overlay(wet_overlay)
sleep(800)
if(wet == 2)
sleep(3200)
wet = 0
if(wet_overlay)
overlays -= wet_overlay
cut_overlay(wet_overlay)
wet_overlay = null
/turf/simulated/proc/freeze_floor()
@@ -38,14 +37,14 @@
return
wet = 3 // icy
if(wet_overlay)
overlays -= wet_overlay
cut_overlay(wet_overlay)
wet_overlay = null
wet_overlay = image('icons/turf/overlays.dmi',src,"snowfloor")
overlays += wet_overlay
add_overlay(wet_overlay)
spawn(5 MINUTES)
wet = 0
if(wet_overlay)
overlays -= wet_overlay
cut_overlay(wet_overlay)
wet_overlay = null
/turf/simulated/clean_blood()

View File

@@ -60,7 +60,7 @@
//This proc auto corrects the grass tiles' siding.
/turf/simulated/floor/proc/make_plating(var/place_product, var/defer_icon_update)
overlays.Cut()
cut_overlays()
// VOREStation Edit - We are flooring switching to plating, swap out old_decals for decals.
if(flooring)
var/tmp/list/underfloor_decals = old_decals

View File

@@ -4,40 +4,15 @@
return 0
if(flooring)
if(istype(C, /obj/item/weapon/crowbar))
if(broken || burnt)
to_chat(user, "<span class='notice'>You remove the broken [flooring.descriptor].</span>")
make_plating()
else if(flooring.flags & TURF_IS_FRAGILE)
to_chat(user, "<span class='danger'>You forcefully pry off the [flooring.descriptor], destroying them in the process.</span>")
make_plating()
else if(flooring.flags & TURF_REMOVE_CROWBAR)
to_chat(user, "<span class='notice'>You lever off the [flooring.descriptor].</span>")
make_plating(1)
else
return
playsound(src, C.usesound, 80, 1)
return
else if(istype(C, /obj/item/weapon/screwdriver) && (flooring.flags & TURF_REMOVE_SCREWDRIVER))
if(broken || burnt)
return
to_chat(user, "<span class='notice'>You unscrew and remove the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, C.usesound, 80, 1)
return
else if(istype(C, /obj/item/weapon/wrench) && (flooring.flags & TURF_REMOVE_WRENCH))
to_chat(user, "<span class='notice'>You unwrench and remove the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, C.usesound, 80, 1)
return
else if(istype(C, /obj/item/weapon/shovel) && (flooring.flags & TURF_REMOVE_SHOVEL))
to_chat(user, "<span class='notice'>You shovel off the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
if(istype(C, /obj/item/weapon))
try_deconstruct_tile(C, user)
return
else if(istype(C, /obj/item/stack/cable_coil))
to_chat(user, "<span class='warning'>You must remove the [flooring.descriptor] first.</span>")
return
else if(istype(C, /obj/item/stack/tile))
try_replace_tile(C, user)
return
else
if(istype(C, /obj/item/stack/cable_coil))
@@ -87,4 +62,48 @@
burnt = null
broken = null
else
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
/turf/simulated/floor/proc/try_deconstruct_tile(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/crowbar))
if(broken || burnt)
to_chat(user, "<span class='notice'>You remove the broken [flooring.descriptor].</span>")
make_plating()
else if(flooring.flags & TURF_IS_FRAGILE)
to_chat(user, "<span class='danger'>You forcefully pry off the [flooring.descriptor], destroying them in the process.</span>")
make_plating()
else if(flooring.flags & TURF_REMOVE_CROWBAR)
to_chat(user, "<span class='notice'>You lever off the [flooring.descriptor].</span>")
make_plating(1)
else
return 0
playsound(src, W.usesound, 80, 1)
return 1
else if(istype(W, /obj/item/weapon/screwdriver) && (flooring.flags & TURF_REMOVE_SCREWDRIVER))
if(broken || burnt)
return 0
to_chat(user, "<span class='notice'>You unscrew and remove the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, W.usesound, 80, 1)
return 1
else if(istype(W, /obj/item/weapon/wrench) && (flooring.flags & TURF_REMOVE_WRENCH))
to_chat(user, "<span class='notice'>You unwrench and remove the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, W.usesound, 80, 1)
return 1
else if(istype(W, /obj/item/weapon/shovel) && (flooring.flags & TURF_REMOVE_SHOVEL))
to_chat(user, "<span class='notice'>You shovel off the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
return 1
return 0
/turf/simulated/floor/proc/try_replace_tile(obj/item/stack/tile/T as obj, mob/user as mob)
if(T.type == flooring.build_type)
return
var/obj/item/weapon/W = user.is_holding_item_of_type(/obj/item/weapon)
if(!try_deconstruct_tile(W, user))
return
if(flooring)
return
attackby(T, user)

View File

@@ -15,7 +15,7 @@ var/image/no_ceiling_image = null
if(lava)
return
overlays.Cut()
cut_overlays()
if(flooring)
// Set initial icon and strings.
@@ -38,17 +38,17 @@ var/image/no_ceiling_image = null
var/turf/simulated/floor/T = get_step(src, step_dir)
if(!istype(T) || !T.flooring || T.flooring.name != flooring.name)
has_border |= step_dir
overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[step_dir]", "[flooring.icon_base]_edges", step_dir)
add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[step_dir]", "[flooring.icon_base]_edges", step_dir))
// There has to be a concise numerical way to do this but I am too noob.
if((has_border & NORTH) && (has_border & EAST))
overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[NORTHEAST]", "[flooring.icon_base]_edges", NORTHEAST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[NORTHEAST]", "[flooring.icon_base]_edges", NORTHEAST))
if((has_border & NORTH) && (has_border & WEST))
overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[NORTHWEST]", "[flooring.icon_base]_edges", NORTHWEST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[NORTHWEST]", "[flooring.icon_base]_edges", NORTHWEST))
if((has_border & SOUTH) && (has_border & EAST))
overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHEAST]", "[flooring.icon_base]_edges", SOUTHEAST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHEAST]", "[flooring.icon_base]_edges", SOUTHEAST))
if((has_border & SOUTH) && (has_border & WEST))
overlays |= get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHWEST]", "[flooring.icon_base]_edges", SOUTHWEST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-edge-[SOUTHWEST]", "[flooring.icon_base]_edges", SOUTHWEST))
if(flooring.flags & TURF_HAS_CORNERS)
// As above re: concise numerical way to do this.
@@ -56,37 +56,36 @@ var/image/no_ceiling_image = null
if(!(has_border & EAST))
var/turf/simulated/floor/T = get_step(src, NORTHEAST)
if(!(istype(T) && T.flooring && T.flooring.name == flooring.name))
overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[NORTHEAST]", "[flooring.icon_base]_corners", NORTHEAST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[NORTHEAST]", "[flooring.icon_base]_corners", NORTHEAST))
if(!(has_border & WEST))
var/turf/simulated/floor/T = get_step(src, NORTHWEST)
if(!(istype(T) && T.flooring && T.flooring.name == flooring.name))
overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[NORTHWEST]", "[flooring.icon_base]_corners", NORTHWEST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[NORTHWEST]", "[flooring.icon_base]_corners", NORTHWEST))
if(!(has_border & SOUTH))
if(!(has_border & EAST))
var/turf/simulated/floor/T = get_step(src, SOUTHEAST)
if(!(istype(T) && T.flooring && T.flooring.name == flooring.name))
overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHEAST]", "[flooring.icon_base]_corners", SOUTHEAST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHEAST]", "[flooring.icon_base]_corners", SOUTHEAST))
if(!(has_border & WEST))
var/turf/simulated/floor/T = get_step(src, SOUTHWEST)
if(!(istype(T) && T.flooring && T.flooring.name == flooring.name))
overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST)
add_overlay(get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST))
// Hack workaround to byond crash bug
//if(decals && decals.len)
//overlays |= decals
apply_decals()
// Re-apply floor decals
if(LAZYLEN(decals))
add_overlay(decals)
if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo
icon = 'icons/turf/flooring/plating.dmi'
icon_state = "dmg[rand(1,4)]"
else if(flooring)
if(!isnull(broken) && (flooring.flags & TURF_CAN_BREAK))
overlays |= get_flooring_overlay("[flooring.icon_base]-broken-[broken]","broken[broken]") // VOREStation Edit - Eris overlays
add_overlay(get_flooring_overlay("[flooring.icon_base]-broken-[broken]","broken[broken]")) // VOREStation Edit - Eris overlays
if(!isnull(burnt) && (flooring.flags & TURF_CAN_BURN))
overlays |= get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","burned[burnt]") // VOREStation Edit - Eris overlays
add_overlay(get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","burned[burnt]")) // VOREStation Edit - Eris overlays
if(weather_overlay)
overlays += weather_overlay
add_overlay(weather_overlay)
if(update_neighbors)
for(var/turf/simulated/floor/F in range(src, 1))
@@ -97,7 +96,7 @@ var/image/no_ceiling_image = null
// Show 'ceilingless' overlay.
var/turf/above = GetAbove(src)
if(above && isopenspace(above) && !istype(src, /turf/simulated/floor/outdoors)) // This won't apply to outdoor turfs since its assumed they don't have a ceiling anyways.
overlays |= no_ceiling_image
add_overlay(no_ceiling_image)
/turf/simulated/floor/proc/get_flooring_overlay(var/cache_key, var/icon_base, var/icon_dir = 0)
if(!flooring_cache[cache_key])

View File

@@ -15,17 +15,19 @@
var/list/decals
New(var/location = null, var/turf/simulated/shuttle/turf)
..(null)
my_turf = turf
/obj/landed_holder/proc/land_on(var/turf/T)
//Gather destination information
var/old_dest_type = T.type
var/old_dest_dir = T.dir
var/old_dest_icon_state = T.icon_state
var/old_dest_icon = T.icon
var/list/old_dest_overlays = T.overlays.Copy()
var/list/old_dest_underlays = T.underlays.Copy()
var/list/old_dest_decals = T.decals ? T.decals.Copy() : null
var/obj/landed_holder/new_holder = new(null)
new_holder.turf_type = T.type
new_holder.dir = T.dir
new_holder.icon = T.icon
new_holder.icon_state = T.icon_state
new_holder.copy_overlays(T, TRUE)
new_holder.underlays = T.underlays.Copy()
new_holder.decals = T.decals ? T.decals.Copy() : null
//Set the destination to be like us
T.Destroy()
@@ -33,7 +35,7 @@
new_dest.set_dir(my_turf.dir)
new_dest.icon_state = my_turf.icon_state
new_dest.icon = my_turf.icon
new_dest.overlays = my_turf.overlays
new_dest.copy_overlays(my_turf, TRUE)
new_dest.underlays = my_turf.underlays
new_dest.decals = my_turf.decals
//Shuttle specific stuff
@@ -43,18 +45,9 @@
new_dest.join_flags = my_turf.join_flags
new_dest.join_group = my_turf.join_group
if(new_dest.decals)
new_dest.apply_decals()
//Tell the new turf about what was there before
new_dest.landed_holder = new(turf = new_dest)
new_dest.landed_holder.turf_type = old_dest_type
new_dest.landed_holder.dir = old_dest_dir
new_dest.landed_holder.icon = old_dest_icon
new_dest.landed_holder.icon_state = old_dest_icon_state
new_dest.landed_holder.overlays = old_dest_overlays
new_dest.landed_holder.underlays = old_dest_underlays
new_dest.landed_holder.decals = old_dest_decals
// Associate the holder with the new turf.
new_holder.my_turf = new_dest
new_dest.landed_holder = new_holder
//Update underlays if necessary (interior corners won't have changed).
if(new_dest.takes_underlays && !new_dest.interior_corner)
@@ -70,11 +63,9 @@
new_source.set_dir(dir)
new_source.icon_state = icon_state
new_source.icon = icon
new_source.overlays = overlays
new_source.copy_overlays(src, TRUE)
new_source.underlays = underlays
new_source.decals = decals
if(new_source.decals)
new_source.apply_decals()
else
new_source = my_turf.ChangeTurf(get_base_turf_by_area(my_turf),,1)

View File

@@ -44,7 +44,9 @@ var/list/outdoor_turfs = list()
planet_controller.unallocateTurf(src)
else // This is happening during map gen, if there's no planet_controller (hopefully).
outdoor_turfs -= src
qdel(weather_overlay)
if(weather_overlay)
cut_overlay(weather_overlay)
qdel_null(weather_overlay)
update_icon()
/turf/simulated/post_change()
@@ -67,15 +69,14 @@ var/list/outdoor_turfs = list()
var/image/I = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
I.plane = 0
turf_edge_cache[cache_key] = I
overlays += turf_edge_cache[cache_key]
add_overlay(turf_edge_cache[cache_key])
/turf/simulated/proc/get_edge_icon_state()
return icon_state
/turf/simulated/floor/outdoors/update_icon()
overlays.Cut()
update_icon_edge()
..()
update_icon_edge()
/turf/simulated/floor/outdoors/mud
name = "mud"

View File

@@ -17,10 +17,9 @@
. = ..()
/turf/simulated/floor/outdoors/snow/update_icon()
overlays.Cut()
..()
for(var/d in crossed_dirs)
overlays += image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d))
add_overlay(image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d)))
/turf/simulated/floor/outdoors/snow/attackby(var/obj/item/W, var/mob/user)
if(istype(W, /obj/item/weapon/shovel))

View File

@@ -47,36 +47,36 @@
if(!damage_overlays[1]) //list hasn't been populated
generate_overlays()
overlays.Cut()
cut_overlays()
var/image/I
if(!density)
I = image('icons/turf/wall_masks.dmi', "[material.icon_base]fwall_open")
I.color = material.icon_colour
overlays += I
add_overlay(I)
return
for(var/i = 1 to 4)
I = image('icons/turf/wall_masks.dmi', "[material.icon_base][wall_connections[i]]", dir = 1<<(i-1))
I.color = material.icon_colour
overlays += I
add_overlay(I)
if(reinf_material)
if(construction_stage != null && construction_stage < 6)
I = image('icons/turf/wall_masks.dmi', "reinf_construct-[construction_stage]")
I.color = reinf_material.icon_colour
overlays += I
add_overlay(I)
else
if("[reinf_material.icon_reinf]0" in icon_states('icons/turf/wall_masks.dmi'))
// Directional icon
for(var/i = 1 to 4)
I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1))
I.color = reinf_material.icon_colour
overlays += I
add_overlay(I)
else
I = image('icons/turf/wall_masks.dmi', reinf_material.icon_reinf)
I.color = reinf_material.icon_colour
overlays += I
add_overlay(I)
if(damage != 0)
var/integrity = material.integrity
@@ -87,7 +87,7 @@
if(overlay > damage_overlays.len)
overlay = damage_overlays.len
overlays += damage_overlays[overlay]
add_overlay(damage_overlays[overlay])
return
/turf/simulated/wall/proc/generate_overlays()

View File

@@ -230,15 +230,7 @@
/turf/simulated/shuttle/wall/voidcraft/update_icon()
if(stripe_color)
overlays = list() //VOREStation Edit - Another place with overlay nonsense.
cut_overlays()
var/image/I = image(icon = src.icon, icon_state = "o_[icon_state]")
I.color = stripe_color
//VOREStation Add - Shenanigans around this because of the bullshit byond bug
var/pre_overlays = overlays.len
overlays.Add(I)
var/post_overlays = overlays.len
if(post_overlays != (pre_overlays + 1))
world.log << "Corrupted overlays on [x],[y],[z] voidcraft wall"
new type(src)
return
//VOREStation Add End
add_overlay(I)

View File

@@ -26,7 +26,7 @@
var/list/flesh_overlay_cache = list()
/turf/simulated/flesh/update_icon(var/update_neighbors)
overlays.Cut()
cut_overlays()
if(density)
icon = 'icons/turf/stomach_vr.dmi'
@@ -37,7 +37,7 @@ var/list/flesh_overlay_cache = list()
var/place_dir = turn(direction, 180)
if(!flesh_overlay_cache["flesh_side_[place_dir]"])
flesh_overlay_cache["flesh_side_[place_dir]"] = image('icons/turf/stomach_vr.dmi', "flesh_side", dir = place_dir)
T.overlays += flesh_overlay_cache["flesh_side_[place_dir]"]
add_overlay(flesh_overlay_cache["flesh_side_[place_dir]"])
if(update_neighbors)
for(var/direction in alldirs)

View File

@@ -16,7 +16,6 @@
update_icon()
/turf/simulated/floor/water/update_icon()
overlays.Cut()
..() // To get the edges.
icon_state = water_state
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
@@ -129,16 +128,16 @@ var/list/shoreline_icon_cache = list()
// Water sprites are really annoying, so let BYOND sort it out.
/turf/simulated/floor/water/shoreline/update_icon()
underlays.Cut()
overlays.Cut()
cut_overlays()
..() // Get the underlay first.
var/cache_string = "[initial(icon_state)]_[water_state]_[dir]"
if(cache_string in shoreline_icon_cache) // Check to see if an icon already exists.
overlays += shoreline_icon_cache[cache_string]
add_overlay(shoreline_icon_cache[cache_string])
else // If not, make one, but only once.
var/icon/shoreline_water = icon(src.icon, "shoreline_water", src.dir)
var/icon/shoreline_subtract = icon(src.icon, "[initial(icon_state)]_subtract", src.dir)
shoreline_water.Blend(shoreline_subtract,ICON_SUBTRACT)
shoreline_icon_cache[cache_string] = shoreline_water
overlays += shoreline_icon_cache[cache_string]
add_overlay(shoreline_icon_cache[cache_string])

View File

@@ -26,12 +26,12 @@
. = ..()
/turf/snow/update_icon()
overlays.Cut()
cut_overlays()
for(var/d in crossed_dirs)
var/amt = crossed_dirs[d]
for(var/i in 1 to amt)
overlays += icon(icon, "footprint[i]", text2num(d))
add_overlay(image(icon, "footprint[i]", text2num(d)))
/turf/snow/snow2
name = "snow"

View File

@@ -10,7 +10,8 @@
/turf/space/cracked_asteroid/is_space() // So people don't start floating when standing on it.
return FALSE
/turf/space/cracked_asteroid/New()
..()
spawn(2 SECONDS)
overlays.Cut()
// u wot m8? ~Leshana
// /turf/space/cracked_asteroid/New()
// ..()
// spawn(2 SECONDS)
// overlays.Cut()

View File

@@ -17,7 +17,7 @@
/turf/unsimulated/beach/water/New()
..()
overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1)
add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water2","layer"=MOB_LAYER+0.1))
/turf/simulated/floor/beach
name = "Beach"
@@ -56,4 +56,4 @@
/turf/simulated/floor/beach/water/New()
..()
overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1)
add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1))

View File

@@ -184,7 +184,7 @@ var/static/list/scarySounds = list(
var/max_explosion_range = 14
// Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it.
var/global/obj/item/device/radio/intercom/global_announcer = new /obj/item/device/radio/intercom{channels=list("Engineering")}(null)
var/global/obj/item/device/radio/intercom/omni/global_announcer = new /obj/item/device/radio/intercom/omni(null)
var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian")

View File

@@ -380,7 +380,7 @@ proc/admin_notice(var/message, var/rights)
if(3)
dat+={"
Creating new Feed Message...
<HR><B><A href='?src=\ref[src];ac_set_channel_receiving=1'>Receiving Channel</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>" //MARK
<HR><B><A href='?src=\ref[src];ac_set_channel_receiving=1'>Receiving Channel</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>
<B>Message Author:</B> <FONT COLOR='green'>[src.admincaster_signature]</FONT><BR>
<B><A href='?src=\ref[src];ac_set_new_message=1'>Message Body</A>:</B> [src.admincaster_feed_message.body] <BR>
<BR><A href='?src=\ref[src];ac_submit_new_message=1'>Submit</A><BR><BR><A href='?src=\ref[src];ac_setScreen=[0]'>Cancel</A><BR>
@@ -677,10 +677,7 @@ var/datum/announcement/minor/admin_min_announcer = new
set desc = "Send an intercom message, like an arrivals announcement."
if(!check_rights(0)) return
//This is basically how death alarms do it
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/omni(null)
var/channel = input("Channel for message:","Channel", null) as null|anything in (list("Common") + a.keyslot2.channels) // + a.keyslot1.channels
var/channel = input("Channel for message:","Channel", null) as null|anything in radiochannels
if(channel) //They picked a channel
var/sender = input("Name of sender (max 75):", "Announcement", "Announcement Computer") as null|text
@@ -691,11 +688,94 @@ var/datum/announcement/minor/admin_min_announcer = new
if(message) //They put a message
message = sanitize(message, 500, extra = 0)
a.autosay("[message]", "[sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set.
global_announcer.autosay("[message]", "[sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set.
log_admin("Intercom: [key_name(usr)] : [sender]:[message]")
qdel(a)
feedback_add_details("admin_verb","IN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/intercom_convo()
set category = "Fun"
set name = "Intercom Convo"
set desc = "Send an intercom conversation, like several uses of the Intercom Msg verb."
set waitfor = FALSE //Why bother? We have some sleeps. You can leave tho!
if(!check_rights(0)) return
var/channel = input("Channel for message:","Channel", null) as null|anything in radiochannels
if(!channel) //They picked a channel
return
to_chat(usr,"<span class='notice'><B>Intercom Convo Directions</B><br>Start the conversation with the sender, a pipe (|), and then the message on one line. Then hit enter to \
add another line, and type a (whole) number of seconds to pause between that message, and the next message, then repeat the message syntax up to 20 times. For example:<br>\
--- --- ---<br>\
Some Guy|Hello guys, what's up?<br>\
5<br>\
Other Guy|Hey, good to see you.<br>\
5<br>\
Some Guy|Yeah, you too.<br>\
--- --- ---<br>\
The above will result in those messages playing, with a 5 second gap between each. Maximum of 20 messages allowed.</span>")
var/list/decomposed
var/message = input(usr,"See your chat box for instructions. Keep a copy elsewhere in case it is rejected when you click OK.", "Input Conversation", "") as null|message
if(!message)
return
//Split on pipe or \n
decomposed = splittext(message,regex("\\||$","m"))
decomposed += "0" //Tack on a final 0 sleep to make 3-per-message evenly
//Time to find how they screwed up.
//Wasn't the right length
if((decomposed.len) % 3) //+1 to accomidate the lack of a wait time for the last message
to_chat(usr,"<span class='warning'>You passed [decomposed.len] segments (senders+messages+pauses). You must pass a multiple of 3, minus 1 (no pause after the last message). That means a sender and message on every other line (starting on the first), separated by a pipe character (|), and a number every other line that is a pause in seconds.</span>")
return
//Too long a conversation
if((decomposed.len / 3) > 20)
to_chat(usr,"<span class='warning'>This conversation is too long! 20 messages maximum, please.</span>")
return
//Missed some sleeps, or sanitized to nothing.
for(var/i = 1; i < decomposed.len; i++)
//Sanitize sender
var/clean_sender = sanitize(decomposed[i])
if(!clean_sender)
to_chat(usr,"<span class='warning'>One part of your conversation was not able to be sanitized. It was the sender of the [(i+2)/3]\th message.</span>")
return
decomposed[i] = clean_sender
//Sanitize message
var/clean_message = sanitize(decomposed[++i])
if(!clean_message)
to_chat(usr,"<span class='warning'>One part of your conversation was not able to be sanitized. It was the body of the [(i+2)/3]\th message.</span>")
return
decomposed[i] = clean_message
//Sanitize wait time
var/clean_time = text2num(decomposed[++i])
if(!isnum(clean_time))
to_chat(usr,"<span class='warning'>One part of your conversation was not able to be sanitized. It was the wait time after the [(i+2)/3]\th message.</span>")
return
if(clean_time > 60)
to_chat(usr,"<span class='warning'>Max 60 second wait time between messages for sanity's sake please.</span>")
return
decomposed[i] = clean_time
log_admin("Intercom convo started by: [key_name(usr)] : [sanitize(message)]")
feedback_add_details("admin_verb","IN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//Sanitized AND we still have a chance to send it? Wow!
if(LAZYLEN(decomposed))
for(var/i = 1; i < decomposed.len; i++)
var/this_sender = decomposed[i]
var/this_message = decomposed[++i]
var/this_wait = decomposed[++i]
global_announcer.autosay("[this_message]", "[this_sender]", "[channel == "Common" ? null : channel]") //Common is a weird case, as it's not a "channel", it's just talking into a radio without a channel set.
sleep(this_wait SECONDS)
/datum/admins/proc/toggleooc()
set category = "Server"
set desc="Globally Toggles OOC"

View File

@@ -26,6 +26,7 @@ var/list/admin_verbs_admin = list(
/datum/admins/proc/toggleguests, //toggles whether guests can join the current game,
/datum/admins/proc/announce, //priority announce something to all clients.,
/datum/admins/proc/intercom, //send a fake intercom message, like an arrivals announcement,
/datum/admins/proc/intercom_convo, //send a fake intercom conversation, like an ATC exchange,
/client/proc/colorooc, //allows us to set a custom colour for everythign we say in ooc,
/client/proc/admin_ghost, //allows us to ghost/reenter body at will,
/client/proc/toggle_view_range, //changes how far we can see,

View File

@@ -143,7 +143,12 @@
vtext = "<a href='?_src_=vars;Vars=\ref[C]'>\ref[C]</a> - [C] ([C.type])"
else if(islist(value))
var/list/L = value
vtext = "/list ([L.len])"
var/removed = 0
if(varname == "contents")
var/list/original = value
L = original.Copy() //We'll take a copy to manipulate
removed = D.view_variables_filter_contents(L)
vtext = "/list ([L.len]+[removed]H)"
if(!(varname in view_variables_dont_expand) && L.len > 0 && L.len < 100)
extra = "<ul>"
var/index = 1
@@ -158,3 +163,21 @@
vtext = "[value]"
return "<li>[ecm][varname] = <span class='value'>[vtext]</span>[extra]</li>"
//Allows us to mask out some contents when it's not necessary to show them
//For example, organs on humans, as the organs are stored in other lists which will also be present
//So there's really no need to list them twice.
/datum/proc/view_variables_filter_contents(list/L)
return 0 //Return how many items you removed.
/mob/living/carbon/human/view_variables_filter_contents(list/L)
. = ..()
L -= ability_master
.++
/mob/living/carbon/human/view_variables_filter_contents(list/L)
. = ..()
var/len_before = L.len
L -= organs
L -= internal_organs
. += len_before - L.len

View File

@@ -86,7 +86,18 @@ var/list/_client_preferences_by_type
preference_mob.stop_all_music()
else
preference_mob.update_music()
//VOREStation Add - Need to put it here because it should be ordered riiiight here.
/datum/client_preference/eating_noises
description = "Eating Noises"
key = "EATING_NOISES"
enabled_description = "Noisy"
disabled_description = "Silent"
/datum/client_preference/digestion_noises
description = "Digestion Noises"
key = "DIGEST_NOISES"
enabled_description = "Noisy"
disabled_description = "Silent"
//VOREStation Add End
/datum/client_preference/ghost_ears
description ="Ghost ears"
key = "CHAT_GHOSTEARS"

View File

@@ -147,4 +147,17 @@
display_name = "cloth footwraps"
path = /obj/item/clothing/shoes/footwraps
sort_category = "Xenowear"
cost = 1
cost = 1
/datum/gear/uniform/cohesionsuits
display_name = "cohesion suit selection (Promethean)"
path = /obj/item/clothing/under/cohesion
sort_category = "Xenowear"
/datum/gear/uniform/cohesionsuits/New()
..()
var/list/cohesionsuits = list()
for(var/cohesionsuit in (typesof(/obj/item/clothing/under/cohesion)))
var/obj/item/clothing/under/cohesion/cohesion_type = cohesionsuit
cohesionsuits[initial(cohesion_type.name)] = cohesion_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cohesionsuits))

View File

@@ -1,11 +1,9 @@
/obj/item/clothing/proc/can_attach_accessory(obj/item/clothing/accessory/A)
var/obj/item/clothing/accessory/attach = A
if(src.valid_accessory_slots && (attach.slot in src.valid_accessory_slots))
if(accessories.len && restricted_accessory_slots && (attach.slot in restricted_accessory_slots))
if(src.valid_accessory_slots && (A.slot in src.valid_accessory_slots))
if(accessories.len && restricted_accessory_slots && (A.slot in restricted_accessory_slots))
for(var/obj/item/clothing/accessory/AC in accessories)
if (AC.slot == attach.slot)
if (AC.slot == A.slot)
return FALSE
return TRUE
return TRUE
else
return FALSE

View File

@@ -83,12 +83,8 @@
var/username = FindNameFromID(H) || "Unknown"
var/message = "[username] has overridden [A] (airlock) in \the [get_area(A)] at [A.x],[A.y],[A.z] with \the [src]."
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
a.icon = icon
a.icon_state = icon_state
a.autosay(message, "Security Subsystem", "Command")
a.autosay(message, "Security Subsystem", "Security")
qdel(a)
global_announcer.autosay(message, "Security Subsystem", "Command")
global_announcer.autosay(message, "Security Subsystem", "Security")
return 1
/obj/item/rig_module/rescue_pharm

View File

@@ -816,4 +816,30 @@
/obj/item/clothing/under/explorer
desc = "A green uniform for operating in hazardous environments."
name = "explorer's jumpsuit"
icon_state = "explorer"
icon_state = "explorer"
/obj/item/clothing/under/cohesion
name = "black cohesion suit"
desc = "A plain black cohesion suit intended to assist Prometheans in maintaining their form and prevent direct skin exposure."
icon_state = "cohesionsuit"
rolled_sleeves = -1 // defeats the purpose!!!
/obj/item/clothing/under/cohesion/striped
name = "red striped cohesion suit"
desc = "A black cohesion suit with red stripes intended to assist Prometheans in maintaining their form and prevent direct skin exposure."
icon_state = "cohesionsuit_striped"
/obj/item/clothing/under/cohesion/decal
name = "purple decaled cohesion suit"
desc = "A white cohesion suit with purple decals intended to assist Prometheans in maintaining their form and prevent direct skin exposure."
icon_state = "cohesionsuit_decal"
/obj/item/clothing/under/cohesion/pattern
name = "blue patterned cohesion suit"
desc = "A white cohesion suit with blue patterns intended to assist Prometheans in maintaining their form and prevent direct skin exposure."
icon_state = "cohesionsuit_pattern"
/obj/item/clothing/under/cohesion/hazard
name = "hazard cohesion suit"
desc = "An orange cohesion suit with yellow hazard stripes intended to assist Prometheans in maintaining their form and prevent direct skin exposure."
icon_state = "cohesionsuit_hazard"

View File

@@ -1,21 +1,5 @@
/obj/item/clothing/var/hides_bulges = FALSE // OwO wats this?
/mob/living/carbon/human/proc/show_pudge()
//A uniform could hide it.
if(istype(w_uniform,/obj/item/clothing))
var/obj/item/clothing/under = w_uniform
if(under.hides_bulges)
return FALSE
//We return as soon as we find one, no need for 'else' really.
if(istype(wear_suit,/obj/item/clothing))
var/obj/item/clothing/suit = wear_suit
if(suit.hides_bulges)
return FALSE
return TRUE
/obj/item/clothing/under/permit
name = "public nudity permit"
desc = "This permit entitles the bearer to conduct their duties without a uniform. Normally issued to furred crewmembers or those with nothing to hide."

View File

@@ -107,7 +107,7 @@
/turf/simulated/floor/holofloor/desert/New()
..()
if(prob(10))
overlays += "asteroid[rand(0,9)]"
add_overlay("asteroid[rand(0,9)]")
/obj/structure/holostool
name = "stool"

View File

@@ -19,6 +19,7 @@
/obj/item/seeds/limeseed = 3,
/obj/item/seeds/mtearseed = 2,
/obj/item/seeds/orangeseed = 3,
/obj/item/seeds/onionseed = 3,
/obj/item/seeds/peanutseed = 3,
/obj/item/seeds/plumpmycelium = 3,
/obj/item/seeds/poppyseed = 3,

View File

@@ -186,6 +186,6 @@
/material/wood/sif/generate_recipes()
..()
recipes += new/datum/stack_recipe("alien wood floor tile", /obj/item/stack/tile/sifwood, 1, 4, 20)
recipes += new/datum/stack_recipe("alien wood floor tile", /obj/item/stack/tile/wood/sif, 1, 4, 20)
recipes -= new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20)
recipes -= new/datum/stack_recipe("wooden chair", /obj/structure/bed/chair/wood, 3, time = 10, one_per_turf = 1, on_floor = 1)

View File

@@ -42,7 +42,7 @@
// Galactic common languages (systemwide accepted standards).
/datum/language/trader
name = LANGUAGE_TRADEBAND
desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining."
desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining." //VOREstation Edit
speech_verb = "enunciates"
colour = "say_quote"
key = "2"
@@ -53,10 +53,22 @@
"nt","ti","us","it","en","at","tu","te","ri","es","et","ra","ta","an","ni","li","on","or","se",
"am","ae","ia","di","ue","em","ar","ui","st","si","de","ci","iu","ne","pe","co","os","ur","ru")
/datum/language/terminus
name = LANGUAGE_TERMINUS
desc = "A soft language spoken by the people of the sparsely populated, socially-conscious Precursors' Crypt region."
speech_verb = "mentions"
exclaim_verb = "insinuates"
colour = "terminus"
key = "4"
flags = WHITELISTED
syllables = list ("die", "en", "skei", "van", "son", "der", "aar", "ch", "op", "ruk", "aa", "be", "ne", "het",
"ek", "ras", "ver", "zan", "das", "waa", "geb", "vol", "lu", "min", "breh", "rus", "stv", "ee", "goe", "sk",
"la", "ver", "we", "ge", "luk", "an", "ar", "at", "es", "et", "bel", "du", "jaa", "ch", "kk", "gh", "ll", "uu", "wat")
// Criminal language.
/datum/language/gutter
name = LANGUAGE_GUTTER
desc = "There is no true language named Gutter. 'Gutter' is a catchall term for a collection of unofficial SolCom dialects that has somehow managed to spread across the stars."
desc = "Gutter originated as a Thieves' Cant of sorts during the early colonization era. The language eventually spread from the cartels and triads to the disenfranchised people of the Bowl."
speech_verb = "growls"
colour = "rough"
key = "3"

View File

@@ -92,7 +92,7 @@
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
key = "4"
key = "u"
flags = RESTRICTED
syllables = list("sss","sSs","SSS")
@@ -115,3 +115,18 @@
return 1
return 0
//for your antag purposes.
/datum/language/minbus
name = LANGUAGE_MINBUS
desc = "The Powers That Be have seen it fit to grace you with a special language that sounds like Russian for some reason."
speech_verb = "says"
ask_verb = "asks"
exclaim_verb = "shouts"
colour = "deadsay"
key = "r"
machine_understands = 0
flags = RESTRICTED
syllables = list("rus","zem","ave","groz","ski","ska","ven","konst","pol","lin","svy",
"danya","da","mied","zan","das","krem","myka","cyka","blyat","to","st","no","na","ni",
"ko","ne","en","po","ra","li","on","byl","cto","eni","ost","ol","ego","ver","stv","pro")

View File

@@ -85,6 +85,20 @@
flags = WHITELISTED
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix")
/datum/language/skrellfar
name = LANGUAGE_SKRELLIANFAR
desc = "The most common language among the Skrellian Far Kingdoms. Has an even higher than usual concentration of inaudible phonemes."
speech_verb = "warbles"
ask_verb = "warbles"
exclaim_verb = "sings"
whisper_verb = "hums"
colour = "skrellfar"
key = "p"
space_chance = 30
flags = WHITELISTED
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix", "...", "oo", "q", "nq", "x", "xq", "ll", "...", "...", "...") //should sound like there's holes in it
/datum/language/human
name = LANGUAGE_SOL_COMMON
desc = "A bastardized hybrid of many languages, including Chinese, English, French, and more; it is the common language of the Sol system."
@@ -114,7 +128,7 @@
/datum/language/machine
name = LANGUAGE_EAL
desc = "An efficient language of encoded tones developed by synthetics and cyborgs."
desc = "An efficient language of encoded tones developed by positronics."
speech_verb = "whistles"
ask_verb = "chirps"
exclaim_verb = "whistles loudly"
@@ -244,4 +258,4 @@
"tod", "ser", "su", "no", "nue", "el",
"ad", "al", "an", "ar", "as", "ci", "co", "de", "do", "el", "en", "er", "es", "ie", "in", "la", "lo", "me", "na",
"no", "nt", "or", "os", "pa", "qu", "ra", "re", "ro", "se", "st", "ta", "te", "to", "ue", "un",
"tod", "ser", "su", "no", "nue", "el")
"tod", "ser", "su", "no", "nue", "el")

View File

@@ -8,6 +8,7 @@
use_me = 0 //Can't use the me verb, it's a freaking immobile brain
icon = 'icons/obj/surgery.dmi'
icon_state = "brain1"
no_vore = TRUE //VOREStation Edit - PLEASE. lol.
New()
var/datum/reagents/R = new/datum/reagents(1000)

View File

@@ -302,7 +302,7 @@
msg += attempt_vr(src,"examine_bellies",args) //VOREStation Code
msg += attempt_vr(src,"examine_pickup_size",args) //VOREStation Code
msg += attempt_vr(src,"examine_step_size",args) //VOREStation Code
msg += attempt_vr(src,"nif_examine",args) //VOREStation Code
msg += attempt_vr(src,"examine_nif",args) //VOREStation Code
if(mSmallsize in mutations)
msg += "[T.He] [T.is] small halfling!\n"

View File

@@ -107,17 +107,6 @@
message = "<span class='warning'>[t_He] [t_is] so absolutely stuffed that you aren't sure how it's possible to move. [t_He] can't seem to swell any bigger. The surface of [t_his] belly looks sorely strained!</span>\n"
return message
/mob/living/carbon/human/proc/examine_bellies()
if(!show_pudge()) //Some clothing or equipment can hide this.
return ""
var/message = ""
for (var/I in src.vore_organs)
var/datum/belly/B = vore_organs[I]
message += B.get_examine_msg()
return message
//For OmniHUD records access for appropriate models
/proc/hasHUD_vr(mob/living/carbon/human/H, hudtype)
if(H.nif)
@@ -141,23 +130,18 @@
return FALSE
/mob/living/carbon/human/proc/examine_pickup_size(mob/living/carbon/human/H)
/mob/living/carbon/human/proc/examine_pickup_size(mob/living/H)
var/message = ""
if(isliving(src) && (H.get_effective_size() - src.get_effective_size()) >= 0.50)
if(istype(H) && (H.get_effective_size() - src.get_effective_size()) >= 0.50)
message = "<font color='blue'>They are small enough that you could easily pick them up!</font>\n"
return message
/mob/living/carbon/human/proc/examine_step_size(mob/living/carbon/human/H)
/mob/living/carbon/human/proc/examine_step_size(mob/living/H)
var/message = ""
if(isliving(src) && (H.get_effective_size() - src.get_effective_size()) >= 0.75)
if(istype(H) && (H.get_effective_size() - src.get_effective_size()) >= 0.75)
message = "<font color='red'>They are small enough that you could easily trample them!</font>\n"
return message
/mob/living/carbon/human/proc/nif_examine(mob/living/carbon/human/H)
var/message = ""
if(!src.nif || src.conceal_nif || !src.nif_examine) //Do they have a nif, do they have the NIF concealed, and do they have a NIF examine message?
return "" //If so, no message.
else
message += "[src.nif_examine]\n"
return message
/mob/living/carbon/human/proc/examine_nif(mob/living/carbon/human/H)
if(nif && nif.examine_msg) //If you have one set, anyway.
return "<span class='notice'>[nif.examine_msg]</span>\n"

View File

@@ -66,7 +66,8 @@
list_body = null
LAZYCLEARLIST(list_huds)
list_huds = null
if(nif) qdel_null(nif) //VOREStation Add
qdel_null(nif) //VOREStation Add
qdel_null_list(vore_organs) //VOREStation Add
return ..()
/mob/living/carbon/human/Stat()

View File

@@ -43,7 +43,7 @@
var/obj/item/organ/external/E = get_organ(organ_name)
if(!E || E.is_stump())
tally += 4
else if(E.splinted)
else if(E.splinted && E.splinted.loc != E)
tally += 0.5
else if(E.status & ORGAN_BROKEN)
tally += 1.5
@@ -55,7 +55,7 @@
var/obj/item/organ/external/E = get_organ(organ_name)
if(!E || E.is_stump())
tally += 4
else if(E.splinted)
else if(E.splinted && E.splinted.loc != E)
tally += 0.5
else if(E.status & ORGAN_BROKEN)
tally += 1.5

View File

@@ -1,3 +1,6 @@
/mob/living/carbon/human/dummy
no_vore = TRUE //Dummies don't need bellies.
/mob/living/carbon/human/sergal/New(var/new_loc)
h_style = "Sergal Plain"
..(new_loc, "Sergal")

View File

@@ -319,7 +319,7 @@ This saves us from having to call add_fingerprint() any time something is put in
for(var/obj/item/clothing/C in worn_clothing)
if(istype(W, /obj/item/clothing/accessory))
var/obj/item/clothing/accessory/A = W
if(C.attempt_attach_accessory(A))
if(C.attempt_attach_accessory(A, src))
return
else
src << "<font color='red'>You are trying to equip this item to an unsupported inventory slot. How the heck did you manage that? Stop it...</font>"

View File

@@ -156,9 +156,9 @@ VOREStation Removal End */
H.adjustFireLoss(-heal_rate)
H.adjustOxyLoss(-heal_rate)
H.adjustToxLoss(-heal_rate)
else
/* else //VOREStation Edit Start.
H.adjustToxLoss(2*heal_rate) // Doubled because 0.5 is miniscule, and fire_stacks are capped in both directions
*/ //VOREStation Edit End
/datum/species/shapeshifter/promethean/get_blood_colour(var/mob/living/carbon/human/H)
return (H ? rgb(H.r_skin, H.g_skin, H.b_skin) : ..())

View File

@@ -9,6 +9,7 @@
mob_size = MOB_MEDIUM
num_alternate_languages = 1 //Let's at least give them one
appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | RADIATION_GLOWS | HAS_UNDERWEAR
trashcan = 1 //They have goopy bodies. They can just dissolve things within them.
inherent_verbs = list(
/mob/living/carbon/human/proc/shapeshifter_select_shape,
/mob/living/carbon/human/proc/shapeshifter_select_colour,
@@ -20,7 +21,8 @@
/mob/living/carbon/human/proc/succubus_drain,
/mob/living/carbon/human/proc/succubus_drain_finalize,
/mob/living/carbon/human/proc/succubus_drain_lethal,
/mob/living/carbon/human/proc/slime_feed
/mob/living/carbon/human/proc/slime_feed,
/mob/living/proc/eat_trash
)

View File

@@ -10,7 +10,7 @@
worlds tumultous at best."
num_alternate_languages = 3
species_language = LANGUAGE_SOL_COMMON
secondary_langs = list(LANGUAGE_SOL_COMMON)
secondary_langs = list(LANGUAGE_SOL_COMMON, LANGUAGE_TERMINUS)
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 18
max_age = 130

View File

@@ -606,9 +606,6 @@
C.absorbing_prey = 0
return
/mob/living/carbon/human/proc/succubus_drain_finalize()
set name = "Drain/Feed Finalization"
set desc = "Toggle to allow for draining to be prolonged. Turn this on to make it so prey will be knocked out/die while being drained, or you will feed yourself to the prey's selected stomach if you're feeding them. Can be toggled at any time."
@@ -618,110 +615,134 @@
C.drain_finalized = !C.drain_finalized
to_chat(C, "<span class='notice'>You will [C.drain_finalized?"now":"not"] finalize draining/feeding.</span>")
/mob/living/carbon/human/proc/shred_limb() //If you're looking at this, nothing but pain and suffering lies below.
//Test to see if we can shred a mob. Some child override needs to pass us a target. We'll return it if you can.
/mob/living/var/vore_shred_time = 45 SECONDS
/mob/living/proc/can_shred(var/mob/living/carbon/human/target)
//Needs to have organs to be able to shred them.
if(!istype(target))
to_chat(src,"<span class='warning'>You can't shred that type of creature.</span>")
return FALSE
//Needs to be capable (replace with incapacitated call?)
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
to_chat(src,"<span class='warning'>You cannot do that in your current state!</span>")
return FALSE
//Needs to be adjacent, at the very least.
if(!Adjacent(target))
to_chat(src,"<span class='warning'>You must be next to your target.</span>")
return FALSE
//Cooldown on abilities
if(last_special > world.time)
to_chat(src,"<span class='warning'>You can't perform an ability again so soon!</span>")
return FALSE
return target
//Human test for shreddability, returns the mob if they can be shredded.
/mob/living/carbon/human/vore_shred_time = 10 SECONDS
/mob/living/carbon/human/can_shred()
//Humans need a grab
var/obj/item/weapon/grab/G = get_active_hand()
if(!istype(G))
to_chat(src,"<span class='warning'>You have to have a very strong grip on someone first!</span>")
return FALSE
if(G.state != GRAB_NECK)
to_chat(src,"<span class='warning'>You must have a tighter grip to severely damage this creature!</span>")
return FALSE
return ..(G.affecting)
//PAIs don't need a grab or anything
/mob/living/silicon/pai/can_shred(var/mob/living/carbon/human/target)
if(!target)
var/list/choices = list()
for(var/mob/living/carbon/human/M in oviewers(1))
choices += M
if(!choices.len)
to_chat(src,"<span class='warning'>There's nobody nearby to use this on.</span>")
target = input(src,"Who do you wish to target?","Damage/Remove Prey's Organ") as null|anything in choices
if(!istype(target))
return FALSE
return ..(target)
/mob/living/proc/shred_limb()
set name = "Damage/Remove Prey's Organ"
set desc = "Severely damages prey's organ. If the limb is already severely damaged, it will be torn off."
set category = "Abilities"
if(!ishuman(src))
return //If you're not a human you don't have permission to do this.
if(last_special > world.time)
//can_shred() will return a mob we can shred, if we can shred any.
var/mob/living/carbon/human/T = can_shred()
if(!istype(T))
return //Silent, because can_shred does messages.
//Let them pick any of the target's external organs
var/obj/item/organ/external/T_ext = input(src,"What do you wish to severely damage?") as null|anything in T.organs //D for destroy.
if(!T_ext) //Picking something here is critical.
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
to_chat(src, "You cannot severely damage anything in your current state!")
return
var/mob/living/carbon/human/C = src
var/obj/item/weapon/grab/G = src.get_active_hand()
if(!istype(G))
to_chat(C, "<span class='warning'>We must be grabbing a creature in our active hand to severely damage them.</span>")
return
var/mob/living/carbon/human/T = G.affecting
if(!istype(T)) //Are they a mob?
to_chat(C, "<span class='warning'>\The [T] is not able to be severely damaged!</span>")
return
if(G.state != GRAB_NECK)
to_chat(C, "<span class='warning'>You must have a tighter grip to severely damage this creature.</span>")
return
if(!T || !C || C.stat)
return
if(!Adjacent(T))
return
var/list/choices2 = list()
for(var/obj/item/organ/O in T.organs) //External organs
choices2 += O
var/obj/item/organ/external/D = input(C,"What do you wish to severely damage?") as null|anything in choices2 //D for destroy.
if(D.vital)
if(alert("Are you sure you wish to severely damage their [D]? It most likely will kill the prey...",,"Yes", "No") != "Yes")
if(T_ext.vital)
if(alert("Are you sure you wish to severely damage their [T_ext]? It will likely kill [T]...",,"Yes", "No") != "Yes")
return //If they reconsider, don't continue.
var/list/choices3 = list()
for(var/obj/item/organ/internal/I in D.internal_organs) //Look for the internal organ in the organ being shreded.
choices3 += I
//Any internal organ, if there are any
var/obj/item/organ/internal/T_int = input(src,"Do you wish to severely damage an internal organ, as well? If not, click 'cancel'") as null|anything in T_ext.internal_organs
if(T_int && T_int.vital)
if(alert("Are you sure you wish to severely damage their [T_int]? It will likely kill [T]...",,"Yes", "No") != "Yes")
return //If they reconsider, don't continue.
var/obj/item/organ/internal/P = input(C,"Do you wish to severely damage an internal organ, as well? If not, click 'cancel'") as null|anything in choices3
//And a belly, if they want
var/obj/belly/B = input(src,"Do you wish to swallow the organ if you tear if out? If not, click 'cancel'") as null|anything in vore_organs
var/eat_limb = input(C,"Do you wish to swallow the organ if you tear if out? If so, select which stomach.") as null|anything in C.vore_organs //EXTREMELY EFFICIENT
if(last_special > world.time)
if(can_shred(T) != T)
to_chat(src,"<span class='warning'>Looks like you lost your chance...</span>")
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
to_chat(C, "You cannot shred in your current state.")
return
last_special = world.time + vore_shred_time
visible_message("<span class='danger'>[src] appears to be preparing to do something to [T]!</span>") //Let everyone know that bad times are ahead
last_special = world.time + 100 //10 seconds.
C.visible_message("<font color='red'><b>[C] appears to be preparing to do something to [T]!</b></font>") //Let everyone know that bad times are head
if(do_after(src, vore_shred_time, T)) //Ten seconds. You have to be in a neckgrab for this, so you're already in a bad position.
if(can_shred(T) != T)
to_chat(src,"<span class='warning'>Looks like you lost your chance...</span>")
return
//Removing an internal organ
if(T_int && T_int.damage >= 25) //Internal organ and it's been severely damaged
T.apply_damage(15, BRUTE, T_ext) //Damage the external organ they're going through.
T_int.removed()
if(B)
T_int.forceMove(B) //Move to pred's gut
visible_message("<span class='danger'>[src] severely damages [T_int.name] of [T]!</span>")
else
T_int.forceMove(T.loc)
visible_message("<span class='danger'>[src] severely damages [T_ext.name] of [T], resulting in their [T_int.name] coming out!</span>","<span class='warning'>You tear out [T]'s [T_int.name]!</span>")
if(do_after(C, 100, T)) //Ten seconds. You have to be in a neckgrab for this, so you're already in a bad position.
if(!Adjacent(T)) return
if(P && P.damage >= 25) //Internal organ and it's been severely damage
T.apply_damage(15, BRUTE, D) //Damage the external organ they're going through.
P.removed()
P.forceMove(T.loc) //Move to where prey is.
log_and_message_admins("tore out [P] of [T].", C)
if(eat_limb)
var/datum/belly/S = C.vore_organs[eat_limb]
P.forceMove(C) //Move to pred's gut
S.internal_contents |= P //Add to pred's gut.
C.visible_message("<font color='red'><b>[C] severely damages [D] of [T]!</b></font>") // Same as below, but (pred) damages the (right hand) of (person)
to_chat(C, "[P] of [T] moves into your [S]!") //Quietly eat their internal organ! Comes out "The (right hand) of (person) moves into your (stomach)
playsound(C, S.vore_sound, 70, 1)
log_and_message_admins("tore out and ate [P] of [T].", C)
//Removing an external organ
else if(!T_int && (T_ext.damage >= 25 || T_ext.brute_dam >= 25))
T_ext.droplimb(1,DROPLIMB_EDGE) //Clean cut so it doesn't kill the prey completely.
//Is it groin/chest? You can't remove those.
if(T_ext.cannot_amputate)
T.apply_damage(25, BRUTE, T_ext)
visible_message("<span class='danger'>[src] severely damages [T]'s [T_ext.name]!</span>")
else if(B)
T_ext.forceMove(B)
visible_message("<span class='warning'>[src] swallows [T]'s [T_ext.name] into their [lowertext(B.name)]!</span>")
else
log_and_message_admins("tore out [P] of [T].", C)
C.visible_message("<font color='red'><b>[C] severely damages [D] of [T], resulting in their [P] coming out!</b></font>")
else if(!P && (D.damage >= 25 || D.brute_dam >= 25)) //Not targeting an internal organ & external organ has been severely damaged already.
D.droplimb(1,DROPLIMB_EDGE) //Clean cut so it doesn't kill the prey completely.
if(D.cannot_amputate) //Is it groin/chest? You can't remove those.
T.apply_damage(25, BRUTE, D)
C.visible_message("<font color='red'><b>[C] severely damage [T]'s [D]!</b></font>") //Keep it vague. Let the /me's do the talking.
log_and_message_admins("shreded [T]'s [D].", C)
return
if(eat_limb)
var/datum/belly/S = C.vore_organs[eat_limb]
D.forceMove(C) //Move to pred's gut
S.internal_contents |= D //Add to pred's gut.
C.visible_message("<span class='warning'>[C] swallows [D] of [T] into their [S]!</span>","You swallow [D] of [T]!")
playsound(C, S.vore_sound, 70, 1)
to_chat(C, "Their [D] moves into your [S]!")
log_and_message_admins("tore off and ate [D] of [T].", C)
else
C.visible_message("<span class='warning'>[C] tears off [D] of [T]!</span>","You tear out [D] of [T]!") //Will come out "You tear out (the right foot) of (person)
log_and_message_admins("tore off [T]'s [D].", C)
else //Not targeting an internal organ w/ > 25 damage , and the limb doesn't have < 25 damage.
if(P)
P.damage = 25 //Internal organs can only take damage, not brute damage.
T.apply_damage(25, BRUTE, D)
C.visible_message("<font color='red'><b>[C] severely damages [D] of [T]!</b></font>") //Keep it vague. Let the /me's do the talking.
log_and_message_admins("shreded [D] of [T].", C)
T_ext.forceMove(T.loc)
visible_message("<span class='warning'>[src] tears off [T]'s [T_ext.name]!</span>","<span class='warning'>You tear off [T]'s [T_ext.name]!</span>")
//Not targeting an internal organ w/ > 25 damage , and the limb doesn't have < 25 damage.
else
if(T_int)
T_int.damage = 25 //Internal organs can only take damage, not brute damage.
T.apply_damage(25, BRUTE, T_ext)
visible_message("<span class='danger'>[src] severely damages [T]'s [T_ext.name]!</span>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Shred_limb'd [T.real_name] ([T.ckey])</font>")
T.attack_log += text("\[[time_stamp()]\] <font color='red'>[src.real_name] ([src.ckey]) shred_limb'd me</font>")
msg_admin_attack("[src.real_name] ([src.ckey]) shredded (shred_limb) [T.real_name] ([T.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
/mob/living/proc/flying_toggle()
set name = "Toggle Flight"

View File

@@ -28,7 +28,7 @@
/mob/living/carbon/human/proc/succubus_drain_finalize,
/mob/living/carbon/human/proc/succubus_drain_lethal,
/mob/living/carbon/human/proc/bloodsuck,
/mob/living/carbon/human/proc/shred_limb,
/mob/living/proc/shred_limb,
/mob/living/proc/flying_toggle,
/mob/living/proc/start_wings_hovering) //Xenochimera get all the special verbs since they can't select traits.

View File

@@ -32,7 +32,7 @@
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
flesh_color = "#AFA59E"
base_color = "#777777"
@@ -76,7 +76,7 @@
secondary_langs = list(LANGUAGE_SKRELLIAN)
name_language = LANGUAGE_SKRELLIAN
color_mult = 1
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
min_age = 18
max_age = 110
@@ -120,7 +120,7 @@
secondary_langs = list(LANGUAGE_BIRDSONG)
name_language = LANGUAGE_BIRDSONG
color_mult = 1
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb,/mob/living/proc/flying_toggle,/mob/living/proc/start_wings_hovering)
inherent_verbs = list(/mob/living/proc/shred_limb,/mob/living/proc/flying_toggle,/mob/living/proc/start_wings_hovering)
min_age = 18
max_age = 110
@@ -182,7 +182,7 @@
"You feel uncomfortably warm.",
"Your overheated skin itches."
)
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
/datum/species/fl_zorren
name = "Flatland Zorren"
@@ -213,7 +213,7 @@
flesh_color = "#AFA59E"
base_color = "#333333"
color_mult = 1
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
@@ -239,7 +239,7 @@
// gluttonous = 1
num_alternate_languages = 3
color_mult = 1
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \
dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \
@@ -293,7 +293,7 @@
"You feel uncomfortably warm.",
"Your chitin feels hot."
)
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
/datum/species/unathi
spawn_flags = SPECIES_CAN_JOIN //Species_can_join is the only spawn flag all the races get, so that none of them will be whitelist only if whitelist is enabled.
@@ -302,7 +302,7 @@
tail_animation = 'icons/mob/species/unathi/tail_vr.dmi'
color_mult = 1
min_age = 18
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
/datum/species/tajaran
spawn_flags = SPECIES_CAN_JOIN
@@ -312,7 +312,7 @@
color_mult = 1
min_age = 18
gluttonous = 0 //Moving this here so I don't have to fix this conflict every time polaris glances at station.dm
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
/datum/species/skrell
spawn_flags = SPECIES_CAN_JOIN
@@ -338,7 +338,7 @@
inherent_verbs = list(
/mob/living/carbon/human/proc/sonar_ping,
/mob/living/proc/hide,
/mob/living/carbon/human/proc/shred_limb,
/mob/living/proc/shred_limb,
/mob/living/proc/toggle_pass_table
)
@@ -359,7 +359,7 @@
min_age = 18
icobase = 'icons/mob/human_races/r_vox_old.dmi'
deform = 'icons/mob/human_races/r_def_vox_old.dmi'
inherent_verbs = list(/mob/living/carbon/human/proc/shred_limb)
inherent_verbs = list(/mob/living/proc/shred_limb)
datum/species/harpy
name = "Rapala"

View File

@@ -87,7 +87,7 @@
/datum/trait/hard_vore/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
H.verbs |= /mob/living/carbon/human/proc/shred_limb
H.verbs |= /mob/living/proc/shred_limb
/datum/trait/trashcan
name = "Trash Can"

View File

@@ -29,8 +29,6 @@
//Random events (vomiting etc)
handle_random_events()
attempt_vr(src,"handle_internal_contents",args) //VOREStation Code
. = 1
//Chemicals in the body, this is moved over here so that blood can be added after death

View File

@@ -1212,3 +1212,18 @@ default behaviour is:
item.throw_at(target, throw_range, item.throw_speed, src)
/mob/living/get_sound_env(var/pressure_factor)
if (hallucination)
return PSYCHOTIC
else if (druggy)
return DRUGGED
else if (drowsyness)
return DIZZY
else if (confused)
return DIZZY
else if (sleeping)
return UNDERWATER
else
return ..()

View File

@@ -151,12 +151,14 @@ var/list/ai_verbs_default = list(
add_language(LANGUAGE_UNATHI, 1)
add_language(LANGUAGE_SIIK, 1)
add_language(LANGUAGE_SKRELLIAN, 1)
add_language(LANGUAGE_SKRELLIANFAR, 0)
add_language(LANGUAGE_TRADEBAND, 1)
add_language(LANGUAGE_GUTTER, 1)
add_language(LANGUAGE_EAL, 1)
add_language(LANGUAGE_SCHECHI, 1)
add_language(LANGUAGE_SIGN, 1)
add_language(LANGUAGE_ROOTLOCAL, 1)
add_language(LANGUAGE_TERMINUS, 1)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.

View File

@@ -7,7 +7,7 @@
if(!src.client) msg += "\nIt appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS) msg += "\n<span class='warning'>It doesn't seem to be responding.</span>\n"
if(DEAD) msg += "\n<span class='deadsay'>It looks completely unsalvageable.</span>\n"
msg += attempt_vr(src,"examine_bellies_pai",args) //VOREStation Edit
msg += attempt_vr(src,"examine_bellies",args) //VOREStation Edit
// VOREStation Edit: Start
if(ooc_notes)

View File

@@ -21,7 +21,6 @@
src << "<font color=green>Communication circuit reinitialized. Speech and messaging functionality restored.</font>"
handle_statuses()
handle_internal_contents() //VOREStation edit
if(health <= 0)
death(null,"gives one shrill beep before falling lifeless.")

View File

@@ -99,6 +99,7 @@
add_language(LANGUAGE_TRADEBAND, 1)
add_language(LANGUAGE_GUTTER, 1)
add_language(LANGUAGE_EAL, 1)
add_language(LANGUAGE_TERMINUS, 1)
add_language(LANGUAGE_SIGN, 0)
verbs += /mob/living/silicon/pai/proc/choose_chassis
@@ -298,7 +299,7 @@
if(istype(T)) T.visible_message("<b>[src]</b> folds outwards, expanding into a mobile form.")
verbs += /mob/living/silicon/pai/proc/pai_nom //VOREStation edit
verbs += /mob/living/proc/set_size //VOREStation edit
verbs += /mob/living/silicon/pai/proc/shred_limb //VORREStation edit
verbs += /mob/living/proc/shred_limb //VORREStation edit
/mob/living/silicon/pai/verb/fold_up()
set category = "pAI Commands"
@@ -389,9 +390,7 @@
if(src.loc == card)
return
for(var/I in vore_organs) //VOREStation edit. Release all their stomach contents. Don't want them to be in the PAI when they fold or weird things might happen.
var/datum/belly/B = vore_organs[I] //VOREStation edit
B.release_all_contents() //VOREStation edit
release_vore_contents() //VOREStation Add
var/turf/T = get_turf(src)
if(istype(T)) T.visible_message("<b>[src]</b> neatly folds inwards, compacting down to a rectangular card.")

View File

@@ -13,13 +13,12 @@
/mob/living/silicon/pai/proc/update_fullness_pai() //Determines if they have something in their stomach. Copied and slightly modified.
var/new_people_eaten = 0
for(var/I in vore_organs)
var/datum/belly/B = vore_organs[I]
for(var/mob/living/M in B.internal_contents)
for(var/belly in vore_organs)
var/obj/belly/B = belly
for(var/mob/living/M in B)
new_people_eaten += M.size_multiplier
people_eaten = min(1, new_people_eaten)
/mob/living/silicon/pai/update_icon() //Some functions cause this to occur, such as resting
..()
update_fullness_pai()
@@ -43,114 +42,3 @@
icon_state = "[chassis]_full"
else if(people_eaten && resting)
icon_state = "[chassis]_rest_full"
/mob/living/silicon/pai/proc/examine_bellies_pai()
var/message = ""
for (var/I in src.vore_organs)
var/datum/belly/B = vore_organs[I]
message += B.get_examine_msg()
return message
//PAI Remove Limb code
/mob/living/silicon/pai/proc/shred_limb()
set name = "Damage/Remove Prey's Organ"
set desc = "Severely damages prey's organ. If the limb is already severely damaged, it will be torn off."
set category = "Abilities"
if(!ispAI(src))
return //If you're not a pai you don't have permission to do this.
var/mob/living/silicon/pai/C = src
if(last_special > world.time)
return
var/list/choices = list()
for(var/mob/living/carbon/human/M in view(1,src))
if(!istype(M,/mob/living/silicon) && Adjacent(M))
choices += M
choices -= src
var/mob/living/carbon/human/T = input(src,"Who do you wish to target?") as null|anything in choices
if(!T || !src || src.stat) return
if(!Adjacent(T)) return
if(last_special > world.time) return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot target in your current state."
return
var/list/choices2 = list()
for(var/obj/item/organ/O in T.organs) //External organs
choices2 += O
var/obj/item/organ/external/D = input(C,"What do you wish to severely damage?") as null|anything in choices2 //D for destroy.
if(D.vital)
if(alert("Are you sure you wish to severely damage their [D]? It most likely will kill the prey...",,"Yes", "No") != "Yes")
return //If they reconsider, don't continue.
var/list/choices3 = list()
for(var/obj/item/organ/internal/I in D.internal_organs) //Look for the internal organ in the organ being shreded.
choices3 += I
var/obj/item/organ/internal/P = input(C,"Do you wish to severely damage an internal organ, as well? If not, click 'cancel'") as null|anything in choices3
var/eat_limb = input(C,"Do you wish to swallow the organ if you tear if out? If so, select which stomach.") as null|anything in C.vore_organs //EXTREMELY EFFICIENT
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
to_chat(C, "You cannot shred in your current state.")
return
last_special = world.time + 450 //45 seconds.
C.visible_message("<font color='red'><b>[C] appears to be preparing to do something to [T]!</b></font>") //Let everyone know that bad times are head
if(do_after(C, 450, T)) //Fourty-Five seconds. You don't need a neckgrab for this, so it's going to take a long while.
if(!Adjacent(T)) return
if(P && P.damage >= 25) //Internal organ and it's been severely damage
T.apply_damage(15, BRUTE, D) //Damage the external organ they're going through.
P.removed()
P.forceMove(T.loc) //Move to where prey is.
log_and_message_admins("tore out [P] of [T].", C)
if(eat_limb)
var/datum/belly/S = C.vore_organs[eat_limb]
P.forceMove(C) //Move to pred's gut
S.internal_contents |= P //Add to pred's gut.
C.visible_message("<font color='red'><b>[C] severely damages [D] of [T]!</b></font>") // Same as below, but (pred) damages the (right hand) of (person)
to_chat(C, "[P] of [T] moves into your [S]!") //Quietly eat their internal organ! Comes out "The (right hand) of (person) moves into your (stomach)
playsound(C, S.vore_sound, 70, 1)
log_and_message_admins("tore out and ate [P] of [T].", C)
else
log_and_message_admins("tore out [P] of [T].", C)
C.visible_message("<font color='red'><b>[C] severely damages [D] of [T], resulting in their [P] coming out!</b></font>")
else if(!P && (D.damage >= 25 || D.brute_dam >= 25)) //Not targeting an internal organ & external organ has been severely damaged already.
D.droplimb(1,DROPLIMB_EDGE) //Clean cut so it doesn't kill the prey completely.
if(D.cannot_amputate) //Is it groin/chest? You can't remove those.
T.apply_damage(25, BRUTE, D)
C.visible_message("<font color='red'><b>[C] severely damage [T]'s [D]!</b></font>") //Keep it vague. Let the /me's do the talking.
log_and_message_admins("shreded [T]'s [D].", C)
return
if(eat_limb)
var/datum/belly/S = C.vore_organs[eat_limb]
D.forceMove(C) //Move to pred's gut
S.internal_contents |= D //Add to pred's gut.
C.visible_message("<span class='warning'>[C] swallows [D] of [T] into their [S]!</span>","You swallow [D] of [T]!")
playsound(C, S.vore_sound, 70, 1)
to_chat(C, "Their [D] moves into your [S]!")
log_and_message_admins("tore off and ate [D] of [T].", C)
else
C.visible_message("<span class='warning'>[C] tears off [D] of [T]!</span>","You tear out [D] of [T]!") //Will come out "You tear out (the right foot) of (person)
log_and_message_admins("tore off [T]'s [D].", C)
else //Not targeting an internal organ w/ > 25 damage , and the limb doesn't have < 25 damage.
if(P)
P.damage = 25 //Internal organs can only take damage, not brute damage.
T.apply_damage(25, BRUTE, D)
C.visible_message("<font color='red'><b>[C] severely damages [D] of [T]!</b></font>") //Keep it vague. Let the /me's do the talking.
log_and_message_admins("shreded [D] of [T].", C)

View File

@@ -527,15 +527,12 @@
hearer << deathsound
T << deathsound
if(is_vore_predator(T))
for (var/bellytype in T.vore_organs)
var/datum/belly/belly = T.vore_organs[bellytype]
for (var/obj/thing in belly.internal_contents)
thing.loc = src
belly.internal_contents -= thing
for (var/mob/subprey in belly.internal_contents)
subprey.loc = src
belly.internal_contents -= subprey
to_chat(subprey, "As [T] melts away around you, you find yourself in [hound]'s [name]")
for(var/belly in T.vore_organs)
var/obj/belly/B = belly
for(var/atom/movable/thing in B)
thing.forceMove(src)
if(ismob(thing))
to_chat(thing, "As [T] melts away around you, you find yourself in [hound]'s [name]")
for(var/obj/item/I in T)
if(istype(I,/obj/item/organ/internal/mmi_holder/posibrain))
var/obj/item/organ/internal/mmi_holder/MMI = I

View File

@@ -1,8 +1,8 @@
/mob/living/silicon/robot/proc/examine_bellies_borg()
var/message = ""
for (var/I in src.vore_organs)
var/datum/belly/B = vore_organs[I]
for(var/belly in vore_organs)
var/obj/belly/B = belly
message += B.get_examine_msg()
return message

View File

@@ -256,3 +256,9 @@
/mob/living/silicon/robot/put_in_hands(var/obj/item/W) // No hands.
W.loc = get_turf(src)
return 1
/mob/living/silicon/robot/is_holding_item_of_type(typepath)
for(var/obj/item/I in list(module_state_1, module_state_2, module_state_3))
if(istype(I, typepath))
return I
return FALSE

View File

@@ -24,7 +24,6 @@
process_killswitch()
process_locks()
process_queued_alarms()
handle_internal_contents() //VOREStation Edit
update_canmove()
/mob/living/silicon/robot/proc/clamp_values()

Some files were not shown because too many files have changed in this diff Show More