diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 9af84740ad8..9a687fb4421 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,4 +1,4 @@
-#### Brief description of the issue
+#### Brief description of the bug
#### What you expected to happen
diff --git a/code/ATMOSPHERICS/components/shutoff.dm b/code/ATMOSPHERICS/components/shutoff.dm
new file mode 100644
index 00000000000..de69f5e395e
--- /dev/null
+++ b/code/ATMOSPHERICS/components/shutoff.dm
@@ -0,0 +1,57 @@
+GLOBAL_LIST_EMPTY(shutoff_valves)
+
+/obj/machinery/atmospherics/valve/shutoff
+ icon = 'icons/atmos/clamp.dmi'
+ icon_state = "map_vclamp0"
+ pipe_state = "vclamp"
+
+ name = "automatic shutoff valve"
+ desc = "An automatic valve with control circuitry and pipe integrity sensor, capable of automatically isolating damaged segments of the pipe network."
+ var/close_on_leaks = TRUE // If false it will be always open
+ level = 1
+
+/obj/machinery/atmospherics/valve/shutoff/update_icon()
+ icon_state = "vclamp[open]"
+
+/obj/machinery/atmospherics/valve/shutoff/examine(var/mob/user)
+ ..()
+ to_chat(user, "The automatic shutoff circuit is [close_on_leaks ? "enabled" : "disabled"].")
+
+/obj/machinery/atmospherics/valve/shutoff/Initialize()
+ . = ..()
+ open()
+ GLOB.shutoff_valves += src
+ hide(1)
+
+/obj/machinery/atmospherics/valve/shutoff/Destroy()
+ GLOB.shutoff_valves -= src
+ ..()
+
+/obj/machinery/atmospherics/valve/shutoff/attack_ai(mob/user as mob)
+ return src.attack_hand(user)
+
+/obj/machinery/atmospherics/valve/shutoff/attack_hand(var/mob/user)
+ src.add_fingerprint(usr)
+ update_icon(1)
+ close_on_leaks = !close_on_leaks
+ to_chat(user, "You [close_on_leaks ? "enable" : "disable"] the automatic shutoff circuit.")
+ return TRUE
+
+/obj/machinery/atmospherics/valve/shutoff/process()
+ ..()
+
+ if (!network_node1 || !network_node2)
+ if(open)
+ close()
+ return
+
+ if (!close_on_leaks)
+ if (!open)
+ open()
+ return
+
+ if (network_node1.leaks.len || network_node2.leaks.len)
+ if (open)
+ close()
+ else if (!open)
+ open()
diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm
index ee1379ac288..61ace40879b 100644
--- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm
+++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm
@@ -1,4 +1,4 @@
-//Basically a one way passive valve. If the pressure inside is greater than the environment then gas will flow passively,
+//Basically a one way passive valve. If the pressure inside is greater than the environment then gas will flow passively,
//but it does not permit gas to flow back from the environment into the injector. Can be turned off to prevent any gas flow.
//When it receives the "inject" signal, it will try to pump it's entire contents into the environment regardless of pressure, using power.
@@ -13,7 +13,7 @@
use_power = 0
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 15000 //15000 W ~ 20 HP
-
+
var/injecting = 0
var/volume_rate = 50 //flow rate limit
@@ -26,7 +26,7 @@
/obj/machinery/atmospherics/unary/outlet_injector/New()
..()
- air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP + 500 //Give it a small reservoir for injecting. Also allows it to have a higher flow rate limit than vent pumps, to differentiate injectors a bit more.
+ air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP + 500 //Give it a small reservoir for injecting. Also allows it to have a higher flow rate limit than vent pumps, to differentiate injectors a bit more.
/obj/machinery/atmospherics/unary/outlet_injector/Destroy()
unregister_radio(src, frequency)
@@ -60,21 +60,21 @@
if((stat & (NOPOWER|BROKEN)) || !use_power)
return
-
+
var/power_draw = -1
var/datum/gas_mixture/environment = loc.return_air()
-
+
if(environment && air_contents.temperature > 0)
var/transfer_moles = (volume_rate/air_contents.volume)*air_contents.total_moles //apply flow rate limit
power_draw = pump_gas(src, air_contents, environment, transfer_moles, power_rating)
-
+
if (power_draw >= 0)
last_power_draw = power_draw
use_power(power_draw)
-
+
if(network)
network.update = 1
-
+
return 1
/obj/machinery/atmospherics/unary/outlet_injector/proc/inject()
@@ -84,7 +84,7 @@
var/datum/gas_mixture/environment = loc.return_air()
if (!environment)
return 0
-
+
injecting = 1
if(air_contents.temperature > 0)
@@ -155,4 +155,23 @@
update_icon()
/obj/machinery/atmospherics/unary/outlet_injector/hide(var/i)
- update_underlays()
\ No newline at end of file
+ update_underlays()
+
+/obj/machinery/atmospherics/unary/outlet_injector/attack_hand(mob/user as mob)
+ to_chat(user, "You toggle \the [src].")
+ injecting = !injecting
+ use_power = injecting
+ update_icon()
+
+/obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
+ if (!W.is_wrench())
+ return ..()
+
+ playsound(src, W.usesound, 50, 1)
+ to_chat(user, "You begin to unfasten \the [src]...")
+ if (do_after(user, 40 * W.toolspeed))
+ user.visible_message( \
+ "\The [user] unfastens \the [src].", \
+ "You have unfastened \the [src].", \
+ "You hear a ratchet.")
+ deconstruct()
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index ce2eb97e677..1f7414e17f1 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -16,7 +16,7 @@
desc = "Has a valve and pump attached to it"
use_power = 0
idle_power_usage = 150 //internal circuitry, friction losses and stuff
- power_rating = 7500 //7500 W ~ 10 HP
+ power_rating = 30000 //7500 W ~ 10 HP //VOREStation Edit - 30000 W
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY //connects to regular and supply pipes
@@ -89,7 +89,7 @@
/obj/machinery/atmospherics/unary/vent_pump/high_volume
name = "Large Air Vent"
power_channel = EQUIP
- power_rating = 15000 //15 kW ~ 20 HP
+ power_rating = 45000 //15 kW ~ 20 HP //VOREStation Edit - 45000
/obj/machinery/atmospherics/unary/vent_pump/high_volume/New()
..()
diff --git a/code/ATMOSPHERICS/datum_pipe_network.dm b/code/ATMOSPHERICS/datum_pipe_network.dm
index eb5e89276ef..a611e30a893 100644
--- a/code/ATMOSPHERICS/datum_pipe_network.dm
+++ b/code/ATMOSPHERICS/datum_pipe_network.dm
@@ -8,76 +8,83 @@ var/global/list/datum/pipe_network/pipe_networks = list() // TODO - Move into SS
var/list/datum/pipeline/line_members = list()
//membership roster to go through for updates and what not
+ var/list/leaks = list()
+
var/update = 1
//var/datum/gas_mixture/air_transient = null
- Destroy()
- STOP_PROCESSING_PIPENET(src)
- for(var/datum/pipeline/line_member in line_members)
- line_member.network = null
- for(var/obj/machinery/atmospherics/normal_member in normal_members)
- normal_member.reassign_network(src, null)
- gases.Cut() // Do not qdel the gases, we don't own them
- return ..()
+/datum/pipe_network/Destroy()
+ STOP_PROCESSING_PIPENET(src)
+ for(var/datum/pipeline/line_member in line_members)
+ line_member.network = null
+ for(var/obj/machinery/atmospherics/normal_member in normal_members)
+ normal_member.reassign_network(src, null)
+ gases.Cut() // Do not qdel the gases, we don't own them
+ leaks.Cut()
+ return ..()
- process()
- //Equalize gases amongst pipe if called for
- if(update)
- update = 0
- reconcile_air() //equalize_gases(gases)
+/datum/pipe_network/process()
+ //Equalize gases amongst pipe if called for
+ if(update)
+ update = 0
+ reconcile_air() //equalize_gases(gases)
- //Give pipelines their process call for pressure checking and what not. Have to remove pressure checks for the time being as pipes dont radiate heat - Mport
- //for(var/datum/pipeline/line_member in line_members)
- // line_member.process()
+ listclearnulls(leaks) // Let's not have forever-seals.
- proc/build_network(obj/machinery/atmospherics/start_normal, obj/machinery/atmospherics/reference)
- //Purpose: Generate membership roster
- //Notes: Assuming that members will add themselves to appropriate roster in network_expand()
+ //Give pipelines their process call for pressure checking and what not. Have to remove pressure checks for the time being as pipes dont radiate heat - Mport
+ //for(var/datum/pipeline/line_member in line_members)
+ // line_member.process()
- if(!start_normal)
- qdel(src)
- return
+/datum/pipe_network/proc/build_network(obj/machinery/atmospherics/start_normal, obj/machinery/atmospherics/reference)
+ //Purpose: Generate membership roster
+ //Notes: Assuming that members will add themselves to appropriate roster in network_expand()
- start_normal.network_expand(src, reference)
+ if(!start_normal)
+ qdel(src)
+ return
- update_network_gases()
+ start_normal.network_expand(src, reference)
- if((normal_members.len>0)||(line_members.len>0))
- START_PROCESSING_PIPENET(src)
- else
- qdel(src)
+ update_network_gases()
- proc/merge(datum/pipe_network/giver)
- if(giver==src) return 0
+ if((normal_members.len>0)||(line_members.len>0))
+ START_PROCESSING_PIPENET(src)
+ else
+ qdel(src)
- normal_members |= giver.normal_members
+/datum/pipe_network/proc/merge(datum/pipe_network/giver)
+ if(giver==src) return 0
- line_members |= giver.line_members
+ normal_members |= giver.normal_members
- for(var/obj/machinery/atmospherics/normal_member in giver.normal_members)
- normal_member.reassign_network(giver, src)
+ line_members |= giver.line_members
- for(var/datum/pipeline/line_member in giver.line_members)
- line_member.network = src
+ leaks |= giver.leaks
- update_network_gases()
- return 1
+ for(var/obj/machinery/atmospherics/normal_member in giver.normal_members)
+ normal_member.reassign_network(giver, src)
- proc/update_network_gases()
- //Go through membership roster and make sure gases is up to date
+ for(var/datum/pipeline/line_member in giver.line_members)
+ line_member.network = src
- gases = list()
- volume = 0
+ update_network_gases()
+ return 1
- for(var/obj/machinery/atmospherics/normal_member in normal_members)
- var/result = normal_member.return_network_air(src)
- if(result) gases += result
+/datum/pipe_network/proc/update_network_gases()
+ //Go through membership roster and make sure gases is up to date
- for(var/datum/pipeline/line_member in line_members)
- gases += line_member.air
+ gases = list()
+ volume = 0
- for(var/datum/gas_mixture/air in gases)
- volume += air.volume
+ for(var/obj/machinery/atmospherics/normal_member in normal_members)
+ var/result = normal_member.return_network_air(src)
+ if(result) gases += result
- proc/reconcile_air()
- equalize_gases(gases)
+ for(var/datum/pipeline/line_member in line_members)
+ gases += line_member.air
+
+ for(var/datum/gas_mixture/air in gases)
+ volume += air.volume
+
+/datum/pipe_network/proc/reconcile_air()
+ equalize_gases(gases)
diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm
index fc47bca9381..b53d722458b 100644
--- a/code/ATMOSPHERICS/datum_pipeline.dm
+++ b/code/ATMOSPHERICS/datum_pipeline.dm
@@ -1,219 +1,234 @@
-datum/pipeline
+/datum/pipeline
var/datum/gas_mixture/air
var/list/obj/machinery/atmospherics/pipe/members
var/list/obj/machinery/atmospherics/pipe/edges //Used for building networks
+ // Nodes that are leaking. Used for A.S. Valves.
+ var/list/leaks = list()
+
var/datum/pipe_network/network
var/alert_pressure = 0
- Destroy()
- QDEL_NULL(network)
+/datum/pipeline/Destroy()
+ QDEL_NULL(network)
- if(air && air.volume)
- temporarily_store_air()
- for(var/obj/machinery/atmospherics/pipe/P in members)
- P.parent = null
- members = null
- edges = null
- . = ..()
+ if(air && air.volume)
+ temporarily_store_air()
+ for(var/obj/machinery/atmospherics/pipe/P in members)
+ P.parent = null
+ members = null
+ edges = null
+ leaks = null
+ . = ..()
- process()//This use to be called called from the pipe networks
-
- //Check to see if pressure is within acceptable limits
- var/pressure = air.return_pressure()
- if(pressure > alert_pressure)
- for(var/obj/machinery/atmospherics/pipe/member in members)
- if(!member.check_pressure(pressure))
- break //Only delete 1 pipe per process
-
- proc/temporarily_store_air()
- //Update individual gas_mixtures by volume ratio
+/datum/pipeline/process()//This use to be called called from the pipe networks
+ //Check to see if pressure is within acceptable limits
+ var/pressure = air.return_pressure()
+ if(pressure > alert_pressure)
for(var/obj/machinery/atmospherics/pipe/member in members)
- member.air_temporary = new
- member.air_temporary.copy_from(air)
- member.air_temporary.volume = member.volume
- member.air_temporary.multiply(member.volume / air.volume)
+ if(!member.check_pressure(pressure))
+ break //Only delete 1 pipe per process
- proc/build_pipeline(obj/machinery/atmospherics/pipe/base)
+/datum/pipeline/proc/temporarily_store_air()
+ //Update individual gas_mixtures by volume ratio
+
+ for(var/obj/machinery/atmospherics/pipe/member in members)
+ member.air_temporary = new
+ member.air_temporary.copy_from(air)
+ member.air_temporary.volume = member.volume
+ member.air_temporary.multiply(member.volume / air.volume)
+
+/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/pipe/base)
+ air = new
+
+ var/list/possible_expansions = list(base)
+ members = list(base)
+ edges = list()
+
+ var/volume = base.volume
+ base.parent = src
+ alert_pressure = base.alert_pressure
+
+ if(base.air_temporary)
+ air = base.air_temporary
+ base.air_temporary = null
+ else
air = new
- var/list/possible_expansions = list(base)
- members = list(base)
- edges = list()
+ if(base.leaking)
+ leaks |= base
- var/volume = base.volume
- base.parent = src
- alert_pressure = base.alert_pressure
+ while(possible_expansions.len>0)
+ for(var/obj/machinery/atmospherics/pipe/borderline in possible_expansions)
- if(base.air_temporary)
- air = base.air_temporary
- base.air_temporary = null
- else
- air = new
+ var/list/result = borderline.pipeline_expansion()
+ var/edge_check = result.len
- while(possible_expansions.len>0)
- for(var/obj/machinery/atmospherics/pipe/borderline in possible_expansions)
+ if(result.len>0)
+ for(var/obj/machinery/atmospherics/pipe/item in result)
- var/list/result = borderline.pipeline_expansion()
- var/edge_check = result.len
+ if(item.in_stasis)
+ continue
- if(result.len>0)
- for(var/obj/machinery/atmospherics/pipe/item in result)
- if(!members.Find(item))
- members += item
- possible_expansions += item
+ if(!members.Find(item))
+ members += item
+ possible_expansions += item
- volume += item.volume
- item.parent = src
+ volume += item.volume
+ item.parent = src
- alert_pressure = min(alert_pressure, item.alert_pressure)
+ alert_pressure = min(alert_pressure, item.alert_pressure)
- if(item.air_temporary)
- air.merge(item.air_temporary)
+ if(item.air_temporary)
+ air.merge(item.air_temporary)
- edge_check--
+ if(item.leaking)
+ leaks |= item
- if(edge_check>0)
- edges += borderline
+ edge_check--
- possible_expansions -= borderline
+ if(edge_check>0)
+ edges += borderline
- air.volume = volume
+ possible_expansions -= borderline
- proc/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
+ air.volume = volume
- if(new_network.line_members.Find(src))
- return 0
+/datum/pipeline/proc/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
- new_network.line_members += src
+ if(new_network.line_members.Find(src))
+ return 0
- network = new_network
+ new_network.line_members += src
- for(var/obj/machinery/atmospherics/pipe/edge in edges)
- for(var/obj/machinery/atmospherics/result in edge.pipeline_expansion())
- if(!istype(result,/obj/machinery/atmospherics/pipe) && (result!=reference))
- result.network_expand(new_network, edge)
+ network = new_network
+ network.leaks |= leaks
- return 1
+ for(var/obj/machinery/atmospherics/pipe/edge in edges)
+ for(var/obj/machinery/atmospherics/result in edge.pipeline_expansion())
+ if(!istype(result,/obj/machinery/atmospherics/pipe) && (result!=reference))
+ result.network_expand(new_network, edge)
- proc/return_network(obj/machinery/atmospherics/reference)
- if(!network)
- network = new /datum/pipe_network()
- network.build_network(src, null)
- //technically passing these parameters should not be allowed
- //however pipe_network.build_network(..) and pipeline.network_extend(...)
- // were setup to properly handle this case
+ return 1
- return network
+/datum/pipeline/proc/return_network(obj/machinery/atmospherics/reference)
+ if(!network)
+ network = new /datum/pipe_network()
+ network.build_network(src, null)
+ //technically passing these parameters should not be allowed
+ //however pipe_network.build_network(..) and pipeline.network_extend(...)
+ // were setup to properly handle this case
- proc/mingle_with_turf(turf/simulated/target, mingle_volume)
- var/datum/gas_mixture/air_sample = air.remove_ratio(mingle_volume/air.volume)
- air_sample.volume = mingle_volume
+ return network
- if(istype(target) && target.zone)
- //Have to consider preservation of group statuses
- var/datum/gas_mixture/turf_copy = new
- var/datum/gas_mixture/turf_original = new
+/datum/pipeline/proc/mingle_with_turf(turf/simulated/target, mingle_volume)
+ var/datum/gas_mixture/air_sample = air.remove_ratio(mingle_volume/air.volume)
+ air_sample.volume = mingle_volume
- turf_copy.copy_from(target.zone.air)
- turf_copy.volume = target.zone.air.volume //Copy a good representation of the turf from parent group
- turf_original.copy_from(turf_copy)
+ if(istype(target) && target.zone)
+ //Have to consider preservation of group statuses
+ var/datum/gas_mixture/turf_copy = new
+ var/datum/gas_mixture/turf_original = new
- equalize_gases(list(air_sample, turf_copy))
- air.merge(air_sample)
+ turf_copy.copy_from(target.zone.air)
+ turf_copy.volume = target.zone.air.volume //Copy a good representation of the turf from parent group
+ turf_original.copy_from(turf_copy)
+
+ equalize_gases(list(air_sample, turf_copy))
+ air.merge(air_sample)
- target.zone.air.remove(turf_original.total_moles)
- target.zone.air.merge(turf_copy)
+ target.zone.air.remove(turf_original.total_moles)
+ target.zone.air.merge(turf_copy)
- else
- var/datum/gas_mixture/turf_air = target.return_air()
+ else
+ var/datum/gas_mixture/turf_air = target.return_air()
- equalize_gases(list(air_sample, turf_air))
- air.merge(air_sample)
- //turf_air already modified by equalize_gases()
+ equalize_gases(list(air_sample, turf_air))
+ air.merge(air_sample)
+ //turf_air already modified by equalize_gases()
- if(network)
- network.update = 1
+ if(network)
+ network.update = 1
- proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
- var/total_heat_capacity = air.heat_capacity()
- var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
+/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
+ var/total_heat_capacity = air.heat_capacity()
+ var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
- if(istype(target, /turf/simulated))
- var/turf/simulated/modeled_location = target
+ if(istype(target, /turf/simulated))
+ var/turf/simulated/modeled_location = target
- if(modeled_location.blocks_air)
+ if(modeled_location.blocks_air)
- if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
- var/delta_temperature = air.temperature - modeled_location.temperature
-
- var/heat = thermal_conductivity*delta_temperature* \
- (partial_heat_capacity*modeled_location.heat_capacity/(partial_heat_capacity+modeled_location.heat_capacity))
-
- air.temperature -= heat/total_heat_capacity
- modeled_location.temperature += heat/modeled_location.heat_capacity
-
- else
- var/delta_temperature = 0
- var/sharer_heat_capacity = 0
-
- if(modeled_location.zone)
- delta_temperature = (air.temperature - modeled_location.zone.air.temperature)
- sharer_heat_capacity = modeled_location.zone.air.heat_capacity()
- else
- delta_temperature = (air.temperature - modeled_location.air.temperature)
- sharer_heat_capacity = modeled_location.air.heat_capacity()
-
- var/self_temperature_delta = 0
- var/sharer_temperature_delta = 0
-
- if((sharer_heat_capacity>0) && (partial_heat_capacity>0))
- var/heat = thermal_conductivity*delta_temperature* \
- (partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity))
-
- self_temperature_delta = -heat/total_heat_capacity
- sharer_temperature_delta = heat/sharer_heat_capacity
- else
- return 1
-
- air.temperature += self_temperature_delta
-
- if(modeled_location.zone)
- modeled_location.zone.air.temperature += sharer_temperature_delta/modeled_location.zone.air.group_multiplier
- else
- modeled_location.air.temperature += sharer_temperature_delta
-
-
- else
- if((target.heat_capacity>0) && (partial_heat_capacity>0))
- var/delta_temperature = air.temperature - target.temperature
+ if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
+ var/delta_temperature = air.temperature - modeled_location.temperature
var/heat = thermal_conductivity*delta_temperature* \
- (partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
+ (partial_heat_capacity*modeled_location.heat_capacity/(partial_heat_capacity+modeled_location.heat_capacity))
air.temperature -= heat/total_heat_capacity
- if(network)
- network.update = 1
+ modeled_location.temperature += heat/modeled_location.heat_capacity
- //surface must be the surface area in m^2
- proc/radiate_heat_to_space(surface, thermal_conductivity)
- var/gas_density = air.total_moles/air.volume
- thermal_conductivity *= min(gas_density / ( RADIATOR_OPTIMUM_PRESSURE/(R_IDEAL_GAS_EQUATION*GAS_CRITICAL_TEMPERATURE) ), 1) //mult by density ratio
+ else
+ var/delta_temperature = 0
+ var/sharer_heat_capacity = 0
- // We only get heat from the star on the exposed surface area.
- // If the HE pipes gain more energy from AVERAGE_SOLAR_RADIATION than they can radiate, then they have a net heat increase.
- var/heat_gain = AVERAGE_SOLAR_RADIATION * (RADIATOR_EXPOSED_SURFACE_AREA_RATIO * surface) * thermal_conductivity
+ if(modeled_location.zone)
+ delta_temperature = (air.temperature - modeled_location.zone.air.temperature)
+ sharer_heat_capacity = modeled_location.zone.air.heat_capacity()
+ else
+ delta_temperature = (air.temperature - modeled_location.air.temperature)
+ sharer_heat_capacity = modeled_location.air.heat_capacity()
- // Previously, the temperature would enter equilibrium at 26C or 294K.
- // Only would happen if both sides (all 2 square meters of surface area) were exposed to sunlight. We now assume it aligned edge on.
- // It currently should stabilise at 129.6K or -143.6C
- heat_gain -= surface * STEFAN_BOLTZMANN_CONSTANT * thermal_conductivity * (air.temperature - COSMIC_RADIATION_TEMPERATURE) ** 4
+ var/self_temperature_delta = 0
+ var/sharer_temperature_delta = 0
- air.add_thermal_energy(heat_gain)
- if(network)
- network.update = 1
+ if((sharer_heat_capacity>0) && (partial_heat_capacity>0))
+ var/heat = thermal_conductivity*delta_temperature* \
+ (partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity))
+
+ self_temperature_delta = -heat/total_heat_capacity
+ sharer_temperature_delta = heat/sharer_heat_capacity
+ else
+ return 1
+
+ air.temperature += self_temperature_delta
+
+ if(modeled_location.zone)
+ modeled_location.zone.air.temperature += sharer_temperature_delta/modeled_location.zone.air.group_multiplier
+ else
+ modeled_location.air.temperature += sharer_temperature_delta
+
+
+ else
+ if((target.heat_capacity>0) && (partial_heat_capacity>0))
+ var/delta_temperature = air.temperature - target.temperature
+
+ var/heat = thermal_conductivity*delta_temperature* \
+ (partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
+
+ air.temperature -= heat/total_heat_capacity
+ if(network)
+ network.update = 1
+
+//surface must be the surface area in m^2
+/datum/pipeline/proc/radiate_heat_to_space(surface, thermal_conductivity)
+ var/gas_density = air.total_moles/air.volume
+ thermal_conductivity *= min(gas_density / ( RADIATOR_OPTIMUM_PRESSURE/(R_IDEAL_GAS_EQUATION*GAS_CRITICAL_TEMPERATURE) ), 1) //mult by density ratio
+
+ // We only get heat from the star on the exposed surface area.
+ // If the HE pipes gain more energy from AVERAGE_SOLAR_RADIATION than they can radiate, then they have a net heat increase.
+ var/heat_gain = AVERAGE_SOLAR_RADIATION * (RADIATOR_EXPOSED_SURFACE_AREA_RATIO * surface) * thermal_conductivity
+
+ // Previously, the temperature would enter equilibrium at 26C or 294K.
+ // Only would happen if both sides (all 2 square meters of surface area) were exposed to sunlight. We now assume it aligned edge on.
+ // It currently should stabilise at 129.6K or -143.6C
+ heat_gain -= surface * STEFAN_BOLTZMANN_CONSTANT * thermal_conductivity * (air.temperature - COSMIC_RADIATION_TEMPERATURE) ** 4
+
+ air.add_thermal_energy(heat_gain)
+ if(network)
+ network.update = 1
diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm
index a03ce16af55..1e32aa62952 100644
--- a/code/ATMOSPHERICS/pipes/cap.dm
+++ b/code/ATMOSPHERICS/pipes/cap.dm
@@ -54,7 +54,7 @@
alpha = 255
overlays.Cut()
- overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap")
+ overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap[icon_connect_type]")
/obj/machinery/atmospherics/pipe/cap/atmos_init()
for(var/obj/machinery/atmospherics/target in get_step(src, dir))
diff --git a/code/ATMOSPHERICS/pipes/he_pipes.dm b/code/ATMOSPHERICS/pipes/he_pipes.dm
index 2d77e3a4ca9..1b283e3ba4d 100644
--- a/code/ATMOSPHERICS/pipes/he_pipes.dm
+++ b/code/ATMOSPHERICS/pipes/he_pipes.dm
@@ -67,8 +67,22 @@
return
update_icon()
+ handle_leaking()
return
+/obj/machinery/atmospherics/pipe/simple/heat_exchanging/set_leaking(var/new_leaking) // They already process, no need for manual processing toggles.
+ if(new_leaking && !leaking)
+ leaking = TRUE
+ if(parent)
+ parent.leaks |= src
+ if(parent.network)
+ parent.network.leaks |= src
+ else if (!new_leaking && leaking)
+ leaking = FALSE
+ if(parent)
+ parent.leaks -= src
+ if(parent.network)
+ parent.network.leaks -= src
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process()
if(!parent)
@@ -180,4 +194,5 @@
return
update_icon()
+ handle_leaking()
return
diff --git a/code/ATMOSPHERICS/pipes/he_pipes_vr.dm b/code/ATMOSPHERICS/pipes/he_pipes_vr.dm
new file mode 100644
index 00000000000..d763f75b74c
--- /dev/null
+++ b/code/ATMOSPHERICS/pipes/he_pipes_vr.dm
@@ -0,0 +1,2 @@
+/obj/machinery/atmospherics/pipe/simple/heat_exchanging/set_leaking(var/new_leaking)
+ return //Nope
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm
index 524d420d392..f44bfc56866 100644
--- a/code/ATMOSPHERICS/pipes/manifold.dm
+++ b/code/ATMOSPHERICS/pipes/manifold.dm
@@ -68,9 +68,24 @@
node3 = null
update_icon()
+ handle_leaking()
..()
+/obj/machinery/atmospherics/pipe/manifold/handle_leaking()
+ if(node1 && node2 && node3)
+ set_leaking(FALSE)
+ else
+ set_leaking(TRUE)
+
+/obj/machinery/atmospherics/pipe/manifold/process()
+ if(!parent)
+ ..()
+ else if(leaking)
+ parent.mingle_with_turf(loc, volume)
+ else
+ . = PROCESS_KILL
+
/obj/machinery/atmospherics/pipe/manifold/change_color(var/new_color)
..()
//for updating connected atmos device pipes (i.e. vents, manifolds, etc)
@@ -154,6 +169,7 @@
var/turf/T = get_turf(src)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
+ handle_leaking()
/obj/machinery/atmospherics/pipe/manifold/visible
icon_state = "map"
diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm
index 0cc022423b1..197c1a090b7 100644
--- a/code/ATMOSPHERICS/pipes/manifold4w.dm
+++ b/code/ATMOSPHERICS/pipes/manifold4w.dm
@@ -66,9 +66,24 @@
node4 = null
update_icon()
+ handle_leaking()
..()
+/obj/machinery/atmospherics/pipe/manifold4w/handle_leaking()
+ if(node1 && node2 && node3 && node4)
+ set_leaking(FALSE)
+ else
+ set_leaking(TRUE)
+
+/obj/machinery/atmospherics/pipe/manifold4w/process()
+ if(!parent)
+ ..()
+ else if(leaking)
+ parent.mingle_with_turf(loc, volume)
+ else
+ . = PROCESS_KILL
+
/obj/machinery/atmospherics/pipe/manifold4w/change_color(var/new_color)
..()
//for updating connected atmos device pipes (i.e. vents, manifolds, etc)
@@ -156,6 +171,7 @@
var/turf/T = get_turf(src)
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
+ handle_leaking()
/obj/machinery/atmospherics/pipe/manifold4w/visible
icon_state = "map_4way"
diff --git a/code/ATMOSPHERICS/pipes/pipe_base.dm b/code/ATMOSPHERICS/pipes/pipe_base.dm
index a035857e549..d1bb92fac77 100644
--- a/code/ATMOSPHERICS/pipes/pipe_base.dm
+++ b/code/ATMOSPHERICS/pipes/pipe_base.dm
@@ -6,6 +6,7 @@
var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke
var/datum/pipeline/parent
var/volume = 0
+ var/leaking = FALSE // Do not set directly, use set_leaking(TRUE/FALSE)
layer = PIPES_LAYER
use_power = 0
@@ -13,6 +14,7 @@
pipe_flags = 0 // Does not have PIPING_DEFAULT_LAYER_ONLY flag.
var/alert_pressure = 80*ONE_ATMOSPHERE
+ var/in_stasis = FALSE
//minimum pressure before check_pressure(...) should be called
can_buckle = 1
@@ -30,6 +32,31 @@
/obj/machinery/atmospherics/pipe/hides_under_flooring()
return level != 2
+/obj/machinery/atmospherics/pipe/proc/set_leaking(var/new_leaking)
+ if(new_leaking && !leaking)
+ if(!speed_process)
+ START_MACHINE_PROCESSING(src)
+ else
+ START_PROCESSING(SSfastprocess, src)
+ leaking = TRUE
+ if(parent)
+ parent.leaks |= src
+ if(parent.network)
+ parent.network.leaks |= src
+ else if (!new_leaking && leaking)
+ if(!speed_process)
+ STOP_MACHINE_PROCESSING(src)
+ else
+ STOP_PROCESSING(SSfastprocess, src)
+ leaking = FALSE
+ if(parent)
+ parent.leaks -= src
+ if(parent.network)
+ parent.network.leaks -= src
+
+/obj/machinery/atmospherics/pipe/proc/handle_leaking() // Used specifically to update leaking status on different pipes.
+ return
+
/obj/machinery/atmospherics/pipe/proc/pipeline_expansion()
return null
diff --git a/code/ATMOSPHERICS/pipes/pipe_base_vr.dm b/code/ATMOSPHERICS/pipes/pipe_base_vr.dm
new file mode 100644
index 00000000000..d20e73ae89f
--- /dev/null
+++ b/code/ATMOSPHERICS/pipes/pipe_base_vr.dm
@@ -0,0 +1,2 @@
+/obj/machinery/atmospherics/pipe/set_leaking(var/new_leaking)
+ return // N O P E
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm
index 6aee81807e8..eb980c3b476 100644
--- a/code/ATMOSPHERICS/pipes/simple.dm
+++ b/code/ATMOSPHERICS/pipes/simple.dm
@@ -1,6 +1,6 @@
//
// Simple Pipes - Just a tube, maybe bent
-//
+//
/obj/machinery/atmospherics/pipe/simple
icon = 'icons/atmos/pipes.dmi'
icon_state = ""
@@ -34,6 +34,14 @@
icon = null
alpha = 255
+/obj/machinery/atmospherics/pipe/simple/process()
+ if(!parent)
+ ..()
+ else if(leaking)
+ parent.mingle_with_turf(loc, volume)
+ else
+ . = PROCESS_KILL
+
/obj/machinery/atmospherics/pipe/simple/check_pressure(pressure)
var/datum/gas_mixture/environment = loc.return_air()
@@ -147,6 +155,7 @@
var/turf/T = loc
if(level == 1 && !T.is_plating()) hide(1)
update_icon()
+ handle_leaking()
/obj/machinery/atmospherics/pipe/simple/disconnect(obj/machinery/atmospherics/reference)
if(reference == node1)
@@ -160,9 +169,16 @@
node2 = null
update_icon()
+ handle_leaking()
return null
+/obj/machinery/atmospherics/pipe/simple/handle_leaking()
+ if(node1 && node2)
+ set_leaking(FALSE)
+ else
+ set_leaking(TRUE)
+
/obj/machinery/atmospherics/pipe/simple/visible
icon_state = "intact"
level = 2
diff --git a/code/ATMOSPHERICS/pipes/universal.dm b/code/ATMOSPHERICS/pipes/universal.dm
index 2d8bd09dff8..00d2746947a 100644
--- a/code/ATMOSPHERICS/pipes/universal.dm
+++ b/code/ATMOSPHERICS/pipes/universal.dm
@@ -48,7 +48,7 @@
construction_type = /obj/item/pipe/binary
pipe_state = "universal"
-/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0)
+/obj/machinery/atmospherics/pipe/simple/hidden/universal/update_icon(var/safety = 0) // Doesn't leak. It's a special pipe.
if(!check_icon_cache())
return
diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm
index b7ab1999f03..6ffec0be995 100644
--- a/code/ZAS/Phoron.dm
+++ b/code/ZAS/Phoron.dm
@@ -47,6 +47,12 @@ obj/var/contaminated = 0
return 0
else if(istype(src,/obj/item/weapon/storage/backpack))
return 0 //Cannot be washed :(
+ //VOREStation Addition start
+ else if(isbelly(loc))
+ return 0
+ else if(ismob(loc) && isbelly(loc.loc))
+ return 0
+ //VOREStation Addition end
else if(istype(src,/obj/item/clothing))
return 1
diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm
index 9692409d458..c87b9942dfc 100644
--- a/code/__defines/damage_organs.dm
+++ b/code/__defines/damage_organs.dm
@@ -8,6 +8,7 @@
#define HALLOSS "halloss"
#define ELECTROCUTE "electrocute"
#define BIOACID "bioacid"
+#define SEARING "searing"
#define CUT "cut"
#define BRUISE "bruise"
diff --git a/code/__defines/lighting_vr.dm b/code/__defines/lighting_vr.dm
new file mode 100644
index 00000000000..0cd6b060a17
--- /dev/null
+++ b/code/__defines/lighting_vr.dm
@@ -0,0 +1,2 @@
+#define LIGHT_COLOR_INCANDESCENT_TUBE "#E0EFF0"
+#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8"
\ No newline at end of file
diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm
index 48babcae96a..43937e0cbe5 100644
--- a/code/__defines/machinery.dm
+++ b/code/__defines/machinery.dm
@@ -34,6 +34,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define NETWORK_CRESCENT "Spaceport"
// #define NETWORK_CAFE_DOCK "Cafe Dock"
#define NETWORK_CARGO "Cargo"
+#define NETWORK_CIRCUITS "Circuits"
#define NETWORK_CIVILIAN "Civilian"
// #define NETWORK_CIVILIAN_EAST "Civilian East"
// #define NETWORK_CIVILIAN_WEST "Civilian West"
@@ -54,7 +55,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define NETWORK_SECURITY "Security"
#define NETWORK_INTERROGATION "Interrogation"
#define NETWORK_TELECOM "Tcomms"
-#define NETWORK_THUNDER "Thunderdome"
+#define NETWORK_THUNDER "Entertainment" //VOREStation Edit: broader definition
#define NETWORK_COMMUNICATORS "Communicators"
#define NETWORK_ALARM_ATMOS "Atmosphere Alarms"
#define NETWORK_ALARM_POWER "Power Alarms"
@@ -109,7 +110,7 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret
#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged
#define SUPERMATTER_DANGER 4 // Integrity < 50%
#define SUPERMATTER_EMERGENCY 5 // Integrity < 25%
-#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.
+#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.
//wIP - PORT ALL OF THESE TO SUBSYSTEMS AND GET RID OF THE WHOLE LIST PROCESS THING
// Fancy-pants START/STOP_PROCESSING() macros that lets us custom define what the list is.
diff --git a/code/__defines/map.dm b/code/__defines/map.dm
index 7d0f3706aff..fce63b9955c 100644
--- a/code/__defines/map.dm
+++ b/code/__defines/map.dm
@@ -9,4 +9,4 @@
#define MAP_LEVEL_XENOARCH_EXEMPT 0x080 // Z-levels exempt from xenoarch digsite generation.
// Misc map defines.
-#define SUBMAP_MAP_EDGE_PAD 15 // Automatically created submaps are forbidden from being this close to the main map's edge.
\ No newline at end of file
+#define SUBMAP_MAP_EDGE_PAD 8 // Automatically created submaps are forbidden from being this close to the main map's edge. //VOREStation Edit
\ No newline at end of file
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 2dc4afe70aa..7f7e9e705ef 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -175,6 +175,7 @@
#define MAT_LEAD "lead"
#define MAT_SUPERMATTER "supermatter"
#define MAT_METALHYDROGEN "mhydrogen"
+#define MAT_OSMIUM "osmium"
#define SHARD_SHARD "shard"
#define SHARD_SHRAPNEL "shrapnel"
diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index 8426edcfcfe..efb94d49631 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -210,13 +210,17 @@
#define O_GBLADDER "gas bladder"
#define O_POLYP "polyp segment"
#define O_ANCHOR "anchoring ligament"
+#define O_REGBRUTE "pneumoregenitor"
+#define O_REGBURN "thermoregenitor"
+#define O_REGOXY "respiroregenitor"
+#define O_REGTOX "toxoregenitor"
#define O_ACID "acid gland"
#define O_EGG "egg sac"
#define O_RESIN "resin spinner"
#define O_AREJECT "immune hub"
#define O_VENTC "morphoplastic node"
#define O_VRLINK "virtual node"
-#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_ACID, O_EGG, O_RESIN, O_AREJECT, O_VENTC, O_VRLINK)
+#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_REGBRUTE, O_REGBURN, O_REGOXY, O_REGTOX, O_ACID, O_EGG, O_RESIN, O_AREJECT, O_VENTC, O_VRLINK)
// External organs, aka limbs
#define BP_L_FOOT "l_foot"
diff --git a/code/__defines/species_languages_vr.dm b/code/__defines/species_languages_vr.dm
index 224478646db..1004c1e22c1 100644
--- a/code/__defines/species_languages_vr.dm
+++ b/code/__defines/species_languages_vr.dm
@@ -1,3 +1,5 @@
+#define SPECIES_WHITELIST_SELECTABLE 0x20 // Can select and customize, but not join as
+
#define LANGUAGE_BIRDSONG "Birdsong"
#define LANGUAGE_SAGARU "Sagaru"
#define LANGUAGE_CANILUNZT "Canilunzt"
diff --git a/code/__defines/xenoarcheaology.dm b/code/__defines/xenoarcheaology.dm
index 45e40cfbdeb..8a4988b78c0 100644
--- a/code/__defines/xenoarcheaology.dm
+++ b/code/__defines/xenoarcheaology.dm
@@ -36,7 +36,8 @@
#define ARCHAEO_ALIEN_ITEM 36
#define ARCHAEO_ALIEN_BOAT 37
#define ARCHAEO_IMPERION_CIRCUIT 38
-#define MAX_ARCHAEO 38
+#define ARCHAEO_TELECUBE 39
+#define MAX_ARCHAEO 39
#define DIGSITE_GARDEN 1
#define DIGSITE_ANIMAL 2
diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm
index 4618bb536df..846291edc46 100644
--- a/code/_helpers/global_lists_vr.dm
+++ b/code/_helpers/global_lists_vr.dm
@@ -11,6 +11,8 @@ var/global/list/positive_traits = list() // Positive custom species traits, inde
var/global/list/traits_costs = list() // Just path = cost list, saves time in char setup
var/global/list/all_traits = list() // All of 'em at once (same instances)
+var/global/list/sensorpreflist = list("Off", "Binary", "Vitals", "Tracking", "No Preference") //TFF 5/8/19 - Suit Sensors global list
+
var/global/list/custom_species_bases = list() // Species that can be used for a Custom Species icon base
//stores numeric player size options indexed by name
@@ -121,6 +123,7 @@ var/global/list/tf_vore_egg_types = list(
"Xenomorph" = /obj/structure/closet/secure_closet/egg/xenomorph)
var/global/list/edible_trash = list(/obj/item/broken_device,
+ /obj/item/clothing/accessory/collar, //TFF 10/7/19 - add option to nom collars,
/obj/item/clothing/mask,
/obj/item/clothing/glasses,
/obj/item/clothing/gloves,
diff --git a/code/_helpers/icons_vr.dm b/code/_helpers/icons_vr.dm
index be5de68e82d..60765578e71 100644
--- a/code/_helpers/icons_vr.dm
+++ b/code/_helpers/icons_vr.dm
@@ -42,4 +42,18 @@
for(var/x_pixel = 1 to I.Width())
if (I.GetPixel(x_pixel, y_pixel))
return y_pixel - 1
- return null
\ No newline at end of file
+ return null
+
+//Standard behaviour is to cut pixels from the main icon that are covered by pixels from the mask icon unless passed mask_ready, see below.
+/proc/get_icon_difference(var/icon/main, var/icon/mask, var/mask_ready)
+ /*You should skip prep if the mask is already sprited properly. This significantly improves performance by eliminating most of the realtime icon work.
+ e.g. A 'ready' mask is a mask where the part you want cut out is missing (no pixels, 0 alpha) from the sprite, and everything else is solid white.*/
+
+ if(istype(main) && istype(mask))
+ if(!mask_ready) //Prep the mask if we're using a regular old sprite and not a special-made mask.
+ mask.Blend(rgb(255,255,255), ICON_SUBTRACT) //Make all pixels on the mask as black as possible.
+ mask.Opaque(rgb(255,255,255)) //Make the transparent pixels (background) white.
+ mask.BecomeAlphaMask() //Make all the black pixels vanish (fully transparent), leaving only the white background pixels.
+
+ main.AddAlphaMask(mask) //Make the pixels in the main icon that are in the transparent zone of the mask icon also vanish (fully transparent).
+ return main
diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index 96c97ec9f6a..220f896436c 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -235,6 +235,12 @@ Proc for attack log creation, because really why not
var/atom/original_loc = user.loc
+ var/obj/mecha/M = null
+
+ if(istype(user.loc, /obj/mecha))
+ original_loc = get_turf(original_loc)
+ M = user.loc
+
var/holding = user.get_active_hand()
var/datum/progressbar/progbar
@@ -253,7 +259,12 @@ Proc for attack log creation, because really why not
. = FALSE
break
- if(user.loc != original_loc && !ignore_movement)
+ if(M)
+ if(user.loc != M || (M.loc != original_loc && !ignore_movement)) // Mech coooooode.
+ . = FALSE
+ break
+
+ else if(user.loc != original_loc && !ignore_movement)
. = FALSE
break
diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm
index 0343fe42498..eb363c08cb3 100644
--- a/code/_helpers/text.dm
+++ b/code/_helpers/text.dm
@@ -84,7 +84,6 @@
// 0 .. 9
if(48 to 57) //Numbers
- if(!last_char_group) continue //suppress at start of string
if(!allow_numbers) continue // If allow_numbers is 0, then don't do this.
output += ascii2text(ascii_char)
number_of_alphanumeric++
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 643ab6d7905..6cde2645660 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -114,6 +114,19 @@
trigger_aiming(TARGET_CAN_CLICK)
return 1
+ // VOREStation Addition Start: inbelly item interaction
+ if(isbelly(loc) && (loc == A.loc))
+ if(W)
+ var/resolved = W.resolve_attackby(A,src)
+ if(!resolved && A && W)
+ W.afterattack(A, src, 1, params) // 1: clicking something Adjacent
+ else
+ if(ismob(A)) // No instant mob attacking
+ setClickCooldown(get_attack_speed())
+ UnarmedAttack(A, 1)
+ return
+ // VOREStation Addition End
+
if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that
return
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index e367769b077..3bd1a0afb2d 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -2,6 +2,9 @@
/atom/proc/attack_generic(mob/user as mob)
return 0
+/atom/proc/take_damage(var/damage)
+ return 0
+
/*
Humans:
Adds an exception for gloves, to allow special glove types like the ninja ones.
diff --git a/code/controllers/subsystems/garbage.dm b/code/controllers/subsystems/garbage.dm
index a741869b5b3..9938fa20eb0 100644
--- a/code/controllers/subsystems/garbage.dm
+++ b/code/controllers/subsystems/garbage.dm
@@ -240,9 +240,9 @@ SUBSYSTEM_DEF(garbage)
time = TICK_DELTA_TO_MS(tick)/100
if (time > highest_del_time)
highest_del_time = time
- if (time > 10)
- log_game("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete)")
- message_admins("Error: [type]([refID]) took longer than 1 second to delete (took [time/10] seconds to delete).")
+ if (time > 20) //VOREStation Edit
+ log_game("Error: [type]([refID]) took longer than 2 seconds to delete (took [time/10] seconds to delete)") //VOREStation Edit
+ message_admins("Error: [type]([refID]) took longer than 2 seconds to delete (took [time/10] seconds to delete).") //VOREStation Edit
postpone(time)
/datum/controller/subsystem/garbage/proc/HardQueue(datum/D)
diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm
index a049a4456ca..91c9ec37b7a 100644
--- a/code/datums/autolathe/autolathe.dm
+++ b/code/datums/autolathe/autolathe.dm
@@ -8,9 +8,12 @@ var/datum/category_collection/autolathe/autolathe_recipes
for(var/material in I.matter)
var/coeff = (no_scale ? 1 : 1.25) //most objects are more expensive to produce than to recycle
resources[material] = I.matter[material]*coeff // but if it's a sheet or RCD cartridge, it's 1:1
- if(is_stack && istype(I, /obj/item/stack))
- var/obj/item/stack/IS = I
- max_stack = IS.max_amount
+ if(is_stack)
+ if(istype(I, /obj/item/stack))
+ var/obj/item/stack/IS = I
+ max_stack = IS.max_amount
+ else
+ max_stack = 10
qdel(I)
/****************************
@@ -65,7 +68,7 @@ var/datum/category_collection/autolathe/autolathe_recipes
var/list/resources
var/hidden
var/power_use = 0
- var/is_stack
+ var/is_stack // Creates multiple of an item if applied to non-stack items
var/max_stack
var/no_scale
diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm
index 2e2fa3c6fba..2f4436bf55b 100644
--- a/code/datums/autolathe/general.dm
+++ b/code/datums/autolathe/general.dm
@@ -105,10 +105,12 @@
/datum/category_item/autolathe/general/tube
name = "light tube"
path =/obj/item/weapon/light/tube
+ is_stack = TRUE
/datum/category_item/autolathe/general/bulb
name = "light bulb"
path =/obj/item/weapon/light/bulb
+ is_stack = TRUE
/datum/category_item/autolathe/general/ashtray_glass
name = "glass ashtray"
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 541ba771942..089a6be7224 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -205,7 +205,7 @@
if(telemob.can_be_drop_prey && telenommer.can_be_drop_pred)
return 1
obstructed = 1
- else if(!isturf(destination.loc) || !destination.x || !destination.y || !destination.z) //If we're inside something or outside universe
+ else if(!((isturf(destination) && !destination.density) || (isturf(destination.loc) && !destination.loc.density)) || !destination.x || !destination.y || !destination.z) //If we're inside something or outside universe
obstructed = 1
to_chat(teleatom, "Something is blocking way on the other side!")
if(obstructed)
diff --git a/code/datums/helper_datums/teleport_vr.dm b/code/datums/helper_datums/teleport_vr.dm
index b3054a44c09..d8e84285358 100644
--- a/code/datums/helper_datums/teleport_vr.dm
+++ b/code/datums/helper_datums/teleport_vr.dm
@@ -1,5 +1,5 @@
//wrapper
-/proc/do_noeffect_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, local=TRUE)
+/proc/do_noeffect_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, local=FALSE)
new /datum/teleport/instant/science/noeffect(arglist(args))
return
diff --git a/code/datums/outfits/military/fleet.dm b/code/datums/outfits/military/fleet.dm
index cf5028978d0..915917918cf 100644
--- a/code/datums/outfits/military/fleet.dm
+++ b/code/datums/outfits/military/fleet.dm
@@ -1,21 +1,21 @@
/decl/hierarchy/outfit/military/fleet/pt
name = OUTFIT_MILITARY("Fleet PT")
- uniform = /obj/item/clothing/under/pt/fleet
+ uniform = /obj/item/clothing/under/solgov/pt/fleet
shoes = /obj/item/clothing/shoes/black
/decl/hierarchy/outfit/military/fleet/utility
name = OUTFIT_MILITARY("Fleet Utility")
- uniform = /obj/item/clothing/under/utility/fleet
- shoes = /obj/item/clothing/shoes/boots/jackboots
+ uniform = /obj/item/clothing/under/solgov/utility/fleet
+ shoes = /obj/item/clothing/shoes/boots/duty
/decl/hierarchy/outfit/military/fleet/service
name = OUTFIT_MILITARY("Fleet Service")
- uniform = /obj/item/clothing/under/service/fleet
+ uniform = /obj/item/clothing/under/solgov/service/fleet
shoes = /obj/item/clothing/shoes/dress/white
/decl/hierarchy/outfit/military/fleet/dress
name = OUTFIT_MILITARY("Fleet Dress")
- uniform = /obj/item/clothing/under/service/fleet
+ uniform = /obj/item/clothing/under/solgov/service/fleet
shoes = /obj/item/clothing/shoes/dress/white
suit = /obj/item/clothing/suit/storage/toggle/dress/fleet
gloves = /obj/item/clothing/gloves/white
diff --git a/code/datums/outfits/military/marines.dm b/code/datums/outfits/military/marines.dm
index d818dabcaaa..719b36c6909 100644
--- a/code/datums/outfits/military/marines.dm
+++ b/code/datums/outfits/military/marines.dm
@@ -1,22 +1,22 @@
/decl/hierarchy/outfit/military/marine/pt
name = OUTFIT_MILITARY("Marine PT")
- uniform = /obj/item/clothing/under/pt/marine
+ uniform = /obj/item/clothing/under/solgov/pt/marine
shoes = /obj/item/clothing/shoes/black
/decl/hierarchy/outfit/military/marine/utility
name = OUTFIT_MILITARY("Marine Utility")
- uniform = /obj/item/clothing/under/utility/marine
+ uniform = /obj/item/clothing/under/solgov/utility/marine
shoes = /obj/item/clothing/shoes/boots/jungle
/decl/hierarchy/outfit/military/marine/service
name = OUTFIT_MILITARY("Marine Service")
- uniform = /obj/item/clothing/under/service/marine
+ uniform = /obj/item/clothing/under/solgov/service/marine
shoes = /obj/item/clothing/shoes/dress
suit = /obj/item/clothing/suit/storage/service/marine
/decl/hierarchy/outfit/military/marine/dress
name = OUTFIT_MILITARY("Marine Dress")
- uniform = /obj/item/clothing/under/mildress/marine
+ uniform = /obj/item/clothing/under/solgov/mildress/marine
shoes = /obj/item/clothing/shoes/dress/white
suit = /obj/item/clothing/suit/dress/marine
gloves = /obj/item/clothing/gloves/white
diff --git a/code/datums/outfits/military/sifguard.dm b/code/datums/outfits/military/sifguard.dm
index e1280f0cfed..9348224a9eb 100644
--- a/code/datums/outfits/military/sifguard.dm
+++ b/code/datums/outfits/military/sifguard.dm
@@ -1,22 +1,22 @@
/decl/hierarchy/outfit/military/sifguard/pt
name = OUTFIT_MILITARY("SifGuard PT")
- uniform = /obj/item/clothing/under/pt/sifguard
+ uniform = /obj/item/clothing/under/solgov/pt/sifguard
shoes = /obj/item/clothing/shoes/black
/decl/hierarchy/outfit/military/sifguard/utility
name = OUTFIT_MILITARY("SifGuard Utility")
- uniform = /obj/item/clothing/under/utility/sifguard
- shoes = /obj/item/clothing/shoes/boots/jackboots
+ uniform = /obj/item/clothing/under/solgov/utility/sifguard
+ shoes = /obj/item/clothing/shoes/boots/tactical
/decl/hierarchy/outfit/military/sifguard/service
name = OUTFIT_MILITARY("SifGuard Service")
- uniform = /obj/item/clothing/under/utility/sifguard
- shoes = /obj/item/clothing/shoes/boots/jackboots
+ uniform = /obj/item/clothing/under/solgov/utility/sifguard
+ shoes = /obj/item/clothing/shoes/boots/tactical
suit = /obj/item/clothing/suit/storage/service/sifguard
/decl/hierarchy/outfit/military/sifguard/dress
name = OUTFIT_MILITARY("SifGuard Dress")
- uniform = /obj/item/clothing/under/mildress/sifguard
+ uniform = /obj/item/clothing/under/solgov/mildress/sifguard
shoes = /obj/item/clothing/shoes/dress
suit = /obj/item/clothing/suit/dress/expedition
gloves = /obj/item/clothing/gloves/white
diff --git a/code/datums/riding.dm b/code/datums/riding.dm
index 746cc6dcf75..4f9513397a7 100644
--- a/code/datums/riding.dm
+++ b/code/datums/riding.dm
@@ -101,7 +101,7 @@
if(keycheck(user))
if(!Process_Spacemove(direction) || !isturf(ridden.loc))
return
- step(ridden, direction)
+ ridden.Move(get_step(ridden, direction))
handle_vehicle_layer()
handle_vehicle_offsets()
diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm
index e3b9a148cce..e387309da7a 100644
--- a/code/datums/supplypacks/engineering.dm
+++ b/code/datums/supplypacks/engineering.dm
@@ -21,6 +21,20 @@
containertype = /obj/structure/closet/crate/engineering
containername = "Superconducting Magnetic Coil crate"
+/datum/supply_pack/eng/smescoil/super_capacity
+ name = "Superconducting Capacitance Coil"
+ contains = list(/obj/item/weapon/smes_coil/super_capacity)
+ cost = 90
+ containertype = /obj/structure/closet/crate/engineering
+ containername = "Superconducting Capacitance Coil crate"
+
+/datum/supply_pack/eng/smescoil/super_io
+ name = "Superconducting Transmission Coil"
+ contains = list(/obj/item/weapon/smes_coil/super_io)
+ cost = 90
+ containertype = /obj/structure/closet/crate/engineering
+ containername = "Superconducting Transmission Coil crate"
+
/datum/supply_pack/eng/shield_capacitor
name = "Shield Capacitor"
contains = list(/obj/machinery/shield_capacitor)
@@ -290,4 +304,4 @@
cost = 75
containername = "Tritium crate"
containertype = /obj/structure/closet/crate/engineering
- contains = list(/obj/fiftyspawner/tritium)
\ No newline at end of file
+ contains = list(/obj/fiftyspawner/tritium)
diff --git a/code/datums/supplypacks/hospitality_vr.dm b/code/datums/supplypacks/hospitality_vr.dm
index 95a921f8176..decb7027db1 100644
--- a/code/datums/supplypacks/hospitality_vr.dm
+++ b/code/datums/supplypacks/hospitality_vr.dm
@@ -1,3 +1,6 @@
+/datum/supply_pack/randomised/hospitality/pizza
+ cost = 50
+
/datum/supply_pack/randomised/hospitality/burgers_vr
num_contained = 5
contains = list(
@@ -79,6 +82,3 @@
cost = 50
containertype = /obj/structure/closet/crate/freezer
containername = "Chinese takeout crate"
-
-/datum/supply_pack/randomised/hospitality/pizza
- cost = 25
diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm
index 555df731c47..e345b18505f 100644
--- a/code/datums/supplypacks/medical.dm
+++ b/code/datums/supplypacks/medical.dm
@@ -62,7 +62,7 @@
/obj/item/weapon/surgical/circular_saw
)
cost = 25
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Surgery crate"
access = access_medical
@@ -73,7 +73,7 @@
/obj/item/weapon/storage/box/cdeathalarm_kit
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Death Alarm crate"
access = access_medical
@@ -83,7 +83,7 @@
/obj/item/weapon/storage/firstaid/clotting
)
cost = 100
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Clotting Medicine crate"
access = access_medical
@@ -97,7 +97,7 @@
/obj/item/weapon/storage/belt/medical = 3
)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Sterile equipment crate"
/datum/supply_pack/med/extragear
@@ -109,7 +109,7 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3
)
cost = 10
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical surplus equipment"
access = access_medical
@@ -133,7 +133,7 @@
/obj/item/weapon/reagent_containers/syringe
)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Chief medical officer equipment"
access = access_cmo
@@ -156,7 +156,7 @@
/obj/item/weapon/reagent_containers/syringe
)
cost = 20
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical Doctor equipment"
access = access_medical_equip
@@ -179,7 +179,7 @@
/obj/item/weapon/reagent_containers/syringe
)
cost = 20
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Chemist equipment"
access = access_chemistry
@@ -207,7 +207,7 @@
/obj/item/clothing/accessory/storage/white_vest
)
cost = 20
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Paramedic equipment"
access = access_medical_equip
@@ -226,7 +226,7 @@
/obj/item/weapon/cartridge/medical
)
cost = 20
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Psychiatrist equipment"
access = access_psychiatrist
@@ -247,7 +247,7 @@
/obj/item/weapon/storage/box/gloves
)
cost = 10
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical scrubs crate"
access = access_medical_equip
@@ -264,7 +264,7 @@
/obj/item/weapon/pen
)
cost = 20
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Autopsy equipment crate"
access = access_morgue
@@ -291,7 +291,7 @@
/obj/item/weapon/storage/box/gloves
)
cost = 10
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical uniform crate"
access = access_medical_equip
@@ -309,7 +309,7 @@
/obj/item/weapon/storage/box/gloves
)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical biohazard equipment"
access = access_medical_equip
@@ -317,7 +317,7 @@
name = "Portable freezers crate"
contains = list(/obj/item/weapon/storage/box/freezer = 7)
cost = 25
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Portable freezers"
access = access_medical_equip
@@ -325,7 +325,7 @@
name = "Virus sample crate"
contains = list(/obj/item/weapon/virusdish/random = 4)
cost = 25
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Virus sample crate"
access = access_cmo
@@ -334,4 +334,18 @@
contains = list(/obj/item/device/defib_kit = 2)
cost = 30
containertype = /obj/structure/closet/crate/medical
- containername = "Defibrillator crate"
\ No newline at end of file
+ containername = "Defibrillator crate"
+
+/datum/supply_pack/med/distillery
+ name = "Chemical distiller crate"
+ contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1)
+ cost = 175
+ containertype = /obj/structure/largecrate
+ containername = "Chemical distiller crate"
+
+/datum/supply_pack/med/advdistillery
+ name = "Industrial Chemical distiller crate"
+ contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1)
+ cost = 250
+ containertype = /obj/structure/largecrate
+ containername = "Industrial Chemical distiller crate"
diff --git a/code/datums/supplypacks/medical_vr.dm b/code/datums/supplypacks/medical_vr.dm
index 5a080c5e9f4..0538f838679 100644
--- a/code/datums/supplypacks/medical_vr.dm
+++ b/code/datums/supplypacks/medical_vr.dm
@@ -1,38 +1,50 @@
-/datum/supply_pack/med/medicalbiosuits
- contains = list(
- /obj/item/clothing/head/bio_hood/scientist = 3,
- /obj/item/clothing/suit/bio_suit/scientist = 3,
- /obj/item/clothing/suit/bio_suit/virology = 3,
- /obj/item/clothing/head/bio_hood/virology = 3,
- /obj/item/clothing/suit/bio_suit/cmo,
- /obj/item/clothing/head/bio_hood/cmo,
- /obj/item/clothing/shoes/white = 7,
- /obj/item/clothing/mask/gas = 7,
- /obj/item/weapon/tank/oxygen = 7,
- /obj/item/weapon/storage/box/masks,
- /obj/item/weapon/storage/box/gloves
- )
- cost = 40
-
-/datum/supply_pack/med/virologybiosuits
- name = "Virology biohazard gear"
- contains = list(
- /obj/item/clothing/suit/bio_suit/virology = 3,
- /obj/item/clothing/head/bio_hood/virology = 3,
- /obj/item/clothing/mask/gas = 3,
- /obj/item/weapon/tank/oxygen = 3,
- /obj/item/weapon/storage/box/masks,
- /obj/item/weapon/storage/box/gloves
- )
- cost = 40
- containertype = "/obj/structure/closet/crate/secure"
- containername = "Virology biohazard equipment"
- access = access_medical_equip
-
-/datum/supply_pack/med/virus
- name = "Virus sample crate"
- contains = list(/obj/item/weapon/virusdish/random = 4)
- cost = 25
- containertype = "/obj/structure/closet/crate/secure"
- containername = "Virus sample crate"
- access = access_medical_equip
\ No newline at end of file
+/datum/supply_pack/med/medicalbiosuits
+ contains = list(
+ /obj/item/clothing/head/bio_hood/scientist = 3,
+ /obj/item/clothing/suit/bio_suit/scientist = 3,
+ /obj/item/clothing/suit/bio_suit/virology = 3,
+ /obj/item/clothing/head/bio_hood/virology = 3,
+ /obj/item/clothing/suit/bio_suit/cmo,
+ /obj/item/clothing/head/bio_hood/cmo,
+ /obj/item/clothing/shoes/white = 7,
+ /obj/item/clothing/mask/gas = 7,
+ /obj/item/weapon/tank/oxygen = 7,
+ /obj/item/weapon/storage/box/masks,
+ /obj/item/weapon/storage/box/gloves
+ )
+ cost = 40
+
+/datum/supply_pack/med/virologybiosuits
+ name = "Virology biohazard gear"
+ contains = list(
+ /obj/item/clothing/suit/bio_suit/virology = 3,
+ /obj/item/clothing/head/bio_hood/virology = 3,
+ /obj/item/clothing/mask/gas = 3,
+ /obj/item/weapon/tank/oxygen = 3,
+ /obj/item/weapon/storage/box/masks,
+ /obj/item/weapon/storage/box/gloves
+ )
+ cost = 40
+ containertype = /obj/structure/closet/crate/secure
+ containername = "Virology biohazard equipment"
+ access = access_medical_equip
+
+/datum/supply_pack/med/virus
+ name = "Virus sample crate"
+ contains = list(/obj/item/weapon/virusdish/random = 4)
+ cost = 25
+ containertype = /obj/structure/closet/crate/secure
+ containername = "Virus sample crate"
+ access = access_medical_equip
+
+
+/datum/supply_pack/med/bloodpack
+ containertype = /obj/structure/closet/crate/medical/blood
+
+/datum/supply_pack/med/compactdefib
+ name = "Compact Defibrillator crate"
+ contains = list(/obj/item/device/defib_kit/compact = 1)
+ cost = 90
+ containertype = /obj/structure/closet/crate/secure
+ containername = "Compact Defibrillator crate"
+ access = access_medical_equip
diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm
index c4cd4992c14..bf5b8ba53b4 100644
--- a/code/datums/supplypacks/misc.dm
+++ b/code/datums/supplypacks/misc.dm
@@ -103,7 +103,7 @@
/obj/item/weapon/storage/fancy/candle_box = 3
)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Chaplain equipment crate"
/datum/supply_pack/misc/hoverpod
@@ -126,7 +126,7 @@
/obj/item/clothing/accessory/storage/webbing
)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Webbing crate"
/datum/supply_pack/misc/holoplant
@@ -142,5 +142,31 @@
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5
)
cost = 25
- containertype = "obj/structure/closet/crate"
- containername = "Glucose Hypo Crate"
\ No newline at end of file
+ containertype = /obj/structure/closet/crate
+ containername = "Glucose Hypo Crate"
+
+/datum/supply_pack/misc/mre_rations
+ num_contained = 6
+ name = "Emergency - MREs"
+ contains = list(/obj/item/weapon/storage/mre,
+ /obj/item/weapon/storage/mre/menu2,
+ /obj/item/weapon/storage/mre/menu3,
+ /obj/item/weapon/storage/mre/menu4,
+ /obj/item/weapon/storage/mre/menu5,
+ /obj/item/weapon/storage/mre/menu6,
+ /obj/item/weapon/storage/mre/menu7,
+ /obj/item/weapon/storage/mre/menu8,
+ /obj/item/weapon/storage/mre/menu9,
+ /obj/item/weapon/storage/mre/menu10)
+ cost = 50
+ containertype = /obj/structure/closet/crate/freezer
+ containername = "ready to eat rations"
+
+/datum/supply_pack/misc/paste_rations
+ name = "Emergency - Paste"
+ contains = list(
+ /obj/item/weapon/storage/mre/menu11 = 2
+ )
+ cost = 25
+ containertype = /obj/structure/closet/crate/freezer
+ containername = "emergency rations"
diff --git a/code/datums/supplypacks/misc_vr.dm b/code/datums/supplypacks/misc_vr.dm
index f85d7b97232..9e4ee3879d5 100644
--- a/code/datums/supplypacks/misc_vr.dm
+++ b/code/datums/supplypacks/misc_vr.dm
@@ -13,24 +13,6 @@
containername = "Belt-miner gear crate"
access = access_mining
-/datum/supply_pack/misc/rations
- name = "Emergency rations"
- contains = list(
- /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 4,
- )
- cost = 20
- containertype = /obj/structure/closet/crate/freezer
- containername = "emergency rations"
-
-/datum/supply_pack/misc/proteinrations
- name = "Emergency meat rations"
- contains = list(
- /obj/item/weapon/reagent_containers/food/snacks/liquidprotein = 4,
- )
- cost = 30
- containertype = /obj/structure/closet/crate/freezer
- containername = "emergency meat rations"
-
/datum/supply_pack/misc/eva_rig
name = "eva hardsuit (empty)"
contains = list(
@@ -43,6 +25,7 @@
access_eva,
access_explorer,
access_pilot)
+ one_access = TRUE
/datum/supply_pack/misc/mining_rig
name = "industrial hardsuit (empty)"
@@ -53,4 +36,5 @@
containertype = /obj/structure/closet/crate/secure/gear
containername = "industrial hardsuit crate"
access = list(access_mining,
- access_eva)
\ No newline at end of file
+ access_eva)
+ one_access = TRUE
\ No newline at end of file
diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm
index 7059e43755b..357f0eaeadc 100644
--- a/code/datums/supplypacks/recreation.dm
+++ b/code/datums/supplypacks/recreation.dm
@@ -55,7 +55,7 @@
/obj/item/weapon/wrapping_paper = 3
)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Arts and Crafts crate"
/datum/supply_pack/recreation/painters
@@ -87,4 +87,14 @@
contains = list(
/obj/item/weapon/storage/box/wormcan,
/obj/item/weapon/storage/box/wormcan/deluxe
+ )
+
+/datum/supply_pack/recreation/ltagturrets
+ name = "Laser Tag Turrets"
+ cost = 40
+ containername = "laser tag turret crate"
+ containertype = /obj/structure/closet/crate
+ contains = list(
+ /obj/machinery/porta_turret/lasertag/blue,
+ /obj/machinery/porta_turret/lasertag/red
)
\ No newline at end of file
diff --git a/code/datums/supplypacks/recreation_vr.dm b/code/datums/supplypacks/recreation_vr.dm
index c4d7ee0ccc5..2e61f93473c 100644
--- a/code/datums/supplypacks/recreation_vr.dm
+++ b/code/datums/supplypacks/recreation_vr.dm
@@ -40,11 +40,11 @@
containertype = /obj/structure/closet/crate
containername = "wolfgirl cosplay crate"
-/datum/supply_pack/randomised/recreation/figures_vr
+/datum/supply_pack/randomised/recreation/figures
name = "Action figures crate"
num_contained = 5
contains = list(
- /obj/random/action_figure
+ /obj/random/action_figure/supplypack
)
cost = 200
containertype = /obj/structure/closet/crate
diff --git a/code/datums/supplypacks/science.dm b/code/datums/supplypacks/science.dm
index 83407c28662..ab55b8571e8 100644
--- a/code/datums/supplypacks/science.dm
+++ b/code/datums/supplypacks/science.dm
@@ -56,3 +56,25 @@
cost = 30
containertype = /obj/structure/closet/crate
containername = "Integrated circuit crate"
+
+/datum/supply_pack/sci/xenoarch
+ name = "Xenoarchaeology Tech crate"
+ contains = list(
+ /obj/item/weapon/pickaxe/excavationdrill,
+ /obj/item/device/xenoarch_multi_tool,
+ /obj/item/clothing/suit/space/anomaly,
+ /obj/item/clothing/head/helmet/space/anomaly,
+ /obj/item/weapon/storage/belt/archaeology,
+ /obj/item/device/flashlight/lantern,
+ /obj/item/device/core_sampler,
+ /obj/item/device/gps,
+ /obj/item/device/beacon_locator,
+ /obj/item/device/radio/beacon,
+ /obj/item/clothing/glasses/meson,
+ /obj/item/weapon/pickaxe,
+ /obj/item/weapon/storage/bag/fossils,
+ /obj/item/weapon/hand_labeler)
+ cost = 100
+ containertype = /obj/structure/closet/crate/secure/science
+ containername = "Xenoarchaeology Tech crate"
+ access = access_research
\ No newline at end of file
diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm
index 4e4c8c13110..6e9e82bdde3 100644
--- a/code/datums/supplypacks/security.dm
+++ b/code/datums/supplypacks/security.dm
@@ -124,6 +124,30 @@
/obj/item/clothing/gloves/black
)
*/
+
+/datum/supply_pack/security/flexitac
+ name = "Armor - Tactical Light"
+ containertype = /obj/structure/closet/crate/secure/gear
+ containername = "Tactical Light armor crate"
+ cost = 75
+ access = access_armory
+ contains = list(
+ /obj/item/clothing/suit/storage/vest/heavy/flexitac,
+ /obj/item/clothing/head/helmet/flexitac,
+ /obj/item/clothing/shoes/leg_guard/flexitac,
+ /obj/item/clothing/gloves/arm_guard/flexitac,
+ /obj/item/clothing/mask/balaclava/tactical,
+ /obj/item/clothing/glasses/sunglasses/sechud/tactical,
+ /obj/item/weapon/storage/belt/security/tactical,
+ /obj/item/clothing/suit/storage/vest/heavy/flexitac,
+ /obj/item/clothing/head/helmet/flexitac,
+ /obj/item/clothing/shoes/leg_guard/flexitac,
+ /obj/item/clothing/gloves/arm_guard/flexitac,
+ /obj/item/clothing/mask/balaclava/tactical,
+ /obj/item/clothing/glasses/sunglasses/sechud/tactical,
+ /obj/item/weapon/storage/belt/security/tactical
+ )
+
/datum/supply_pack/security/securitybarriers
name = "Misc - Security Barriers"
contains = list(/obj/machinery/deployable/barrier = 4)
@@ -372,4 +396,4 @@
cost = 25
containertype = /obj/structure/closet/crate/secure
containername = "Security biohazard gear"
- access = access_security
\ No newline at end of file
+ access = access_security
diff --git a/code/datums/supplypacks/security_vr.dm b/code/datums/supplypacks/security_vr.dm
index 12f2fa33b3f..852b44adee7 100644
--- a/code/datums/supplypacks/security_vr.dm
+++ b/code/datums/supplypacks/security_vr.dm
@@ -6,6 +6,7 @@
access = list(
access_security,
access_xenobiology)
+ one_access = TRUE
/datum/supply_pack/security/guardmutant
name = "VARMAcorp autoNOMous security solution for hostile environments"
@@ -15,6 +16,7 @@
access = list(
access_security,
access_xenobiology)
+ one_access = TRUE
*/
/datum/supply_pack/randomised/security/armor
diff --git a/code/datums/supplypacks/supply.dm b/code/datums/supplypacks/supply.dm
index e8f26993ff9..c0db598cc48 100644
--- a/code/datums/supplypacks/supply.dm
+++ b/code/datums/supplypacks/supply.dm
@@ -61,7 +61,7 @@
/obj/item/weapon/tool/wirecutters,
/obj/item/weapon/tape_roll = 2)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Shipping supplies crate"
/datum/supply_pack/supply/bureaucracy
@@ -111,7 +111,7 @@
/obj/item/clothing/glasses/meson
)
cost = 10
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Shaft miner equipment"
access = access_mining
/* //VOREStation Edit - Pointless on Tether.
diff --git a/code/datums/supplypacks/voidsuits.dm b/code/datums/supplypacks/voidsuits.dm
index 1feb6fe92e2..22bff55fcf3 100644
--- a/code/datums/supplypacks/voidsuits.dm
+++ b/code/datums/supplypacks/voidsuits.dm
@@ -17,7 +17,7 @@
/obj/item/weapon/tank/oxygen = 2,
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Atmospheric voidsuit crate"
access = access_atmospherics
@@ -31,7 +31,7 @@
/obj/item/weapon/tank/oxygen = 2,
)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Heavy Duty Atmospheric voidsuit crate"
access = access_atmospherics
@@ -45,7 +45,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Engineering voidsuit crate"
access = access_engine_equip
@@ -59,7 +59,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Engineering Construction voidsuit crate"
access = access_engine_equip
@@ -73,7 +73,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 45
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Engineering Hazmat voidsuit crate"
access = access_engine_equip
@@ -87,7 +87,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Reinforced Engineering voidsuit crate"
access = access_engine_equip
@@ -101,7 +101,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical voidsuit crate"
access = access_medical_equip
@@ -115,7 +115,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical EMT voidsuit crate"
access = access_medical_equip
@@ -129,7 +129,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 45
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Medical Biohazard voidsuit crate"
access = access_medical_equip
@@ -143,7 +143,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 60
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Vey-Med Medical voidsuit crate"
access = access_medical_equip
@@ -157,7 +157,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Security voidsuit crate"
/datum/supply_pack/voidsuits/security/crowd
@@ -170,7 +170,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Security Crowd Control voidsuit crate"
access = access_armory
@@ -184,7 +184,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Security EVA Riot voidsuit crate"
access = access_armory
@@ -197,7 +197,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 40
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Mining voidsuit crate"
access = access_mining
@@ -210,7 +210,7 @@
/obj/item/weapon/tank/oxygen = 2
)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Frontier Mining voidsuit crate"
access = access_mining
@@ -221,6 +221,6 @@
/obj/item/clothing/mask/gas/zaddat = 1
)
cost = 30
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Zaddat Shroud crate"
access = null
\ No newline at end of file
diff --git a/code/datums/supplypacks/voidsuits_vr.dm b/code/datums/supplypacks/voidsuits_vr.dm
index 8fcfd8ae501..cfadfcf2131 100644
--- a/code/datums/supplypacks/voidsuits_vr.dm
+++ b/code/datums/supplypacks/voidsuits_vr.dm
@@ -79,7 +79,7 @@
/obj/item/weapon/tank/oxygen = 3
)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Exploration voidsuit crate"
access = access_explorer
@@ -93,6 +93,6 @@
/obj/item/weapon/tank/oxygen = 1
)
cost = 20
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Pilot voidsuit crate"
access = access_pilot
\ No newline at end of file
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 5bd34e704bd..482598027af 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -29,6 +29,7 @@
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "soap"
+ flags = NOCONDUCT
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_HOLSTER
throwforce = 0
@@ -395,7 +396,7 @@
display_contents_with_number = 1
max_w_class = ITEMSIZE_NORMAL
max_storage_space = 100
-
+
/obj/item/weapon/storage/part_replacer/adv
name = "advanced rapid part exchange device"
desc = "Special mechanical module made to store, sort, and apply standard machine parts. This one has a greatly upgraded storage capacity"
@@ -718,7 +719,7 @@
desc = "Instant research tool. For testing purposes only."
icon = 'icons/obj/stock_parts.dmi'
icon_state = "smes_coil"
- origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19)
+ origin_tech = list(TECH_MATERIAL = 19, TECH_ENGINEERING = 19, TECH_PHORON = 19, TECH_POWER = 19, TECH_BLUESPACE = 19, TECH_BIO = 19, TECH_COMBAT = 19, TECH_MAGNET = 19, TECH_DATA = 19, TECH_ILLEGAL = 19, TECH_ARCANE = 19, TECH_PRECURSOR = 19)
// Additional construction stock parts
diff --git a/code/game/antagonist/station/highlander.dm b/code/game/antagonist/station/highlander.dm
index e2ec983818a..f483b1df3bd 100644
--- a/code/game/antagonist/station/highlander.dm
+++ b/code/game/antagonist/station/highlander.dm
@@ -47,8 +47,8 @@ var/datum/antagonist/highlander/highlanders
var/obj/item/weapon/card/id/W = new(player)
W.name = "[player.real_name]'s ID Card"
W.icon_state = "centcom"
- W.access = get_all_station_access()
- W.access += get_all_centcom_access()
+ W.access = get_all_station_access().Copy
+ W.access |= get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = player.real_name
player.equip_to_slot_or_del(W, slot_wear_id)
diff --git a/code/game/area/Space Station 13 areas_vr.dm b/code/game/area/Space Station 13 areas_vr.dm
index 396ab608215..c03489b3071 100644
--- a/code/game/area/Space Station 13 areas_vr.dm
+++ b/code/game/area/Space Station 13 areas_vr.dm
@@ -1,121 +1,4 @@
-/area/crew_quarters/sleep/vistor_room_1
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_2
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_3
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_4
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_5
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_6
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_7
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_8
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_9
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_10
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_11
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/vistor_room_12
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_1
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_2
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_3
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_4
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_5
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_6
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_7
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_8
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_9
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/crew_quarters/sleep/Dorm_10
- flags = RAD_SHIELDED | BLUE_SHIELDED
-
-/area/teleporter/departing
- name = "\improper Long-Range Teleporter"
- icon_state = "teleporter"
- music = "signal"
-
-// Override telescience shielding on some areas
-/area/security/armoury
- flags = BLUE_SHIELDED
-
-/area/security/tactical
- flags = BLUE_SHIELDED
-
-/area/security/nuke_storage
- flags = BLUE_SHIELDED
-
-/area/supply
- flags = BLUE_SHIELDED
-
-// Add rad shielding to maintenance and construction sites
-/area/vacant
- flags = RAD_SHIELDED
-
-/area/maintenance
- flags = RAD_SHIELDED
-
-/area/rnd/research_storage //Located entirely in maint under public access, so why not that too
- flags = RAD_SHIELDED
-
-// New shuttles
-/area/shuttle/administration/transit
- name = "Deep Space (AS)"
- icon_state = "shuttle"
-
-/area/shuttle/administration/away_mission
- name = "Away Mission (AS)"
- icon_state = "shuttle"
-
-/area/shuttle/awaymission/home
- name = "NSB Adephagia (AM)"
- icon_state = "shuttle2"
-
-/area/shuttle/awaymission/warp
- name = "Deep Space (AM)"
- icon_state = "shuttle"
-
-/area/shuttle/awaymission/away
- name = "Away Mission (AM)"
- icon_state = "shuttle2"
-
-/area/shuttle/awaymission/oldengbase
- name = "Old Construction Site (AM)"
- icon_state = "shuttle2"
+//TFF 28/8/19 - cleanup of areas placement - removes all but rogueminer_vr stuff.
/area/shuttle/belter/station
name = "Belter Shuttle Landed"
@@ -162,140 +45,6 @@
icon_state = "red2"
shuttle_area = /area/shuttle/belter/belt/zone4
-/area/medical/resleeving
- name = "Resleeving Lab"
- icon_state = "genetics"
-
-/area/bigship
- name = "Bigship"
- requires_power = 0
- flags = RAD_SHIELDED
- sound_env = SMALL_ENCLOSED
- base_turf = /turf/space
- icon_state = "red2"
-
-/area/bigship/teleporter
- name = "Bigship Teleporter Room"
-
-//////// Small Cruiser Areas ////////
-/area/houseboat
- name = "Small Cruiser"
- requires_power = 0
- flags = RAD_SHIELDED
- base_turf = /turf/space
- icon_state = "red2"
- lightswitch = TRUE
-
-/area/houseboat/holodeck_area
- name = "Small Cruiser - Holodeck"
- icon_state = "blue2"
-
-/area/houseboat/holodeck/off
- name = "Small Cruiser Holo - Off"
- icon_state = "blue2"
-/area/houseboat/holodeck/beach
- name = "Small Cruiser Holo - Beach"
- icon_state = "blue2"
-/area/houseboat/holodeck/snow
- name = "Small Cruiser Holo - Snow"
- icon_state = "blue2"
-/area/houseboat/holodeck/desert
- name = "Small Cruiser Holo - Desert"
- icon_state = "blue2"
-/area/houseboat/holodeck/picnic
- name = "Small Cruiser Holo - Picnic"
- icon_state = "blue2"
-/area/houseboat/holodeck/thunderdome
- name = "Small Cruiser Holo - Thunderdome"
- icon_state = "blue2"
-/area/houseboat/holodeck/basketball
- name = "Small Cruiser Holo - Basketball"
- icon_state = "blue2"
-/area/houseboat/holodeck/gaming
- name = "Small Cruiser Holo - Gaming Table"
- icon_state = "blue2"
-/area/houseboat/holodeck/space
- name = "Small Cruiser Holo - Space"
- icon_state = "blue2"
-/area/houseboat/holodeck/bunking
- name = "Small Cruiser Holo - Bunking"
- icon_state = "blue2"
-
-/area/shuttle/cruiser/cruiser
- name = "Small Cruiser Shuttle - Cruiser"
- icon_state = "blue2"
- base_turf = /turf/simulated/floor/tiled/techfloor
-/area/shuttle/cruiser/station
- name = "Small Cruiser Shuttle - Station"
- icon_state = "blue2"
-
-
-// Tether Map has this shuttle
-/area/shuttle/tether/surface
- name = "Tether Shuttle Landed"
- icon_state = "shuttle"
- base_turf = /turf/simulated/floor/reinforced
-
-/area/shuttle/tether/station
- name = "Tether Shuttle Dock"
- icon_state = "shuttle2"
-
-/area/shuttle/tether/transit
- name = "Tether Shuttle Transit"
- icon_state = "shuttle2"
-
-// rnd (Research and Development)
-/area/rnd/research/testingrange
- name = "\improper Weapons Testing Range"
- icon_state = "firingrange"
-
-/area/rnd/research/researchdivision
- name = "\improper Research Division"
- icon_state = "research"
-
-/area/rnd/outpost
- name = "\improper Research Outpost Hallway"
- icon_state = "research"
-
-/area/rnd/outpost/airlock
- name = "\improper Research Outpost Airlock"
- icon_state = "green"
-
-/area/rnd/outpost/eva
- name = "Research Outpost EVA Storage"
- icon_state = "eva"
-
-/area/rnd/outpost/chamber
- name = "\improper Research Outpost Burn Chamber"
- icon_state = "engine"
-
-/area/rnd/outpost/atmos
- name = "Research Outpost Atmospherics"
- icon_state = "atmos"
-
-/area/rnd/outpost/storage
- name = "\improper Research Outpost Gas Storage"
- icon_state = "toxstorage"
-
-/area/rnd/outpost/mixing
- name = "\improper Research Outpost Gas Mixing"
- icon_state = "toxmix"
-
-/area/rnd/outpost/heating
- name = "\improper Research Outpost Gas Heating"
- icon_state = "toxmix"
-
-/area/rnd/outpost/testing
- name = "\improper Research Outpost Testing"
- icon_state = "toxtest"
-
-/area/maintenance/substation/outpost
- name = "Research Outpost Substation"
-
/area/engineering/engine_gas
name = "\improper Engine Gas Storage"
icon_state = "engine_waste"
-
-/area/chapel/observation
- name = "\improper Chapel Observation"
- icon_state = "chapel"
\ No newline at end of file
diff --git a/code/game/area/areas_vr.dm b/code/game/area/areas_vr.dm
new file mode 100644
index 00000000000..d422c1cd0f1
--- /dev/null
+++ b/code/game/area/areas_vr.dm
@@ -0,0 +1,6 @@
+/area/shuttle_arrived()
+ .=..()
+ for(var/obj/machinery/telecomms/relay/R in contents)
+ R.reset_z()
+ for(var/obj/machinery/power/apc/A in contents)
+ A.update_area()
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 7154b9f47d4..c8f0b44c3d5 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1,6 +1,6 @@
/atom/movable
layer = OBJ_LAYER
- appearance_flags = TILE_BOUND|PIXEL_SCALE
+ appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER //VOREStation Edit
var/last_move = null
var/anchored = 0
// var/elevation = 2 - not used anywhere
@@ -68,40 +68,51 @@
if(!newloc.Enter(src, src.loc))
return
+
+ if(!check_multi_tile_move_density_dir(direct, locs)) // We're big, and we can't move that way.
+ return
+
// Past this is the point of no return
- var/atom/oldloc = loc
- var/area/oldarea = get_area(oldloc)
- var/area/newarea = get_area(newloc)
- loc = newloc
- . = TRUE
- oldloc.Exited(src, newloc)
- if(oldarea != newarea)
- oldarea.Exited(src, newloc)
+ if(!locs || locs.len <= 1) // We're not a multi-tile object.
+ var/atom/oldloc = loc
+ var/area/oldarea = get_area(oldloc)
+ var/area/newarea = get_area(newloc)
+ loc = newloc
+ . = TRUE
+ oldloc.Exited(src, newloc)
+ if(oldarea != newarea)
+ oldarea.Exited(src, newloc)
- for(var/i in oldloc)
- if(i == src) // Multi tile objects
- continue
- var/atom/movable/thing = i
- thing.Uncrossed(src)
+ for(var/i in oldloc)
+ if(i == src) // Multi tile objects
+ continue
+ var/atom/movable/thing = i
+ thing.Uncrossed(src)
- newloc.Entered(src, oldloc)
- if(oldarea != newarea)
- newarea.Entered(src, oldloc)
+ newloc.Entered(src, oldloc)
+ if(oldarea != newarea)
+ newarea.Entered(src, oldloc)
+
+ for(var/i in loc)
+ if(i == src) // Multi tile objects
+ continue
+ var/atom/movable/thing = i
+ thing.Crossed(src)
+
+ else if(newloc) // We're a multi-tile object.
+ . = doMove(newloc)
- for(var/i in loc)
- if(i == src) // Multi tile objects
- continue
- var/atom/movable/thing = i
- thing.Crossed(src)
//
////////////////////////////////////////
-/atom/movable/Move(atom/newloc, direct)
+/atom/movable/Move(atom/newloc, direct = 0)
if(!loc || !newloc)
return FALSE
var/atom/oldloc = loc
if(loc != newloc)
+ if(!direct)
+ direct = get_dir(oldloc, newloc)
if (!(direct & (direct - 1))) //Cardinal move
. = ..()
else //Diagonal move, split it into cardinal moves
@@ -197,6 +208,13 @@
. = TRUE
return CanPass(AM, loc)
+/atom/movable/CanPass(atom/movable/mover, turf/target)
+ . = ..()
+ if(locs && locs.len >= 2) // If something is standing on top of us, let them pass.
+ if(mover.loc in locs)
+ . = TRUE
+ return .
+
//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called!
/atom/movable/Crossed(atom/movable/AM, oldloc)
return
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 7118aafe804..8560582ee82 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -2,6 +2,7 @@
name = "cult blade"
desc = "An arcane weapon wielded by the followers of Nar-Sie."
icon_state = "cultblade"
+ origin_tech = list(TECH_COMBAT = 1, TECH_ARCANE = 1)
w_class = ITEMSIZE_LARGE
force = 30
throwforce = 10
@@ -49,6 +50,7 @@
name = "cult hood"
icon_state = "culthood"
desc = "A hood worn by the followers of Nar-Sie."
+ origin_tech = list(TECH_MATERIAL = 3, TECH_ARCANE = 1)
flags_inv = HIDEFACE
body_parts_covered = HEAD
armor = list(melee = 50, bullet = 30, laser = 50, energy = 80, bomb = 25, bio = 10, rad = 0)
@@ -73,6 +75,7 @@
name = "cult robes"
desc = "A set of armored robes worn by the followers of Nar-Sie."
icon_state = "cultrobes"
+ origin_tech = list(TECH_MATERIAL = 3, TECH_ARCANE = 1)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade)
armor = list(melee = 50, bullet = 30, laser = 50, energy = 80, bomb = 25, bio = 10, rad = 0)
@@ -96,6 +99,7 @@
name = "cult helmet"
desc = "A space worthy helmet used by the followers of Nar-Sie."
icon_state = "cult_helmet"
+ origin_tech = list(TECH_MATERIAL = 3, TECH_ARCANE = 1)
armor = list(melee = 60, bullet = 50, laser = 30, energy = 80, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0
@@ -105,6 +109,7 @@
/obj/item/clothing/suit/space/cult
name = "cult armour"
icon_state = "cult_armour"
+ origin_tech = list(TECH_MATERIAL = 3, TECH_ARCANE = 1)
desc = "A bulky suit of armour, bristling with spikes. It looks space-worthy."
w_class = ITEMSIZE_NORMAL
allowed = list(/obj/item/weapon/book/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency/oxygen,/obj/item/device/suit_cooling_unit)
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index c87427bc44d..24c2ed5f527 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -35,6 +35,22 @@
/obj/structure/cult/pylon/attackby(obj/item/W as obj, mob/user as mob)
attackpylon(user, W.force)
+/obj/structure/cult/pylon/take_damage(var/damage)
+ pylonhit(damage)
+
+/obj/structure/cult/pylon/bullet_act(var/obj/item/projectile/Proj)
+ pylonhit(Proj.get_structure_damage())
+
+/obj/structure/cult/pylon/proc/pylonhit(var/damage)
+ if(!isbroken)
+ if(prob(1+ damage * 5))
+ visible_message("The pylon shatters!")
+ playsound(get_turf(src), 'sound/effects/Glassbr3.ogg', 75, 1)
+ isbroken = 1
+ density = 0
+ icon_state = "pylon-broken"
+ set_light(0)
+
/obj/structure/cult/pylon/proc/attackpylon(mob/user as mob, var/damage)
if(!isbroken)
if(prob(1+ damage * 5))
diff --git a/code/game/gamemodes/cult/soulstone.dm b/code/game/gamemodes/cult/soulstone.dm
index 61db88917a6..9980f94d129 100644
--- a/code/game/gamemodes/cult/soulstone.dm
+++ b/code/game/gamemodes/cult/soulstone.dm
@@ -10,7 +10,7 @@
desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefacts power."
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
- origin_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 4)
+ origin_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 4, TECH_ARCANE = 1)
var/imprinted = "empty"
var/possible_constructs = list("Juggernaut","Wraith","Artificer","Harvester")
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index f0aa03253f7..eb2a88b4979 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -126,7 +126,7 @@ var/global/datum/controller/gameticker/ticker
create_characters() //Create player characters and transfer them.
collect_minds()
equip_characters()
- data_core.manifest()
+ //data_core.manifest() //VOREStation Removal
callHook("roundstart")
@@ -280,8 +280,13 @@ var/global/datum/controller/gameticker/ticker
else if(!player.mind.assigned_role)
continue
else
- if (player.create_character()) // VOREStation Edit
+ //VOREStation Edit Start
+ var/mob/living/carbon/human/new_char = player.create_character()
+ if(new_char)
qdel(player)
+ if(istype(new_char) && !(new_char.mind.assigned_role=="Cyborg"))
+ data_core.manifest_inject(new_char)
+ //VOREStation Edit End
proc/collect_minds()
diff --git a/code/game/jobs/job/assistant.dm b/code/game/jobs/job/assistant.dm
index b79314b8716..06c22a4c8bc 100644
--- a/code/game/jobs/job/assistant.dm
+++ b/code/game/jobs/job/assistant.dm
@@ -13,7 +13,7 @@
access = list() //See /datum/job/assistant/get_access()
minimal_access = list() //See /datum/job/assistant/get_access()
outfit_type = /decl/hierarchy/outfit/job/assistant/intern
- alt_titles = list("Apprentice Engineer","Medical Intern","Lab Assistant","Security Cadet","Jr. Cargo Tech") //VOREStation Edit
+ alt_titles = list("Apprentice Engineer","Medical Intern","Lab Assistant","Security Cadet","Jr. Cargo Tech", "Jr. Explorer") //VOREStation Edit
timeoff_factor = 0 //VOREStation Edit - Interns, noh
//VOREStation Add
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index 94a32c3841b..450f59ec32c 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -31,7 +31,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
H.implant_loyalty(src)
*/
/datum/job/captain/get_access()
- return get_all_station_access()
+ return get_all_station_access().Copy()
/datum/job/hop
title = "Head of Personnel"
diff --git a/code/game/jobs/job/special.dm b/code/game/jobs/job/special.dm
index 7d1ccead195..fbed7452404 100644
--- a/code/game/jobs/job/special.dm
+++ b/code/game/jobs/job/special.dm
@@ -37,8 +37,7 @@
return 1
get_access()
- var/access = get_all_accesses()
- return access
+ return get_all_accesses().Copy()
/*/datum/job/centcom_visitor //For Pleasure // You mean for admin abuse... -Ace
title = "CentCom Visitor"
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index f7a454a7de5..889e11c4e4c 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -80,7 +80,7 @@
if(C == user)
user.visible_message("[user] climbs on \the [src].","You climb on \the [src].")
else
- visible_message("\The [C] has been laid on \the [src] by [user].", 3)
+ visible_message("\The [C] has been laid on \the [src] by [user].")
if(C.client)
C.client.perspective = EYE_PERSPECTIVE
C.client.eye = src
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index b259fe1dedc..f89927e375c 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -29,8 +29,7 @@
sleeper = sleepernew
sleepernew.console = src
set_dir(get_dir(src, sleepernew))
- return
- return
+
/obj/machinery/sleep_console/attack_ai(var/mob/user)
return attack_hand(user)
@@ -45,7 +44,7 @@
to_chat(user, "Sleeper not found!")
return
- if(sleeper.panel_open)
+ if(panel_open)
to_chat(user, "Close the maintenance panel first.")
return
@@ -108,6 +107,7 @@
else
data["beaker"] = -1
data["filtering"] = S.filtering
+ data["pump"] = S.pumping
var/stasis_level_name = "Error!"
for(var/N in S.stasis_choices)
@@ -142,6 +142,9 @@
if(href_list["sleeper_filter"])
if(S.filtering != text2num(href_list["sleeper_filter"]))
S.toggle_filter()
+ if(href_list["pump"])
+ if(S.pumping != text2num(href_list["pump"]))
+ S.toggle_pump()
if(href_list["chemical"] && href_list["amount"])
if(S.occupant && S.occupant.stat != DEAD)
if(href_list["chemical"] in S.available_chemicals) // Your hacks are bad and you should feel bad
@@ -166,6 +169,7 @@
var/list/base_chemicals = list("inaprovaline" = "Inaprovaline", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin")
var/obj/item/weapon/reagent_containers/glass/beaker = null
var/filtering = 0
+ var/pumping = 0
var/obj/machinery/sleep_console/console
var/stasis_level = 0 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1)
var/stasis_choices = list("Complete (1%)" = 100, "Deep (10%)" = 10, "Moderate (20%)" = 5, "Light (50%)" = 2, "None (100%)" = 0)
@@ -263,6 +267,17 @@
else
toggle_filter()
+ if(pumping > 0)
+ if(beaker)
+ if(beaker.reagents.total_volume < beaker.reagents.maximum_volume)
+ var/pumped = 0
+ for(var/datum/reagent/x in occupant.ingested.reagent_list)
+ occupant.reagents.trans_to_obj(beaker, 3)
+ pumped++
+ if(ishuman(occupant))
+ occupant.ingested.trans_to_obj(beaker, pumped + 1)
+ else
+ toggle_pump()
/obj/machinery/sleeper/update_icon()
icon_state = "sleeper_[occupant ? "1" : "0"]"
@@ -301,14 +316,12 @@
return
if(UNCONSCIOUS)
to_chat(usr, "You struggle through the haze to hit the eject button. This will take a couple of minutes...")
- sleep(2 MINUTES)
- if(!src || !usr || !occupant || (occupant != usr)) //Check if someone's released/replaced/bombed him already
- return
- go_out()
+ if(do_after(usr, 2 MINUTES, src))
+ go_out()
if(CONSCIOUS)
go_out()
else
- if(usr.stat != 0)
+ if(usr.stat != CONSCIOUS)
return
go_out()
add_fingerprint(usr)
@@ -326,6 +339,9 @@
if(filtering)
toggle_filter()
+ if(pumping)
+ toggle_pump()
+
if(stat & (BROKEN|NOPOWER))
..(severity)
return
@@ -340,6 +356,12 @@
return
filtering = !filtering
+/obj/machinery/sleeper/proc/toggle_pump()
+ if(!occupant || !beaker)
+ pumping = 0
+ return
+ pumping = !pumping
+
/obj/machinery/sleeper/proc/go_in(var/mob/M, var/mob/user)
if(!M)
return
@@ -370,7 +392,8 @@
update_icon()
/obj/machinery/sleeper/proc/go_out()
- if(!occupant)
+ if(!occupant || occupant.loc != src)
+ occupant = null // JUST IN CASE
return
if(occupant.client)
occupant.client.eye = occupant.client.mob
@@ -387,6 +410,7 @@
update_use_power(1)
update_icon()
toggle_filter()
+ toggle_pump()
/obj/machinery/sleeper/proc/remove_beaker()
if(beaker)
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index ed238841038..484678c942b 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -448,4 +448,8 @@ update_flag
..()
src.air_contents.adjust_gas("phoron", MolesForPressure())
src.update_icon()
- return 1
\ No newline at end of file
+ return 1
+
+/obj/machinery/portable_atmospherics/canister/take_damage(var/damage)
+ src.health -= damage
+ healthcheck()
\ No newline at end of file
diff --git a/code/game/machinery/atmoalter/clamp.dm b/code/game/machinery/atmoalter/clamp.dm
new file mode 100644
index 00000000000..318145c2292
--- /dev/null
+++ b/code/game/machinery/atmoalter/clamp.dm
@@ -0,0 +1,154 @@
+//Good luck. --BlueNexus
+
+//Static version of the clamp
+/obj/machinery/clamp
+ name = "stasis clamp"
+ desc = "A magnetic clamp which can halt the flow of gas in a pipe, via a localised stasis field."
+ description_info = "Click-dragging this to yourself while adjacent will attempt to remove it from the pipe."
+ icon = 'icons/atmos/clamp.dmi'
+ icon_state = "pclamp0"
+ anchored = 1.0
+ var/obj/machinery/atmospherics/pipe/simple/target = null
+ var/open = 1
+
+ var/datum/pipe_network/network_node1
+ var/datum/pipe_network/network_node2
+
+/obj/machinery/clamp/New(loc, var/obj/machinery/atmospherics/pipe/simple/to_attach = null)
+ ..()
+ if(istype(to_attach))
+ target = to_attach
+ else
+ target = locate(/obj/machinery/atmospherics/pipe/simple) in loc
+ if(target)
+ update_networks()
+ dir = target.dir
+ return 1
+
+/obj/machinery/clamp/proc/update_networks()
+ if(!target)
+ return
+ else
+ var/obj/machinery/atmospherics/pipe/node1 = target.node1
+ var/obj/machinery/atmospherics/pipe/node2 = target.node2
+ if(istype(node1))
+ var/datum/pipeline/P1 = node1.parent
+ network_node1 = P1.network
+ if(istype(node2))
+ var/datum/pipeline/P2 = node2.parent
+ network_node2 = P2.network
+
+/obj/machinery/clamp/attack_hand(var/mob/user)
+ if(!target)
+ return FALSE
+ if(!open)
+ open()
+ else
+ close()
+ to_chat(user, "You turn [open ? "off" : "on"] \the [src]")
+ return TRUE
+
+/obj/machinery/clamp/Destroy()
+ if(!open)
+ spawn(-1) open()
+ . = ..()
+
+/obj/machinery/clamp/proc/open()
+ if(open || !target)
+ return 0
+
+ target.build_network()
+
+
+ if(network_node1&&network_node2)
+ network_node1.merge(network_node2)
+ network_node2 = network_node1
+
+ if(network_node1)
+ network_node1.update = 1
+ else if(network_node2)
+ network_node2.update = 1
+
+ update_networks()
+
+ open = 1
+ icon_state = "pclamp0"
+ target.in_stasis = 0
+ return 1
+
+/obj/machinery/clamp/proc/close()
+ if(!open)
+ return 0
+
+ qdel(target.parent)
+
+ if(network_node1)
+ qdel(network_node1)
+ if(network_node2)
+ qdel(network_node2)
+
+ var/obj/machinery/atmospherics/pipe/node1 = null
+ var/obj/machinery/atmospherics/pipe/node2 = null
+
+ if(target.node1)
+ target.node1.build_network()
+ node1 = target.node1
+ if(target.node2)
+ target.node2.build_network()
+ node2 = target.node2
+ if(istype(node1) && node1.parent)
+ var/datum/pipeline/P1 = node1.parent
+ P1.build_pipeline(node1)
+ qdel(P1)
+ if(istype(node2) && node2.parent)
+ var/datum/pipeline/P2 = node2.parent
+ P2.build_pipeline(node2)
+ qdel(P2)
+// P1.build_network()
+// P2.build_network()
+
+ open = 0
+ icon_state = "pclamp1"
+ target.in_stasis = 1
+
+ return 1
+
+/obj/machinery/clamp/MouseDrop(obj/over_object as obj)
+ if(!usr)
+ return
+
+ if(open && over_object == usr && Adjacent(usr))
+ to_chat(usr, "You begin to remove \the [src]...")
+ if (do_after(usr, 30, src))
+ to_chat(usr, "You have removed \the [src].")
+ var/obj/item/clamp/C = new/obj/item/clamp(src.loc)
+ C.forceMove(usr.loc)
+ if(ishuman(usr))
+ usr.put_in_hands(C)
+ qdel(src)
+ return
+ else
+ to_chat(usr, "You can't remove \the [src] while it's active!")
+
+/obj/item/clamp
+ name = "stasis clamp"
+ desc = "A magnetic clamp which can halt the flow of gas in a pipe, via a localised stasis field."
+ icon = 'icons/atmos/clamp.dmi'
+ icon_state = "pclamp0"
+ origin_tech = list(TECH_ENGINEERING = 4, TECH_MAGNET = 4)
+
+/obj/item/clamp/afterattack(var/atom/A, mob/user as mob, proximity)
+ if(!proximity)
+ return
+
+ if (istype(A, /obj/machinery/atmospherics/pipe/simple))
+ to_chat(user, "You begin to attach \the [src] to \the [A]...")
+ var/C = locate(/obj/machinery/clamp) in get_turf(A)
+ if (do_after(user, 30, src) && !C)
+ if(!user.unEquip(src))
+ return
+ to_chat(user, "You have attached \the [src] to \the [A].")
+ new/obj/machinery/clamp(A.loc, A)
+ qdel(src)
+ if(C)
+ to_chat(user, "\The [C] is already attached to the pipe at this location!")
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index 8778b4e5f3b..085c070f7d8 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -149,6 +149,8 @@
var/power_losses
var/last_power_draw = 0
var/obj/item/weapon/cell/cell
+ var/use_cell = TRUE
+ var/removeable_cell = TRUE
/obj/machinery/portable_atmospherics/powered/powered()
if(use_power) //using area power
@@ -158,7 +160,7 @@
return 0
/obj/machinery/portable_atmospherics/powered/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/weapon/cell))
+ if(use_cell && istype(I, /obj/item/weapon/cell))
if(cell)
to_chat(user, "There is already a power cell installed.")
return
@@ -173,7 +175,7 @@
power_change()
return
- if(I.is_screwdriver())
+ if(I.is_screwdriver() && removeable_cell)
if(!cell)
to_chat(user, "There is no power cell installed.")
return
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 223a81ebfd9..fa71e660220 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -277,9 +277,13 @@
//Create the desired item.
var/obj/item/I = new making.path(src.loc)
- if(multiplier > 1 && istype(I, /obj/item/stack))
- var/obj/item/stack/S = I
- S.amount = multiplier
+ if(multiplier > 1)
+ if(istype(I, /obj/item/stack))
+ var/obj/item/stack/S = I
+ S.amount = multiplier
+ else
+ for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack.
+ new making.path(src.loc)
updateUsrDialog()
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index b3d5af5f3ec..34fda2bb06f 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -113,7 +113,7 @@
triggerCameraAlarm()
update_icon()
update_coverage()
- START_PROCESSING(SSobj, src)
+ START_PROCESSING(SSobj, src)
/obj/machinery/camera/bullet_act(var/obj/item/projectile/P)
take_damage(P.get_structure_damage())
@@ -283,7 +283,7 @@
icon_state = initial(icon_state)
add_hiddenprint(user)
-/obj/machinery/camera/proc/take_damage(var/force, var/message)
+/obj/machinery/camera/take_damage(var/force, var/message)
//prob(25) gives an average of 3-4 hits
if (force >= toughness && (force > toughness*4 || prob(25)))
destroy()
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index abd0434c5e9..206dffaa432 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -25,7 +25,7 @@ var/global/list/station_networks = list(
var/global/list/engineering_networks = list(
NETWORK_ENGINE,
NETWORK_ENGINEERING,
- NETWORK_ENGINEERING_OUTPOST,
+ //NETWORK_ENGINEERING_OUTPOST, //VOREStation Edit: Tether has no Engineering Outpost,
NETWORK_ALARM_ATMOS,
NETWORK_ALARM_FIRE,
NETWORK_ALARM_POWER)
@@ -43,6 +43,9 @@ var/global/list/engineering_networks = list(
/obj/machinery/camera/network/civilian
network = list(NETWORK_CIVILIAN)
+/obj/machinery/camera/network/circuits
+ network = list(NETWORK_CIRCUITS)
+
/*
/obj/machinery/camera/network/civilian_east
network = list(NETWORK_CIVILIAN_EAST)
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index bad819a985d..7c7f7043920 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -7,9 +7,19 @@
use_power = 1
idle_power_usage = 5
active_power_usage = 60000 //60 kW. (this the power drawn when charging)
+ var/efficiency = 60000 //will provide the modified power rate when upgraded
power_channel = EQUIP
var/obj/item/weapon/cell/charging = null
var/chargelevel = -1
+ circuit = /obj/item/weapon/circuitboard/cell_charger
+
+/obj/machinery/cell_charger/New()
+ component_parts = list()
+ component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
+ component_parts += new /obj/item/stack/cable_coil(src, 5)
+ RefreshParts()
+ ..()
+ return
/obj/machinery/cell_charger/update_icon()
icon_state = "ccharger[charging ? 1 : 0]"
@@ -32,9 +42,9 @@
if(!..(user, 5))
return
- user << "There's [charging ? "a" : "no"] cell in the charger."
+ to_chat(user, "[charging ? "[charging]" : "Nothing"] is in [src].")
if(charging)
- user << "Current charge: [charging.charge]"
+ to_chat(user, "Current charge: [charging.charge] / [charging.maxcharge]")
/obj/machinery/cell_charger/attackby(obj/item/weapon/W, mob/user)
if(stat & BROKEN)
@@ -42,56 +52,60 @@
if(istype(W, /obj/item/weapon/cell) && anchored)
if(istype(W, /obj/item/weapon/cell/device))
- user << " The charger isn't fitted for that type of cell."
+ to_chat(user, "\The [src] isn't fitted for that type of cell.")
return
if(charging)
- user << "There is already a cell in the charger."
+ to_chat(user, "There is already [charging] in [src].")
return
else
var/area/a = loc.loc // Gets our locations location, like a dream within a dream
if(!isarea(a))
return
if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
- user << "The [name] blinks red as you try to insert the cell!"
+ to_chat(user, "\The [src] blinks red as you try to insert [W]!")
return
user.drop_item()
W.loc = src
charging = W
- user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.")
+ user.visible_message("[user] inserts [charging] into [src].", "You insert [charging] into [src].")
chargelevel = -1
update_icon()
else if(W.is_wrench())
if(charging)
- user << "Remove the cell first!"
+ to_chat(user, "Remove [charging] first!")
return
anchored = !anchored
- user << "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground"
+ to_chat(user, "You [anchored ? "attach" : "detach"] [src] [anchored ? "to" : "from"] the ground")
playsound(src, W.usesound, 75, 1)
+ else if(default_deconstruction_screwdriver(user, W))
+ return
+ else if(default_deconstruction_crowbar(user, W))
+ return
+ else if(default_part_replacement(user, W))
+ return
/obj/machinery/cell_charger/attack_hand(mob/user)
+ add_fingerprint(user)
+
if(charging)
- usr.put_in_hands(charging)
- charging.add_fingerprint(user)
+ user.put_in_hands(charging)
charging.update_icon()
+ user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].")
charging = null
- user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.")
chargelevel = -1
update_icon()
/obj/machinery/cell_charger/attack_ai(mob/user)
if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) // Borgs can remove the cell if they are near enough
- if(!charging)
- return
-
- charging.loc = src.loc
- charging.update_icon()
- charging = null
- update_icon()
- user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.")
-
+ if(charging)
+ user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].")
+ charging.loc = src.loc
+ charging.update_icon()
+ charging = null
+ update_icon()
/obj/machinery/cell_charger/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
@@ -108,9 +122,15 @@
return
if(charging && !charging.fully_charged())
- charging.give(active_power_usage*CELLRATE)
+ charging.give(efficiency*CELLRATE)
update_use_power(2)
update_icon()
else
update_use_power(1)
+
+/obj/machinery/cell_charger/RefreshParts()
+ var/E = 0
+ for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
+ E += C.rating
+ efficiency = active_power_usage * (1+ (E - 1)*0.5)
\ No newline at end of file
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 9b1dd198d92..eb78d41e263 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -279,7 +279,7 @@
if ("terminate")
if (is_authenticated())
- modify.assignment = "Terminated"
+ modify.assignment = "Dismissed" //VOREStation Edit: setting adjustment
modify.access = list()
callHook("terminate_employee", list(modify))
diff --git a/code/game/machinery/computer/shutoff_monitor.dm b/code/game/machinery/computer/shutoff_monitor.dm
new file mode 100644
index 00000000000..4dd79376c92
--- /dev/null
+++ b/code/game/machinery/computer/shutoff_monitor.dm
@@ -0,0 +1,42 @@
+/obj/machinery/computer/shutoff_monitor
+ name = "automated shutoff valve monitor"
+ desc = "Console used to remotely monitor shutoff valves on the station."
+ icon_keyboard = "power_key"
+ icon_screen = "power:0"
+ light_color = "#a97faa"
+ circuit = /obj/item/weapon/circuitboard/shutoff_monitor
+
+/obj/machinery/computer/shutoff_monitor/attack_hand(var/mob/user)
+ ..()
+ ui_interact(user)
+
+/obj/machinery/computer/shutoff_monitor/attack_robot(var/mob/user) // Borgs and AI will want to see this too
+ ..()
+ ui_interact(user)
+
+/obj/machinery/computer/shutoff_monitor/attack_ai(var/mob/user)
+ ui_interact(user)
+
+/obj/machinery/computer/shutoff_monitor/ui_interact(mob/user, ui_key = "shutoff_monitor", var/datum/nanoui/ui = null, var/force_open = 1, var/key_state = null)
+ var/data[0]
+ data["valves"] = list()
+ for(var/obj/machinery/atmospherics/valve/shutoff/S in GLOB.shutoff_valves)
+ data["valves"][++data["valves"].len] = list("name" = S.name, "enable" = S.close_on_leaks, "open" = S.open, "x" = S.x, "y" = S.y, "z" = S.z)
+
+ // update the ui if it exists, returns null if no ui is passed/found
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if(!ui)
+ // the ui does not exist, so we'll create a new() one
+ // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
+ ui = new(user, src, ui_key, "shutoff_monitor.tmpl", "Automated Shutoff Valve Monitor", 625, 700, state = key_state)
+ // when the ui is first opened this is the data it will use
+ ui.set_initial_data(data)
+ // open the new ui window
+ ui.open()
+ // auto update every 20 Master Controller tick
+ ui.set_auto_update(20) // Longer term to reduce the rate of data collection and processing
+
+/obj/machinery/computer/shutoff_monitor/update_icon()
+ ..()
+ if(!(stat & (NOPOWER|BROKEN)))
+ overlays += image('icons/obj/computer.dmi', "ai-fixer-empty", overlay_layer)
diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm
index f992aaab102..4969e89334b 100644
--- a/code/game/machinery/computer/timeclock_vr.dm
+++ b/code/game/machinery/computer/timeclock_vr.dm
@@ -170,6 +170,7 @@
foundjob.current_positions++
var/mob/living/carbon/human/H = usr
H.mind.assigned_role = foundjob.title
+ H.mind.role_alt_title = newjob
announce.autosay("[card.registered_name] has moved On-Duty as [card.assignment].", "Employee Oversight")
return
@@ -200,6 +201,7 @@
callHook("reassign_employee", list(card))
var/mob/living/carbon/human/H = usr
H.mind.assigned_role = ptojob.title
+ H.mind.role_alt_title = ptojob.title
foundjob.current_positions--
announce.autosay("[card.registered_name], [oldtitle], has moved Off-Duty.", "Employee Oversight")
return
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index 765ced8a398..42725bbe285 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -2,52 +2,6 @@
CONTAINS:
Deployable items
Barricades
-
-for reference:
- access_security = 1
- access_brig = 2
- access_armory = 3
- access_forensics_lockers= 4
- access_medical = 5
- access_morgue = 6
- access_tox = 7
- access_tox_storage = 8
- access_genetics = 9
- access_engine = 10
- access_engine_equip= 11
- access_maint_tunnels = 12
- access_external_airlocks = 13
- access_emergency_storage = 14
- access_change_ids = 15
- access_ai_upload = 16
- access_teleporter = 17
- access_eva = 18
- access_heads = 19
- access_captain = 20
- access_all_personal_lockers = 21
- access_chapel_office = 22
- access_tech_storage = 23
- access_atmospherics = 24
- access_bar = 25
- access_janitor = 26
- access_crematorium = 27
- access_kitchen = 28
- access_robotics = 29
- access_rd = 30
- access_cargo = 31
- access_construction = 32
- access_chemistry = 33
- access_cargo_bot = 34
- access_hydroponics = 35
- access_manufacturing = 36
- access_library = 37
- access_lawyer = 38
- access_virology = 39
- access_cmo = 40
- access_qm = 41
- access_court = 42
- access_clown = 43
- access_mime = 44
*/
//Barricades!
@@ -80,6 +34,7 @@ for reference:
return material
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
+ user.setClickCooldown(user.get_attack_speed(W))
if(istype(W, /obj/item/stack))
var/obj/item/stack/D = W
if(D.get_material_name() != material.name)
@@ -96,37 +51,54 @@ for reference:
return
return
else
- user.setClickCooldown(user.get_attack_speed(W))
switch(W.damtype)
if("fire")
health -= W.force * 1
if("brute")
health -= W.force * 0.75
- else
- if(health <= 0)
- visible_message("The barricade is smashed apart!")
- dismantle()
- qdel(src)
- return
+ if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
+ playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
+ else
+ playsound(src, 'sound/weapons/smash.ogg', 50, 1)
+ CheckHealth()
..()
+/obj/structure/barricade/proc/CheckHealth()
+ if(health <= 0)
+ dismantle()
+ return
+
+/obj/structure/barricade/take_damage(var/damage)
+ health -= damage
+ CheckHealth()
+ return
+
+/obj/structure/barricade/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ visible_message("[user] [attack_verb] the [src]!")
+ if(material == get_material_by_name("resin"))
+ playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
+ else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
+ playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
+ else
+ playsound(src, 'sound/weapons/smash.ogg', 50, 1)
+ user.do_attack_animation(src)
+ health -= damage
+ CheckHealth()
+ return
+
/obj/structure/barricade/proc/dismantle()
material.place_dismantled_product(get_turf(src))
+ visible_message("\The [src] falls apart!")
qdel(src)
return
/obj/structure/barricade/ex_act(severity)
switch(severity)
if(1.0)
- visible_message("\The [src] is blown apart!")
- qdel(src)
- return
+ dismantle()
if(2.0)
health -= 25
- if(health <= 0)
- visible_message("\The [src] is blown apart!")
- dismantle()
- return
+ CheckHealth()
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(istype(mover) && mover.checkpass(PASSTABLE))
@@ -158,6 +130,7 @@ for reference:
icon_state = "barrier[locked]"
/obj/machinery/deployable/barrier/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(istype(W, /obj/item/weapon/card/id/))
if(allowed(user))
if (emagged < 2.0)
@@ -196,11 +169,28 @@ for reference:
health -= W.force * 0.75
if("brute")
health -= W.force * 0.5
- else
- if(health <= 0)
- explode()
+ playsound(src, 'sound/weapons/smash.ogg', 50, 1)
+ CheckHealth()
..()
+/obj/machinery/deployable/barrier/proc/CheckHealth()
+ if(health <= 0)
+ explode()
+ return
+
+/obj/machinery/deployable/barrier/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ visible_message("[user] [attack_verb] the [src]!")
+ playsound(src, 'sound/weapons/smash.ogg', 50, 1)
+ user.do_attack_animation(src)
+ health -= damage
+ CheckHealth()
+ return
+
+/obj/machinery/deployable/barrier/take_damage(var/damage)
+ health -= damage
+ CheckHealth()
+ return
+
/obj/machinery/deployable/barrier/ex_act(severity)
switch(severity)
if(1.0)
@@ -208,8 +198,7 @@ for reference:
return
if(2.0)
health -= 25
- if(health <= 0)
- explode()
+ CheckHealth()
return
/obj/machinery/deployable/barrier/emp_act(severity)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index d276efef354..c55a7d8345f 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -308,7 +308,7 @@
operating = -1
return 1
-/obj/machinery/door/proc/take_damage(var/damage)
+/obj/machinery/door/take_damage(var/damage)
var/initialhealth = src.health
src.health = max(0, src.health - damage)
if(src.health <= 0 && initialhealth > 0)
diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm
index c54734aec0d..0baa68cf223 100644
--- a/code/game/machinery/frame.dm
+++ b/code/game/machinery/frame.dm
@@ -90,12 +90,24 @@
circuit = /obj/item/weapon/circuitboard/recharger
frame_size = 3
+/datum/frame/frame_types/cell_charger
+ name = "Heavy-Duty Cell Charger"
+ frame_class = FRAME_CLASS_MACHINE
+ circuit = /obj/item/weapon/circuitboard/cell_charger
+ frame_size = 3
+
/datum/frame/frame_types/grinder
name = "Grinder"
frame_class = FRAME_CLASS_MACHINE
circuit = /obj/item/weapon/circuitboard/grinder
frame_size = 3
+/datum/frame/frame_types/reagent_distillery
+ name = "Distillery"
+ frame_class = FRAME_CLASS_MACHINE
+ circuit = /obj/item/weapon/circuitboard/distiller
+ frame_size = 4
+
/datum/frame/frame_types/display
name = "Display"
frame_class = FRAME_CLASS_DISPLAY
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 6a86dcfcb3d..4251a0e6067 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -415,11 +415,15 @@ Class Procs:
var/obj/item/weapon/circuitboard/M = circuit
A.circuit = M
A.anchored = 1
- A.density = 1
A.frame_type = M.board_type
if(A.frame_type.circuit)
A.need_circuit = 0
+ if(A.frame_type.frame_class == FRAME_CLASS_ALARM || A.frame_type.frame_class == FRAME_CLASS_DISPLAY)
+ A.density = 0
+ else
+ A.density = 1
+
if(A.frame_type.frame_class == FRAME_CLASS_MACHINE)
for(var/obj/D in component_parts)
D.forceMove(src.loc)
diff --git a/code/game/machinery/pipe/pipe_recipes.dm b/code/game/machinery/pipe/pipe_recipes.dm
index f0ae4830552..a54cdd4eee7 100644
--- a/code/game/machinery/pipe/pipe_recipes.dm
+++ b/code/game/machinery/pipe/pipe_recipes.dm
@@ -27,6 +27,7 @@ var/global/list/atmos_pipe_recipes = null
new /datum/pipe_recipe/pipe("Gas Pump", /obj/machinery/atmospherics/binary/pump),
new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate),
new /datum/pipe_recipe/pipe("High Power Gas Pump",/obj/machinery/atmospherics/binary/pump/high_power),
+ //new /datum/pipe_recipe/pipe("Automatic Shutoff Valve",/obj/machinery/atmospherics/valve/shutoff), //VOREStation Removal: Without leaks, those are just regular valves,
new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber),
new /datum/pipe_recipe/meter("Meter"),
new /datum/pipe_recipe/pipe("Gas Filter", /obj/machinery/atmospherics/trinary/atmos_filter),
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 948ef595c8d..56fa5c75a03 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -36,83 +36,75 @@
name = "turret"
catalogue_data = list(/datum/category_item/catalogue/technology/turret)
icon = 'icons/obj/turrets.dmi'
- icon_state = "turret_cover"
- anchored = 1
+ icon_state = "turret_cover_normal"
+ anchored = TRUE
- density = 0
- use_power = 1 //this turret uses and requires power
+ density = FALSE
+ use_power = TRUE //this turret uses and requires power
idle_power_usage = 50 //when inactive, this turret takes up constant 50 Equipment power
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
power_channel = EQUIP //drains power from the EQUIPMENT channel
req_one_access = list(access_security, access_heads)
- // icon_states for turrets.
- // These are for the turret covers.
- var/closed_state = "turret_cover" // For when it is closed.
- var/raising_state = "popup" // When turret is opening.
- var/opened_state = "open" // When fully opened.
- var/lowering_state = "popdown" // When closing.
- var/gun_active_state = "target_prism" // The actual gun's icon_state when active.
- var/gun_disabled_state = "grey_target_prism" // Gun sprite when depowered/disabled.
- var/gun_destroyed_state = "destroyed_target_prism" // Turret sprite for when the turret dies.
-
- var/raised = 0 //if the turret cover is "open" and the turret is raised
- var/raising= 0 //if the turret is currently opening or closing its cover
- var/health = 80 //the turret's health
- var/maxhealth = 80 //turrets maximal health.
- var/auto_repair = 0 //if 1 the turret slowly repairs itself.
- var/locked = 1 //if the turret's behaviour control access is locked
- var/controllock = 0 //if the turret responds to control panels
+ var/raised = FALSE //if the turret cover is "open" and the turret is raised
+ var/raising= FALSE //if the turret is currently opening or closing its cover
+ var/health = 80 //the turret's health
+ var/maxhealth = 80 //turrets maximal health.
+ var/auto_repair = FALSE //if 1 the turret slowly repairs itself.
+ var/locked = TRUE //if the turret's behaviour control access is locked
+ var/controllock = FALSE //if the turret responds to control panels
var/installation = /obj/item/weapon/gun/energy/gun //the type of weapon installed
- var/gun_charge = 0 //the charge of the gun inserted
- var/projectile = null //holder for bullettype
- var/eprojectile = null //holder for the shot when emagged
- var/reqpower = 500 //holder for power needed
- var/iconholder = null //holder for the icon_state. 1 for sprite based on icon_color, null for blue.
- var/icon_color = "orange" // When iconholder is set to 1, the icon_state changes based on what is in this variable.
- var/egun = null //holder to handle certain guns switching bullettypes
+ var/gun_charge = 0 //the charge of the gun inserted
+ var/projectile = null //holder for bullettype
+ var/lethal_projectile = null //holder for the shot when emagged
+ var/reqpower = 500 //holder for power needed
+ var/turret_type = "normal"
+ var/icon_color = "blue"
+ var/lethal_icon_color = "blue"
- var/last_fired = 0 //1: if the turret is cooling down from a shot, 0: turret is ready to fire
- var/shot_delay = 15 //1.5 seconds between each shot
+ var/last_fired = FALSE //TRUE: if the turret is cooling down from a shot, FALSE: turret is ready to fire
+ var/shot_delay = 1.5 SECONDS //1.5 seconds between each shot
- var/check_arrest = 1 //checks if the perp is set to arrest
- var/check_records = 1 //checks if a security record exists at all
- var/check_weapons = 0 //checks if it can shoot people that have a weapon they aren't authorized to have
- var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements
- var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos)
- var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg
- var/check_all = 0 //If active, will fire on anything, including synthetics.
- var/ailock = 0 // AI cannot use this
- var/faction = null //if set, will not fire at people in the same faction for any reason.
+ var/check_arrest = TRUE //checks if the perp is set to arrest
+ var/check_records = TRUE //checks if a security record exists at all
+ var/check_weapons = FALSE //checks if it can shoot people that have a weapon they aren't authorized to have
+ var/check_access = TRUE //if this is active, the turret shoots everything that does not meet the access requirements
+ var/check_anomalies = TRUE //checks if it can shoot at unidentified lifeforms (ie xenos)
+ var/check_synth = FALSE //if active, will shoot at anything not an AI or cyborg
+ var/check_all = FALSE //If active, will fire on anything, including synthetics.
+ var/ailock = FALSE // AI cannot use this
+ var/check_down = FALSE //If active, will shoot to kill when lethals are also on
+ var/faction = null //if set, will not fire at people in the same faction for any reason.
- var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
+ var/attacked = FALSE //if set to TRUE, the turret gets pissed off and shoots at people nearby (unless they have sec access!)
- var/enabled = 1 //determines if the turret is on
- var/lethal = 0 //whether in lethal or stun mode
- var/disabled = 0
+ var/enabled = TRUE //determines if the turret is on
+ var/lethal = FALSE //whether in lethal or stun mode
+ var/disabled = FALSE
- var/shot_sound //what sound should play when the turret fires
- var/eshot_sound //what sound should play when the emagged turret fires
+ var/shot_sound //what sound should play when the turret fires
+ var/lethal_shot_sound //what sound should play when the emagged turret fires
var/datum/effect/effect/system/spark_spread/spark_system //the spark system, used for generating... sparks?
- var/wrenching = 0
+ var/wrenching = FALSE
var/last_target //last target fired at, prevents turrets from erratically firing at all valid targets in range
var/timeout = 10 // When a turret pops up, then finds nothing to shoot at, this number decrements until 0, when it pops down.
var/can_salvage = TRUE // If false, salvaging doesn't give you anything.
/obj/machinery/porta_turret/crescent
req_one_access = list(access_cent_specops)
- enabled = 0
- ailock = 1
- check_synth = 0
- check_access = 1
- check_arrest = 1
- check_records = 1
- check_weapons = 1
- check_anomalies = 1
- check_all = 0
+ enabled = FALSE
+ ailock = TRUE
+ check_synth = FALSE
+ check_access = TRUE
+ check_arrest = TRUE
+ check_records = TRUE
+ check_weapons = TRUE
+ check_anomalies = TRUE
+ check_all = FALSE
+ check_down = TRUE
/obj/machinery/porta_turret/can_catalogue(mob/user) // Dead turrets can't be scanned.
if(stat & BROKEN)
@@ -121,8 +113,8 @@
return ..()
/obj/machinery/porta_turret/stationary
- ailock = 1
- lethal = 1
+ ailock = TRUE
+ lethal = TRUE
installation = /obj/item/weapon/gun/energy/laser
/obj/machinery/porta_turret/stationary/syndie // Generic turrets for POIs that need to not shoot their buddies.
@@ -139,7 +131,6 @@
health = 250 // Since lasers do 40 each.
maxhealth = 250
-
/datum/category_item/catalogue/anomalous/precursor_a/alien_turret
name = "Precursor Alpha Object - Turrets"
desc = "An autonomous defense turret created by unknown ancient aliens. It utilizes an \
@@ -156,7 +147,7 @@
name = "interior anti-boarding turret"
desc = "A very tough looking turret made by alien hands."
catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_turret)
- icon_state = "alien_turret_cover"
+ icon_state = "turret_cover_alien"
req_one_access = list(access_alien)
installation = /obj/item/weapon/gun/energy/alien
enabled = TRUE
@@ -165,22 +156,51 @@
check_all = TRUE
health = 250 // Similar to the AI turrets.
maxhealth = 250
-
- closed_state = "alien_turret_cover"
- raising_state = "alien_popup"
- opened_state = "alien_open"
- lowering_state = "alien_popdown"
- gun_active_state = "alien_gun"
- gun_disabled_state = "alien_gun_disabled"
- gun_destroyed_state = "alien_gun_destroyed"
+ turret_type = "alien"
/obj/machinery/porta_turret/alien/destroyed // Turrets that are already dead, to act as a warning of what the rest of the submap contains.
name = "broken interior anti-boarding turret"
desc = "A very tough looking turret made by alien hands. This one looks destroyed, thankfully."
- icon_state = "alien_gun_destroyed"
+ icon_state = "destroyed_target_prism_alien"
stat = BROKEN
can_salvage = FALSE // So you need to actually kill a turret to get the alien gun.
+/obj/machinery/porta_turret/industrial
+ name = "industrial turret"
+ desc = "This variant appears to be much more rugged."
+ req_one_access = list(access_heads)
+ icon_state = "turret_cover_industrial"
+ installation = /obj/item/weapon/gun/energy/phasegun
+ health = 200
+ maxhealth = 200
+ turret_type = "industrial"
+
+/obj/machinery/porta_turret/industrial/bullet_act(obj/item/projectile/Proj)
+ var/damage = round(Proj.get_structure_damage() * 1.33)
+
+ if(!damage)
+ return
+
+ if(enabled)
+ if(!attacked && !emagged)
+ attacked = TRUE
+ spawn()
+ sleep(60)
+ attacked = FALSE
+
+ take_damage(damage)
+
+/obj/machinery/porta_turret/industrial/attack_generic(mob/living/L, damage)
+ return ..(L, damage * 0.8)
+
+/obj/machinery/porta_turret/industrial/teleport_defense
+ name = "defense turret"
+ desc = "This variant appears to be much more durable, with a rugged outer coating."
+ req_one_access = list(access_heads)
+ installation = /obj/item/weapon/gun/energy/gun/burst
+ health = 250
+ maxhealth = 250
+
/obj/machinery/porta_turret/poi //These are always angry
enabled = TRUE
lethal = TRUE
@@ -188,6 +208,98 @@
check_all = TRUE
can_salvage = FALSE // So you can't just twoshot a turret and get a fancy gun
+/obj/machinery/porta_turret/lasertag
+ name = "lasertag turret"
+ turret_type = "normal"
+ req_one_access = list()
+ installation = /obj/item/weapon/gun/energy/lasertag/omni
+
+ locked = FALSE
+ enabled = FALSE
+ anchored = FALSE
+ //These two are used for lasertag
+ check_synth = FALSE
+ check_weapons = FALSE
+ //These vars aren't used
+ check_access = FALSE
+ check_arrest = FALSE
+ check_records = FALSE
+ check_anomalies = FALSE
+ check_all = FALSE
+ check_down = FALSE
+
+/obj/machinery/porta_turret/lasertag/red
+ turret_type = "red"
+ installation = /obj/item/weapon/gun/energy/lasertag/red
+ check_weapons = TRUE // Used to target blue players
+
+/obj/machinery/porta_turret/lasertag/blue
+ turret_type = "blue"
+ installation = /obj/item/weapon/gun/energy/lasertag/blue
+ check_synth = TRUE // Used to target red players
+
+/obj/machinery/porta_turret/lasertag/assess_living(var/mob/living/L)
+ if(!ishuman(L))
+ return TURRET_NOT_TARGET
+
+ if(L.invisibility >= INVISIBILITY_LEVEL_ONE) // Cannot see him. see_invisible is a mob-var
+ return TURRET_NOT_TARGET
+
+ if(get_dist(src, L) > 7) //if it's too far away, why bother?
+ return TURRET_NOT_TARGET
+
+ if(!(L in check_trajectory(L, src))) //check if we have true line of sight
+ return TURRET_NOT_TARGET
+
+ if(L.lying) //Don't need to stun-lock the players
+ return TURRET_NOT_TARGET
+
+ if(ishuman(L))
+ var/mob/living/carbon/human/M = L
+ if(istype(M.wear_suit, /obj/item/clothing/suit/redtag) && check_synth) // Checks if they are a red player
+ return TURRET_PRIORITY_TARGET
+
+ if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag) && check_weapons) // Checks if they are a blue player
+ return TURRET_PRIORITY_TARGET
+
+/obj/machinery/porta_turret/lasertag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
+ data["access"] = !isLocked(user)
+ data["locked"] = locked
+ data["enabled"] = enabled
+ data["is_lethal"] = 1
+ data["lethal"] = lethal
+
+ if(data["access"])
+ var/settings[0]
+ settings[++settings.len] = list("category" = "Target Red", "setting" = "check_synth", "value" = check_synth) // Could not get the UI to work with new vars specifically for lasertag turrets -Nalarac
+ settings[++settings.len] = list("category" = "Target Blue", "setting" = "check_weapons", "value" = check_weapons) // So I'm using these variables since they don't do anything else in this case
+ data["settings"] = settings
+
+ ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(1)
+
+/obj/machinery/porta_turret/lasertag/Topic(href, href_list)
+ if(..())
+ return 1
+
+ if(href_list["command"] && href_list["value"])
+ var/value = text2num(href_list["value"])
+ if(href_list["command"] == "enable")
+ enabled = value
+ else if(href_list["command"] == "lethal")
+ lethal = value
+ else if(href_list["command"] == "check_synth")
+ check_synth = value
+ else if(href_list["command"] == "check_weapons")
+ check_weapons = value
+
+ return 1
+
/obj/machinery/porta_turret/Initialize()
//Sets up a spark system
spark_system = new /datum/effect/effect/system/spark_spread
@@ -197,7 +309,7 @@
setup()
// If turrets ever switch overlays, this will need to be cached and reapplied each time overlays_cut() is called.
- var/image/turret_opened_overlay = image(icon, opened_state)
+ var/image/turret_opened_overlay = image(icon, "open_[turret_type]")
turret_opened_overlay.layer = layer-0.1
add_overlay(turret_opened_overlay)
return ..()
@@ -209,81 +321,85 @@
/obj/machinery/porta_turret/update_icon()
if(stat & BROKEN) // Turret is dead.
- icon_state = gun_destroyed_state
+ icon_state = "destroyed_target_prism_[turret_type]"
else if(raised || raising)
// Turret is open.
if(powered() && enabled)
// Trying to shoot someone.
- icon_state = gun_active_state
+ if(lethal)
+ icon_state = "[lethal_icon_color]_target_prism_[turret_type]"
+ else
+ icon_state = "[icon_color]_target_prism_[turret_type]"
else
// Disabled.
- icon_state = gun_disabled_state
+ icon_state = "grey_target_prism_[turret_type]"
else
// Its closed.
- icon_state = closed_state
+ icon_state = "turret_cover_[turret_type]"
/obj/machinery/porta_turret/proc/setup()
var/obj/item/weapon/gun/energy/E = installation //All energy-based weapons are applicable
+ var/obj/item/projectile/P = initial(E.projectile_type)
//var/obj/item/ammo_casing/shottype = E.projectile_type
- projectile = initial(E.projectile_type)
- eprojectile = projectile
- shot_sound = initial(E.fire_sound)
- eshot_sound = shot_sound
+ projectile = P
+ lethal_projectile = projectile
+ shot_sound = initial(P.fire_sound)
+ lethal_shot_sound = shot_sound
+
+ if(istype(P, /obj/item/projectile/energy))
+ icon_color = "orange"
+
+ else if(istype(P, /obj/item/projectile/beam/stun))
+ icon_color = "blue"
+
+ else if(istype(P, /obj/item/projectile/beam/lasertag))
+ icon_color = "blue"
+
+ else if(istype(P, /obj/item/projectile/beam))
+ icon_color = "red"
+
+ else
+ icon_color = "blue"
+
+ lethal_icon_color = icon_color
weapon_setup(installation)
/obj/machinery/porta_turret/proc/weapon_setup(var/guntype)
switch(guntype)
- if(/obj/item/weapon/gun/energy/laser/practice)
- iconholder = 1
- eprojectile = /obj/item/projectile/beam
+ if(/obj/item/weapon/gun/energy/gun/burst)
+ lethal_icon_color = "red"
+ lethal_projectile = /obj/item/projectile/beam/burstlaser
+ lethal_shot_sound = 'sound/weapons/Laser.ogg'
+ shot_delay = 1 SECOND
-// if(/obj/item/weapon/gun/energy/laser/practice/sc_laser)
-// iconholder = 1
-// eprojectile = /obj/item/projectile/beam
-
- if(/obj/item/weapon/gun/energy/retro)
- iconholder = 1
-
-// if(/obj/item/weapon/gun/energy/retro/sc_retro)
-// iconholder = 1
-
- if(/obj/item/weapon/gun/energy/captain)
- iconholder = 1
-
- if(/obj/item/weapon/gun/energy/lasercannon)
- iconholder = 1
-
- if(/obj/item/weapon/gun/energy/taser)
- eprojectile = /obj/item/projectile/beam
- eshot_sound = 'sound/weapons/Laser.ogg'
-
- if(/obj/item/weapon/gun/energy/stunrevolver)
- eprojectile = /obj/item/projectile/beam
- eshot_sound = 'sound/weapons/Laser.ogg'
+ if(/obj/item/weapon/gun/energy/phasegun)
+ icon_color = "orange"
+ lethal_icon_color = "orange"
+ lethal_projectile = /obj/item/projectile/energy/phase/heavy
+ shot_delay = 1 SECOND
if(/obj/item/weapon/gun/energy/gun)
- eprojectile = /obj/item/projectile/beam //If it has, going to kill mode
- eshot_sound = 'sound/weapons/Laser.ogg'
- egun = 1
+ lethal_icon_color = "red"
+ lethal_projectile = /obj/item/projectile/beam //If it has, going to kill mode
+ lethal_shot_sound = 'sound/weapons/Laser.ogg'
if(/obj/item/weapon/gun/energy/gun/nuclear)
- eprojectile = /obj/item/projectile/beam //If it has, going to kill mode
- eshot_sound = 'sound/weapons/Laser.ogg'
- egun = 1
+ lethal_icon_color = "red"
+ lethal_projectile = /obj/item/projectile/beam //If it has, going to kill mode
+ lethal_shot_sound = 'sound/weapons/Laser.ogg'
if(/obj/item/weapon/gun/energy/xray)
- eprojectile = /obj/item/projectile/beam/xray
+ lethal_icon_color = "green"
+ lethal_projectile = /obj/item/projectile/beam/xray
projectile = /obj/item/projectile/beam/stun // Otherwise we fire xrays on both modes.
- eshot_sound = 'sound/weapons/eluger.ogg'
+ lethal_shot_sound = 'sound/weapons/eluger.ogg'
shot_sound = 'sound/weapons/Taser.ogg'
- iconholder = 1
- icon_color = "green"
/obj/machinery/porta_turret/proc/isLocked(mob/user)
if(ailock && issilicon(user))
@@ -291,7 +407,7 @@
return 1
if(locked && !issilicon(user))
- to_chat(user, "Access denied.")
+ to_chat(user, "Controls locked.")
return 1
return 0
@@ -325,6 +441,7 @@
settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access)
settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies)
settings[++settings.len] = list("category" = "Neutralize All Entities", "setting" = "check_all", "value" = check_all)
+ settings[++settings.len] = list("category" = "Neutralize Downed Entities", "setting" = "check_down", "value" = check_down)
data["settings"] = settings
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
@@ -376,6 +493,8 @@
check_anomalies = value
else if(href_list["command"] == "check_all")
check_all = value
+ else if(href_list["command"] == "check_down")
+ check_down = value
return 1
@@ -426,20 +545,20 @@
"You begin [anchored ? "un" : ""]securing the turret." \
)
- wrenching = 1
+ wrenching = TRUE
if(do_after(user, 50 * I.toolspeed))
//This code handles moving the turret around. After all, it's a portable turret!
if(!anchored)
playsound(loc, I.usesound, 100, 1)
- anchored = 1
+ anchored = TRUE
update_icon()
to_chat(user, "You secure the exterior bolts on the turret.")
else if(anchored)
playsound(loc, I.usesound, 100, 1)
- anchored = 0
+ anchored = FALSE
to_chat(user, "You unsecure the exterior bolts on the turret.")
update_icon()
- wrenching = 0
+ wrenching = FALSE
else if(istype(I, /obj/item/weapon/card/id)||istype(I, /obj/item/device/pda))
//Behavior lock/unlock mangement
@@ -480,15 +599,14 @@
//the turret shoot much, much faster.
to_chat(user, "You short out [src]'s threat assessment circuits.")
visible_message("[src] hums oddly...")
- emagged = 1
- iconholder = 1
- controllock = 1
- enabled = 0 //turns off the turret temporarily
+ emagged = TRUE
+ controllock = TRUE
+ enabled = FALSE //turns off the turret temporarily
sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit
- enabled = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here
+ enabled = TRUE //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here
return 1
-/obj/machinery/porta_turret/proc/take_damage(var/force)
+/obj/machinery/porta_turret/take_damage(var/force)
if(!raised && !raising)
force = force / 8
if(force < 5)
@@ -511,7 +629,7 @@
attacked = 1
spawn()
sleep(60)
- attacked = 0
+ attacked = FALSE
..()
@@ -527,12 +645,12 @@
check_access = prob(20) // check_access is a pretty big deal, so it's least likely to get turned on
check_anomalies = prob(50)
if(prob(5))
- emagged = 1
+ emagged = TRUE
enabled=0
spawn(rand(60,600))
if(!enabled)
- enabled=1
+ enabled = TRUE
..()
@@ -617,10 +735,10 @@
if(faction && L.faction == faction)
return TURRET_NOT_TARGET
- if(!emagged && issilicon(L) && check_all == 0) // Don't target silica, unless told to neutralize everything.
+ if(!emagged && issilicon(L) && check_all == FALSE) // Don't target silica, unless told to neutralize everything.
return TURRET_NOT_TARGET
- if(L.stat && !emagged) //if the perp is dead/dying, no need to bother really
+ if(L.stat == DEAD && !emagged) //if the perp is dead, no need to bother really
return TURRET_NOT_TARGET //move onto next potential victim!
if(get_dist(src, L) > 7) //if it's too far away, why bother?
@@ -637,13 +755,13 @@
if(check_synth || check_all) //If it's set to attack all non-silicons or everything, target them!
if(L.lying)
- return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
+ return check_down ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
return TURRET_PRIORITY_TARGET
if(iscuffed(L)) // If the target is handcuffed, leave it alone
return TURRET_NOT_TARGET
- if(isanimal(L) || issmall(L)) // Animals are not so dangerous
+ if(isanimal(L)) // Animals are not so dangerous
return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
if(isxenomorph(L) || isalien(L)) // Xenos are dangerous
@@ -654,7 +772,7 @@
return TURRET_NOT_TARGET //if threat level < 4, keep going
if(L.lying) //if the perp is lying down, it's still a target but a less-important target
- return lethal ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
+ return check_down ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee
@@ -690,7 +808,7 @@
var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc)
flick_holder.layer = layer + 0.1
- flick(raising_state, flick_holder)
+ flick("popup_[turret_type]", flick_holder)
sleep(10)
qdel(flick_holder)
@@ -711,7 +829,7 @@
var/atom/flick_holder = new /atom/movable/porta_turret_cover(loc)
flick_holder.layer = layer + 0.1
- flick(lowering_state, flick_holder)
+ flick("popdown_[turret_type]", flick_holder)
sleep(10)
qdel(flick_holder)
@@ -742,10 +860,10 @@
if(!(emagged || attacked)) //if it hasn't been emagged or attacked, it has to obey a cooldown rate
if(last_fired || !raised) //prevents rapid-fire shooting, unless it's been emagged
return
- last_fired = 1
+ last_fired = TRUE
spawn()
sleep(shot_delay)
- last_fired = 0
+ last_fired = FALSE
var/turf/T = get_turf(src)
var/turf/U = get_turf(target)
@@ -758,8 +876,8 @@
update_icon()
var/obj/item/projectile/A
if(emagged || lethal)
- A = new eprojectile(loc)
- playsound(loc, eshot_sound, 75, 1)
+ A = new lethal_projectile(loc)
+ playsound(loc, lethal_shot_sound, 75, 1)
else
A = new projectile(loc)
playsound(loc, shot_sound, 75, 1)
@@ -780,8 +898,7 @@
//Shooting Code:
A.firer = src
A.old_style_target(target)
- A.def_zone = def_zone
- A.fire()
+ A.launch_projectile_from_turf(target, def_zone, src)
// Reset the time needed to go back down, since we just tried to shoot at someone.
timeout = 10
@@ -803,7 +920,6 @@
return
enabled = TC.enabled
lethal = TC.lethal
- iconholder = TC.lethal
check_synth = TC.check_synth
check_access = TC.check_access
@@ -839,7 +955,7 @@
if(I.is_wrench() && !anchored)
playsound(loc, I.usesound, 100, 1)
to_chat(user, "You secure the external bolts.")
- anchored = 1
+ anchored = TRUE
build_step = 1
return
@@ -864,7 +980,7 @@
else if(I.is_wrench())
playsound(loc, I.usesound, 75, 1)
to_chat(user, "You unfasten the external bolts.")
- anchored = 0
+ anchored = FALSE
build_step = 0
return
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 3205d16a619..691492a88fd 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -1,6 +1,7 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-obj/machinery/recharger
+/obj/machinery/recharger
name = "recharger"
+ desc = "A standard recharger for all devices that use power."
icon = 'icons/obj/stationobjs_vr.dmi' //VOREStation Edit
icon_state = "recharger0"
anchored = 1
@@ -24,10 +25,16 @@ obj/machinery/recharger
..()
return
-/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
- if(istype(user,/mob/living/silicon))
+/obj/machinery/recharger/examine(mob/user)
+ if(!..(user, 5))
return
+ to_chat(user, "[charging ? "[charging]" : "Nothing"] is in [src].")
+ if(charging)
+ var/obj/item/weapon/cell/C = charging.get_cell()
+ to_chat(user, "Current charge: [C.charge] / [C.maxcharge]")
+
+/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
var/allowed = 0
for (var/allowed_type in allowed_devices)
if(istype(G, allowed_type)) allowed = 1
@@ -38,32 +45,49 @@ obj/machinery/recharger
return
// Checks to make sure he's not in space doing it, and that the area got proper power.
if(!powered())
- to_chat(user, "The [name] blinks red as you try to insert the item!")
+ to_chat(user, "\The [src] blinks red as you try to insert [G]!")
return
if(istype(G, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = G
if(E.self_recharge)
- to_chat(user, "Your gun has no recharge port.")
+ to_chat(user, "\The [E] has no recharge port.")
return
if(istype(G, /obj/item/modular_computer))
var/obj/item/modular_computer/C = G
if(!C.battery_module)
- to_chat(user, "This device does not have a battery installed.")
+ to_chat(user, "\The [C] does not have a battery installed. ")
+ return
+ if(istype(G, /obj/item/weapon/melee/baton))
+ var/obj/item/weapon/melee/baton/B = G
+ if(B.use_external_power)
+ to_chat(user, "\The [B] has no recharge port.")
+ return
+ if(istype(G, /obj/item/device/flash))
+ var/obj/item/device/flash/F = G
+ if(F.use_external_power)
+ to_chat(user, "\The [F] has no recharge port.")
+ return
+ if(istype(G, /obj/item/weapon/weldingtool/electric))
+ var/obj/item/weapon/weldingtool/electric/EW = G
+ if(EW.use_external_power)
+ to_chat(user, "\The [EW] has no recharge port.")
return
else if(!G.get_cell() && !istype(G, /obj/item/ammo_casing/nsfw_batt)) //VOREStation Edit: NSFW charging
- to_chat(user, "This device does not have a battery installed.")
+ to_chat(user, "\The [G] does not have a battery installed.")
return
user.drop_item()
G.loc = src
charging = G
update_icon()
+ user.visible_message("[user] inserts [charging] into [src].", "You insert [charging] into [src].")
+
else if(portable && G.is_wrench())
if(charging)
to_chat(user, "Remove [charging] first!")
return
anchored = !anchored
- to_chat(user, "You [anchored ? "attached" : "detached"] the recharger.")
+ to_chat(user, "You [anchored ? "attached" : "detached"] [src].")
playsound(loc, G.usesound, 75, 1)
else if(default_deconstruction_screwdriver(user, G))
return
@@ -73,17 +97,24 @@ obj/machinery/recharger
return
/obj/machinery/recharger/attack_hand(mob/user as mob)
- if(istype(user,/mob/living/silicon))
- return
-
add_fingerprint(user)
if(charging)
+ user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].")
charging.update_icon()
user.put_in_hands(charging)
charging = null
update_icon()
+/obj/machinery/cell_charger/attack_ai(mob/user)
+ if(istype(user, /mob/living/silicon/robot) && Adjacent(user)) // Borgs can remove the cell if they are near enough
+ if(charging)
+ user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].")
+ charging.update_icon()
+ charging.loc = src.loc
+ charging = null
+ update_icon()
+
/obj/machinery/recharger/process()
if(stat & (NOPOWER|BROKEN) || !anchored)
update_use_power(0)
@@ -164,6 +195,7 @@ obj/machinery/recharger
/obj/machinery/recharger/wallcharger
name = "wall recharger"
+ desc = "A more powerful recharger designed for energy weapons."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "wrecharger0"
plane = TURF_PLANE
diff --git a/code/game/machinery/telecomms/presets_vr.dm b/code/game/machinery/telecomms/presets_vr.dm
index 1bd6b92460d..01a07a5f5ed 100644
--- a/code/game/machinery/telecomms/presets_vr.dm
+++ b/code/game/machinery/telecomms/presets_vr.dm
@@ -3,3 +3,6 @@
hide = 1
produces_heat = 0
autolinkers = list("hb_relay")
+
+/obj/machinery/telecomms/relay/proc/reset_z()
+ listening_level = z
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 43911b54d87..663230b11ff 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -1153,7 +1153,7 @@
/obj/item/toy/plushie/tabby_cat = 50)
/obj/machinery/vending/fishing
- name = "loot trawler"
+ name = "Loot Trawler"
desc = "A special vendor for fishing equipment."
product_ads = "Tired of trawling across the ocean floor? Get our loot!;Chum and rods.;Don't get baited into fishing without us!;Baby is your star-sign pisces? We'd make a perfect match.;Do not fear, plenty to catch around here.;Don't get reeled in helplessly, get your own rod today!"
icon_state = "fishvendor"
diff --git a/code/game/machinery/vending_vr.dm b/code/game/machinery/vending_vr.dm
index 6027bc5eaf7..19a24e669ee 100644
--- a/code/game/machinery/vending_vr.dm
+++ b/code/game/machinery/vending_vr.dm
@@ -6,7 +6,6 @@
/obj/machinery/vending/security/New()
products += list(/obj/item/weapon/gun/energy/taser = 8,/obj/item/weapon/gun/energy/stunrevolver = 4,
/obj/item/weapon/reagent_containers/spray/pepper = 6,/obj/item/taperoll/police = 6,
- /obj/item/weapon/gun/projectile/sec/flash = 4, /obj/item/ammo_magazine/m45/flash = 8,
/obj/item/clothing/glasses/omnihud/sec = 6)
..()
diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm
index 54e2b9c87b4..b58956579ac 100644
--- a/code/game/mecha/combat/combat.dm
+++ b/code/game/mecha/combat/combat.dm
@@ -2,7 +2,7 @@
force = 30
var/melee_cooldown = 10
var/melee_can_hit = 1
- var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall, /obj/structure/girder)
+ //var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall, /obj/structure/girder)
internal_damage_threshold = 50
maint_access = 0
//add_req_access = 0
@@ -26,14 +26,15 @@
return
*/
-/obj/mecha/combat/melee_action(target as obj|mob|turf)
+/obj/mecha/combat/melee_action(atom/T)
if(internal_damage&MECHA_INT_CONTROL_LOST)
- target = safepick(oview(1,src))
- if(!melee_can_hit || !istype(target, /atom)) return
- if(istype(target, /mob/living))
- var/mob/living/M = target
+ T = safepick(oview(1,src))
+ if(!melee_can_hit)
+ return
+ if(istype(T, /mob/living))
+ var/mob/living/M = T
if(src.occupant.a_intent == I_HURT || istype(src.occupant, /mob/living/carbon/brain)) //Brains cannot change intents; Exo-piloting brains lack any form of physical feedback for control, limiting the ability to 'play nice'.
- playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
+ playsound(src, 'sound/weapons/heavysmash.ogg', 50, 1)
if(damtype == "brute")
step_away(M,src,15)
/*
@@ -44,8 +45,8 @@
melee_can_hit = 1
return
*/
- if(istype(target, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = target
+ if(ishuman(T))
+ var/mob/living/carbon/human/H = T
// if (M.health <= 0) return
var/obj/item/organ/external/temp = H.get_organ(pick(BP_TORSO, BP_TORSO, BP_TORSO, BP_HEAD))
@@ -63,6 +64,8 @@
H.reagents.add_reagent("carpotoxin", force)
if(H.reagents.get_reagent_amount("cryptobiolin") + force < force*2)
H.reagents.add_reagent("cryptobiolin", force)
+ if("halloss")
+ H.stun_effect_act(1, force / 2, BP_TORSO, src)
else
return
if(update) H.UpdateDamageIcon()
@@ -84,12 +87,12 @@
else
return
M.updatehealth()
- src.occupant_message("You hit [target].")
- src.visible_message("[src.name] hits [target].")
+ src.occupant_message("You hit [T].")
+ src.visible_message("[src.name] hits [T].")
else
step_away(M,src)
- src.occupant_message("You push [target] out of the way.")
- src.visible_message("[src] pushes [target] out of the way.")
+ src.occupant_message("You push [T] out of the way.")
+ src.visible_message("[src] pushes [T] out of the way.")
melee_can_hit = 0
if(do_after(melee_cooldown))
@@ -97,27 +100,23 @@
return
else
- if(damtype == "brute")
- for(var/target_type in src.destroyable_obj)
- if(istype(target, target_type) && hascall(target, "attackby"))
- src.occupant_message("You hit [target].")
- src.visible_message("[src.name] hits [target]")
- if(!istype(target, /turf/simulated/wall) && !istype(target, /obj/structure/girder))
- target:attackby(src,src.occupant)
- else if(prob(5))
- target:dismantle_wall(1)
- src.occupant_message("You smash through the wall.")
- src.visible_message("[src.name] smashes through the wall")
- playsound(src, 'sound/weapons/smash.ogg', 50, 1)
- else if(istype(target, /turf/simulated/wall))
- target:take_damage(force)
- else if(istype(target, /obj/structure/girder))
- target:take_damage(force * 3) //Girders have 200 health by default. Steel, non-reinforced walls take four punches, girders take (with this value-mod) two, girders took five without.
- melee_can_hit = 0
+ if(istype(T, /obj/machinery/disposal)) // Stops mechs from climbing into disposals
+ return
+ if(src.occupant.a_intent == I_HURT || istype(src.occupant, /mob/living/carbon/brain)) // Don't smash unless we mean it
+ if(damtype == "brute")
+ src.occupant_message("You hit [T].")
+ src.visible_message("[src.name] hits [T]")
+ playsound(src, 'sound/weapons/heavysmash.ogg', 50, 1)
- if(do_after(melee_cooldown))
- melee_can_hit = 1
- break
+ if(istype(T, /obj/structure/girder))
+ T:take_damage(force * 3) //Girders have 200 health by default. Steel, non-reinforced walls take four punches, girders take (with this value-mod) two, girders took five without.
+ else
+ T:take_damage(force)
+
+ melee_can_hit = 0
+
+ if(do_after(melee_cooldown))
+ melee_can_hit = 1
return
/*
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index 58b187670f6..48a46fae56c 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -15,6 +15,7 @@
icon_state = "mecha_equip"
force = 5
origin_tech = list(TECH_MATERIAL = 2)
+ description_info = "Some equipment may gain new abilities or advantages if equipped to certain types of Exosuits."
var/equip_cooldown = 0
var/equip_ready = 1
var/energy_drain = 0
@@ -25,6 +26,7 @@
var/equip_type = null //mechaequip2
var/allow_duplicate = FALSE
var/ready_sound = 'sound/mecha/mech_reload_default.ogg' //Sound to play once the fire delay passed.
+ var/enable_special = FALSE // Will the tool do its special?
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1)
sleep(equip_cooldown)
@@ -122,6 +124,15 @@
/obj/item/mecha_parts/mecha_equipment/proc/is_melee()
return range&MELEE
+/obj/item/mecha_parts/mecha_equipment/proc/enable_special_checks(atom/target)
+ if(ispath(required_type))
+ return istype(target, required_type)
+
+ for (var/path in required_type)
+ if (istype(target, path))
+ return 1
+
+ return 0
/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target)
if(!target)
@@ -202,6 +213,10 @@
M.equipment += src
chassis = M
src.loc = M
+
+ if(enable_special_checks(M))
+ enable_special = TRUE
+
M.log_message("[src] initialized.")
if(!M.selected)
M.selected = src
@@ -235,15 +250,14 @@
chassis.log_message("[src] removed from equipment.")
chassis = null
set_ready_state(1)
+ enable_special = FALSE
return
-
/obj/item/mecha_parts/mecha_equipment/Topic(href,href_list)
if(href_list["detach"])
src.detach()
return
-
/obj/item/mecha_parts/mecha_equipment/proc/set_ready_state(state)
equip_ready = state
if(chassis)
@@ -259,3 +273,6 @@
if(chassis)
chassis.log_message("[src]: [message]")
return
+
+/obj/item/mecha_parts/mecha_equipment/proc/MoveAction() //Allows mech equipment to do an action upon the mech moving
+ return
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index a7f0d418361..b61ada6d187 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -6,11 +6,11 @@
origin_tech = list(TECH_DATA = 2, TECH_BIO = 3)
energy_drain = 20
range = MELEE
- equip_cooldown = 50
+ equip_cooldown = 30
var/mob/living/carbon/human/occupant = null
var/datum/global_iterator/pr_mech_sleeper
var/inject_amount = 5
- required_type = /obj/mecha/medical
+ required_type = list(/obj/mecha/medical)
salvageable = 0
allow_duplicate = TRUE
@@ -247,144 +247,6 @@
return
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer
- name = "Cable Layer"
- icon_state = "mecha_wire"
- var/datum/event/event
- var/turf/old_turf
- var/obj/structure/cable/last_piece
- var/obj/item/stack/cable_coil/cable
- var/max_cable = 1000
- required_type = /obj/mecha/working
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/New()
- cable = new(src)
- cable.amount = 0
- ..()
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/attach()
- ..()
- event = chassis.events.addEvent("onMove",src,"layCable")
- return
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/detach()
- chassis.events.clearEvent("onMove",event)
- return ..()
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/destroy()
- chassis.events.clearEvent("onMove",event)
- return ..()
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/action(var/obj/item/stack/cable_coil/target)
- if(!action_checks(target))
- return
- var/result = load_cable(target)
- var/message
- if(isnull(result))
- message = "Unable to load [target] - no cable found."
- else if(!result)
- message = "Reel is full."
- else
- message = "[result] meters of cable successfully loaded."
- send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
- occupant_message(message)
- return
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/Topic(href,href_list)
- ..()
- if(href_list["toggle"])
- set_ready_state(!equip_ready)
- occupant_message("[src] [equip_ready?"dea":"a"]ctivated.")
- log_message("[equip_ready?"Dea":"A"]ctivated.")
- return
- if(href_list["cut"])
- if(cable && cable.amount)
- var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1)
- m = min(m, cable.amount)
- if(m)
- use_cable(m)
- var/obj/item/stack/cable_coil/CC = new (get_turf(chassis))
- CC.amount = m
- else
- occupant_message("There's no more cable on the reel.")
- return
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/get_equip_info()
- var/output = ..()
- if(output)
- return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]"
- return
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/load_cable(var/obj/item/stack/cable_coil/CC)
- if(istype(CC) && CC.amount)
- var/cur_amount = cable? cable.amount : 0
- var/to_load = max(max_cable - cur_amount,0)
- if(to_load)
- to_load = min(CC.amount, to_load)
- if(!cable)
- cable = new(src)
- cable.amount = 0
- cable.amount += to_load
- CC.use(to_load)
- return to_load
- else
- return 0
- return
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/use_cable(amount)
- if(!cable || cable.amount<1)
- set_ready_state(1)
- occupant_message("Cable depleted, [src] deactivated.")
- log_message("Cable depleted, [src] deactivated.")
- return
- if(cable.amount < amount)
- occupant_message("No enough cable to finish the task.")
- return
- cable.use(amount)
- update_equip_info()
- return 1
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/reset()
- last_piece = null
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/dismantleFloor(var/turf/new_turf)
- if(istype(new_turf, /turf/simulated/floor))
- var/turf/simulated/floor/T = new_turf
- if(!T.is_plating())
- T.make_plating(!(T.broken || T.burnt))
- return new_turf.is_plating()
-
-/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/layCable(var/turf/new_turf)
- if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf))
- return reset()
- var/fdirn = turn(chassis.dir,180)
- for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already
- if(LC.d1 == fdirn || LC.d2 == fdirn)
- return reset()
- if(!use_cable(1))
- return reset()
- var/obj/structure/cable/NC = new(new_turf)
- NC.cableColor("red")
- NC.d1 = 0
- NC.d2 = fdirn
- NC.update_icon()
-
- var/datum/powernet/PN
- if(last_piece && last_piece.d2 != chassis.dir)
- last_piece.d1 = min(last_piece.d2, chassis.dir)
- last_piece.d2 = max(last_piece.d2, chassis.dir)
- last_piece.update_icon()
- PN = last_piece.powernet
-
- if(!PN)
- PN = new()
- PN.add_cable(NC)
- NC.mergeConnectedNetworks(NC.d2)
-
- //NC.mergeConnectedNetworksOnTurf()
- last_piece = NC
- return 1
-
/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun
name = "syringe gun"
desc = "Exosuit-mounted chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur. (Can be attached to: Medical Exosuits)"
@@ -402,7 +264,7 @@
range = MELEE|RANGED
equip_cooldown = 10
origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4, TECH_MAGNET = 4, TECH_DATA = 3)
- required_type = /obj/mecha/medical
+ required_type = list(/obj/mecha/medical)
//This is a list of datums so as to allow id changes, and force compile errors if removed.
var/static/list/allowed_reagents = list(
@@ -515,8 +377,7 @@
if(M)
S.icon_state = initial(S.icon_state)
S.icon = initial(S.icon)
- if(M.can_inject())
- S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD)
+ S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD)
M.take_organ_damage(2)
S.visible_message(" [M] was hit by the syringe!")
break
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index b621d97cba5..f8219451440 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -8,11 +8,13 @@
energy_drain = 10
var/dam_force = 20
var/obj/mecha/working/ripley/cargo_holder
- required_type = /obj/mecha/working
+ required_type = list(/obj/mecha/working)
+ ready_sound = 'sound/mecha/gasdisconnected.ogg'
/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/attach(obj/mecha/M as obj)
..()
cargo_holder = M
+
return
/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/action(atom/target)
@@ -28,7 +30,48 @@
occupant_message("You can't load living things into the cargo compartment.")
return
if(O.anchored)
- occupant_message("[target] is firmly secured.")
+ if(enable_special)
+ if(istype(O, /obj/machinery/door/firedoor)) // I love doors.
+ var/obj/machinery/door/firedoor/FD = O
+ if(FD.blocked)
+ FD.visible_message("\The [chassis] begins prying on \the [FD]!")
+ if(do_after(chassis.occupant,10 SECONDS,FD))
+ playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1)
+ FD.blocked = 0
+ FD.update_icon()
+ FD.open(1)
+ FD.visible_message("\The [chassis] tears \the [FD] open!")
+ else if(FD.density)
+ FD.visible_message("\The [chassis] begins forcing \the [FD] open!")
+ if(do_after(chassis.occupant, 5 SECONDS,FD))
+ playsound(FD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1)
+ FD.visible_message("\The [chassis] forces \the [FD] open!")
+ FD.open(1)
+ else
+ FD.visible_message("\The [chassis] forces \the [FD] closed!")
+ FD.close(1)
+ else if(istype(O, /obj/machinery/door/airlock)) // D o o r s.
+ var/obj/machinery/door/airlock/AD = O
+ if(AD.locked)
+ occupant_message("The airlock's bolts prevent it from being forced.")
+ else if(!AD.operating)
+ if(AD.welded)
+ AD.visible_message("\The [chassis] begins prying on \the [AD]!")
+ if(do_after(chassis.occupant, 15 SECONDS,AD) && chassis.Adjacent(AD))
+ AD.welded = FALSE
+ AD.update_icon()
+ playsound(AD.loc, 'sound/machines/airlock_creaking.ogg', 100, 1)
+ AD.visible_message("\The [chassis] tears \the [AD] open!")
+ if(!AD.welded)
+ if(density)
+ spawn(0)
+ AD.open(1)
+ else
+ spawn(0)
+ AD.close(1)
+ return
+ else
+ occupant_message("[target] is firmly secured.")
return
if(cargo_holder.cargo.len >= cargo_holder.cargo_capacity)
occupant_message("Not enough room in cargo compartment.")
@@ -62,6 +105,15 @@
occupant_message("You squeeze [target] with [src.name]. Something cracks.")
playsound(src.loc, "fracture", 5, 1, -2) //CRACK
chassis.visible_message("[chassis] squeezes [target].")
+ else if(chassis.occupant.a_intent == I_DISARM && enable_special)
+ playsound(src.loc, 'sound/mecha/hydraulic.ogg', 10, 1, -2)
+ M.take_overall_damage(dam_force/2)
+ M.adjustOxyLoss(round(dam_force/3))
+ M.updatehealth()
+ occupant_message("You slam [target] with [src.name]. Something cracks.")
+ playsound(src.loc, "fracture", 3, 1, -2) //CRACK 2
+ chassis.visible_message("[chassis] slams [target].")
+ M.throw_at(get_step(M,get_dir(src, M)), 14, 1.5, chassis)
else
step_away(M,chassis)
occupant_message("You push [target] out of the way.")
@@ -73,12 +125,12 @@
/obj/item/mecha_parts/mecha_equipment/tool/drill
name = "drill"
- desc = "This is the drill that'll pierce the heavens! (Can be attached to: Combat and Engineering Exosuits)"
+ desc = "This is the drill that'll pierce the heavens!"
icon_state = "mecha_drill"
equip_cooldown = 30
energy_drain = 10
force = 15
- required_type = list(/obj/mecha/working/ripley, /obj/mecha/combat)
+ required_type = list(/obj/mecha/working/ripley)
/obj/item/mecha_parts/mecha_equipment/tool/drill/action(atom/target)
if(!action_checks(target)) return
@@ -101,23 +153,20 @@
log_message("Drilled through [target]")
target.ex_act(2)
else if(istype(target, /turf/simulated/mineral))
- for(var/turf/simulated/mineral/M in range(chassis,1))
- if(get_dir(chassis,M)&chassis.dir)
- M.GetDrilled()
+ if(enable_special)
+ for(var/turf/simulated/mineral/M in range(chassis,1))
+ if(get_dir(chassis,M)&chassis.dir)
+ M.GetDrilled()
+ else
+ var/turf/simulated/mineral/M1 = target
+ M1.GetDrilled()
log_message("Drilled through [target]")
if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment)
var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo
if(ore_box)
for(var/obj/item/weapon/ore/ore in range(chassis,1))
if(get_dir(chassis,ore)&chassis.dir)
- ore.Move(ore_box)
- log_message("Drilled through [target]")
- if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment)
- var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo
- if(ore_box)
- for(var/obj/item/weapon/ore/ore in range(chassis,1))
- if(get_dir(chassis,ore)&chassis.dir)
- ore.Move(ore_box)
+ ore.forceMove(ore_box)
else if(target.loc == C)
log_message("Drilled through [target]")
target.ex_act(2)
@@ -125,7 +174,7 @@
/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill
name = "diamond drill"
- desc = "This is an upgraded version of the drill that'll pierce the heavens! (Can be attached to: Combat and Engineering Exosuits)"
+ desc = "This is an upgraded version of the drill that'll pierce the heavens!"
icon_state = "mecha_diamond_drill"
origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3)
equip_cooldown = 10
@@ -150,21 +199,115 @@
log_message("Drilled through [target]")
target.ex_act(3)
else if(istype(target, /turf/simulated/mineral))
- for(var/turf/simulated/mineral/M in range(chassis,1))
- if(get_dir(chassis,M)&chassis.dir)
- M.GetDrilled()
+ if(enable_special)
+ for(var/turf/simulated/mineral/M in range(chassis,1))
+ if(get_dir(chassis,M)&chassis.dir)
+ M.GetDrilled()
+ else
+ var/turf/simulated/mineral/M1 = target
+ M1.GetDrilled()
log_message("Drilled through [target]")
if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment)
var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo
if(ore_box)
for(var/obj/item/weapon/ore/ore in range(chassis,1))
if(get_dir(chassis,ore)&chassis.dir)
- ore.Move(ore_box)
+ ore.forceMove(ore_box)
else if(target.loc == C)
log_message("Drilled through [target]")
target.ex_act(2)
return 1
+/obj/item/mecha_parts/mecha_equipment/tool/drill/bore
+ name = "depth bore"
+ desc = "This is the drill that'll pierce the depths!"
+ icon_state = "mecha_bore"
+ equip_cooldown = 5 SECONDS
+ energy_drain = 30
+ force = 20
+ required_type = list(/obj/mecha/working/ripley)
+
+/obj/item/mecha_parts/mecha_equipment/tool/drill/bore/action(atom/target)
+ if(!action_checks(target)) return
+ if(isobj(target))
+ var/obj/target_obj = target
+ if(target_obj.unacidable) return
+ set_ready_state(0)
+ chassis.use_power(energy_drain)
+ chassis.visible_message("[chassis] starts to bore into \the [target]", "You hear the bore.")
+ occupant_message("You start to bore into \the [target]")
+ var/T = chassis.loc
+ var/C = target.loc
+ if(do_after_cooldown(target))
+ if(T == chassis.loc && src == chassis.selected)
+ if(istype(target, /turf/simulated/wall))
+ var/turf/simulated/wall/W = target
+ if(W.reinf_material)
+ occupant_message("[target] is too durable to bore through.")
+ else
+ log_message("Bored through [target]")
+ target.ex_act(2)
+ else if(istype(target, /turf/simulated/mineral))
+ var/turf/simulated/mineral/M = target
+ if(enable_special && !M.density)
+ M.ex_act(2)
+ log_message("Bored into [target]")
+ else
+ M.GetDrilled()
+ log_message("Bored through [target]")
+ if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment)
+ var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo
+ if(ore_box)
+ for(var/obj/item/weapon/ore/ore in range(chassis,1))
+ if(get_dir(chassis,ore)&chassis.dir)
+ ore.forceMove(ore_box)
+ else if(target.loc == C)
+ log_message("Drilled through [target]")
+ target.ex_act(2)
+ return 1
+
+/obj/item/mecha_parts/mecha_equipment/tool/orescanner
+ name = "mounted ore scanner"
+ desc = "An exosuit-mounted ore scanner."
+ icon_state = "mecha_analyzer"
+ origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2)
+ equip_cooldown = 5
+ energy_drain = 30
+ range = MELEE|RANGED
+ equip_type = EQUIP_SPECIAL
+ ready_sound = 'sound/items/goggles_charge.ogg'
+ required_type = list(/obj/mecha/working/ripley)
+
+ var/obj/item/weapon/mining_scanner/my_scanner = null
+ var/exact_scan = FALSE
+
+/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Initialize()
+ my_scanner = new(src)
+ return ..()
+
+/obj/item/mecha_parts/mecha_equipment/tool/orescanner/Destroy()
+ QDEL_NULL(my_scanner)
+ return ..()
+
+/obj/item/mecha_parts/mecha_equipment/tool/orescanner/action(var/atom/target)
+ if(!action_checks(target) || get_dist(chassis, target) > 5)
+ return FALSE
+
+ if(!enable_special)
+ target = get_turf(chassis)
+
+ var/datum/beam/ScanBeam = chassis.Beam(target,"g_beam",'icons/effects/beam.dmi',time=2 SECONDS,10,/obj/effect/ebeam,2)
+
+ if(do_after(chassis.occupant, 2 SECONDS))
+ my_scanner.ScanTurf(target, chassis.occupant, exact_scan)
+
+ QDEL_NULL(ScanBeam)
+
+/obj/item/mecha_parts/mecha_equipment/tool/orescanner/advanced
+ name = "advanced ore scanner"
+ icon_state = "mecha_analyzer_adv"
+ exact_scan = TRUE
+
/obj/item/mecha_parts/mecha_equipment/tool/extinguisher
name = "extinguisher"
desc = "Exosuit-mounted extinguisher (Can be attached to: Engineering exosuits)"
@@ -172,7 +315,7 @@
equip_cooldown = 5
energy_drain = 0
range = MELEE|RANGED
- required_type = /obj/mecha/working
+ required_type = list(/obj/mecha/working)
var/spray_particles = 5
var/spray_amount = 5 //units of liquid per particle. 5 is enough to wet the floor - it's a big fire extinguisher, so should be fine
var/max_water = 1000
@@ -235,6 +378,48 @@
/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/on_reagent_change()
return
+/obj/item/mecha_parts/mecha_equipment/tool/powertool
+ name = "pneumatic wrench"
+ desc = "An exosuit-mounted hydraulic wrench."
+ icon_state = "mecha_wrench"
+ origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 2, TECH_POWER = 2)
+ equip_cooldown = 3
+ energy_drain = 15
+ range = MELEE
+ equip_type = EQUIP_UTILITY
+ ready_sound = 'sound/items/Ratchet.ogg'
+ required_type = list(/obj/mecha/working/ripley)
+
+ var/obj/item/my_tool = null
+ var/tooltype = /obj/item/weapon/tool/wrench/power
+
+/obj/item/mecha_parts/mecha_equipment/tool/powertool/Initialize()
+ my_tool = new tooltype(src)
+ my_tool.name = name
+ my_tool.anchored = TRUE
+ my_tool.canremove = FALSE
+ return ..()
+
+/obj/item/mecha_parts/mecha_equipment/tool/powertool/Destroy()
+ QDEL_NULL(my_tool)
+ return ..()
+
+/obj/item/mecha_parts/mecha_equipment/tool/powertool/action(var/atom/target)
+ if(!action_checks(target))
+ return FALSE
+
+ if(isliving(target))
+ my_tool.attack(target, chassis.occupant, BP_TORSO)
+
+ target.attackby(my_tool,chassis.occupant)
+
+/obj/item/mecha_parts/mecha_equipment/tool/powertool/prybar
+ name = "pneumatic prybar"
+ desc = "An exosuit-mounted pneumatic prybar."
+ icon_state = "mecha_crowbar"
+ tooltype = /obj/item/weapon/tool/crowbar/power
+ ready_sound = 'sound/mecha/gasdisconnected.ogg'
+
/obj/item/mecha_parts/mecha_equipment/tool/rcd
name = "mounted RCD"
desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)"
@@ -1029,7 +1214,7 @@
energy_drain = 0
var/dam_force = 0
var/obj/mecha/working/ripley/cargo_holder
- required_type = /obj/mecha/working/ripley
+ required_type = list(/obj/mecha/working/ripley)
equip_type = EQUIP_SPECIAL
@@ -1330,3 +1515,154 @@
sleep(equip_cooldown)
wait = 0
return 1
+
+/obj/item/mecha_parts/mecha_equipment/speedboost
+ name = "ripley leg actuator overdrive"
+ desc = "System enhancements and overdrives to make a ripley's legs move faster."
+ icon_state = "tesla"
+ origin_tech = list( TECH_POWER = 5, TECH_MATERIAL = 4, TECH_ENGINEERING = 4)
+ required_type = list(/obj/mecha/working/ripley)
+
+ equip_type = EQUIP_HULL
+
+/obj/item/mecha_parts/mecha_equipment/speedboost/attach(obj/mecha/M as obj)
+ ..()
+ if(enable_special)
+ chassis.step_in = (chassis.step_in-2) // Make the ripley as fast as a durand
+ else
+ chassis.step_in = (chassis.step_in+1) // Improper parts slow the mech down
+ return
+
+/obj/item/mecha_parts/mecha_equipment/speedboost/detach()
+ chassis.step_in = initial(chassis.step_in)
+ ..()
+ return
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer
+ name = "Cable Layer"
+ icon_state = "mecha_wire"
+ var/turf/old_turf
+ var/obj/structure/cable/last_piece
+ var/obj/item/stack/cable_coil/cable
+ var/max_cable = 1000
+ required_type = list(/obj/mecha/working)
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/New()
+ cable = new(src)
+ cable.amount = 0
+ ..()
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/MoveAction()
+ layCable()
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/action(var/obj/item/stack/cable_coil/target)
+ if(!action_checks(target))
+ return
+ var/result = load_cable(target)
+ var/message
+ if(isnull(result))
+ message = "Unable to load [target] - no cable found."
+ else if(!result)
+ message = "Reel is full."
+ else
+ message = "[result] meters of cable successfully loaded."
+ send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
+ occupant_message(message)
+ return
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/Topic(href,href_list)
+ ..()
+ if(href_list["toggle"])
+ set_ready_state(!equip_ready)
+ occupant_message("[src] [equip_ready?"dea":"a"]ctivated.")
+ log_message("[equip_ready?"Dea":"A"]ctivated.")
+ return
+ if(href_list["cut"])
+ if(cable && cable.amount)
+ var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1)
+ m = min(m, cable.amount)
+ if(m)
+ use_cable(m)
+ var/obj/item/stack/cable_coil/CC = new (get_turf(chassis))
+ CC.amount = m
+ else
+ occupant_message("There's no more cable on the reel.")
+ return
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/get_equip_info()
+ var/output = ..()
+ if(output)
+ return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]"
+ return
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/load_cable(var/obj/item/stack/cable_coil/CC)
+ if(istype(CC) && CC.amount)
+ var/cur_amount = cable? cable.amount : 0
+ var/to_load = max(max_cable - cur_amount,0)
+ if(to_load)
+ to_load = min(CC.amount, to_load)
+ if(!cable)
+ cable = new(src)
+ cable.amount = 0
+ cable.amount += to_load
+ CC.use(to_load)
+ return to_load
+ else
+ return 0
+ return
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/use_cable(amount)
+ if(!cable || cable.amount<1)
+ set_ready_state(1)
+ occupant_message("Cable depleted, [src] deactivated.")
+ log_message("Cable depleted, [src] deactivated.")
+ return
+ if(cable.amount < amount)
+ occupant_message("No enough cable to finish the task.")
+ return
+ cable.use(amount)
+ update_equip_info()
+ return 1
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/reset()
+ last_piece = null
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/dismantleFloor(var/turf/new_turf)
+ new_turf = get_turf(chassis)
+ if(istype(new_turf, /turf/simulated/floor))
+ var/turf/simulated/floor/T = new_turf
+ if(!T.is_plating())
+ T.make_plating(!(T.broken || T.burnt))
+ return new_turf.is_plating()
+
+/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/layCable(var/turf/new_turf)
+ new_turf = get_turf(chassis)
+ if(equip_ready || !istype(new_turf, /turf/simulated/floor) || !dismantleFloor(new_turf))
+ return reset()
+ var/fdirn = turn(chassis.dir,180)
+ for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already
+ if(LC.d1 == fdirn || LC.d2 == fdirn)
+ return reset()
+ if(!use_cable(1))
+ return reset()
+ var/obj/structure/cable/NC = new(new_turf)
+ NC.cableColor("red")
+ NC.d1 = 0
+ NC.d2 = fdirn
+ NC.update_icon()
+
+ var/datum/powernet/PN
+ if(last_piece && last_piece.d2 != chassis.dir)
+ last_piece.d1 = min(last_piece.d2, chassis.dir)
+ last_piece.d2 = max(last_piece.d2, chassis.dir)
+ last_piece.update_icon()
+ PN = last_piece.powernet
+
+ if(!PN)
+ PN = new()
+ PN.add_cable(NC)
+ NC.mergeConnectedNetworks(NC.d2)
+
+ //NC.mergeConnectedNetworksOnTurf()
+ last_piece = NC
+ return 1
\ No newline at end of file
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 3ea93b6f77f..5df2c54d10f 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -34,11 +34,18 @@
var/turf/aimloc = targloc
if(deviation)
aimloc = locate(targloc.x+GaussRandRound(deviation,1),targloc.y+GaussRandRound(deviation,1),targloc.z)
- if(!aimloc || aimloc == curloc)
+ if(!aimloc || aimloc == curloc || (locs && aimloc in locs))
break
playsound(chassis, fire_sound, fire_volume, 1)
projectiles--
- var/P = new projectile(curloc)
+ var/turf/projectile_turf
+ if(chassis.locs && chassis.locs.len) // Multi tile.
+ for(var/turf/Tloc in chassis.locs)
+ if(get_dist(Tloc, aimloc) < get_dist(loc, aimloc))
+ projectile_turf = get_turf(Tloc)
+ if(!projectile_turf)
+ projectile_turf = get_turf(curloc)
+ var/P = new projectile(projectile_turf)
Fire(P, target, params)
if(i == 1)
set_ready_state(0)
@@ -61,11 +68,14 @@
return
/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, params)
- var/obj/item/projectile/P = A
- P.dispersion = deviation
- process_accuracy(P, chassis.occupant, target)
- P.preparePixelProjectile(target, chassis.occupant, params)
- P.fire()
+ if(istype(A, /obj/item/projectile)) // Sanity.
+ var/obj/item/projectile/P = A
+ P.dispersion = deviation
+ process_accuracy(P, chassis.occupant, target)
+ P.launch_projectile_from_turf(target, chassis.occupant.zone_sel.selecting, chassis.occupant, params)
+ else if(istype(A, /atom/movable))
+ var/atom/movable/AM = A
+ AM.throw_at(target, 7, 1, chassis)
/obj/item/mecha_parts/mecha_equipment/weapon/proc/process_accuracy(obj/projectile, mob/living/user, atom/target)
var/obj/item/projectile/P = projectile
@@ -416,6 +426,7 @@
var/heavy_blast = 1
var/light_blast = 2
var/flash_blast = 4
+ does_spin = FALSE // No fun corkscrew missiles.
/obj/item/missile/proc/warhead_special(var/target)
explosion(target, devastation, heavy_blast, light_blast, flash_blast)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 9b17cb8613b..74cdb2d368b 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -49,6 +49,8 @@
var/mech_faction = null
var/firstactivation = 0 //It's simple. If it's 0, no one entered it yet. Otherwise someone entered it at least once.
+ var/stomp_sound = 'sound/mecha/mechstep.ogg'
+ var/swivel_sound = 'sound/mecha/mechturn.ogg'
//inner atmos
var/use_internal_tank = 0
@@ -382,9 +384,16 @@
/obj/mecha/Move()
. = ..()
if(.)
- events.fireEvent("onMove",get_turf(src))
+ MoveAction()
return
+/obj/mecha/proc/MoveAction() //Allows mech equipment to do an action once the mech moves
+ if(!equipment.len)
+ return
+
+ for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
+ ME.MoveAction()
+
/obj/mecha/relaymove(mob/user,direction)
if(user != src.occupant) //While not "realistic", this piece is player friendly.
if(istype(user,/mob/living/carbon/brain))
@@ -441,21 +450,24 @@
/obj/mecha/proc/mechturn(direction)
set_dir(direction)
- playsound(src,'sound/mecha/mechturn.ogg',40,1)
+ if(swivel_sound)
+ playsound(src,swivel_sound,40,1)
return 1
/obj/mecha/proc/mechstep(direction)
- var/result = step(src,direction)
- if(result)
- playsound(src,"mechstep",40,1)
+ var/result = get_step(src,direction)
+ if(result && Move(result))
+ if(stomp_sound)
+ playsound(src,stomp_sound,40,1)
handle_equipment_movement()
return result
/obj/mecha/proc/mechsteprand()
- var/result = step_rand(src)
- if(result)
- playsound(src,"mechstep",40,1)
+ var/result = get_step_rand(src)
+ if(result && Move(result))
+ if(stomp_sound)
+ playsound(src,stomp_sound,40,1)
handle_equipment_movement()
return result
@@ -473,9 +485,10 @@
else //I have no idea why I disabled this
obstacle.Bumped(src)
else if(istype(obstacle, /mob))
- step(obstacle,src.dir)
+ var/mob/M = obstacle
+ M.Move(get_step(obstacle,src.dir))
else
- obstacle.Bumped(src)
+ . = ..(obstacle)
return
///////////////////////////////////
@@ -529,7 +542,7 @@
//////// Health related procs ////////
////////////////////////////////////////
-/obj/mecha/proc/take_damage(amount, type="brute")
+/obj/mecha/take_damage(amount, type="brute")
if(amount)
var/damage = absorbDamage(amount,type)
health -= damage
@@ -615,6 +628,11 @@
/obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper
+ if(istype(Proj, /obj/item/projectile/test))
+ var/obj/item/projectile/test/Test = Proj
+ Test.hit |= occupant // Register a hit on the occupant, for things like turrets, or in simple-mob cases stopping friendly fire in firing line mode.
+ return
+
src.log_message("Hit by projectile. Type: [Proj.name]([Proj.check_armour]).",1)
call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment
..()
diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm
index 3e1b0aafc86..9894784e157 100644
--- a/code/game/mecha/mecha_wreckage.dm
+++ b/code/game/mecha/mecha_wreckage.dm
@@ -221,3 +221,11 @@
name = "Janus wreckage"
icon_state = "janus-broken"
description_info = "Due to the incredibly intricate design of this exosuit, it is impossible to salvage components from it."
+
+/obj/effect/decal/mecha_wreckage/shuttlecraft
+ name = "Shuttlecraft wreckage"
+ desc = "Remains of some unfortunate shuttlecraft. Completely unrepairable."
+ icon = 'icons/mecha/mecha64x64.dmi'
+ icon_state = "shuttle_standard-broken"
+ bound_width = 64
+ bound_height = 64
diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm
index 90ab62681a3..6e9dee50475 100644
--- a/code/game/mecha/medical/medical.dm
+++ b/code/game/mecha/medical/medical.dm
@@ -5,6 +5,8 @@
max_universal_equip = 1
max_special_equip = 1
+ stomp_sound = 'sound/mecha/mechmove01.ogg'
+
cargo_capacity = 1
/obj/mecha/medical/Initialize()
@@ -13,7 +15,7 @@
if(isPlayerLevel(T.z))
new /obj/item/mecha_parts/mecha_tracking(src)
-
+/* // One horrific bastardization of glorious inheritence dead. A billion to go. ~Mech
/obj/mecha/medical/mechturn(direction)
set_dir(direction)
playsound(src,'sound/mecha/mechmove01.ogg',40,1)
@@ -29,4 +31,5 @@
var/result = step_rand(src)
if(result)
playsound(src,'sound/mecha/mechstep.ogg',25,1)
- return result
\ No newline at end of file
+ return result
+*/
diff --git a/code/game/mecha/micro/micro_equipment.dm b/code/game/mecha/micro/micro_equipment.dm
index b8e4557b476..d36f9fa0a3e 100644
--- a/code/game/mecha/micro/micro_equipment.dm
+++ b/code/game/mecha/micro/micro_equipment.dm
@@ -146,7 +146,7 @@
occupant_message("The ore compartment is full.")
return 1
else
- ore.Move(ore_box)
+ ore.forceMove(ore_box)
else if(target.loc == C)
log_message("Drilled through [target]")
target.ex_act(2)
diff --git a/code/game/mecha/working/hoverpod.dm b/code/game/mecha/space/hoverpod.dm
similarity index 91%
rename from code/game/mecha/working/hoverpod.dm
rename to code/game/mecha/space/hoverpod.dm
index 8c19c2b0040..85fc59d564b 100644
--- a/code/game/mecha/working/hoverpod.dm
+++ b/code/game/mecha/space/hoverpod.dm
@@ -17,6 +17,9 @@
var/datum/effect/effect/system/ion_trail_follow/ion_trail
var/stabilization_enabled = 1
+ stomp_sound = 'sound/machines/hiss.ogg'
+ swivel_sound = null
+
max_hull_equip = 2
max_weapon_equip = 0
max_utility_equip = 2
@@ -49,7 +52,7 @@
output += ..()
return output
-//No space drifting
+// No space drifting
/obj/mecha/working/hoverpod/check_for_support()
//does the hoverpod have enough charge left to stabilize itself?
if (!has_charge(step_energy_drain))
@@ -62,6 +65,11 @@
return ..()
+// No falling if we've got our boosters on
+/obj/mecha/working/hoverpod/can_fall()
+ return (stabilization_enabled && has_charge(step_energy_drain))
+
+/* // One horrific bastardization of glorious inheritence dead. A billion to go. ~Mech
//these three procs overriden to play different sounds
/obj/mecha/working/hoverpod/mechturn(direction)
set_dir(direction)
@@ -80,7 +88,7 @@
if(result)
playsound(src,'sound/machines/hiss.ogg',40,1)
return result
-
+*/
//Hoverpod variants
/obj/mecha/working/hoverpod/combatpod
diff --git a/code/game/mecha/space/shuttle.dm b/code/game/mecha/space/shuttle.dm
new file mode 100644
index 00000000000..7e361ece0c6
--- /dev/null
+++ b/code/game/mecha/space/shuttle.dm
@@ -0,0 +1,99 @@
+/obj/mecha/working/hoverpod/shuttlecraft
+ desc = "A more advanced variant of the hoverpod."
+ name = "Shuttle"
+ catalogue_data = list(/datum/category_item/catalogue/technology/hoverpod)
+ icon = 'icons/mecha/mecha64x64.dmi'
+ icon_state = "shuttle_standard"
+ initial_icon = "shuttle_standard"
+ internal_damage_threshold = 60
+ step_in = 2
+ step_energy_drain = 5
+ max_temperature = 20000
+ health = 300
+ maxhealth = 300
+ infra_luminosity = 6
+ wreckage = /obj/effect/decal/mecha_wreckage/shuttlecraft
+ cargo_capacity = 3
+ max_equip = 3
+
+ opacity = FALSE
+
+ stomp_sound = 'sound/machines/generator/generator_end.ogg'
+ swivel_sound = 'sound/machines/hiss.ogg'
+
+ // Paint colors! Null if not set.
+ var/base_paint
+ var/engine_paint
+ var/central_paint
+ var/front_paint
+
+ var/image/base_paint_mask
+ var/image/engine_paint_mask
+ var/image/central_paint_mask
+ var/image/front_paint_mask
+
+ bound_height = 64
+ bound_width = 64
+
+ max_hull_equip = 2
+ max_weapon_equip = 1
+ max_utility_equip = 2
+ max_universal_equip = 1
+ max_special_equip = 1
+
+/obj/mecha/working/hoverpod/Initialize()
+ ..()
+ ion_trail.stop()
+
+/obj/mecha/working/hoverpod/shuttlecraft/moved_inside(var/mob/living/carbon/human/H as mob)
+ . = ..(H)
+ if(.)
+ ion_trail.start()
+
+/obj/mecha/working/hoverpod/shuttlecraft/go_out()
+ . = ..()
+ if(!occupant)
+ ion_trail.stop()
+
+/obj/mecha/working/hoverpod/shuttlecraft/update_icon()
+ overlays.Cut()
+ ..()
+
+ if(base_paint)
+ if(!base_paint_mask)
+ base_paint_mask = image(icon, "[initial_icon]-mask+base", src.layer + 1)
+ base_paint_mask.color = base_paint
+ overlays |= base_paint_mask
+ if(front_paint)
+ if(!front_paint_mask)
+ front_paint_mask = image(icon, "[initial_icon]-mask+front", src.layer + 1)
+ front_paint_mask.color = front_paint
+ overlays |= front_paint_mask
+ if(engine_paint)
+ if(!engine_paint_mask)
+ engine_paint_mask = image(icon, "[initial_icon]-mask+engine", src.layer + 1)
+ engine_paint_mask.color = engine_paint
+ overlays |= engine_paint_mask
+ if(central_paint)
+ if(!engine_paint_mask)
+ central_paint_mask = image(icon, "[initial_icon]-mask+central", src.layer + 2)
+ central_paint_mask.color = central_paint
+ overlays |= central_paint_mask
+
+/obj/mecha/working/hoverpod/shuttlecraft/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W,/obj/item/device/multitool) && state == 1)
+ var/new_paint_location = input("Please select a target zone.", "Paint Zone", null) as null|anything in list("Central", "Engine", "Base", "Front", "CANCEL")
+ if(new_paint_location && new_paint_location != "CANCEL")
+ var/new_paint_color = input("Please select a paint color.", "Paint Color", null) as color|null
+ if(new_paint_color)
+ switch(new_paint_location)
+ if("Central")
+ central_paint = new_paint_color
+ if("Engine")
+ engine_paint = new_paint_color
+ if("Front")
+ front_paint = new_paint_color
+ if("Base")
+ base_paint = new_paint_color
+ update_icon()
+ else ..()
diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm
index 44963c31d2a..0de8d332b71 100644
--- a/code/game/objects/effects/alien/aliens.dm
+++ b/code/game/objects/effects/alien/aliens.dm
@@ -64,6 +64,19 @@
healthcheck()
return
+/obj/effect/alien/resin/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ visible_message("[user] [attack_verb] the [src]!")
+ playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
+ user.do_attack_animation(src)
+ health -= damage
+ healthcheck()
+ return
+
+/obj/effect/alien/resin/take_damage(var/damage)
+ health -= damage
+ healthcheck()
+ return
+
/obj/effect/alien/resin/ex_act(severity)
switch(severity)
if(1.0)
@@ -246,6 +259,18 @@ Alien plants should do something if theres a lot of poison
health -= damage
healthcheck()
+/obj/effect/alien/weeds/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ visible_message("[user] [attack_verb] the [src]!")
+ user.do_attack_animation(src)
+ health -= damage
+ healthcheck()
+ return
+
+/obj/effect/alien/weeds/take_damage(var/damage)
+ health -= damage
+ healthcheck()
+ return
+
/obj/effect/alien/weeds/proc/healthcheck()
if(health <= 0)
qdel(src)
@@ -401,6 +426,18 @@ Alien plants should do something if theres a lot of poison
healthcheck()
return
+/obj/effect/alien/egg/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ visible_message("[user] [attack_verb] the [src]!")
+ user.do_attack_animation(src)
+ health -= damage
+ healthcheck()
+ return
+
+/obj/effect/alien/egg/take_damage(var/damage)
+ health -= damage
+ healthcheck()
+ return
+
/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
if(health <= 0)
diff --git a/code/game/objects/effects/chem/coating.dm b/code/game/objects/effects/chem/coating.dm
new file mode 100644
index 00000000000..a777bbe5e05
--- /dev/null
+++ b/code/game/objects/effects/chem/coating.dm
@@ -0,0 +1,36 @@
+/*
+ * Home of the floor chemical coating.
+ */
+
+/obj/effect/decal/cleanable/chemcoating
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "dirt"
+
+/obj/effect/decal/cleanable/chemcoating/New()
+ ..()
+ create_reagents(100)
+
+/obj/effect/decal/cleanable/chemcoating/Initialize()
+ ..()
+ var/turf/T = get_turf(src)
+ if(T)
+ for(var/obj/O in get_turf(src))
+ if(O == src)
+ continue
+ if(istype(O, /obj/effect/decal/cleanable/chemcoating))
+ var/obj/effect/decal/cleanable/chemcoating/C = O
+ if(C.reagents && C.reagents.reagent_list.len)
+ C.reagents.trans_to_obj(src,C.reagents.total_volume)
+ qdel(O)
+
+/obj/effect/decal/cleanable/chemcoating/Bumped(A as mob|obj)
+ if(reagents)
+ reagents.touch(A)
+ return ..()
+
+/obj/effect/decal/cleanable/chemcoating/Crossed(AM as mob|obj)
+ Bumped(AM)
+
+/obj/effect/decal/cleanable/chemcoating/update_icon()
+ ..()
+ color = reagents.get_color()
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index 3b1584ca194..8b8bba5a9dd 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -53,7 +53,7 @@ var/global/list/image/splatter_cache=list()
blood_DNA |= B.blood_DNA.Copy()
qdel(B)
drytime = world.time + DRYING_TIME * (amount+1)
- START_PROCESSING(SSobj, src)
+ START_PROCESSING(SSobj, src)
/obj/effect/decal/cleanable/blood/process()
if(world.time > drytime)
@@ -93,7 +93,6 @@ var/global/list/image/splatter_cache=list()
S.overlays += S.blood_overlay
if(S.blood_overlay && S.blood_overlay.color != basecolor)
S.blood_overlay.color = basecolor
- S.overlays.Cut()
S.overlays += S.blood_overlay
S.blood_DNA |= blood_DNA.Copy()
perp.update_inv_shoes()
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index f21d6443fb1..551449a8fb6 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -408,6 +408,10 @@ steam.start() -- spawns the effect
src.processing = 0
spawn(0)
var/turf/T = get_turf(src.holder)
+ if(istype(holder, /atom/movable))
+ var/atom/movable/AM = holder
+ if(AM.locs && AM.locs.len)
+ T = pick(AM.locs)
if(T != src.oldposition)
if(isturf(T))
var/obj/effect/effect/ion_trails/I = new /obj/effect/effect/ion_trails(src.oldposition)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 3ba9c1bac77..4e39439c124 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -492,13 +492,15 @@ var/list/global/slot_flags_enumeration = list(
user << "You cannot locate any eyes on [M]!"
return
- if(U.get_accuracy_penalty(U)) //Should only trigger if they're not aiming well
- var/hit_zone = get_zone_with_miss_chance(U.zone_sel.selecting, M, U.get_accuracy_penalty(U))
- if(!hit_zone)
- U.do_attack_animation(M)
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- visible_message("[U] attempts to stab [M] in the eyes, but misses!")
- return
+ //this should absolutely trigger even if not aim-impaired in some way
+ var/hit_zone = get_zone_with_miss_chance(U.zone_sel.selecting, M, U.get_accuracy_penalty(U))
+ if(!hit_zone)
+ U.do_attack_animation(M)
+ playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
+ //visible_message("[U] attempts to stab [M] in the eyes, but misses!")
+ for(var/mob/V in viewers(M))
+ V.show_message("[U] attempts to stab [M] in the eyes, but misses!")
+ return
add_attack_logs(user,M,"Attack eyes with [name]")
@@ -714,7 +716,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
icon = 'icons/obj/device.dmi'
//Worn icon generation for on-mob sprites
-/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer)
+/obj/item/proc/make_worn_icon(var/body_type,var/slot_name,var/inhands,var/default_icon,var/default_layer,var/icon/clip_mask = null) //VOREStation edit - add 'clip mask' argument.
//Get the required information about the base icon
var/icon/icon2use = get_worn_icon_file(body_type = body_type, slot_name = slot_name, default_icon = default_icon, inhands = inhands)
var/state2use = get_worn_icon_state(slot_name = slot_name)
@@ -736,6 +738,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
if(!inhands)
apply_custom(standing_icon) //Pre-image overridable proc to customize the thing
apply_addblends(icon2use,standing_icon) //Some items have ICON_ADD blend shaders
+ if(istype(clip_mask)) //VOREStation Edit - For taur bodies/tails clipping off parts of uniforms and suits.
+ standing_icon = get_icon_difference(standing_icon, clip_mask, 1)
var/image/standing = image(standing_icon)
standing.alpha = alpha
diff --git a/code/game/objects/items/bells.dm b/code/game/objects/items/bells.dm
index 43046d22b77..c7aa08a440f 100644
--- a/code/game/objects/items/bells.dm
+++ b/code/game/objects/items/bells.dm
@@ -10,6 +10,7 @@
attack_verb = list("annoyed")
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
var/static/radial_use = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_use")
+ var/static/radial_pickup = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup")
/obj/item/weapon/deskbell/examine(mob/user)
..()
@@ -26,6 +27,7 @@
//This defines the radials and what call we're assiging to them.
var/list/options = list()
options["examine"] = radial_examine
+ options["pick up"] = radial_pickup
if(!broken)
options["use"] = radial_use
@@ -54,6 +56,9 @@
ring(user)
add_fingerprint(user)
+ if("pick up")
+ ..()
+
/obj/item/weapon/deskbell/proc/ring(mob/user)
if(user.a_intent == "harm")
playsound(user.loc, 'sound/effects/deskbell_rude.ogg', 50, 1)
@@ -78,9 +83,16 @@
to_chat(user,"You are not able to ring [src].")
return 0
-/obj/item/weapon/deskbell/attackby(obj/item/i, mob/user, params)
- if(!istype(i))
+/obj/item/weapon/deskbell/attackby(obj/item/W, mob/user, params)
+ if(!istype(W))
return
+ if(W.is_wrench() && isturf(loc))
+ if(do_after(5))
+ if(!src) return
+ to_chat(user, "You dissasemble the desk bell")
+ new /obj/item/stack/material/steel(get_turf(src), 1)
+ qdel(src)
+ return
if(!broken)
ring(user)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index c2a77936c4e..46c425bb897 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -577,31 +577,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(mode==3)
- var/turf/T = get_turf(user.loc)
- if(!isnull(T))
- var/datum/gas_mixture/environment = T.return_air()
-
- var/pressure = environment.return_pressure()
- var/total_moles = environment.total_moles
-
- if (total_moles)
- var/o2_level = environment.gas["oxygen"]/total_moles
- var/n2_level = environment.gas["nitrogen"]/total_moles
- var/co2_level = environment.gas["carbon_dioxide"]/total_moles
- var/phoron_level = environment.gas["phoron"]/total_moles
- var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
- data["aircontents"] = list(\
- "pressure" = "[round(pressure,0.1)]",\
- "nitrogen" = "[round(n2_level*100,0.1)]",\
- "oxygen" = "[round(o2_level*100,0.1)]",\
- "carbon_dioxide" = "[round(co2_level*100,0.1)]",\
- "phoron" = "[round(phoron_level*100,0.01)]",\
- "other" = "[round(unknown_level, 0.01)]",\
- "temp" = "[round(environment.temperature-T0C,0.1)]",\
- "reading" = 1\
- )
- if(isnull(data["aircontents"]))
- data["aircontents"] = list("reading" = 0)
+ data["aircontents"] = src.analyze_air()
if(mode==6)
if(has_reception)
feeds.Cut()
@@ -1544,3 +1520,37 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/emp_act(severity)
for(var/atom/A in src)
A.emp_act(severity)
+
+/obj/item/device/pda/proc/analyze_air()
+ var/list/results = list()
+ var/turf/T = get_turf(src.loc)
+ if(!isnull(T))
+ var/datum/gas_mixture/environment = T.return_air()
+ var/pressure = environment.return_pressure()
+ var/total_moles = environment.total_moles
+ if (total_moles)
+ var/o2_level = environment.gas["oxygen"]/total_moles
+ var/n2_level = environment.gas["nitrogen"]/total_moles
+ var/co2_level = environment.gas["carbon_dioxide"]/total_moles
+ var/phoron_level = environment.gas["phoron"]/total_moles
+ var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
+
+ // entry is what the element is describing
+ // Type identifies which unit or other special characters to use
+ // Val is the information reported
+ // Bad_high/_low are the values outside of which the entry reports as dangerous
+ // Poor_high/_low are the values outside of which the entry reports as unideal
+ // Values were extracted from the template itself
+ results = list(
+ list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
+ list("entry" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
+ list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
+ list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
+ list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
+ list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
+ list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
+ )
+
+ if(isnull(results))
+ results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80))
+ return results
diff --git a/code/game/objects/items/devices/communicator/UI.dm b/code/game/objects/items/devices/communicator/UI.dm
index e37587812a0..a4859c08a56 100644
--- a/code/game/objects/items/devices/communicator/UI.dm
+++ b/code/game/objects/items/devices/communicator/UI.dm
@@ -116,7 +116,7 @@
data["flashlight"] = fon
data["manifest"] = PDA_Manifest
data["feeds"] = compile_news()
- data["latest_news"] = get_recent_news()
+ //data["latest_news"] = get_recent_news() //VOREStation Edit, bandaid for catastrophic runtime lag in helper.dm
if(cartridge) // If there's a cartridge, we need to grab the information from it
data["cart_devices"] = cartridge.get_device_status()
data["cart_templates"] = cartridge.ui_templates
diff --git a/code/game/objects/items/devices/communicator/helper.dm b/code/game/objects/items/devices/communicator/helper.dm
index b7a3b752d9f..273686fb463 100644
--- a/code/game/objects/items/devices/communicator/helper.dm
+++ b/code/game/objects/items/devices/communicator/helper.dm
@@ -19,17 +19,17 @@
// Poor_high/_low are the values outside of which the entry reports as unideal
// Values were extracted from the template itself
results = list(
- list("entry" = "Pressure", "type" = "pressure", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
- list("entry" = "Temperature", "type" = "temp", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
- list("entry" = "Oxygen", "type" = "pressure", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
- list("entry" = "Nitrogen", "type" = "pressure", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
- list("entry" = "Carbon Dioxide", "type" = "pressure", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
- list("entry" = "Phoron", "type" = "pressure", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
- list("entry" = "Other", "type" = "pressure", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
+ list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
+ list("entry" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
+ list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
+ list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
+ list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
+ list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
+ list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
)
if(isnull(results))
- results = list(list("entry" = "pressure", "val" = "0"))
+ results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80))
return results
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 1fd41ec768e..acc89b39dc3 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -122,9 +122,9 @@
if(use_external_power)
battery = get_external_power_supply()
- if(times_used <= max_flashes && battery && battery.checked_use(charge_cost))
+ if(times_used <= max_flashes && battery && battery.charge >= charge_cost)
last_used = world.time
- if(prob( max(0, times_used - safe_flashes) * 2 + (times_used >= 1) ) && can_break) //if you use it 10 times in a minute it has a 30% chance to break.
+ if(prob( max(0, times_used - safe_flashes) * 2 + (times_used >= safe_flashes)) && can_break) //if you use it 10 times in a minute it has a 30% chance to break.
broken = TRUE
if(user)
to_chat(user, "The bulb has burnt out!")
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index 839dc7a2dc2..830fa803e42 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -4,12 +4,12 @@ var/list/GPS_list = list()
name = "global positioning system"
desc = "Triangulates the approximate co-ordinates using a nearby satellite network. Alt+click to toggle power."
icon = 'icons/obj/gps.dmi'
- icon_state = "gps-c"
+ icon_state = "gps-gen"
w_class = ITEMSIZE_TINY
slot_flags = SLOT_BELT
origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_MAGNET = 1)
matter = list(DEFAULT_WALL_MATERIAL = 500)
- var/gps_tag = "COM0"
+ var/gps_tag = "GEN0"
var/emped = FALSE
var/tracking = FALSE // Will not show other signals or emit its own signal if false.
var/long_range = FALSE // If true, can see farther, depending on get_map_levels().
@@ -171,22 +171,43 @@ var/list/GPS_list = list()
/obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these.
tracking = TRUE
+/obj/item/device/gps/command
+ icon_state = "gps-com"
+ gps_tag = "COM0"
+
+/obj/item/device/gps/command/on
+ tracking = TRUE
+
+/obj/item/device/gps/security
+ icon_state = "gps-sec"
+ gps_tag = "SEC0"
+
+/obj/item/device/gps/security/on
+ tracking = TRUE
+
+/obj/item/device/gps/medical
+ icon_state = "gps-med"
+ gps_tag = "MED0"
+
+/obj/item/device/gps/medical/on
+ tracking = TRUE
+
/obj/item/device/gps/science
- icon_state = "gps-s"
+ icon_state = "gps-sci"
gps_tag = "SCI0"
/obj/item/device/gps/science/on
tracking = TRUE
/obj/item/device/gps/engineering
- icon_state = "gps-e"
+ icon_state = "gps-eng"
gps_tag = "ENG0"
/obj/item/device/gps/engineering/on
tracking = TRUE
/obj/item/device/gps/mining
- icon_state = "gps-m"
+ icon_state = "gps-mine"
gps_tag = "MINE0"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life. Alt+click to toggle power."
@@ -194,15 +215,15 @@ var/list/GPS_list = list()
tracking = TRUE
/obj/item/device/gps/explorer
- icon_state = "gps-ex"
- gps_tag = "EX0"
+ icon_state = "gps-exp"
+ gps_tag = "EXP0"
desc = "A positioning system helpful for rescuing trapped or injured explorers, keeping one on you at all times while exploring might just save your life. Alt+click to toggle power."
/obj/item/device/gps/explorer/on
tracking = TRUE
/obj/item/device/gps/robot
- icon_state = "gps-b"
+ icon_state = "gps-borg"
gps_tag = "SYNTH0"
desc = "A synthetic internal positioning system. Used as a recovery beacon for damaged synthetic assets, or a collaboration tool for mining or exploration teams. \
Alt+click to toggle power."
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 5a98c7f73cd..68c862db09d 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -526,9 +526,8 @@ var/global/list/default_medbay_channels = list(
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
- if(!position || !(position.z in level))
- if(!bluespace_radio) //VOREStation Edit
- return -1
+ if((!position || !(position.z in level)) && !bluespace_radio) //VOREStation Edit
+ return -1
if(freq in ANTAG_FREQS)
if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys
return -1
diff --git a/code/game/objects/items/devices/radio/radio_vr.dm b/code/game/objects/items/devices/radio/radio_vr.dm
index 26684ce704b..932229d0ad3 100644
--- a/code/game/objects/items/devices/radio/radio_vr.dm
+++ b/code/game/objects/items/devices/radio/radio_vr.dm
@@ -56,14 +56,14 @@
..()
/obj/item/device/subspaceradio/MouseDrop()
- if(ismob(loc))
- if(!CanMouseDrop(src))
- return
- var/mob/M = loc
- if(!M.unEquip(src))
- return
- add_fingerprint(usr)
- M.put_in_any_hand_if_possible(src)
+ if(ismob(loc))
+ if(!CanMouseDrop(src))
+ return
+ var/mob/M = loc
+ if(!M.unEquip(src))
+ return
+ add_fingerprint(usr)
+ M.put_in_any_hand_if_possible(src)
/obj/item/device/subspaceradio/attackby(obj/item/weapon/W, mob/user, params)
if(W == handset)
@@ -114,7 +114,7 @@
if(ismob(handset.loc))
var/mob/M = handset.loc
if(M.drop_from_inventory(handset, src))
- to_chat(user, "\The [handset] snap back into the main unit.")
+ to_chat(user, "\The [handset] snaps back into the main unit.")
else
handset.forceMove(src)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index ec121bfed2f..90ae753da2e 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -1,3 +1,4 @@
+#define DEFIB_TIME_LIMIT (10 MINUTES) //VOREStation addition- past this many seconds, defib is useless.
/*
CONTAINS:
T-RAY
@@ -54,6 +55,8 @@ HALOGEN COUNTER - Radcount on mobs
if (!(ishuman(user) || ticker) && ticker.mode.name != "monkey")
to_chat(user, "You don't have the dexterity to do this!")
return
+
+ flick("[icon_state]-scan", src) //makes it so that it plays the scan animation on a succesful scan
user.visible_message("[user] has analyzed [M]'s vitals.","You have analyzed [M]'s vitals.")
if (!ishuman(M) || M.isSynthetic())
@@ -81,8 +84,13 @@ HALOGEN COUNTER - Radcount on mobs
dat += "\tKey: Suffocation/Toxin/Burns/Brute
"
dat += "\tDamage Specifics: [OX] - [TX] - [BU] - [BR]
"
dat += "Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)
"
- if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
- dat += "Time of Death: [M.tod]
"
+ //VOREStation edit/addition starts
+ if(M.timeofdeath && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
+ dat += "Time of Death: [worldtime2stationtime(M.timeofdeath)]
"
+ var/tdelta = round(world.time - M.timeofdeath)
+ if(tdelta < (DEFIB_TIME_LIMIT * 10))
+ dat += "Subject died [DisplayTimeText(tdelta)] ago - resuscitation may be possible!
"
+ //VOREStation edit/addition ends
if(istype(M, /mob/living/carbon/human) && mode == 1)
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_organs(1,1)
@@ -501,3 +509,5 @@ HALOGEN COUNTER - Radcount on mobs
else
to_chat(user, "No radiation detected.")
return
+
+#undef DEFIB_TIME_LIMIT //VOREStation addition
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 6a51e9eb176..612a14c4d4f 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -220,6 +220,7 @@
W.heal_damage(heal_brute)
playsound(src, pick(apply_sounds), 25)
used = 1 //VOREStation Edit
+ update_icon() // VOREStation Edit - Support for stack icons
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
@@ -266,6 +267,7 @@
use(1)
affecting.salve()
playsound(src, pick(apply_sounds), 25)
+ update_icon() // VOREStation Edit - Support for stack icons
/obj/item/stack/medical/splint
name = "medical splints"
diff --git a/code/game/objects/items/stacks/medical_vr.dm b/code/game/objects/items/stacks/medical_vr.dm
new file mode 100644
index 00000000000..eda72a3fce9
--- /dev/null
+++ b/code/game/objects/items/stacks/medical_vr.dm
@@ -0,0 +1,21 @@
+/obj/item/stack/medical/advanced
+ icon = 'icons/obj/stacks_vr.dmi'
+
+/obj/item/stack/medical/advanced/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/stack/medical/advanced/update_icon()
+ switch(amount)
+ if(1 to 2)
+ icon_state = initial(icon_state)
+ if(3 to 4)
+ icon_state = "[initial(icon_state)]_4"
+ if(5 to 6)
+ icon_state = "[initial(icon_state)]_6"
+ if(7 to 8)
+ icon_state = "[initial(icon_state)]_8"
+ if(9)
+ icon_state = "[initial(icon_state)]_9"
+ else
+ icon_state = "[initial(icon_state)]_10"
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 93c70930d18..7c441e8169f 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -202,4 +202,12 @@
name = "roofing"
singular_name = "roofing"
desc = "A section of roofing material. You can use it to repair the ceiling, or expand it."
- icon_state = "techtile_grid"
\ No newline at end of file
+ icon_state = "techtile_grid"
+
+/obj/item/stack/tile/roofing/cyborg
+ name = "roofing synthesizer"
+ desc = "A device that makes roofing tiles."
+ uses_charge = 1
+ charge_costs = list(250)
+ stacktype = /obj/item/stack/tile/roofing
+ build_type = /obj/item/stack/tile/roofing
\ No newline at end of file
diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm
index 3d9c4ea140c..dd3ddb29caf 100644
--- a/code/game/objects/items/trash.dm
+++ b/code/game/objects/items/trash.dm
@@ -76,6 +76,10 @@
name = "\improper \"LiquidFood\" ration"
icon_state = "liquidfood"
+/obj/item/trash/liquidprotein
+ name = "\improper \"LiquidProtein\" ration"
+ icon_state = "liquidprotein"
+
/obj/item/trash/tastybread
name = "bread tube"
icon_state = "tastybread"
diff --git a/code/game/objects/items/trash_vr.dm b/code/game/objects/items/trash_vr.dm
index 43cadda3f70..20f7e32c4c4 100644
--- a/code/game/objects/items/trash_vr.dm
+++ b/code/game/objects/items/trash_vr.dm
@@ -26,11 +26,6 @@
return
..()
-/obj/item/trash/liquidprotein
- name = "\improper \"LiquidProtein\" ration"
- icon = 'icons/obj/trash_vr.dmi'
- icon_state = "liquidprotein"
-
/obj/item/trash/fancyplate
name = "dirty fancy plate"
icon = 'icons/obj/trash_vr.dmi'
diff --git a/code/game/objects/items/weapons/circuitboards/computer/computer.dm b/code/game/objects/items/weapons/circuitboards/computer/computer.dm
index 8bc26a13f1d..2190650d67e 100644
--- a/code/game/objects/items/weapons/circuitboards/computer/computer.dm
+++ b/code/game/objects/items/weapons/circuitboards/computer/computer.dm
@@ -191,3 +191,8 @@
name = T_BOARD("RCON remote control console")
build_path = /obj/machinery/computer/rcon
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3, TECH_POWER = 5)
+
+/obj/item/weapon/circuitboard/shutoff_monitor
+ name = T_BOARD("automatic shutoff valve monitor")
+ build_path = /obj/machinery/computer/shutoff_monitor
+ origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm
index 913506c9e65..6b59d13ea56 100644
--- a/code/game/objects/items/weapons/circuitboards/frame.dm
+++ b/code/game/objects/items/weapons/circuitboards/frame.dm
@@ -144,6 +144,14 @@
build_path = /obj/machinery/recharger/wallcharger
board_type = new /datum/frame/frame_types/wall_charger
+/obj/item/weapon/circuitboard/cell_charger
+ name = T_BOARD("heavy-duty cell charger")
+ build_path = /obj/machinery/cell_charger
+ board_type = new /datum/frame/frame_types/cell_charger
+ req_components = list(
+ /obj/item/weapon/stock_parts/capacitor = 1,
+ /obj/item/stack/cable_coil = 5)
+
/obj/item/weapon/circuitboard/washing
name = T_BOARD("washing machine")
build_path = /obj/machinery/washing_machine
@@ -162,6 +170,15 @@
/obj/item/weapon/stock_parts/gear = 1,
/obj/item/weapon/reagent_containers/glass/beaker/large = 1)
+/obj/item/weapon/circuitboard/distiller
+ build_path = /obj/machinery/portable_atmospherics/powered/reagent_distillery
+ board_type = new /datum/frame/frame_types/reagent_distillery
+ req_components = list(
+ /obj/item/weapon/stock_parts/capacitor = 1,
+ /obj/item/weapon/stock_parts/micro_laser = 1,
+ /obj/item/weapon/stock_parts/motor = 2,
+ /obj/item/weapon/stock_parts/gear = 1)
+
/obj/item/weapon/circuitboard/teleporter_hub
name = T_BOARD("teleporter hub")
build_path = /obj/machinery/teleport/hub
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index 86e3badc6fd..d4a29d47f33 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -13,6 +13,10 @@
var/atom/target = null
var/open_panel = 0
var/image_overlay = null
+ var/blast_dev = -1
+ var/blast_heavy = -1
+ var/blast_light = 2
+ var/blast_flash = 3
/obj/item/weapon/plastique/New()
wires = new(src)
@@ -72,7 +76,7 @@
if(!target)
target = src
if(location)
- explosion(location, -1, -1, 2, 3)
+ explosion(location, blast_dev, blast_heavy, blast_light, blast_flash)
if(target)
if (istype(target, /turf/simulated/wall))
@@ -88,3 +92,28 @@
/obj/item/weapon/plastique/attack(mob/M as mob, mob/user as mob, def_zone)
return
+
+/obj/item/weapon/plastique/seismic
+ name = "seismic charge"
+ desc = "Used to dig holes in specific areas without too much extra hole."
+
+ blast_heavy = 2
+ blast_light = 4
+ blast_flash = 7
+
+/obj/item/weapon/plastique/seismic/attackby(var/obj/item/I, var/mob/user)
+ . = ..()
+ if(open_panel)
+ if(istype(I, /obj/item/weapon/stock_parts/micro_laser))
+ var/obj/item/weapon/stock_parts/SP = I
+ var/new_blast_power = max(1, round(SP.rating / 2) + 1)
+ if(new_blast_power > blast_heavy)
+ to_chat(user, "You install \the [I] into \the [src].")
+ user.drop_from_inventory(I)
+ qdel(I)
+ blast_heavy = new_blast_power
+ blast_light = blast_heavy + round(new_blast_power * 0.5)
+ blast_flash = blast_light + round(new_blast_power * 0.75)
+ else
+ to_chat(user, "The [I] is not any better than the component already installed into this charge!")
+ return .
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/explosives_vr.dm b/code/game/objects/items/weapons/explosives_vr.dm
new file mode 100644
index 00000000000..a82ca02bbc8
--- /dev/null
+++ b/code/game/objects/items/weapons/explosives_vr.dm
@@ -0,0 +1,17 @@
+/obj/item/weapon/plastique/seismic/locked
+ desc = "Used to dig holes in specific areas without too much extra hole. Has extra mechanism that safely implodes the bomb if it is used in close proximity to the facility."
+
+/obj/item/weapon/plastique/seismic/locked/explode(var/location)
+ if(!target)
+ target = get_atom_on_turf(src)
+ if(!target)
+ target = src
+
+ var/turf/T = get_turf(target)
+ if(T.z in using_map.map_levels)
+ target.visible_message("\The [src] lets out a loud beep as safeties trigger, before imploding and falling apart.")
+ target.overlays -= image_overlay
+ qdel(src)
+ return 0
+ else
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm
index 7d725c36bba..625fb11e0cf 100644
--- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm
+++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm
@@ -41,6 +41,19 @@
/obj/item/weapon/grenade/spawnergrenade/manhacks/raider
spawner_type = /mob/living/simple_mob/mechanical/viscerator/raider
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station
+ desc = "It is set to detonate in 5 seconds. It will deploy three weaponized survey drones."
+ deliveryamt = 3
+ spawner_type = /mob/living/simple_mob/mechanical/viscerator/station
+ origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_ILLEGAL = 1)
+
+/obj/item/weapon/grenade/spawnergrenade/ward
+ name = "sentry delivery grenade"
+ desc = "It is set to detonate in 5 seconds. It will deploy a single thermal-optic sentry drone."
+ spawner_type = /mob/living/simple_mob/mechanical/ward/monitor/crew
+ deliveryamt = 1
+ origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_BLUESPACE = 2)
+
/obj/item/weapon/grenade/spawnergrenade/spesscarp
name = "carp delivery grenade"
spawner_type = /mob/living/simple_mob/animal/space/carp
diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm
new file mode 100644
index 00000000000..56204be9849
--- /dev/null
+++ b/code/game/objects/items/weapons/grenades/spawnergrenade_vr.dm
@@ -0,0 +1,30 @@
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked
+ desc = "It is set to detonate in 5 seconds. It will deploy three weaponized survey drones. This one has a safety interlock that prevents release if used while in proximity to the facility."
+ req_access = list(access_armory) //for toggling safety
+ var/locked = 1
+
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/detonate()
+ if(locked)
+ var/turf/T = get_turf(src)
+ if(T.z in using_map.map_levels)
+ icon_state = initial(icon_state)
+ active = 0
+ return 0
+ return ..()
+
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/attackby(obj/item/I, mob/user)
+ var/obj/item/weapon/card/id/id = I.GetID()
+ if(istype(id))
+ if(check_access(id))
+ locked = !locked
+ to_chat(user, "You [locked ? "enable" : "disable"] the safety lock on \the [src].")
+ else
+ to_chat(user, "Access denied.")
+ user.visible_message("[user] swipes \the [I] against \the [src].")
+ else
+ return ..()
+
+/obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked/emag_act(var/remaining_charges,var/mob/user)
+ ..()
+ locked = !locked
+ to_chat(user, "You [locked ? "enable" : "disable"] the safety lock on \the [src]!")
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/id cards/station_ids.dm b/code/game/objects/items/weapons/id cards/station_ids.dm
index c157d424925..4d37f154b36 100644
--- a/code/game/objects/items/weapons/id cards/station_ids.dm
+++ b/code/game/objects/items/weapons/id cards/station_ids.dm
@@ -31,6 +31,7 @@
var/dorm = 0 // determines if this ID has claimed a dorm already
var/mining_points = 0 // For redeeming at mining equipment vendors
+ var/survey_points = 0 // For redeeming at explorer equipment vendors.
/obj/item/weapon/card/id/examine(mob/user)
set src in oview(1)
@@ -170,7 +171,7 @@
/obj/item/weapon/card/id/synthetic/Initialize()
. = ..()
- access = get_all_station_access() + access_synth
+ access = get_all_station_access().Copy() + access_synth
/obj/item/weapon/card/id/centcom
name = "\improper CentCom. ID"
@@ -181,7 +182,7 @@
/obj/item/weapon/card/id/centcom/Initialize()
. = ..()
- access = get_all_centcom_access()
+ access = get_all_centcom_access().Copy()
/obj/item/weapon/card/id/centcom/station/Initialize()
. = ..()
diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm
index 0db669545c9..4911846d65b 100644
--- a/code/game/objects/items/weapons/manuals.dm
+++ b/code/game/objects/items/weapons/manuals.dm
@@ -98,11 +98,11 @@
| [prize.equipment_name] | [prize.cost] | Purchase |
| [current_species.blurb] | " + //vorestation edit begin + if(current_species.wikilink) + dat += "[current_species.blurb] See the wiki for more details. | "
+ else
+ dat += "[current_species.blurb] | " + //vorestation edit end dat += "" if("preview" in icon_states(current_species.icobase)) usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png") @@ -873,7 +878,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O dat += "You cannot play as this species.If you wish to be whitelisted, you can make an application post on the forums." else if(restricted == 2) dat += "You cannot play as this species.This species is not available for play as a station race.." - if(!restricted || check_rights(R_ADMIN, 0)) + if(!restricted || check_rights(R_ADMIN, 0) || current_species.spawn_flags & SPECIES_WHITELIST_SELECTABLE) //VOREStation Edit: selectability dat += "\[select\]" dat += " |