Merge remote-tracking branch 'origin/master' into what-should-i-name-this-branch
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
"name" = initial(item.name),
|
||||
"desc" = initial(item.desc),
|
||||
// at this point initializing the item is probably faster tbh
|
||||
"sprite" = icon2base64(icon(initial(item.icon), initial(item.icon_state))),
|
||||
"sprite" = icon2base64(icon(initial(item.icon), initial(item.icon_state), SOUTH, 1)),
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
@@ -2038,6 +2038,12 @@
|
||||
var/obj/item/station_charter/charter = locate(href_list["reject_custom_name"])
|
||||
if(istype(charter))
|
||||
charter.reject_proposed(usr)
|
||||
else if(href_list["approve_custom_name"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/obj/item/station_charter/charter = locate(href_list["approve_custom_name"])
|
||||
if(istype(charter))
|
||||
charter.allow_pass(usr)
|
||||
else if(href_list["jumpto"])
|
||||
if(!isobserver(usr) && !check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
var/selectors_used = FALSE
|
||||
var/list/combined_refs = list()
|
||||
do
|
||||
CHECK_TICK
|
||||
stoplag(2)
|
||||
finished = TRUE
|
||||
for(var/i in running)
|
||||
var/datum/SDQL2_query/query = i
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 30)
|
||||
addtimer(CALLBACK(user, /mob/living.proc/dropItemToGround, src, TRUE), 1) //equipped happens before putting stuff on(but not before picking items up), 1). thus, we need to wait for it to be on before forcing it off.
|
||||
|
||||
/obj/item/clothing/head/helmet/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
|
||||
/obj/item/clothing/head/helmet/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
|
||||
if(equipper && !is_servant_of_ratvar(equipper))
|
||||
return 0
|
||||
return ..()
|
||||
@@ -98,7 +98,7 @@
|
||||
max_heat_protection_temperature = initial(max_heat_protection_temperature)
|
||||
min_cold_protection_temperature = initial(min_cold_protection_temperature)
|
||||
|
||||
/obj/item/clothing/suit/armor/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
|
||||
/obj/item/clothing/suit/armor/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
|
||||
if(equipper && !is_servant_of_ratvar(equipper))
|
||||
return 0
|
||||
return ..()
|
||||
@@ -158,7 +158,7 @@
|
||||
max_heat_protection_temperature = initial(max_heat_protection_temperature)
|
||||
min_cold_protection_temperature = initial(min_cold_protection_temperature)
|
||||
|
||||
/obj/item/clothing/gloves/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
|
||||
/obj/item/clothing/gloves/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
|
||||
if(equipper && !is_servant_of_ratvar(equipper))
|
||||
return 0
|
||||
return ..()
|
||||
@@ -208,7 +208,7 @@
|
||||
else
|
||||
clothing_flags &= ~NOSLIP
|
||||
|
||||
/obj/item/clothing/shoes/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
|
||||
/obj/item/clothing/shoes/clockwork/mob_can_equip(M, equipper, slot, disable_warning, bypass_equip_delay_self)
|
||||
if(equipper && !is_servant_of_ratvar(equipper))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
)
|
||||
)
|
||||
fusion_power = 3
|
||||
enthalpy = -393500
|
||||
|
||||
/datum/gas/plasma
|
||||
id = GAS_PLASMA
|
||||
@@ -54,7 +55,10 @@
|
||||
heat_penalty = 15
|
||||
transmit_modifier = 4
|
||||
powermix = 1
|
||||
// no fire info cause it has its own bespoke reaction for trit generation reasons
|
||||
fire_burn_rate = OXYGEN_BURN_RATE_BASE // named when plasma fires were the only fires, surely
|
||||
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
|
||||
fire_products = "plasma_fire"
|
||||
enthalpy = FIRE_PLASMA_ENERGY_RELEASED // 3000000, 3 megajoules, 3000 kj
|
||||
|
||||
/datum/gas/water_vapor
|
||||
id = GAS_H2O
|
||||
@@ -64,6 +68,7 @@
|
||||
moles_visible = MOLES_GAS_VISIBLE
|
||||
fusion_power = 8
|
||||
heat_penalty = 8
|
||||
enthalpy = -241800 // FIRE_HYDROGEN_ENERGY_RELEASED is actually what this was supposed to be
|
||||
powermix = 1
|
||||
breath_reagent = /datum/reagent/water
|
||||
|
||||
@@ -84,6 +89,7 @@
|
||||
fire_products = list(GAS_N2 = 1)
|
||||
oxidation_rate = 0.5
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100
|
||||
enthalpy = 81600
|
||||
heat_resistance = 6
|
||||
|
||||
/datum/gas/nitryl
|
||||
@@ -95,8 +101,22 @@
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
fusion_power = 15
|
||||
fire_products = list(GAS_N2 = 0.5)
|
||||
enthalpy = 33200
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
|
||||
|
||||
/datum/gas/hydrogen
|
||||
id = GAS_HYDROGEN
|
||||
specific_heat = 10
|
||||
name = "Hydrogen"
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
fusion_power = 0
|
||||
powermix = 1
|
||||
heat_penalty = 3
|
||||
transmit_modifier = 10
|
||||
fire_products = list(GAS_H2O = 2)
|
||||
fire_burn_rate = 2
|
||||
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
|
||||
|
||||
/datum/gas/tritium
|
||||
id = GAS_TRITIUM
|
||||
specific_heat = 10
|
||||
@@ -108,13 +128,10 @@
|
||||
powermix = 1
|
||||
heat_penalty = 10
|
||||
transmit_modifier = 30
|
||||
/*
|
||||
these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons
|
||||
fire_provides = list(GAS_H2O = 2)
|
||||
fire_products = list(GAS_H2O = 2)
|
||||
fire_burn_rate = 2
|
||||
fire_energy_released = FIRE_HYDROGEN_ENERGY_RELEASED
|
||||
fire_radiation_released = 50 // arbitrary number, basically 60 moles of trit burning will just barely start to harm you
|
||||
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
|
||||
*/
|
||||
|
||||
/datum/gas/bz
|
||||
id = GAS_BZ
|
||||
@@ -124,6 +141,7 @@
|
||||
fusion_power = 8
|
||||
powermix = 1
|
||||
heat_penalty = 5
|
||||
enthalpy = FIRE_CARBON_ENERGY_RELEASED // it is a mystery
|
||||
transmit_modifier = -2
|
||||
radioactivity_modifier = 5
|
||||
|
||||
@@ -139,7 +157,8 @@
|
||||
name = "Pluoxium"
|
||||
fusion_power = 10
|
||||
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 1000 // it is VERY stable
|
||||
oxidation_rate = 8
|
||||
oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT
|
||||
enthalpy = -50000 // but it reduces the heat output a bit
|
||||
powermix = -1
|
||||
heat_penalty = -1
|
||||
transmit_modifier = -5
|
||||
@@ -172,7 +191,7 @@
|
||||
alert_type = /atom/movable/screen/alert/too_much_ch4
|
||||
)
|
||||
)
|
||||
fire_energy_released = FIRE_CARBON_ENERGY_RELEASED
|
||||
enthalpy = -74600
|
||||
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
|
||||
|
||||
/datum/gas/methyl_bromide
|
||||
@@ -192,7 +211,28 @@
|
||||
alert_type = /atom/movable/screen/alert/too_much_ch3br
|
||||
)
|
||||
)
|
||||
fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BZ = 0.5)
|
||||
fire_energy_released = FIRE_CARBON_ENERGY_RELEASED
|
||||
fire_burn_rate = 0.5
|
||||
fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BROMINE = 0.5)
|
||||
enthalpy = -35400
|
||||
fire_burn_rate = 4 / 7 // oh no
|
||||
fire_temperature = 808 // its autoignition, it apparently doesn't spark readily, so i don't put it lower
|
||||
|
||||
/datum/gas/bromine
|
||||
id = GAS_BROMINE
|
||||
specific_heat = 76
|
||||
name = "Bromine"
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
group = GAS_GROUP_CHEMICALS
|
||||
enthalpy = 193 // yeah it's small but it's good to include it
|
||||
breath_reagent = /datum/reagent/bromine
|
||||
|
||||
/datum/gas/ammonia
|
||||
id = GAS_AMMONIA
|
||||
specific_heat = 35
|
||||
name = "Ammonia"
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
group = GAS_GROUP_CHEMICALS
|
||||
enthalpy = -45900
|
||||
breath_reagent = /datum/reagent/ammonia
|
||||
fire_products = list(GAS_H2O = 1.5, GAS_N2 = 0.5)
|
||||
fire_burn_rate = 4/3
|
||||
fire_temperature = 924
|
||||
|
||||
@@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
/proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas
|
||||
|
||||
/datum/auxgm
|
||||
var/done_initializing = FALSE
|
||||
var/list/datums = list()
|
||||
var/list/specific_heats = list()
|
||||
var/list/names = list()
|
||||
@@ -32,30 +33,34 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
var/list/oxidation_temperatures = list()
|
||||
var/list/oxidation_rates = list()
|
||||
var/list/fire_temperatures = list()
|
||||
var/list/fire_enthalpies = list()
|
||||
var/list/enthalpies = list()
|
||||
var/list/fire_products = list()
|
||||
var/list/fire_burn_rates = list()
|
||||
var/list/supermatter = list()
|
||||
|
||||
var/list/groups_by_gas = list()
|
||||
var/list/groups = list()
|
||||
|
||||
/datum/gas
|
||||
var/id = ""
|
||||
var/specific_heat = 0
|
||||
var/name = ""
|
||||
var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi
|
||||
var/color = "#ffff"
|
||||
var/moles_visible = null
|
||||
var/flags = NONE //currently used by canisters
|
||||
var/group = null // groups for scrubber/filter listing
|
||||
var/fusion_power = 0 // How much the gas destabilizes a fusion reaction
|
||||
var/breath_results = GAS_CO2 // what breathing this breathes out
|
||||
var/breath_reagent = null // what breathing this adds to your reagents
|
||||
var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
|
||||
var/datum/reagent/breath_reagent = null // what breathing this adds to your reagents
|
||||
var/datum/reagent/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
|
||||
var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something
|
||||
var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none
|
||||
var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material
|
||||
var/fire_temperature = null // temperature above which gas may catch fire; null for none
|
||||
var/list/fire_products = null // what results when this gas is burned (oxidizer or fuel); null for none
|
||||
var/fire_energy_released = 0 // how much energy is released per mole of fuel burned
|
||||
var/enthalpy = 0 // Standard enthalpy of formation in joules, used for fires
|
||||
var/fire_burn_rate = 1 // how many moles are burned per product released
|
||||
var/fire_radiation_released = 0 // How much radiation is released when this gas burns
|
||||
var/powermix = 0 // how much this gas contributes to the supermatter's powermix ratio
|
||||
var/heat_penalty = 0 // heat and waste penalty from having the supermatter crystal surrounded by this gas; negative numbers reduce
|
||||
var/transmit_modifier = 0 // bonus to supermatter power generation (multiplicative, since it's % based, and divided by 10)
|
||||
@@ -94,21 +99,31 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
breath_reagents[g] = gas.breath_reagent
|
||||
if(gas.breath_reagent_dangerous)
|
||||
breath_reagents_dangerous[g] = gas.breath_reagent_dangerous
|
||||
|
||||
if(gas.oxidation_temperature)
|
||||
oxidation_temperatures[g] = gas.oxidation_temperature
|
||||
oxidation_rates[g] = gas.oxidation_rate
|
||||
if(gas.fire_products)
|
||||
fire_products[g] = gas.fire_products
|
||||
fire_enthalpies[g] = gas.fire_energy_released
|
||||
enthalpies[g] = gas.enthalpy
|
||||
else if(gas.fire_temperature)
|
||||
fire_temperatures[g] = gas.fire_temperature
|
||||
fire_burn_rates[g] = gas.fire_burn_rate
|
||||
if(gas.fire_products)
|
||||
fire_products[g] = gas.fire_products
|
||||
fire_enthalpies[g] = gas.fire_energy_released
|
||||
enthalpies[g] = gas.enthalpy
|
||||
if(gas.group)
|
||||
if(!(gas.group in groups))
|
||||
groups[gas.group] = list()
|
||||
groups[gas.group] += gas
|
||||
groups_by_gas[g] = gas.group
|
||||
add_supermatter_properties(gas)
|
||||
_auxtools_register_gas(gas)
|
||||
if(done_initializing)
|
||||
for(var/r in SSair.gas_reactions)
|
||||
var/datum/gas_reaction/R = r
|
||||
R.init_reqs()
|
||||
SSair.auxtools_update_reactions()
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_GAS, g)
|
||||
|
||||
/proc/finalize_gas_refs()
|
||||
|
||||
@@ -127,6 +142,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
for(var/breathing_class_path in subtypesof(/datum/breathing_class))
|
||||
var/datum/breathing_class/class = new breathing_class_path
|
||||
breathing_classes[breathing_class_path] = class
|
||||
done_initializing = TRUE
|
||||
finalize_gas_refs()
|
||||
|
||||
|
||||
|
||||
@@ -53,23 +53,68 @@
|
||||
id = "vapor"
|
||||
|
||||
/datum/gas_reaction/water_vapor/init_reqs()
|
||||
min_requirements = list(GAS_H2O = MOLES_GAS_VISIBLE)
|
||||
min_requirements = list(
|
||||
GAS_H2O = MOLES_GAS_VISIBLE,
|
||||
"MAX_TEMP" = T0C + 40
|
||||
)
|
||||
|
||||
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
|
||||
var/turf/open/location = isturf(holder) ? holder : null
|
||||
. = NO_REACTION
|
||||
var/turf/open/location = holder
|
||||
if(!istype(location))
|
||||
return NO_REACTION
|
||||
if (air.return_temperature() <= WATER_VAPOR_FREEZE)
|
||||
if(location && location.freon_gas_act())
|
||||
. = REACTING
|
||||
return REACTING
|
||||
else if(location && location.water_vapor_gas_act())
|
||||
air.adjust_moles(GAS_H2O,-MOLES_GAS_VISIBLE)
|
||||
. = REACTING
|
||||
return REACTING
|
||||
|
||||
// no test cause it's entirely based on location
|
||||
|
||||
/datum/gas_reaction/condensation
|
||||
priority = 0
|
||||
name = "Condensation"
|
||||
id = "condense"
|
||||
exclude = TRUE
|
||||
var/datum/reagent/condensing_reagent
|
||||
|
||||
/datum/gas_reaction/condensation/New(datum/reagent/R)
|
||||
. = ..()
|
||||
if(!istype(R))
|
||||
return
|
||||
min_requirements = list(
|
||||
"MAX_TEMP" = initial(R.boiling_point)
|
||||
)
|
||||
min_requirements[R.get_gas()] = MOLES_GAS_VISIBLE
|
||||
name = "[R.name] condensation"
|
||||
id = "[R.type] condensation"
|
||||
condensing_reagent = R
|
||||
exclude = FALSE
|
||||
|
||||
/datum/gas_reaction/condensation/react(datum/gas_mixture/air, datum/holder)
|
||||
. = NO_REACTION
|
||||
var/turf/open/location = holder
|
||||
if(!istype(location))
|
||||
return
|
||||
var/temperature = air.return_temperature()
|
||||
var/static/datum/reagents/reagents_holder = new
|
||||
reagents_holder.clear_reagents()
|
||||
reagents_holder.chem_temp = temperature
|
||||
var/G = condensing_reagent.get_gas()
|
||||
var/amt = air.get_moles(G)
|
||||
air.adjust_moles(G, -min(initial(condensing_reagent.condensation_amount), amt))
|
||||
reagents_holder.add_reagent(condensing_reagent, amt)
|
||||
. = REACTING
|
||||
for(var/atom/movable/AM in location)
|
||||
if(location.intact && AM.level == 1)
|
||||
continue
|
||||
reagents_holder.reaction(AM, TOUCH)
|
||||
reagents_holder.reaction(location, TOUCH)
|
||||
|
||||
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
|
||||
/datum/gas_reaction/tritfire
|
||||
priority = -1 //fire should ALWAYS be last, but tritium fires happen before plasma fires
|
||||
exclude = TRUE // generic fire now takes care of this
|
||||
name = "Tritium Combustion"
|
||||
id = "tritfire"
|
||||
|
||||
@@ -88,9 +133,9 @@
|
||||
item.temperature_expose(air, temperature, CELL_VOLUME)
|
||||
location.temperature_expose(air, temperature, CELL_VOLUME)
|
||||
|
||||
/proc/radiation_burn(turf/open/location, energy_released)
|
||||
/proc/radiation_burn(turf/open/location, rad_power)
|
||||
if(istype(location) && prob(10))
|
||||
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
|
||||
radiation_pulse(location, rad_power)
|
||||
|
||||
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
|
||||
var/energy_released = 0
|
||||
@@ -151,6 +196,7 @@
|
||||
/datum/gas_reaction/plasmafire
|
||||
priority = -2 //fire should ALWAYS be last, but plasma fires happen after tritium fires
|
||||
name = "Plasma Combustion"
|
||||
exclude = TRUE // generic fire now takes care of this
|
||||
id = "plasmafire"
|
||||
|
||||
/datum/gas_reaction/plasmafire/init_reqs()
|
||||
@@ -300,7 +346,7 @@
|
||||
fuels[fuel] *= oxidation_ratio
|
||||
fuels += oxidizers
|
||||
var/list/fire_products = GLOB.gas_data.fire_products
|
||||
var/list/fire_enthalpies = GLOB.gas_data.fire_enthalpies
|
||||
var/list/fire_enthalpies = GLOB.gas_data.enthalpies
|
||||
for(var/fuel in fuels + oxidizers)
|
||||
var/amt = fuels[fuel]
|
||||
if(!burn_results[fuel])
|
||||
|
||||
@@ -535,7 +535,7 @@
|
||||
for(var/device_id in A.air_scrub_names)
|
||||
send_signal(device_id, list(
|
||||
"power" = 1,
|
||||
"set_filters" = list(GAS_CO2, GAS_MIASMA),
|
||||
"set_filters" = list(GAS_CO2, GAS_MIASMA, GAS_GROUP_CHEMICALS),
|
||||
"scrubbing" = 1,
|
||||
"widenet" = 0,
|
||||
))
|
||||
@@ -554,6 +554,7 @@
|
||||
GAS_MIASMA,
|
||||
GAS_PLASMA,
|
||||
GAS_H2O,
|
||||
GAS_HYDROGEN,
|
||||
GAS_HYPERNOB,
|
||||
GAS_NITROUS,
|
||||
GAS_NITRYL,
|
||||
@@ -562,7 +563,8 @@
|
||||
GAS_STIMULUM,
|
||||
GAS_PLUOXIUM,
|
||||
GAS_METHANE,
|
||||
GAS_METHYL_BROMIDE
|
||||
GAS_METHYL_BROMIDE,
|
||||
GAS_GROUP_CHEMICALS
|
||||
),
|
||||
"scrubbing" = 1,
|
||||
"widenet" = 1,
|
||||
@@ -582,9 +584,16 @@
|
||||
))
|
||||
for(var/device_id in A.air_vent_names)
|
||||
send_signal(device_id, list(
|
||||
"is_pressurizing" = 1,
|
||||
"power" = 1,
|
||||
"checks" = 1,
|
||||
"set_external_pressure" = ONE_ATMOSPHERE*2
|
||||
"set_external_pressure" = ONE_ATMOSPHERE*1.4
|
||||
))
|
||||
send_signal(device_id, list(
|
||||
"is_siphoning" = 1,
|
||||
"power" = 1,
|
||||
"checks" = 1,
|
||||
"set_external_pressure" = ONE_ATMOSPHERE/1.4
|
||||
))
|
||||
if(AALARM_MODE_REFILL)
|
||||
for(var/device_id in A.air_scrub_names)
|
||||
@@ -596,10 +605,15 @@
|
||||
))
|
||||
for(var/device_id in A.air_vent_names)
|
||||
send_signal(device_id, list(
|
||||
"is_pressurizing" = 1,
|
||||
"power" = 1,
|
||||
"checks" = 1,
|
||||
"set_external_pressure" = ONE_ATMOSPHERE * 3
|
||||
))
|
||||
send_signal(device_id, list(
|
||||
"is_siphoning" = 1,
|
||||
"power" = 0,
|
||||
))
|
||||
if(AALARM_MODE_PANIC,
|
||||
AALARM_MODE_REPLACEMENT)
|
||||
for(var/device_id in A.air_scrub_names)
|
||||
@@ -610,8 +624,14 @@
|
||||
))
|
||||
for(var/device_id in A.air_vent_names)
|
||||
send_signal(device_id, list(
|
||||
"is_pressurizing" = 1,
|
||||
"power" = 0
|
||||
))
|
||||
send_signal(device_id, list(
|
||||
"is_siphoning" = 1,
|
||||
"power" = 1,
|
||||
"checks" = 0
|
||||
))
|
||||
if(AALARM_MODE_SIPHON)
|
||||
for(var/device_id in A.air_scrub_names)
|
||||
send_signal(device_id, list(
|
||||
@@ -621,9 +641,14 @@
|
||||
))
|
||||
for(var/device_id in A.air_vent_names)
|
||||
send_signal(device_id, list(
|
||||
"is_pressurizing" = 1,
|
||||
"power" = 0
|
||||
))
|
||||
|
||||
send_signal(device_id, list(
|
||||
"is_siphoning" = 1,
|
||||
"power" = 1,
|
||||
"checks" = 0
|
||||
))
|
||||
if(AALARM_MODE_OFF)
|
||||
for(var/device_id in A.air_scrub_names)
|
||||
send_signal(device_id, list(
|
||||
@@ -641,8 +666,12 @@
|
||||
for(var/device_id in A.air_vent_names)
|
||||
send_signal(device_id, list(
|
||||
"power" = 1,
|
||||
"checks" = 2,
|
||||
"set_internal_pressure" = 0
|
||||
"checks" = 0,
|
||||
"is_pressurizing" = 1
|
||||
))
|
||||
send_signal(device_id, list(
|
||||
"power" = 0,
|
||||
"is_siphoning" = 1
|
||||
))
|
||||
|
||||
/obj/machinery/airalarm/update_icon_state()
|
||||
|
||||
@@ -94,7 +94,10 @@
|
||||
if(transfer_ratio > 0)
|
||||
|
||||
if(filter_type && air2.return_pressure() <= 9000)
|
||||
air1.scrub_into(air2, transfer_ratio, list(filter_type))
|
||||
if(filter_type in GLOB.gas_data.groups)
|
||||
air1.scrub_into(air2, transfer_ratio, GLOB.gas_data.groups[filter_type])
|
||||
else
|
||||
air1.scrub_into(air2, transfer_ratio, list(filter_type))
|
||||
if(air3.return_pressure() <= 9000)
|
||||
air1.transfer_ratio_to(air3, transfer_ratio)
|
||||
|
||||
@@ -119,8 +122,10 @@
|
||||
data["filter_types"] = list()
|
||||
data["filter_types"] += list(list("name" = "Nothing", "id" = "", "selected" = !filter_type))
|
||||
for(var/id in GLOB.gas_data.ids)
|
||||
data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type)))
|
||||
|
||||
if(!(id in GLOB.gas_data.groups_by_gas))
|
||||
data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type)))
|
||||
for(var/group in GLOB.gas_data.groups)
|
||||
data["filter_types"] += list(list("name" = group, "id" = group, "selected" = (group == filter_type)))
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params)
|
||||
|
||||
@@ -178,6 +178,9 @@
|
||||
|
||||
var/mob/signal_sender = signal.data["user"]
|
||||
|
||||
if((("is_siphoning" in signal.data) && pump_direction == RELEASING) || (("is_pressurizing" in signal.data) && pump_direction == SIPHONING))
|
||||
return
|
||||
|
||||
if("purge" in signal.data)
|
||||
pressure_checks &= ~EXT_BOUND
|
||||
pump_direction = SIPHONING
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
var/id_tag = null
|
||||
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
|
||||
|
||||
var/filter_types = list(GAS_CO2)
|
||||
var/filter_types = list(GAS_CO2, GAS_MIASMA, GAS_GROUP_CHEMICALS)
|
||||
var/list/clean_filter_types = null
|
||||
var/volume_rate = 200
|
||||
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
|
||||
var/list/turf/adjacent_turfs = list()
|
||||
@@ -34,6 +35,16 @@
|
||||
..()
|
||||
if(!id_tag)
|
||||
id_tag = assign_uid_vents()
|
||||
generate_clean_filter_types()
|
||||
RegisterSignal(SSdcs,COMSIG_GLOB_NEW_GAS,.proc/generate_clean_filter_types)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/generate_clean_filter_types()
|
||||
clean_filter_types = list()
|
||||
for(var/id in filter_types)
|
||||
if(id in GLOB.gas_data.groups)
|
||||
clean_filter_types += GLOB.gas_data.groups[id]
|
||||
else
|
||||
clean_filter_types += id
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
|
||||
var/area/A = get_base_area(src)
|
||||
@@ -95,7 +106,11 @@
|
||||
|
||||
var/list/f_types = list()
|
||||
for(var/id in GLOB.gas_data.ids)
|
||||
f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types)))
|
||||
if(!(id in GLOB.gas_data.groups_by_gas))
|
||||
f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types)))
|
||||
|
||||
for(var/group in GLOB.gas_data.groups)
|
||||
f_types += list(list("gas_id" = group, "gas_name" = group, "enabled" = (group in filter_types)))
|
||||
|
||||
var/datum/signal/signal = new(list(
|
||||
"tag" = id_tag,
|
||||
@@ -147,11 +162,11 @@
|
||||
var/datum/gas_mixture/environment = tile.return_air()
|
||||
var/datum/gas_mixture/air_contents = airs[1]
|
||||
|
||||
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(filter_types))
|
||||
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(clean_filter_types))
|
||||
return FALSE
|
||||
|
||||
if(scrubbing & SCRUBBING)
|
||||
environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types)
|
||||
environment.scrub_into(air_contents, volume_rate/environment.return_volume(), clean_filter_types)
|
||||
|
||||
tile.air_update_turf()
|
||||
|
||||
@@ -205,11 +220,13 @@
|
||||
|
||||
if("toggle_filter" in signal.data)
|
||||
filter_types ^= signal.data["toggle_filter"]
|
||||
generate_clean_filter_types()
|
||||
|
||||
if("set_filters" in signal.data)
|
||||
filter_types = list()
|
||||
for(var/gas in signal.data["set_filters"])
|
||||
filter_types += gas
|
||||
generate_clean_filter_types()
|
||||
|
||||
if("init" in signal.data)
|
||||
name = signal.data["init"]
|
||||
|
||||
@@ -171,6 +171,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/auto_fit_viewport = FALSE
|
||||
///Should we be in the widescreen mode set by the config?
|
||||
var/widescreenpref = TRUE
|
||||
///Strip menu style
|
||||
var/long_strip_menu = FALSE
|
||||
///What size should pixels be displayed as? 0 is strech to fit
|
||||
var/pixel_size = 0
|
||||
///What scaling method should we use?
|
||||
@@ -829,6 +831,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat +="<td width='300px' height='300px' valign='top'>"
|
||||
dat += "<h2>Citadel Preferences</h2>" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
|
||||
dat += "<b>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
|
||||
dat += "<b>Long strip menu:</b> <a href='?_src_=prefs;preference=long_strip_menu'>[long_strip_menu ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>Auto stand:</b> <a href='?_src_=prefs;preference=autostand'>[autostand ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>Auto OOC:</b> <a href='?_src_=prefs;preference=auto_ooc'>[auto_ooc ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>Force Slot Storage HUD:</b> <a href='?_src_=prefs;preference=no_tetris_storage'>[no_tetris_storage ? "Enabled" : "Disabled"]</a><br>"
|
||||
@@ -2591,6 +2594,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("widescreenpref")
|
||||
widescreenpref = !widescreenpref
|
||||
user.client.view_size.setDefault(getScreenSize(widescreenpref))
|
||||
if("long_strip_menu")
|
||||
long_strip_menu = !long_strip_menu
|
||||
|
||||
if("pixel_size")
|
||||
switch(pixel_size)
|
||||
|
||||
@@ -410,6 +410,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["ambientocclusion"] >> ambientocclusion
|
||||
S["auto_fit_viewport"] >> auto_fit_viewport
|
||||
S["widescreenpref"] >> widescreenpref
|
||||
S["long_strip_menu"] >> long_strip_menu
|
||||
S["pixel_size"] >> pixel_size
|
||||
S["scaling_method"] >> scaling_method
|
||||
S["hud_toggle_flash"] >> hud_toggle_flash
|
||||
@@ -472,6 +473,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
|
||||
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
|
||||
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
|
||||
long_strip_menu = sanitize_integer(long_strip_menu, 0, 1, initial(long_strip_menu))
|
||||
pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size))
|
||||
scaling_method = sanitize_text(scaling_method, initial(scaling_method))
|
||||
hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash))
|
||||
@@ -604,6 +606,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["damagescreenshake"], damagescreenshake)
|
||||
WRITE_FILE(S["arousable"], arousable)
|
||||
WRITE_FILE(S["widescreenpref"], widescreenpref)
|
||||
WRITE_FILE(S["long_strip_menu"], long_strip_menu)
|
||||
WRITE_FILE(S["autostand"], autostand)
|
||||
WRITE_FILE(S["cit_toggles"], cit_toggles)
|
||||
WRITE_FILE(S["preferred_chaos"], preferred_chaos)
|
||||
|
||||
@@ -443,7 +443,7 @@ BLIND // can't see anything
|
||||
..()
|
||||
|
||||
//Species-restricted clothing check. - Thanks Oraclestation, BS13, /vg/station etc.
|
||||
/obj/item/clothing/mob_can_equip(mob/M, slot, disable_warning = TRUE)
|
||||
/obj/item/clothing/mob_can_equip(M, equipper, slot, disable_warning = TRUE, bypass_equip_delay_self)
|
||||
|
||||
//if we can't equip the item anyway, don't bother with species_restricted (also cuts down on spam)
|
||||
if(!..())
|
||||
|
||||
@@ -267,9 +267,15 @@
|
||||
desc = "A specialized pair of combat boots with a built-in propulsion system for rapid foward movement."
|
||||
icon_state = "jetboots"
|
||||
resistance_flags = FIRE_PROOF
|
||||
cold_protection = FEET|LEGS
|
||||
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
|
||||
heat_protection = FEET|LEGS
|
||||
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
|
||||
pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes
|
||||
actions_types = list(/datum/action/item_action/bhop)
|
||||
permeability_coefficient = 0.05
|
||||
unique_reskin = list("Explorer" = "miningjet",
|
||||
"Jackboot" = "jetboots")
|
||||
var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles
|
||||
var/jumpspeed = 3
|
||||
var/recharging_rate = 60 //default 6 seconds between each dash
|
||||
|
||||
@@ -637,7 +637,7 @@
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/clown
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/clown/mob_can_equip(mob/M, slot)
|
||||
/obj/item/clothing/suit/space/hardsuit/clown/mob_can_equip(mob/M, equipper, slot, disable_warning, bypass_equip_delay_self)
|
||||
if(!..() || !ishuman(M))
|
||||
return FALSE
|
||||
if(M.mind && HAS_TRAIT(M.mind, TRAIT_CLOWN_MENTALITY))
|
||||
|
||||
@@ -245,6 +245,8 @@
|
||||
those who wish to spit in the eyes of God. Sacrifices outright damage for \
|
||||
a reliance on backstabs and the ability to give fauna concussions on a parry."
|
||||
attack_verb = list("pummeled", "punched", "jabbed", "hammer-fisted", "uppercut", "slammed")
|
||||
hitsound = 'sound/weapons/resonator_blast.ogg'
|
||||
sharpness = SHARP_NONE // use your survival dagger or smth
|
||||
icon_state = "crusher-hands"
|
||||
item_state = "crusher0-fist"
|
||||
unique_reskin = list("Gauntlets" = "crusher-hands",
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
limb_destroyer = 1
|
||||
hud_type = /datum/hud/alien
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
var/caste = ""
|
||||
var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
|
||||
var/leap_on_click = 0
|
||||
@@ -22,41 +20,26 @@
|
||||
|
||||
can_ventcrawl = TRUE
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_alien_humanoid_items, create_strippable_list(list(
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/Initialize()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
|
||||
. = ..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -3)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_alien_humanoid_items)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
|
||||
return handcuffed
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/list/dat = list()
|
||||
dat += {"
|
||||
<HR>
|
||||
<span class='big bold'>[name]</span>
|
||||
<HR>"}
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=[REF(src)];item=[SLOT_HANDS];hand_index=[i]'>[(I && !(I.item_flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><A href='?src=[REF(src)];pouches=1'>Empty Pouches</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_HANDCUFFED]'>Handcuffed</A>"
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_LEGCUFFED]'>Legcuffed</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=[REF(user)];mach_close=mob[REF(src)]'>Close</A>
|
||||
"}
|
||||
user << browse(dat.Join(), "window=mob[REF(src)];size=325x500")
|
||||
onclose(user, "mob[REF(src)]")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/Topic(href, href_list)
|
||||
..()
|
||||
//strip panel & embeds
|
||||
@@ -70,12 +53,6 @@
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L)
|
||||
return
|
||||
if(href_list["pouches"])
|
||||
visible_message("<span class='danger'>[usr] tries to empty [src]'s pouches.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to empty [src]'s pouches.</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
|
||||
dropItemToGround(r_store)
|
||||
dropItemToGround(l_store)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
|
||||
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
|
||||
|
||||
@@ -51,10 +51,6 @@
|
||||
// new damage icon system
|
||||
// now constructs damage icon for each organ from mask * damage field
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/show_inv(mob/user)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/toggle_throw_mode()
|
||||
return
|
||||
|
||||
|
||||
@@ -229,61 +229,8 @@
|
||||
/mob/living/carbon/proc/canBeHandcuffed()
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/carbon/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>
|
||||
<BR><B>Head:</B> <A href='?src=[REF(src)];item=[SLOT_HEAD]'> [(head && !(head.item_flags & ABSTRACT)) ? head : "Nothing"]</A>
|
||||
<BR><B>Mask:</B> <A href='?src=[REF(src)];item=[SLOT_WEAR_MASK]'> [(wear_mask && !(wear_mask.item_flags & ABSTRACT)) ? wear_mask : "Nothing"]</A>
|
||||
<BR><B>Neck:</B> <A href='?src=[REF(src)];item=[SLOT_NECK]'> [(wear_neck && !(wear_neck.item_flags & ABSTRACT)) ? wear_neck : "Nothing"]</A>"}
|
||||
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B></td><td><A href='?src=[REF(src)];item=[SLOT_HANDS];hand_index=[i]'>[(I && !(I.item_flags & ABSTRACT)) ? I : "Nothing"]</a>"
|
||||
|
||||
dat += "<BR><B>Back:</B> <A href='?src=[REF(src)];item=[SLOT_BACK]'>[back ? back : "Nothing"]</A>"
|
||||
|
||||
if(!HAS_TRAIT(src, TRAIT_NO_INTERNALS) && istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
|
||||
dat += "<BR><A href='?src=[REF(src)];internal=1'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_HANDCUFFED]'>Handcuffed</A>"
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=[REF(src)];item=[SLOT_LEGCUFFED]'>Legcuffed</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=[REF(user)];mach_close=mob[REF(src)]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[REF(src)];size=325x500")
|
||||
onclose(user, "mob[REF(src)]")
|
||||
|
||||
/mob/living/carbon/Topic(href, href_list)
|
||||
..()
|
||||
//strip panel
|
||||
if(usr.canUseTopic(src, BE_CLOSE))
|
||||
if(href_list["internal"] && !HAS_TRAIT(src, TRAIT_NO_INTERNALS))
|
||||
var/slot = text2num(href_list["internal"])
|
||||
var/obj/item/ITEM = get_item_by_slot(slot)
|
||||
if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS))
|
||||
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>", \
|
||||
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on your [ITEM.name].</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You try to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY))
|
||||
if(internal)
|
||||
internal = null
|
||||
update_internals_hud_icon(0)
|
||||
else if(ITEM && istype(ITEM, /obj/item/tank))
|
||||
if((wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS)) || getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
internal = ITEM
|
||||
update_internals_hud_icon(1)
|
||||
|
||||
visible_message("<span class='danger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>", \
|
||||
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on your [ITEM.name].</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>")
|
||||
if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE))
|
||||
var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts
|
||||
if(!L)
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/datum/strippable_item/mob_item_slot/head
|
||||
key = STRIPPABLE_ITEM_HEAD
|
||||
item_slot = SLOT_HEAD
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back
|
||||
key = STRIPPABLE_ITEM_BACK
|
||||
item_slot = SLOT_BACK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/back/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
return strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/mask
|
||||
key = STRIPPABLE_ITEM_MASK
|
||||
item_slot = SLOT_WEAR_MASK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/neck
|
||||
key = STRIPPABLE_ITEM_NECK
|
||||
item_slot = SLOT_NECK
|
||||
|
||||
/datum/strippable_item/mob_item_slot/handcuffs
|
||||
key = STRIPPABLE_ITEM_HANDCUFFS
|
||||
item_slot = SLOT_HANDCUFFED
|
||||
|
||||
/datum/strippable_item/mob_item_slot/handcuffs/should_show(atom/source, mob/user)
|
||||
if (!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
return !isnull(carbon_source.handcuffed)
|
||||
|
||||
// You shouldn't be able to equip things to handcuff slots.
|
||||
/datum/strippable_item/mob_item_slot/handcuffs/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
return FALSE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/legcuffs
|
||||
key = STRIPPABLE_ITEM_LEGCUFFS
|
||||
item_slot = SLOT_LEGCUFFED
|
||||
|
||||
/datum/strippable_item/mob_item_slot/legcuffs/should_show(atom/source, mob/user)
|
||||
if (!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
return !isnull(carbon_source.legcuffed)
|
||||
|
||||
// You shouldn't be able to equip things to legcuff slots.
|
||||
/datum/strippable_item/mob_item_slot/legcuffs/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
return FALSE
|
||||
|
||||
/// A strippable item for a hand
|
||||
/datum/strippable_item/hand
|
||||
// Putting dangerous clothing in our hand is fine.
|
||||
warn_dangerous_clothing = FALSE
|
||||
|
||||
/// Which hand?
|
||||
var/hand_index
|
||||
|
||||
/datum/strippable_item/hand/get_item(atom/source)
|
||||
if (!ismob(source))
|
||||
return null
|
||||
|
||||
var/mob/mob_source = source
|
||||
return mob_source.get_item_for_held_index(hand_index)
|
||||
|
||||
/datum/strippable_item/hand/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
|
||||
if (!ismob(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
|
||||
if (!mob_source.can_put_in_hand(equipping, hand_index))
|
||||
to_chat(src, "<span class='warning'>\The [equipping] doesn't fit in that place!</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/hand/start_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
|
||||
if (!ismob(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
|
||||
if (!do_mob(user, source, equipping.equip_delay_other))
|
||||
return FALSE
|
||||
|
||||
if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY)
|
||||
return FALSE
|
||||
|
||||
if (!mob_source.can_put_in_hand(equipping, hand_index))
|
||||
return FALSE
|
||||
|
||||
if (!user.temporarilyRemoveItemFromInventory(equipping))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/hand/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if (!iscarbon(source))
|
||||
return FALSE
|
||||
|
||||
var/mob/mob_source = source
|
||||
mob_source.put_in_hand(equipping, hand_index)
|
||||
|
||||
/datum/strippable_item/hand/start_unequip(atom/source, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
|
||||
return start_unequip_mob(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/hand/finish_unequip(atom/source, mob/user)
|
||||
..()
|
||||
var/obj/item/item = get_item(source)
|
||||
if (isnull(item))
|
||||
return FALSE
|
||||
|
||||
if (!ismob(source))
|
||||
return FALSE
|
||||
|
||||
return finish_unequip_mob(item, source, user)
|
||||
|
||||
/datum/strippable_item/hand/left
|
||||
key = STRIPPABLE_ITEM_LHAND
|
||||
hand_index = 1
|
||||
|
||||
/datum/strippable_item/hand/right
|
||||
key = STRIPPABLE_ITEM_RHAND
|
||||
hand_index = 2
|
||||
@@ -47,6 +47,7 @@
|
||||
AddElement(/datum/element/flavor_text/carbon, _name = "Flavor Text", _save_key = "flavor_text")
|
||||
AddElement(/datum/element/flavor_text/carbon/temporary, "", "Set Pose (Temporary Flavor Text)", "This should be used only for things pertaining to the current round!", _save_key = null)
|
||||
AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _always_show = TRUE, _save_key = "ooc_notes", _examine_no_preview = TRUE)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_human_items, /mob/living/carbon/human/.proc/should_strip)
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
QDEL_NULL(physiology)
|
||||
@@ -110,106 +111,6 @@
|
||||
var/datum/disease/D = thing
|
||||
. += "* [D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]"
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
|
||||
var/list/obscured = check_obscured_slots()
|
||||
var/list/dat = list()
|
||||
|
||||
dat += "<table>"
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<tr><td><B>[get_held_index_name(i)]:</B></td><td><A href='?src=[REF(src)];item=[SLOT_HANDS];hand_index=[i]'>[(I && !(I.item_flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Back:</B></td><td><A href='?src=[REF(src)];item=[SLOT_BACK]'>[(back && !(back.item_flags & ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(back, /obj/item/tank))
|
||||
dat += " <A href='?src=[REF(src)];internal=[SLOT_BACK]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
|
||||
dat += "</td></tr><tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Head:</B></td><td><A href='?src=[REF(src)];item=[SLOT_HEAD]'>[(head && !(head.item_flags & ABSTRACT)) ? head : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(SLOT_WEAR_MASK in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Mask:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=[REF(src)];item=[SLOT_WEAR_MASK]'>[(wear_mask && !(wear_mask.item_flags & ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(SLOT_NECK in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Neck:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Neck:</B></td><td><A href='?src=[REF(src)];item=[SLOT_NECK]'>[(wear_neck && !(wear_neck.item_flags & ABSTRACT)) ? wear_neck : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(SLOT_GLASSES in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Eyes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Eyes:</B></td><td><A href='?src=[REF(src)];item=[SLOT_GLASSES]'>[(glasses && !(glasses.item_flags & ABSTRACT)) ? glasses : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(SLOT_EARS in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Ears:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Ears:</B></td><td><A href='?src=[REF(src)];item=[SLOT_EARS]'>[(ears && !(ears.item_flags & ABSTRACT)) ? ears : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Exosuit:</B></td><td><A href='?src=[REF(src)];item=[SLOT_WEAR_SUIT]'>[(wear_suit && !(wear_suit.item_flags & ABSTRACT)) ? wear_suit : "<font color=grey>Empty</font>"]</A>"
|
||||
if(wear_suit)
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/space/hardsuit))
|
||||
var/hardsuit_head = head && istype(head, /obj/item/clothing/head/helmet/space/hardsuit)
|
||||
dat += " <A href='?src=[REF(src)];toggle_helmet=[SLOT_WEAR_SUIT]'>[hardsuit_head ? "Retract Helmet" : "Extend Helmet"]</A>"
|
||||
dat += "</td></tr>"
|
||||
dat += "<tr><td> ↳<B>Suit Storage:</B></td><td><A href='?src=[REF(src)];item=[SLOT_S_STORE]'>[(s_store && !(s_store.item_flags & ABSTRACT)) ? s_store : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(s_store, /obj/item/tank))
|
||||
dat += " <A href='?src=[REF(src)];internal=[SLOT_S_STORE]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
dat += "</td></tr>"
|
||||
else
|
||||
dat += "<tr><td><font color=grey> ↳<B>Suit Storage:</B></font></td></tr>"
|
||||
|
||||
if(SLOT_SHOES in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Shoes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Shoes:</B></td><td><A href='?src=[REF(src)];item=[SLOT_SHOES]'>[(shoes && !(shoes.item_flags & ABSTRACT)) ? shoes : "<font color=grey>Empty</font>"]</A>"
|
||||
if(shoes && shoes.can_be_tied && shoes.tied != SHOES_KNOTTED)
|
||||
dat += " <A href='?src=[REF(src)];shoes=[SLOT_SHOES]'>[shoes.tied ? "Untie shoes" : "Knot shoes"]</A>"
|
||||
|
||||
dat += "</td></tr>"
|
||||
|
||||
if(SLOT_GLOVES in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Gloves:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Gloves:</B></td><td><A href='?src=[REF(src)];item=[SLOT_GLOVES]'>[(gloves && !(gloves.item_flags & ABSTRACT)) ? gloves : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(SLOT_W_UNIFORM in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Uniform:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Uniform:</B></td><td><A href='?src=[REF(src)];item=[SLOT_W_UNIFORM]'>[(w_uniform && !(w_uniform.item_flags & ABSTRACT)) ? w_uniform : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (SLOT_W_UNIFORM in obscured))
|
||||
dat += "<tr><td><font color=grey> ↳<B>Pockets:</B></font></td></tr>"
|
||||
dat += "<tr><td><font color=grey> ↳<B>ID:</B></font></td></tr>"
|
||||
dat += "<tr><td><font color=grey> ↳<B>Belt:</B></font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td> ↳<B>Belt:</B></td><td><A href='?src=[REF(src)];item=[SLOT_BELT]'>[(belt && !(belt.item_flags & ABSTRACT)) ? belt : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(belt, /obj/item/tank))
|
||||
dat += " <A href='?src=[REF(src)];internal=[SLOT_BELT]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
|
||||
dat += "</td></tr>"
|
||||
dat += "<tr><td> ↳<B>Pockets:</B></td><td><A href='?src=[REF(src)];pockets=left'>[(l_store && !(l_store.item_flags & ABSTRACT)) ? "Left (Full)" : "<font color=grey>Left (Empty)</font>"]</A>"
|
||||
dat += " <A href='?src=[REF(src)];pockets=right'>[(r_store && !(r_store.item_flags & ABSTRACT)) ? "Right (Full)" : "<font color=grey>Right (Empty)</font>"]</A></td></tr>"
|
||||
dat += "<tr><td> ↳<B>ID:</B></td><td><A href='?src=[REF(src)];item=[SLOT_WEAR_ID]'>[(wear_id && !(wear_id.item_flags & ABSTRACT)) ? wear_id : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<tr><td><B>Handcuffed:</B> <A href='?src=[REF(src)];item=[SLOT_HANDCUFFED]'>Remove</A></td></tr>"
|
||||
if(legcuffed)
|
||||
dat += "<tr><td><A href='?src=[REF(src)];item=[SLOT_LEGCUFFED]'>Legcuffed</A></td></tr>"
|
||||
|
||||
dat += {"</table>
|
||||
<A href='?src=[REF(user)];mach_close=mob[REF(src)]'>Close</A>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob[REF(src)]", "[src]", 440, 510)
|
||||
popup.set_content(dat.Join())
|
||||
popup.open()
|
||||
|
||||
// called when something steps onto a human
|
||||
// this could be made more general, but for now just handle mulebot
|
||||
/mob/living/carbon/human/Crossed(atom/movable/AM)
|
||||
@@ -231,83 +132,6 @@
|
||||
return
|
||||
SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L)
|
||||
return
|
||||
if(href_list["toggle_helmet"])
|
||||
if(!istype(head, /obj/item/clothing/head/helmet/space/hardsuit))
|
||||
return
|
||||
var/obj/item/clothing/head/helmet/space/hardsuit/hardsuit_head = head
|
||||
visible_message("<span class='danger'>[usr] tries to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You try to [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>")
|
||||
if(!do_mob(usr, src, hardsuit_head ? head.strip_delay : POCKET_STRIP_DELAY))
|
||||
return
|
||||
if(!istype(wear_suit, /obj/item/clothing/suit/space/hardsuit) || (hardsuit_head ? (!head || head != hardsuit_head) : head))
|
||||
return
|
||||
var/obj/item/clothing/suit/space/hardsuit/hardsuit = wear_suit //This should be an hardsuit given all our checks
|
||||
if(hardsuit.ToggleHelmet(FALSE))
|
||||
visible_message("<span class='danger'>[usr] [hardsuit_head ? "retract" : "extend"] [src]'s helmet</span>", \
|
||||
"<span class='userdanger'>[usr] [hardsuit_head ? "retract" : "extend"] [src]'s helmet</span>", \
|
||||
target = usr, target_message = "<span class='danger'>You [hardsuit_head ? "retract" : "extend"] [src]'s helmet.</span>")
|
||||
return
|
||||
if(href_list["item"])
|
||||
var/slot = text2num(href_list["item"])
|
||||
if(slot in check_obscured_slots())
|
||||
to_chat(usr, "<span class='warning'>You can't reach that! Something is covering it.</span>")
|
||||
return
|
||||
if(href_list["pockets"])
|
||||
var/strip_mod = 1
|
||||
var/strip_silence = FALSE
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(istype(G))
|
||||
strip_mod = G.strip_mod
|
||||
strip_silence = G.strip_silence
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE)
|
||||
var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store)
|
||||
var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty
|
||||
|
||||
var/delay_denominator = 1
|
||||
if(pocket_item && !(pocket_item.item_flags & ABSTRACT))
|
||||
if(HAS_TRAIT(pocket_item, TRAIT_NODROP))
|
||||
to_chat(usr, "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>")
|
||||
to_chat(usr, "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>")
|
||||
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.item_flags & ABSTRACT))
|
||||
to_chat(usr, "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>")
|
||||
delay_denominator = 4
|
||||
else
|
||||
return
|
||||
|
||||
if(do_mob(usr, src, max(round(POCKET_STRIP_DELAY/(delay_denominator*strip_mod)),1), ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster (and the strip_mod too)
|
||||
if(pocket_item)
|
||||
if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search
|
||||
dropItemToGround(pocket_item)
|
||||
if(!usr.can_hold_items() || !usr.put_in_hands(pocket_item))
|
||||
pocket_item.forceMove(drop_location())
|
||||
log_combat(usr, src, "pickpocketed of item: [pocket_item]")
|
||||
else
|
||||
if(place_item)
|
||||
if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE))
|
||||
usr.temporarilyRemoveItemFromInventory(place_item, TRUE)
|
||||
equip_to_slot(place_item, pocket_id, TRUE)
|
||||
log_combat(usr, src, "placed item [place_item] onto")
|
||||
//do nothing otherwise
|
||||
|
||||
// Update strip window
|
||||
if(usr.machine == src && in_range(src, usr))
|
||||
show_inv(usr)
|
||||
else
|
||||
// Display a warning if the user mocks up
|
||||
if(!strip_silence)
|
||||
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
||||
log_combat(usr, src, "failed to [pocket_item ? "pickpocket item [pocket_item] from" : "place item [place_item] onto "]")
|
||||
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY, null, FALSE))
|
||||
// separate from first canusetopic
|
||||
var/mob/living/user = usr
|
||||
if(istype(user) && href_list["shoes"] && (user.mobility_flags & MOBILITY_USE)) // we need to be on the ground, so we'll be a bit looser
|
||||
shoes.handle_tying(usr)
|
||||
|
||||
..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined
|
||||
|
||||
|
||||
///////HUDs///////
|
||||
if(href_list["hud"])
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
#define INTERNALS_TOGGLE_DELAY (4 SECONDS)
|
||||
#define POCKET_EQUIP_DELAY (1 SECONDS)
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_human_items, create_strippable_list(list(
|
||||
/datum/strippable_item/mob_item_slot/head,
|
||||
/datum/strippable_item/mob_item_slot/back,
|
||||
/datum/strippable_item/mob_item_slot/mask,
|
||||
/datum/strippable_item/mob_item_slot/neck,
|
||||
/datum/strippable_item/mob_item_slot/eyes,
|
||||
/datum/strippable_item/mob_item_slot/ears,
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit,
|
||||
/datum/strippable_item/mob_item_slot/suit,
|
||||
/datum/strippable_item/mob_item_slot/gloves,
|
||||
/datum/strippable_item/mob_item_slot/feet,
|
||||
/datum/strippable_item/mob_item_slot/suit_storage,
|
||||
/datum/strippable_item/mob_item_slot/id,
|
||||
/datum/strippable_item/mob_item_slot/belt,
|
||||
/datum/strippable_item/mob_item_slot/pocket/left,
|
||||
/datum/strippable_item/mob_item_slot/pocket/right,
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
/mob/living/carbon/human/proc/should_strip(mob/user)
|
||||
if (user.pulling != src || user.grab_state != GRAB_AGGRESSIVE)
|
||||
return TRUE
|
||||
|
||||
if (ishuman(user))
|
||||
var/mob/living/carbon/human/human_user = user
|
||||
return !human_user.can_be_firemanned(src)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/eyes
|
||||
key = STRIPPABLE_ITEM_EYES
|
||||
item_slot = SLOT_GLASSES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/ears
|
||||
key = STRIPPABLE_ITEM_EARS
|
||||
item_slot = SLOT_EARS
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit
|
||||
key = STRIPPABLE_ITEM_JUMPSUIT
|
||||
item_slot = SLOT_W_UNIFORM
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
var/obj/item/clothing/under/jumpsuit = get_item(source)
|
||||
if (!istype(jumpsuit))
|
||||
return null
|
||||
return jumpsuit?.can_adjust ? "adjust_jumpsuit" : null
|
||||
|
||||
/datum/strippable_item/mob_item_slot/jumpsuit/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
var/obj/item/clothing/under/jumpsuit = get_item(source)
|
||||
if (!istype(jumpsuit))
|
||||
return null
|
||||
to_chat(source, "<span class='notice'>[user] is trying to adjust your [jumpsuit.name].")
|
||||
if (!do_mob(user, source, jumpsuit.strip_delay * 0.5, ignorehelditem = TRUE))
|
||||
return
|
||||
to_chat(source, "<span class='notice'>[user] successfully adjusted your [jumpsuit.name].")
|
||||
jumpsuit.toggle_jumpsuit_adjust()
|
||||
|
||||
if (!ismob(source))
|
||||
return null
|
||||
|
||||
var/mob/mob_source = source
|
||||
mob_source.update_inv_w_uniform()
|
||||
mob_source.update_body()
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit
|
||||
key = STRIPPABLE_ITEM_SUIT
|
||||
item_slot = SLOT_WEAR_SUIT
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
var/obj/item/clothing/suit/space/hardsuit/suit = get_item(source)
|
||||
if(istype(suit))
|
||||
if(!suit.helmettype)
|
||||
return null
|
||||
return suit?.suittoggled ? "disable_helmet" : "enable_helmet"
|
||||
return null
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit/alternate_action(mob/living/carbon/human/source, mob/user)
|
||||
if(!..())
|
||||
return null
|
||||
if(ishuman(source))
|
||||
var/obj/item/clothing/suit/space/hardsuit/hardsuit = get_item(source)
|
||||
var/obj/item/clothing/head/helmet/space/hardsuit/hardsuit_head = hardsuit.helmet
|
||||
source.visible_message("<span class='danger'>[user] tries to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.</span>", \
|
||||
"<span class='userdanger'>[user] tries to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.</span>", \
|
||||
target = user, target_message = "<span class='danger'>You try to [hardsuit.suittoggled ? "retract" : "extend"] [source]'s helmet.</span>")
|
||||
if(!do_mob(user, source, hardsuit_head ? hardsuit_head.strip_delay : POCKET_STRIP_DELAY, ignorehelditem = TRUE))
|
||||
return null
|
||||
if((source.head != hardsuit_head) && source.head)
|
||||
return null
|
||||
if(hardsuit.ToggleHelmet(FALSE))
|
||||
source.visible_message("<span class='danger'>[user] [hardsuit_head ? "retract" : "extend"] [source]'s helmet</span>", \
|
||||
"<span class='userdanger'>[user] [hardsuit_head ? "retract" : "extend"] [source]'s helmet</span>", \
|
||||
target = user, target_message = "<span class='danger'>You [hardsuit_head ? "retract" : "extend"] [source]'s helmet.</span>")
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/gloves
|
||||
key = STRIPPABLE_ITEM_GLOVES
|
||||
item_slot = SLOT_GLOVES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/feet
|
||||
key = STRIPPABLE_ITEM_FEET
|
||||
item_slot = SLOT_SHOES
|
||||
|
||||
/datum/strippable_item/mob_item_slot/feet/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
var/obj/item/clothing/shoes/shoes = get_item(source)
|
||||
if (!istype(shoes) || !shoes.can_be_tied)
|
||||
return null
|
||||
|
||||
switch (shoes.tied)
|
||||
if (SHOES_UNTIED)
|
||||
return "knot"
|
||||
if (SHOES_TIED)
|
||||
return "untie"
|
||||
if (SHOES_KNOTTED)
|
||||
return "unknot"
|
||||
|
||||
/datum/strippable_item/mob_item_slot/feet/alternate_action(atom/source, mob/user)
|
||||
if(!..())
|
||||
return null
|
||||
var/obj/item/clothing/shoes/shoes = get_item(source)
|
||||
if (!istype(shoes))
|
||||
return null
|
||||
|
||||
shoes.handle_tying(user)
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage
|
||||
key = STRIPPABLE_ITEM_SUIT_STORAGE
|
||||
item_slot = SLOT_S_STORE
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/suit_storage/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
return strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/id
|
||||
key = STRIPPABLE_ITEM_ID
|
||||
item_slot = SLOT_WEAR_ID
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt
|
||||
key = STRIPPABLE_ITEM_BELT
|
||||
item_slot = SLOT_BELT
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt/get_alternate_action(atom/source, mob/user)
|
||||
if(..() == FALSE)
|
||||
return null
|
||||
return get_strippable_alternate_action_internals(get_item(source), source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/belt/alternate_action(atom/source, mob/user)
|
||||
if (!..())
|
||||
return null
|
||||
return strippable_alternate_action_internals(get_item(source), source, user)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket
|
||||
/// Which pocket we're referencing. Used for visible text.
|
||||
var/pocket_side
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/get_obscuring(atom/source)
|
||||
return isnull(get_item(source)) \
|
||||
? STRIPPABLE_OBSCURING_NONE \
|
||||
: STRIPPABLE_OBSCURING_HIDDEN
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/get_equip_delay(obj/item/equipping)
|
||||
return POCKET_EQUIP_DELAY
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/start_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
warn_owner(source)
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/start_unequip(atom/source, mob/user)
|
||||
var/obj/item/item = get_item(source)
|
||||
if (isnull(item))
|
||||
return FALSE
|
||||
|
||||
to_chat(user, span_notice("You try to empty [source]'s [pocket_side] pocket."))
|
||||
|
||||
var/log_message = "[key_name(source)] is being pickpocketed of [item] by [key_name(user)] ([pocket_side])"
|
||||
user.log_message(log_message, LOG_ATTACK, color="red")
|
||||
source.log_message(log_message, LOG_VICTIM, color="red", log_globally=FALSE)
|
||||
item.add_fingerprint(source)
|
||||
|
||||
var/result = start_unequip_mob(item, source, user, POCKET_STRIP_DELAY)
|
||||
|
||||
if (!result)
|
||||
warn_owner(source)
|
||||
|
||||
return result
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/proc/warn_owner(atom/owner)
|
||||
to_chat(owner, span_warning("You feel your [pocket_side] pocket being fumbled with!"))
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/left
|
||||
key = STRIPPABLE_ITEM_LPOCKET
|
||||
item_slot = SLOT_L_STORE
|
||||
pocket_side = "left"
|
||||
|
||||
/datum/strippable_item/mob_item_slot/pocket/right
|
||||
key = STRIPPABLE_ITEM_RPOCKET
|
||||
item_slot = SLOT_R_STORE
|
||||
pocket_side = "right"
|
||||
|
||||
/proc/get_strippable_alternate_action_internals(obj/item/item, atom/source)
|
||||
if (!iscarbon(source))
|
||||
return null
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
var/obj/item/clothing/mask
|
||||
var/internals = FALSE
|
||||
|
||||
for(mask in GET_INTERNAL_SLOTS(carbon_source))
|
||||
if(istype(mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/M = mask
|
||||
if(M.mask_adjusted)
|
||||
if(M.adjustmask(carbon_source))
|
||||
internals = TRUE
|
||||
else
|
||||
internals = TRUE
|
||||
if((mask.clothing_flags & ALLOWINTERNALS))
|
||||
internals = TRUE
|
||||
|
||||
if(carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
internals = TRUE
|
||||
|
||||
if (internals && istype(item, /obj/item/tank))
|
||||
return isnull(carbon_source.internal) ? "enable_internals" : "disable_internals"
|
||||
|
||||
/proc/strippable_alternate_action_internals(obj/item/item, atom/source, mob/user)
|
||||
var/obj/item/tank/tank = item
|
||||
if (!istype(tank))
|
||||
return null
|
||||
|
||||
var/mob/living/carbon/carbon_source = source
|
||||
if (!istype(carbon_source))
|
||||
return null
|
||||
|
||||
var/obj/item/clothing/mask
|
||||
var/internals = FALSE
|
||||
|
||||
for(mask in GET_INTERNAL_SLOTS(carbon_source))
|
||||
if(istype(mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/M = mask
|
||||
if(M.mask_adjusted)
|
||||
if(M.adjustmask(carbon_source))
|
||||
internals = TRUE
|
||||
else
|
||||
internals = TRUE
|
||||
if((mask.clothing_flags & ALLOWINTERNALS))
|
||||
internals = TRUE
|
||||
|
||||
if(!internals)
|
||||
return null
|
||||
|
||||
carbon_source.visible_message(
|
||||
span_danger("[user] tries to [isnull(carbon_source.internal) ? "open": "close"] the valve on [source]'s [item.name]."),
|
||||
span_userdanger("[user] tries to [isnull(carbon_source.internal) ? "open": "close"] the valve on your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
|
||||
to_chat(user, span_notice("You try to [isnull(carbon_source.internal) ? "open": "close"] the valve on [source]'s [item.name]..."))
|
||||
|
||||
if(!do_mob(user, carbon_source, INTERNALS_TOGGLE_DELAY, ignorehelditem = TRUE))
|
||||
return null
|
||||
|
||||
if(carbon_source.internal)
|
||||
carbon_source.internal = null
|
||||
|
||||
// This isn't meant to be FALSE, it correlates to the icon's name.
|
||||
carbon_source.update_internals_hud_icon(0)
|
||||
else if (!QDELETED(item))
|
||||
if(internals || carbon_source.getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
carbon_source.internal = item
|
||||
carbon_source.update_internals_hud_icon(1)
|
||||
|
||||
carbon_source.visible_message(
|
||||
span_danger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on [source]'s [item.name]."),
|
||||
span_userdanger("[user] [isnull(carbon_source.internal) ? "closes": "opens"] the valve on your [item.name]."),
|
||||
ignored_mobs = user,
|
||||
)
|
||||
|
||||
to_chat(user, span_notice("You [isnull(carbon_source.internal) ? "close" : "open"] the valve on [source]'s [item.name]."))
|
||||
|
||||
return TRUE
|
||||
|
||||
#undef INTERNALS_TOGGLE_DELAY
|
||||
#undef POCKET_EQUIP_DELAY
|
||||
@@ -573,9 +573,6 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
if(druggy)
|
||||
adjust_drugginess(-1)
|
||||
|
||||
if(drunkenness)
|
||||
drunkenness = max(drunkenness-1,0)
|
||||
|
||||
if(silent)
|
||||
silent = max(silent-1, 0)
|
||||
|
||||
@@ -583,7 +580,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
handle_hallucinations()
|
||||
|
||||
if(drunkenness)
|
||||
drunkenness = max(drunkenness - (drunkenness * 0.04), 0)
|
||||
drunkenness *= 0.96
|
||||
if(drunkenness >= 6)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "drunk", /datum/mood_event/drunk)
|
||||
if(prob(25))
|
||||
@@ -598,6 +595,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "drunk")
|
||||
clear_alert("drunk")
|
||||
sound_environment_override = SOUND_ENVIRONMENT_NONE
|
||||
drunkenness = max(drunkenness - 0.2, 0)
|
||||
|
||||
if(mind && (mind.assigned_role == "Scientist" || mind.assigned_role == "Research Director"))
|
||||
if(SSresearch.science_tech)
|
||||
|
||||
@@ -16,6 +16,17 @@
|
||||
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
|
||||
hud_type = /datum/hud/monkey
|
||||
|
||||
GLOBAL_LIST_INIT(strippable_monkey_items, create_strippable_list(list(
|
||||
/datum/strippable_item/mob_item_slot/head,
|
||||
/datum/strippable_item/mob_item_slot/back,
|
||||
/datum/strippable_item/mob_item_slot/mask,
|
||||
/datum/strippable_item/mob_item_slot/neck,
|
||||
/datum/strippable_item/hand/left,
|
||||
/datum/strippable_item/hand/right,
|
||||
/datum/strippable_item/mob_item_slot/handcuffs,
|
||||
/datum/strippable_item/mob_item_slot/legcuffs,
|
||||
)))
|
||||
|
||||
/mob/living/carbon/monkey/Initialize(mapload, cubespawned=FALSE, mob/spawner)
|
||||
add_verb(src, /mob/living/proc/mob_sleep)
|
||||
add_verb(src, /mob/living/proc/lay_down)
|
||||
@@ -47,6 +58,7 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, worn_state = "monkey", inv_slots = ITEM_SLOT_HEAD)
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_BAREFOOT, 1, 2)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_monkey_items)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/Destroy()
|
||||
|
||||
@@ -935,13 +935,6 @@
|
||||
what.forceMove(drop_location())
|
||||
log_combat(src, who, "stripped [what] off")
|
||||
|
||||
if(Adjacent(who)) //update inventory window
|
||||
who.show_inv(src)
|
||||
else
|
||||
src << browse(null,"window=mob[REF(who)]")
|
||||
|
||||
who.update_equipment_speed_mods() // Updates speed in case stripped speed affecting item
|
||||
|
||||
// The src mob is trying to place an item on someone
|
||||
// Override if a certain mob should be behave differently when placing items (can't, for example)
|
||||
/mob/living/stripPanelEquip(obj/item/what, mob/who, where)
|
||||
|
||||
@@ -297,7 +297,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message)
|
||||
|
||||
if(!eavesdrop_range && say_test(message) == "2") // Yell hook
|
||||
if(client && !eavesdrop_range && say_test(message) == "2") // Yell hook
|
||||
process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source)
|
||||
|
||||
//speech bubble
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
. = ..()
|
||||
AddElement(/datum/element/wuv, "yaps happily!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "growls!", EMOTE_AUDIBLE)
|
||||
AddElement(/datum/element/mob_holder, held_icon)
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_corgi_items)
|
||||
|
||||
//Corgis and pugs are now under one dog subtype
|
||||
|
||||
@@ -104,18 +105,175 @@
|
||||
..(gibbed)
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user)
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
/datum/strippable_item/corgi_head,
|
||||
/datum/strippable_item/corgi_back,
|
||||
/datum/strippable_item/corgi_collar,
|
||||
/datum/strippable_item/corgi_id,
|
||||
)))
|
||||
|
||||
/datum/strippable_item/corgi_head
|
||||
key = STRIPPABLE_ITEM_HEAD
|
||||
|
||||
/datum/strippable_item/corgi_head/get_item(atom/source)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
|
||||
dat += "<br><B>Head:</B> <A href='?src=[REF(src)];[inventory_head ? "remove_inv=head'>[inventory_head]" : "add_inv=head'>Nothing"]</A>"
|
||||
dat += "<br><B>Back:</B> <A href='?src=[REF(src)];[inventory_back ? "remove_inv=back'>[inventory_back]" : "add_inv=back'>Nothing"]</A>"
|
||||
dat += "<br><B>Collar:</B> <A href='?src=[REF(src)];[pcollar ? "remove_inv=collar'>[pcollar]" : "add_inv=collar'>Nothing"]</A>"
|
||||
return corgi_source.inventory_head
|
||||
|
||||
user << browse(dat, "window=mob[REF(src)];size=325x500")
|
||||
onclose(user, "mob[REF(src)]")
|
||||
/datum/strippable_item/corgi_head/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return FALSE
|
||||
|
||||
corgi_source.place_on_head(equipping, user)
|
||||
|
||||
/datum/strippable_item/corgi_head/finish_unequip(atom/source, mob/user)
|
||||
..()
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
|
||||
finish_unequip_mob(corgi_source.inventory_head, corgi_source, user)
|
||||
corgi_source.inventory_head = null
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.regenerate_icons()
|
||||
|
||||
/datum/strippable_item/corgi_back
|
||||
key = STRIPPABLE_ITEM_BACK
|
||||
|
||||
/datum/strippable_item/corgi_back/get_item(atom/source)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
|
||||
return corgi_source.inventory_back
|
||||
|
||||
/datum/strippable_item/corgi_back/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
|
||||
if (!ispath(equipping.dog_fashion, /datum/dog_fashion/back))
|
||||
to_chat(user, "<span class='warning'>You set [equipping] on [source]'s back, but it falls off!</span>")
|
||||
equipping.forceMove(source.drop_location())
|
||||
if (prob(25))
|
||||
step_rand(equipping)
|
||||
dance_rotate(source, set_original_dir = TRUE)
|
||||
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/corgi_back/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return FALSE
|
||||
|
||||
equipping.forceMove(corgi_source)
|
||||
corgi_source.inventory_back = equipping
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.regenerate_icons()
|
||||
|
||||
/datum/strippable_item/corgi_back/finish_unequip(atom/source, mob/user)
|
||||
..()
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
|
||||
finish_unequip_mob(corgi_source.inventory_back, corgi_source, user)
|
||||
corgi_source.inventory_back = null
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.regenerate_icons()
|
||||
|
||||
/datum/strippable_item/corgi_collar
|
||||
key = STRIPPABLE_ITEM_CORGI_COLLAR
|
||||
|
||||
/datum/strippable_item/corgi_collar/get_item(atom/source)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
|
||||
return corgi_source.pcollar
|
||||
|
||||
/datum/strippable_item/corgi_collar/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
|
||||
if (!istype(equipping, /obj/item/clothing/neck/petcollar))
|
||||
to_chat(user, "<span class='warning'>That's not a collar.</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/corgi_collar/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return FALSE
|
||||
|
||||
corgi_source.add_collar(equipping, user)
|
||||
corgi_source.update_corgi_fluff()
|
||||
|
||||
/datum/strippable_item/corgi_collar/finish_unequip(atom/source, mob/user)
|
||||
..()
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
|
||||
finish_unequip_mob(corgi_source.pcollar, corgi_source, user)
|
||||
corgi_source.pcollar = null
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.regenerate_icons()
|
||||
|
||||
/datum/strippable_item/corgi_id
|
||||
key = STRIPPABLE_ITEM_ID
|
||||
|
||||
/datum/strippable_item/corgi_id/get_item(atom/source)
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
|
||||
return corgi_source.access_card
|
||||
|
||||
/datum/strippable_item/corgi_id/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
|
||||
if (!istype(equipping, /obj/item/card/id))
|
||||
to_chat(user, "<span class='warning'>You can't pin [equipping] to [source]!</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/corgi_id/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return FALSE
|
||||
|
||||
equipping.forceMove(source)
|
||||
corgi_source.access_card = equipping
|
||||
|
||||
/datum/strippable_item/corgi_id/finish_unequip(atom/source, mob/user)
|
||||
..()
|
||||
var/mob/living/simple_animal/pet/dog/corgi/corgi_source = source
|
||||
if (!istype(corgi_source))
|
||||
return
|
||||
|
||||
finish_unequip_mob(corgi_source.access_card, corgi_source, user)
|
||||
corgi_source.access_card = null
|
||||
corgi_source.update_corgi_fluff()
|
||||
corgi_source.regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type)
|
||||
var/armorval = 0
|
||||
@@ -158,114 +316,12 @@
|
||||
..()
|
||||
update_corgi_fluff()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
|
||||
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
usr << browse(null, "window=mob[REF(src)]")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
//Removing from inventory
|
||||
if(href_list["remove_inv"])
|
||||
var/remove_from = href_list["remove_inv"]
|
||||
switch(remove_from)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(inventory_head)
|
||||
usr.put_in_hands(inventory_head)
|
||||
inventory_head = null
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
|
||||
return
|
||||
if("back")
|
||||
if(inventory_back)
|
||||
usr.put_in_hands(inventory_back)
|
||||
inventory_back = null
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
|
||||
return
|
||||
if("collar")
|
||||
if(pcollar)
|
||||
usr.put_in_hands(pcollar)
|
||||
pcollar = null
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
|
||||
show_inv(usr)
|
||||
|
||||
//Adding things to inventory
|
||||
else if(href_list["add_inv"])
|
||||
|
||||
var/add_to = href_list["add_inv"]
|
||||
|
||||
switch(add_to)
|
||||
if("collar")
|
||||
var/obj/item/clothing/neck/petcollar/P = usr.get_active_held_item()
|
||||
if(!istype(P))
|
||||
to_chat(usr,"<span class='warning'>That's not a collar.</span>")
|
||||
return
|
||||
add_collar(P, usr)
|
||||
update_corgi_fluff()
|
||||
|
||||
if(BODY_ZONE_HEAD)
|
||||
place_on_head(usr.get_active_held_item(),usr)
|
||||
|
||||
if("back")
|
||||
if(inventory_back)
|
||||
to_chat(usr, "<span class='warning'>It's already wearing something!</span>")
|
||||
return
|
||||
else
|
||||
var/obj/item/item_to_add = usr.get_active_held_item()
|
||||
|
||||
if(!item_to_add)
|
||||
usr.visible_message("[usr] pets [src].","<span class='notice'>You rest your hand on [src]'s back for a moment.</span>")
|
||||
return
|
||||
|
||||
if(!usr.temporarilyRemoveItemFromInventory(item_to_add))
|
||||
to_chat(usr, "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s back!</span>")
|
||||
return
|
||||
|
||||
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,usr,1)
|
||||
return
|
||||
|
||||
//The objects that corgis can wear on their backs.
|
||||
var/allowed = FALSE
|
||||
if(ispath(item_to_add.dog_fashion, /datum/dog_fashion/back))
|
||||
allowed = TRUE
|
||||
|
||||
if(!allowed)
|
||||
to_chat(usr, "<span class='warning'>You set [item_to_add] on [src]'s back, but it falls off!</span>")
|
||||
item_to_add.forceMove(drop_location())
|
||||
if(prob(25))
|
||||
step_rand(item_to_add)
|
||||
for(var/i in list(1,2,4,8,4,8,4,dir))
|
||||
setDir(i)
|
||||
sleep(1)
|
||||
return
|
||||
|
||||
item_to_add.forceMove(src)
|
||||
src.inventory_back = item_to_add
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
|
||||
show_inv(usr)
|
||||
else
|
||||
return ..()
|
||||
|
||||
//Corgis are supposed to be simpler, so only a select few objects can actually be put
|
||||
//to be compatible with them. The objects are below.
|
||||
//Many hats added, Some will probably be removed, just want to see which ones are popular.
|
||||
// > some will probably be removed
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
|
||||
|
||||
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
|
||||
INVOKE_ASYNC(item_to_add, /obj/item.proc/afterattack, src, user, 1)
|
||||
return
|
||||
|
||||
if(inventory_head)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You can't put more than one hat on [src]!</span>")
|
||||
@@ -303,9 +359,7 @@
|
||||
item_to_add.forceMove(drop_location())
|
||||
if(prob(25))
|
||||
step_rand(item_to_add)
|
||||
for(var/i in list(1,2,4,8,4,8,4,dir))
|
||||
setDir(i)
|
||||
sleep(1)
|
||||
dance_rotate(src, set_original_dir = TRUE)
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
@@ -124,6 +124,9 @@
|
||||
/mob/living/simple_animal/parrot/proc/toggle_mode,
|
||||
/mob/living/simple_animal/parrot/proc/perch_mob_player))
|
||||
|
||||
/mob/living/simple_animal/parrot/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/strippable, GLOB.strippable_parrot_items)
|
||||
|
||||
/mob/living/simple_animal/parrot/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -183,91 +186,101 @@
|
||||
|
||||
return 0
|
||||
|
||||
/*
|
||||
* Inventory
|
||||
*/
|
||||
/mob/living/simple_animal/parrot/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list(
|
||||
/datum/strippable_item/parrot_headset,
|
||||
)))
|
||||
|
||||
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
|
||||
dat += "<br><B>Headset:</B> <A href='?src=[REF(src)];[ears ? "remove_inv=ears'>[ears]" : "add_inv=ears'>Nothing"]</A>"
|
||||
/datum/strippable_item/parrot_headset
|
||||
key = STRIPPABLE_ITEM_PARROT_HEADSET
|
||||
|
||||
user << browse(dat, "window=mob[REF(src)];size=325x500")
|
||||
onclose(user, "window=mob[REF(src)]")
|
||||
/datum/strippable_item/parrot_headset/get_item(atom/source)
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
return istype(parrot_source) ? parrot_source.ears : null
|
||||
|
||||
/datum/strippable_item/parrot_headset/try_equip(atom/source, obj/item/equipping, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/parrot/Topic(href, href_list)
|
||||
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
usr << browse(null, "window=mob[REF(src)]")
|
||||
usr.unset_machine()
|
||||
if (!istype(equipping, /obj/item/radio/headset))
|
||||
to_chat(user, "<span class='warning'>[equipping] won't fit!</span>")
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
// There is no delay for putting a headset on a parrot.
|
||||
/datum/strippable_item/parrot_headset/start_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(get_obscuring(source) == STRIPPABLE_OBSCURING_COMPLETELY)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/strippable_item/parrot_headset/finish_equip(atom/source, obj/item/equipping, mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/obj/item/radio/headset/radio = equipping
|
||||
if (!istype(radio))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
if (!istype(parrot_source))
|
||||
return FALSE
|
||||
|
||||
if (!user.transferItemToLoc(radio, source))
|
||||
return FALSE
|
||||
|
||||
parrot_source.ears = radio
|
||||
|
||||
to_chat(user, "<span class='notice'>You fit [radio] onto [source].</span>")
|
||||
|
||||
parrot_source.available_channels.Cut()
|
||||
|
||||
for (var/channel in radio.channels)
|
||||
var/channel_to_add
|
||||
|
||||
switch (channel)
|
||||
if (RADIO_CHANNEL_ENGINEERING)
|
||||
channel_to_add = RADIO_TOKEN_ENGINEERING
|
||||
if (RADIO_CHANNEL_COMMAND)
|
||||
channel_to_add = RADIO_TOKEN_COMMAND
|
||||
if (RADIO_CHANNEL_SECURITY)
|
||||
channel_to_add = RADIO_TOKEN_SECURITY
|
||||
if (RADIO_CHANNEL_SCIENCE)
|
||||
channel_to_add = RADIO_TOKEN_SCIENCE
|
||||
if (RADIO_CHANNEL_MEDICAL)
|
||||
channel_to_add = RADIO_TOKEN_MEDICAL
|
||||
if (RADIO_CHANNEL_SUPPLY)
|
||||
channel_to_add = RADIO_TOKEN_SUPPLY
|
||||
if (RADIO_CHANNEL_SERVICE)
|
||||
channel_to_add = RADIO_TOKEN_SERVICE
|
||||
|
||||
if (channel_to_add)
|
||||
parrot_source.available_channels += channel_to_add
|
||||
|
||||
if (radio.translate_binary)
|
||||
parrot_source.available_channels.Add(MODE_TOKEN_BINARY)
|
||||
|
||||
/datum/strippable_item/parrot_headset/start_unequip(atom/source, mob/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return FALSE
|
||||
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
if (!istype(parrot_source))
|
||||
return
|
||||
|
||||
//Removing from inventory
|
||||
if(href_list["remove_inv"])
|
||||
var/remove_from = href_list["remove_inv"]
|
||||
switch(remove_from)
|
||||
if("ears")
|
||||
if(!ears)
|
||||
to_chat(usr, "<span class='warning'>There is nothing to remove from its [remove_from]!</span>")
|
||||
return
|
||||
if(!stat)
|
||||
say("[available_channels.len ? "[pick(available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
ears.forceMove(drop_location())
|
||||
ears = null
|
||||
for(var/possible_phrase in speak)
|
||||
if(copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys)
|
||||
possible_phrase = copytext_char(possible_phrase, 3)
|
||||
if (!parrot_source.stat)
|
||||
parrot_source.say("[parrot_source.available_channels.len ? "[pick(parrot_source.available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
|
||||
//Adding things to inventory
|
||||
else if(href_list["add_inv"])
|
||||
var/add_to = href_list["add_inv"]
|
||||
if(!usr.get_active_held_item())
|
||||
to_chat(usr, "<span class='warning'>You have nothing in your hand to put on its [add_to]!</span>")
|
||||
return
|
||||
switch(add_to)
|
||||
if("ears")
|
||||
if(ears)
|
||||
to_chat(usr, "<span class='warning'>It's already wearing something!</span>")
|
||||
return
|
||||
else
|
||||
var/obj/item/item_to_add = usr.get_active_held_item()
|
||||
if(!item_to_add)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
if( !istype(item_to_add, /obj/item/radio/headset) )
|
||||
to_chat(usr, "<span class='warning'>This object won't fit!</span>")
|
||||
return
|
||||
|
||||
var/obj/item/radio/headset/headset_to_add = item_to_add
|
||||
|
||||
if(!usr.transferItemToLoc(headset_to_add, src))
|
||||
return
|
||||
ears = headset_to_add
|
||||
to_chat(usr, "<span class='notice'>You fit the headset onto [src].</span>")
|
||||
|
||||
clearlist(available_channels)
|
||||
for(var/ch in headset_to_add.channels)
|
||||
switch(ch)
|
||||
if(RADIO_CHANNEL_ENGINEERING)
|
||||
available_channels.Add(RADIO_TOKEN_ENGINEERING)
|
||||
if(RADIO_CHANNEL_COMMAND)
|
||||
available_channels.Add(RADIO_TOKEN_COMMAND)
|
||||
if(RADIO_CHANNEL_SECURITY)
|
||||
available_channels.Add(RADIO_TOKEN_SECURITY)
|
||||
if(RADIO_CHANNEL_SCIENCE)
|
||||
available_channels.Add(RADIO_TOKEN_SCIENCE)
|
||||
if(RADIO_CHANNEL_MEDICAL)
|
||||
available_channels.Add(RADIO_TOKEN_MEDICAL)
|
||||
if(RADIO_CHANNEL_SUPPLY)
|
||||
available_channels.Add(RADIO_TOKEN_SUPPLY)
|
||||
if(RADIO_CHANNEL_SERVICE)
|
||||
available_channels.Add(RADIO_TOKEN_SERVICE)
|
||||
|
||||
if(headset_to_add.translate_binary)
|
||||
available_channels.Add(MODE_TOKEN_BINARY)
|
||||
else
|
||||
return ..()
|
||||
/datum/strippable_item/parrot_headset/finish_unequip(atom/source, mob/user)
|
||||
..()
|
||||
var/mob/living/simple_animal/parrot/parrot_source = source
|
||||
if (!istype(parrot_source))
|
||||
return
|
||||
|
||||
finish_unequip_mob(parrot_source.ears, parrot_source, user)
|
||||
parrot_source.ears = null
|
||||
|
||||
/*
|
||||
* Attack responces
|
||||
|
||||
@@ -289,9 +289,6 @@
|
||||
SEND_SIGNAL(src, COMSIG_MOB_RESET_PERSPECTIVE, A)
|
||||
return TRUE
|
||||
|
||||
/mob/proc/show_inv(mob/user)
|
||||
return
|
||||
|
||||
//view() but with a signal, to allow blacklisting some of the otherwise visible atoms.
|
||||
/mob/proc/fov_view(dist = world.view)
|
||||
. = view(dist, src)
|
||||
@@ -508,10 +505,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
|
||||
if(href_list["refresh"])
|
||||
if(machine && in_range(src, usr))
|
||||
show_inv(machine)
|
||||
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
if(href_list["item"])
|
||||
var/slot = text2num(href_list["item"])
|
||||
@@ -528,12 +521,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
else
|
||||
usr.stripPanelEquip(what,src,slot)
|
||||
|
||||
if(usr.machine == src)
|
||||
if(Adjacent(usr))
|
||||
show_inv(usr)
|
||||
else
|
||||
usr << browse(null,"window=mob[REF(src)]")
|
||||
|
||||
// The src mob is trying to strip an item from someone
|
||||
// Defined in living.dm
|
||||
/mob/proc/stripPanelUnequip(obj/item/what, mob/who)
|
||||
@@ -555,12 +542,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
if(isAI(M))
|
||||
return
|
||||
|
||||
/mob/MouseDrop_T(atom/dropping, atom/user)
|
||||
. = ..()
|
||||
if(ismob(dropping) && dropping != user)
|
||||
var/mob/M = dropping
|
||||
M.show_inv(user)
|
||||
|
||||
/mob/proc/is_muzzled()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -825,7 +825,7 @@
|
||||
pH = REAGENT_NORMAL_PH
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1)
|
||||
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1, from_gas = 0)
|
||||
var/react_type
|
||||
if(isliving(A))
|
||||
react_type = "LIVING"
|
||||
@@ -849,7 +849,7 @@
|
||||
touch_protection = L.get_permeability_protection()
|
||||
R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection)
|
||||
if("TURF")
|
||||
R.reaction_turf(A, R.volume * volume_modifier, show_message)
|
||||
R.reaction_turf(A, R.volume * volume_modifier, show_message, from_gas)
|
||||
if("OBJ")
|
||||
R.reaction_obj(A, R.volume * volume_modifier, show_message)
|
||||
|
||||
@@ -859,17 +859,16 @@
|
||||
return FALSE
|
||||
|
||||
//Returns the average specific heat for all reagents currently in this holder.
|
||||
/datum/reagents/proc/specific_heat()
|
||||
/datum/reagents/proc/heat_capacity()
|
||||
. = 0
|
||||
var/cached_amount = total_volume //cache amount
|
||||
var/list/cached_reagents = reagent_list //cache reagents
|
||||
for(var/I in cached_reagents)
|
||||
var/datum/reagent/R = I
|
||||
. += R.specific_heat * (R.volume / cached_amount)
|
||||
. += R.specific_heat * R.volume
|
||||
|
||||
/datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000)
|
||||
var/S = specific_heat()
|
||||
chem_temp = clamp(chem_temp + (J / (S * total_volume)), min_temp, max_temp)
|
||||
var/S = heat_capacity()
|
||||
chem_temp = clamp(chem_temp + (J / S), min_temp, max_temp)
|
||||
if(istype(my_atom, /obj/item/reagent_containers))
|
||||
var/obj/item/reagent_containers/RC = my_atom
|
||||
RC.temp_check()
|
||||
|
||||
@@ -390,11 +390,11 @@
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent]
|
||||
if(R)
|
||||
var/state = "Unknown"
|
||||
if(initial(R.reagent_state) == 1)
|
||||
if(initial(R.reagent_state) == SOLID)
|
||||
state = "Solid"
|
||||
else if(initial(R.reagent_state) == 2)
|
||||
else if(initial(R.reagent_state) == LIQUID)
|
||||
state = "Liquid"
|
||||
else if(initial(R.reagent_state) == 3)
|
||||
else if(initial(R.reagent_state) == GAS)
|
||||
state = "Gas"
|
||||
var/const/P = 3 //The number of seconds between life ticks
|
||||
var/T = initial(R.metabolization_rate) * (60 / P)
|
||||
|
||||
@@ -53,10 +53,10 @@
|
||||
return
|
||||
beaker = new /obj/item/reagent_containers/glass/beaker/bluespace(src)
|
||||
visible_message("<span class='notice'>[src] dispenses a bluespace beaker.</span>")
|
||||
if("amount")
|
||||
var/input = text2num(params["amount"])
|
||||
if("synth_amount")
|
||||
var/input = text2num(params["synth_amount"])
|
||||
if(input)
|
||||
amount = input
|
||||
amount = max(input, 0)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/chem_dispenser/chem_synthesizer/proc/find_reagent(input)
|
||||
|
||||
@@ -53,6 +53,10 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
var/chemical_flags = REAGENT_ORGANIC_PROCESS // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME, REAGENT_ORGANIC_PROCESS, REAGENT_ROBOTIC_PROCESS
|
||||
var/value = REAGENT_VALUE_NONE //How much does it sell for in cargo?
|
||||
var/datum/material/material //are we made of material?
|
||||
var/gas = null //do we have an associated gas? (expects a string, not a datum typepath!)
|
||||
var/boiling_point = null // point at which this gas boils; if null, will never boil (and thus not become a gas)
|
||||
var/condensation_amount = 1
|
||||
var/molarity = 5 // How many units per mole of this reagent. Technically this is INVERSE molarity, but hey.
|
||||
|
||||
/datum/reagent/New()
|
||||
. = ..()
|
||||
@@ -77,10 +81,23 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
return 1
|
||||
|
||||
/datum/reagent/proc/reaction_obj(obj/O, volume)
|
||||
return
|
||||
if(O && volume && boiling_point)
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
if(temp > boiling_point)
|
||||
O.atmos_spawn_air("[get_gas()]=[volume/molarity];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/proc/reaction_turf(turf/T, volume)
|
||||
return
|
||||
/datum/reagent/proc/reaction_turf(turf/T, volume, show_message, from_gas)
|
||||
if(!from_gas && boiling_point)
|
||||
var/temp = holder?.chem_temp
|
||||
if(!temp)
|
||||
if(isopenturf(T))
|
||||
var/turf/open/O = T
|
||||
var/datum/gas_mixture/air = O.return_air()
|
||||
temp = air.return_temperature()
|
||||
else
|
||||
temp = T20C
|
||||
if(temp > boiling_point)
|
||||
T.atmos_spawn_air("[get_gas()]=[volume/molarity];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/proc/on_mob_life(mob/living/carbon/M)
|
||||
current_cycle++
|
||||
@@ -235,6 +252,44 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
|
||||
return rs.Join(" | ")
|
||||
|
||||
/datum/reagent/proc/define_gas()
|
||||
if(reagent_state == SOLID)
|
||||
return null // doesn't make that much sense
|
||||
var/list/cached_reactions = GLOB.chemical_reactions_list
|
||||
for(var/reaction in cached_reactions[src.type])
|
||||
var/datum/chemical_reaction/C = reaction
|
||||
if(!istype(C))
|
||||
continue
|
||||
if(C.required_reagents.len < 2) // no reagents that react on their own
|
||||
return null
|
||||
var/datum/gas/G = new
|
||||
G.id = "[src.type]"
|
||||
G.name = name
|
||||
G.specific_heat = specific_heat / 10
|
||||
G.color = color
|
||||
G.breath_reagent = src.type
|
||||
G.group = GAS_GROUP_CHEMICALS
|
||||
return G
|
||||
|
||||
/datum/reagent/proc/create_gas()
|
||||
var/datum/gas/G = define_gas()
|
||||
if(istype(G)) // if this reagent should never be a gas, define_gas may return null
|
||||
GLOB.gas_data.add_gas(G)
|
||||
var/datum/gas_reaction/condensation/condensation_reaction = new(src) // did you know? you can totally just add new reactions at runtime. it's allowed
|
||||
SSair.add_reaction(condensation_reaction)
|
||||
return G
|
||||
|
||||
|
||||
/datum/reagent/proc/get_gas()
|
||||
if(gas)
|
||||
return gas
|
||||
else
|
||||
var/datum/auxgm/cached_gas_data = GLOB.gas_data
|
||||
. = "[src.type]"
|
||||
if(!(. in cached_gas_data.ids))
|
||||
create_gas()
|
||||
|
||||
|
||||
//For easy bloodsucker disgusting and blood removal
|
||||
/datum/reagent/proc/disgust_bloodsucker(mob/living/carbon/C, disgust, blood_change, blood_puke = TRUE, force)
|
||||
if(AmBloodsucker(C))
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
taste_description = "alcohol"
|
||||
var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning
|
||||
pH = 7.33
|
||||
boiling_point = 351.38
|
||||
value = REAGENT_VALUE_VERY_COMMON //don't bother tweaking all drinks values, way too many can easily be done roundstart or with an upgraded dispenser.
|
||||
|
||||
/*
|
||||
@@ -85,6 +86,31 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
// +10% success propability on each step, useful while operating in less-than-perfect conditions
|
||||
return ..()
|
||||
|
||||
/datum/reagent/consumable/ethanol/define_gas() // So that all alcohols have the same gas, i.e. "ethanol"
|
||||
var/datum/gas/G = new
|
||||
G.id = GAS_ETHANOL
|
||||
G.name = "Ethanol"
|
||||
G.enthalpy = -234800
|
||||
G.specific_heat = 38
|
||||
G.fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5)
|
||||
G.fire_burn_rate = 1 / 3
|
||||
G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
|
||||
G.color = "#404030"
|
||||
G.breath_reagent = /datum/reagent/consumable/ethanol
|
||||
G.group = GAS_GROUP_CHEMICALS
|
||||
return G
|
||||
|
||||
/datum/reagent/consumable/ethanol/get_gas()
|
||||
var/datum/auxgm/cached_gas_data = GLOB.gas_data
|
||||
. = GAS_ETHANOL
|
||||
if(!(. in cached_gas_data.ids))
|
||||
var/datum/gas/G = define_gas()
|
||||
if(istype(G))
|
||||
cached_gas_data.add_gas(G)
|
||||
else // this codepath should probably not happen at all, since we never use get_gas() on anything with no boiling point
|
||||
return null
|
||||
|
||||
|
||||
/datum/reagent/consumable/ethanol/beer
|
||||
name = "Beer"
|
||||
description = "An alcoholic beverage brewed since ancient times on Old Earth. Still popular today."
|
||||
|
||||
@@ -909,20 +909,11 @@
|
||||
description = "A colorless, odorless gas. Grows on trees but is still pretty valuable."
|
||||
reagent_state = GAS
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
gas = GAS_O2
|
||||
boiling_point = 90.188
|
||||
taste_mult = 0 // oderless and tasteless
|
||||
pH = 9.2//It's acutally a huge range and very dependant on the chemistry but pH is basically a made up var in it's implementation anyways
|
||||
|
||||
/datum/reagent/oxygen/reaction_obj(obj/O, reac_volume)
|
||||
if((!O) || (!reac_volume))
|
||||
return 0
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
O.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/oxygen/reaction_turf(turf/open/T, reac_volume)
|
||||
if(istype(T))
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
T.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]")
|
||||
return
|
||||
molarity = 2
|
||||
|
||||
/datum/reagent/copper
|
||||
name = "Copper"
|
||||
@@ -943,26 +934,18 @@
|
||||
name = "Nitrogen"
|
||||
description = "A colorless, odorless, tasteless gas. A simple asphyxiant that can silently displace vital oxygen."
|
||||
reagent_state = GAS
|
||||
gas = GAS_N2
|
||||
boiling_point = 77.355
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
taste_mult = 0
|
||||
|
||||
|
||||
/datum/reagent/nitrogen/reaction_obj(obj/O, reac_volume)
|
||||
if((!O) || (!reac_volume))
|
||||
return 0
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
O.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/nitrogen/reaction_turf(turf/open/T, reac_volume)
|
||||
if(istype(T))
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
T.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]")
|
||||
return
|
||||
molarity = 2
|
||||
|
||||
/datum/reagent/hydrogen
|
||||
name = "Hydrogen"
|
||||
description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas."
|
||||
reagent_state = GAS
|
||||
gas = GAS_HYDROGEN
|
||||
boiling_point = 20.271
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
taste_mult = 0
|
||||
pH = 0.1//Now I'm stuck in a trap of my own design. Maybe I should make -ve pHes? (not 0 so I don't get div/0 errors)
|
||||
@@ -1015,9 +998,10 @@
|
||||
name = "Chlorine"
|
||||
description = "A pale yellow gas that's well known as an oxidizer. While it forms many harmless molecules in its elemental form it is far from harmless."
|
||||
reagent_state = GAS
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
color = "#c0c0a0" // rgb: 192, 192, 160
|
||||
taste_description = "chlorine"
|
||||
pH = 7.4
|
||||
boiling_point = 239.11
|
||||
|
||||
// You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial
|
||||
/datum/reagent/chlorine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
|
||||
@@ -1291,7 +1275,15 @@
|
||||
glass_name = "glass of welder fuel"
|
||||
glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption."
|
||||
pH = 4
|
||||
boiling_point = 400
|
||||
|
||||
/datum/reagent/fuel/define_gas()
|
||||
var/datum/gas/G = ..()
|
||||
G.enthalpy = 227400
|
||||
G.fire_burn_rate = 2 / 5
|
||||
G.fire_products = list(GAS_CO2 = 2, GAS_H2O = 1)
|
||||
G.fire_temperature = T0C+300
|
||||
return G
|
||||
|
||||
/datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite!
|
||||
if(method == TOUCH || method == VAPOR)
|
||||
@@ -1309,6 +1301,7 @@
|
||||
description = "A compound used to clean things. Now with 50% more sodium hypochlorite!"
|
||||
color = "#A5F0EE" // rgb: 165, 240, 238
|
||||
taste_description = "sourness"
|
||||
boiling_point = T0C+50
|
||||
pH = 5.5
|
||||
|
||||
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
|
||||
@@ -1321,6 +1314,7 @@
|
||||
O.clean_blood()
|
||||
|
||||
/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume)
|
||||
..()
|
||||
if(reac_volume >= 1)
|
||||
T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
|
||||
@@ -1488,6 +1482,7 @@
|
||||
name = "Ammonia"
|
||||
description = "A caustic substance commonly used in fertilizer or household cleaners."
|
||||
reagent_state = GAS
|
||||
gas = GAS_AMMONIA
|
||||
color = "#404030" // rgb: 64, 64, 48
|
||||
taste_description = "mordant"
|
||||
pH = 11.6
|
||||
@@ -1506,8 +1501,17 @@
|
||||
description = "A secondary amine, mildly corrosive."
|
||||
color = "#604030" // rgb: 96, 64, 48
|
||||
taste_description = "iron"
|
||||
boiling_point = 328
|
||||
pH = 12
|
||||
|
||||
/datum/reagent/diethylamine/define_gas()
|
||||
var/datum/gas/G = ..()
|
||||
G.fire_burn_rate = 1 / 6
|
||||
G.fire_products = list(GAS_H2O = 4, GAS_AMMONIA = 1, GAS_CO2 = 4)
|
||||
G.enthalpy = -131000
|
||||
G.fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
|
||||
return G
|
||||
|
||||
// This is more bad ass, and pests get hurt by the corrosive nature of it, not the plant. The new trade off is it culls stability.
|
||||
/datum/reagent/diethylamine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
|
||||
. = ..()
|
||||
@@ -1524,40 +1528,23 @@
|
||||
description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs."
|
||||
color = "#B0B0B0" // rgb : 192, 192, 192
|
||||
taste_description = "something unknowable"
|
||||
boiling_point = 195.68 // technically sublimation, not boiling, but same deal
|
||||
molarity = 5
|
||||
gas = GAS_CO2
|
||||
pH = 6
|
||||
|
||||
/datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume)
|
||||
if((!O) || (!reac_volume))
|
||||
return 0
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
O.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/carbondioxide/reaction_turf(turf/open/T, reac_volume)
|
||||
if(istype(T))
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
T.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]")
|
||||
return
|
||||
|
||||
/datum/reagent/nitrous_oxide
|
||||
name = "Nitrous Oxide"
|
||||
description = "A potent oxidizer used as fuel in rockets and as an anaesthetic during surgery."
|
||||
reagent_state = LIQUID
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
color = "#808080"
|
||||
boiling_point = 184.67
|
||||
molarity = 5
|
||||
gas = GAS_NITROUS
|
||||
taste_description = "sweetness"
|
||||
pH = 5.8
|
||||
|
||||
/datum/reagent/nitrous_oxide/reaction_obj(obj/O, reac_volume)
|
||||
if((!O) || (!reac_volume))
|
||||
return 0
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
O.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/nitrous_oxide/reaction_turf(turf/open/T, reac_volume)
|
||||
if(istype(T))
|
||||
var/temp = holder ? holder.chem_temp : T20C
|
||||
T.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/nitrous_oxide/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
if(method == VAPOR)
|
||||
M.drowsyness += max(round(reac_volume, 1), 2)
|
||||
@@ -1576,9 +1563,11 @@
|
||||
name = "Stimulum"
|
||||
description = "An unstable experimental gas that greatly increases the energy of those that inhale it"
|
||||
reagent_state = GAS
|
||||
gas = GAS_STIMULUM
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "E1A116"
|
||||
boiling_point = 150
|
||||
taste_description = "sourness"
|
||||
value = REAGENT_VALUE_EXCEPTIONAL
|
||||
|
||||
@@ -1602,9 +1591,11 @@
|
||||
name = "Nitryl"
|
||||
description = "A highly reactive gas that makes you feel faster"
|
||||
reagent_state = GAS
|
||||
gas = GAS_NITRYL
|
||||
metabolization_rate = REAGENTS_METABOLISM
|
||||
color = "90560B"
|
||||
color = "#90560B"
|
||||
taste_description = "burning"
|
||||
boiling_point = 294.3
|
||||
pH = 2
|
||||
value = REAGENT_VALUE_VERY_RARE
|
||||
|
||||
@@ -1811,6 +1802,8 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#b37740"
|
||||
taste_description = "chemicals"
|
||||
gas = GAS_BROMINE
|
||||
boiling_point = 332
|
||||
pH = 7.8
|
||||
|
||||
/datum/reagent/phenol
|
||||
@@ -2482,6 +2475,7 @@
|
||||
var/decal_path = /obj/effect/decal/cleanable/semen
|
||||
|
||||
/datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume)
|
||||
..()
|
||||
if(!istype(T))
|
||||
return
|
||||
if(reac_volume < 10)
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
metabolization_rate = 4
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "burning"
|
||||
/* no gaseous CLF3 until i can think of a good way to get it to burn that doesn't destroy matter in mysterious ways
|
||||
boiling_point = 289.4
|
||||
*/
|
||||
condensation_amount = 2
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
/datum/reagent/clf3/on_mob_life(mob/living/carbon/M)
|
||||
@@ -84,6 +88,12 @@
|
||||
if(!locate(/obj/effect/hotspot) in M.loc)
|
||||
new /obj/effect/hotspot(M.loc)
|
||||
|
||||
/datum/reagent/clf3/define_gas()
|
||||
var/datum/gas/G = ..()
|
||||
G.enthalpy = -163200
|
||||
G.oxidation_temperature = T0C - 50
|
||||
return G
|
||||
|
||||
/datum/reagent/sorium
|
||||
name = "Sorium"
|
||||
description = "Sends everything flying from the detonation point."
|
||||
@@ -152,8 +162,17 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FA00AF"
|
||||
taste_description = "burning"
|
||||
boiling_point = T20C-10
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
|
||||
/datum/reagent/phlogiston/define_gas()
|
||||
var/datum/gas/G = ..()
|
||||
G.enthalpy = FIRE_PLASMA_ENERGY_RELEASED / 100
|
||||
G.fire_products = list(GAS_O2 = 0.25, GAS_METHANE = 0.75) // meanwhile this is just magic
|
||||
G.fire_burn_rate = 1
|
||||
G.fire_temperature = T20C+1
|
||||
return G
|
||||
|
||||
/datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
M.adjust_fire_stacks(1)
|
||||
var/burndmg = max(0.3*M.fire_stacks, 0.3)
|
||||
@@ -288,6 +307,9 @@
|
||||
taste_description = "the inside of a fire extinguisher"
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
|
||||
/datum/reagent/firefighting_foam/define_gas()
|
||||
return null
|
||||
|
||||
/datum/reagent/firefighting_foam/reaction_turf(turf/open/T, reac_volume)
|
||||
if (!istype(T))
|
||||
return
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
for(var/gas in breath.get_gases())
|
||||
if(gas in breath_reagents)
|
||||
var/datum/reagent/R = breath_reagents[gas]
|
||||
H.reagents.add_reagent(R, PP(breath,gas))
|
||||
H.reagents.add_reagent(R, breath.get_moles(gas) * initial(R.molarity))
|
||||
mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - breath.get_moles(gas) : -breath.get_moles(gas)
|
||||
|
||||
for(var/gas in mole_adjustments)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/unit_test/reactions/Run()
|
||||
for(var/datum/gas_reaction/G in SSair.gas_reactions)
|
||||
var/test_info = G.test()
|
||||
if(!test_info["success"])
|
||||
var/message = test_info["message"]
|
||||
Fail("Gas reaction [G.name] is failing its unit test with the following message: [message]")
|
||||
if(!G.exclude)
|
||||
var/test_info = G.test()
|
||||
if(!test_info["success"])
|
||||
var/message = test_info["message"]
|
||||
Fail("Gas reaction [G.name] is failing its unit test with the following message: [message]")
|
||||
|
||||
Reference in New Issue
Block a user