diff --git a/baystation12.dme b/baystation12.dme index a8eeac7aed..23435efd1d 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1512,6 +1512,7 @@ #include "code\modules\reagents\Chemistry-Colours.dm" #include "code\modules\reagents\Chemistry-Holder.dm" #include "code\modules\reagents\Chemistry-Machinery.dm" +#include "code\modules\reagents\Chemistry-Metabolism.dm" #include "code\modules\reagents\Chemistry-Readme.dm" #include "code\modules\reagents\Chemistry-Reagents.dm" #include "code\modules\reagents\Chemistry-Recipes.dm" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index af4d8ef296..77bda01654 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -91,6 +91,7 @@ var/list/gamemode_cache = list() var/guests_allowed = 1 var/debugparanoid = 0 + var/serverurl var/server var/banappeals var/wikiurl @@ -163,6 +164,7 @@ var/list/gamemode_cache = list() var/use_irc_bot = 0 var/irc_bot_host = "" + var/irc_bot_export = 0 // whether the IRC bot in use is a Bot32 (or similar) instance; Bot32 uses world.Export() instead of nudge.py/libnudge var/main_irc = "" var/admin_irc = "" var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix @@ -385,6 +387,9 @@ var/list/gamemode_cache = list() if ("hostedby") config.hostedby = value + if ("serverurl") + config.serverurl = value + if ("server") config.server = value @@ -500,6 +505,9 @@ var/list/gamemode_cache = list() if("use_irc_bot") use_irc_bot = 1 + if("irc_bot_export") + irc_bot_export = 1 + if("ticklag") Ticklag = text2num(value) diff --git a/code/game/objects/effects/chem/water.dm b/code/game/objects/effects/chem/water.dm index eac107923e..30f436db9a 100644 --- a/code/game/objects/effects/chem/water.dm +++ b/code/game/objects/effects/chem/water.dm @@ -30,7 +30,7 @@ else if(ismob(A) && !M) M = A if(M) - reagents.splash_mob(M, reagents.total_volume) + reagents.trans_to(M, reagents.total_volume) break if(T == get_turf(target)) break diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 1974b4bdd2..f83e121643 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -61,7 +61,7 @@ else if(O.reagents.total_volume >= 1) if(O.reagents.has_reagent("pacid", 1)) user << "The acid chews through the balloon!" - O.reagents.splash_mob(user, reagents.total_volume) + O.reagents.splash(user, reagents.total_volume) qdel(src) else src.desc = "A translucent balloon with some form of liquid sloshing around in it." diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index d486cf64ad..42b75a2541 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -55,8 +55,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM return /obj/item/weapon/flame/match/dropped(mob/user as mob) + //If dropped, put ourselves out + //not before lighting up the turf we land on, though. if(lit) - burn_out() + spawn(0) + var/turf/location = src.loc + if(istype(location)) + location.hotspot_expose(700, 5) + burn_out() return ..() /obj/item/weapon/flame/match/proc/burn_out() diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 3fac8f0978..545b72cb95 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -225,6 +225,12 @@ if(M.back) if(M.back.clean_blood()) M.update_inv_back(0) + + //flush away reagents on the skin + if(M.touching) + var/remove_amount = M.touching.maximum_volume * M.reagent_permeability() //take off your suit first + M.touching.remove_any(remove_amount) + if(ishuman(M)) var/mob/living/carbon/human/H = M var/washgloves = 1 diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm index 8006652139..19df691757 100644 --- a/code/modules/ext_scripts/irc.dm +++ b/code/modules/ext_scripts/irc.dm @@ -1,17 +1,20 @@ /proc/send2irc(var/channel, var/msg) if(config.use_irc_bot && config.irc_bot_host) - if(config.use_lib_nudge) - var/nudge_lib - if(world.system_type == MS_WINDOWS) - nudge_lib = "lib\\nudge.dll" - else - nudge_lib = "lib/nudge.so" - - spawn(0) - call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]") + if(config.irc_bot_export) + world.Export("http://[config.irc_bot_host]:45678?[list2params(list(pwd=config.comms_password, chan=channel, mesg=msg))]") else - spawn(0) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]") + if(config.use_lib_nudge) + var/nudge_lib + if(world.system_type == MS_WINDOWS) + nudge_lib = "lib\\nudge.dll" + else + nudge_lib = "lib/nudge.so" + + spawn(0) + call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]") + else + spawn(0) + ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]") return /proc/send2mainirc(var/msg) @@ -26,6 +29,6 @@ /hook/startup/proc/ircNotify() - send2mainirc("Server starting up on [config.server? "byond://[config.server]" : "byond://[world.address]:[world.port]"]") + send2mainirc("Server starting up on byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]") return 1 diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm index 64f4564941..c3a6c69a5a 100644 --- a/code/modules/mob/living/carbon/brain/life.dm +++ b/code/modules/mob/living/carbon/brain/life.dm @@ -102,6 +102,9 @@ if(reagents) reagents.metabolize(0, CHEM_BLOOD) + if(touching) touching.metabolize() + if(ingested) ingested.metabolize() + if(bloodstr) bloodstr.metabolize() if(CE_PAINKILLER in chem_effects) analgesic = chem_effects[CE_PAINKILLER] diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index a485a09236..336c1b772b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1,11 +1,10 @@ /mob/living/carbon/New() - create_reagents(1000) - var/datum/reagents/R1 = new/datum/reagents(1000) - var/datum/reagents/R2 = new/datum/reagents(1000) - ingested = R1 - touching = R2 - R1.my_atom = src - R2.my_atom = src + //setup reagent holders + bloodstr = new/datum/reagents/metabolism(1000, src, CHEM_BLOOD) + ingested = new/datum/reagents/metabolism(1000, src, CHEM_INGEST) + touching = new/datum/reagents/metabolism(1000, src, CHEM_TOUCH) + reagents = bloodstr + ..() /mob/living/carbon/Life() diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index e617506c23..1478108b2a 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -18,7 +18,8 @@ //Active emote/pose var/pose = null var/list/chem_effects = list() - var/datum/reagents/ingested = null - var/datum/reagents/touching = null + var/datum/reagents/metabolism/bloodstr = null + var/datum/reagents/metabolism/ingested = null + var/datum/reagents/metabolism/touching = null var/pulse = PULSE_NORM //current pulse level diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 675d3c41df..65a05fdcea 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -438,4 +438,41 @@ emp_act if(!istype(wear_suit,/obj/item/clothing/suit/space)) return var/obj/item/clothing/suit/space/SS = wear_suit var/penetrated_dam = max(0,(damage - SS.breach_threshold)) - if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam) \ No newline at end of file + if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam) + +/mob/living/human/reagent_permeability() + var/perm = 0 + + var/list/perm_by_part = list( + "head" = THERMAL_PROTECTION_HEAD, + "upper_torso" = THERMAL_PROTECTION_UPPER_TORSO, + "lower_torso" = THERMAL_PROTECTION_LOWER_TORSO, + "legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT, + "feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT, + "arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT, + "hands" = THERMAL_PROTECTION_HAND_LEFT + THERMAL_PROTECTION_HAND_RIGHT + ) + + for(var/obj/item/clothing/C in src.get_equipped_items()) + if(C.permeability_coefficient == 1 || !C.body_parts_covered) + continue + if(C.body_parts_covered & HEAD) + perm_by_part["head"] *= C.permeability_coefficient + if(C.body_parts_covered & UPPER_TORSO) + perm_by_part["upper_torso"] *= C.permeability_coefficient + if(C.body_parts_covered & LOWER_TORSO) + perm_by_part["lower_torso"] *= C.permeability_coefficient + if(C.body_parts_covered & LEGS) + perm_by_part["legs"] *= C.permeability_coefficient + if(C.body_parts_covered & FEET) + perm_by_part["feet"] *= C.permeability_coefficient + if(C.body_parts_covered & ARMS) + perm_by_part["arms"] *= C.permeability_coefficient + if(C.body_parts_covered & HANDS) + perm_by_part["hands"] *= C.permeability_coefficient + + for(var/part in perm_by_part) + perm += perm_by_part[part] + + return perm + diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 25299f19fa..a17c6c8b10 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -845,17 +845,17 @@ return min(1,thermal_protection) + return min(1,thermal_protection) + /mob/living/carbon/human/proc/handle_chemicals_in_body() - if(reagents) + if(!(species.flags & IS_SYNTHETIC)) //Synths don't process reagents. chem_effects.Cut() analgesic = 0 - var/alien = 0 - if(species && species.reagent_tag) - alien = species.reagent_tag - touching.metabolize(alien, CHEM_TOUCH) - if(!(species.flags & NO_BLOOD)) - ingested.metabolize(alien, CHEM_INGEST) - reagents.metabolize(alien, CHEM_BLOOD) + + if(touching) touching.metabolize() + if(ingested) ingested.metabolize() + if(bloodstr) bloodstr.metabolize() + if(CE_PAINKILLER in chem_effects) analgesic = chem_effects[CE_PAINKILLER] diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 00d28b3a37..a2fafd15ec 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -78,12 +78,9 @@ chem_effects.Cut() analgesic = 0 - if(touching) - touching.metabolize(0, CHEM_TOUCH) - if(ingested) - ingested.metabolize(0, CHEM_INGEST) - if(reagents) - reagents.metabolize(0, CHEM_BLOOD) + if(touching) touching.metabolize() + if(ingested) ingested.metabolize() + if(bloodstr) bloodstr.metabolize() if(CE_PAINKILLER in chem_effects) analgesic = chem_effects[CE_PAINKILLER] diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index 9a511504f3..c99a8bd599 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -3,14 +3,14 @@ //drop && roll if(on_fire) - fire_stacks -= 2 //reduced - Weaken(3) - spin(32,2) + fire_stacks -= 2 + Weaken(5) + spin(52,2) visible_message( "[src] rolls on the floor, trying to put themselves out!", "You stop, drop, and roll!" ) - sleep(30) + sleep(50) if(fire_stacks <= 0) visible_message( "[src] has successfully extinguished themselves!", diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index e0385e7d2b..74a3117cb9 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -236,7 +236,7 @@ location.hotspot_expose(fire_burn_temperature(), 50, 1) /mob/living/fire_act() - adjust_fire_stacks(0.5) + adjust_fire_stacks(2) IgniteMob() //Finds the effective temperature that the mob is burning at. @@ -245,6 +245,11 @@ return 0 //Scale quadratically so that single digit numbers of fire stacks don't burn ridiculously hot. + //lower limit of 700 K, same as matches and roughly the temperature of a cool flame. + return max(2.25*round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2), 700) + +/mob/living/proc/reagent_permeability() + return 1 return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2) /mob/living/regular_hud_updates() diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index f785408392..928f67f3ef 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -6,9 +6,21 @@ var/maximum_volume = 100 var/atom/my_atom = null -/datum/reagents/New(var/max = 100) +/datum/reagents/New(var/max = 100, atom/A = null) ..() maximum_volume = max + my_atom = A + + //I dislike having these here but map-objects are initialised before world/New() is called. >_> + if(!chemical_reagents_list) + //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id + var/paths = typesof(/datum/reagent) - /datum/reagent + chemical_reagents_list = list() + for(var/path in paths) + var/datum/reagent/D = new path() + if(!D.name) + continue + chemical_reagents_list[D.id] = D /datum/reagents/Destroy() ..() @@ -265,53 +277,26 @@ /* Holder-to-atom and similar procs */ -/datum/reagents/proc/touch(var/atom/target) // This picks the appropriate reaction. Reagents are not guaranteed to transfer to the target. - if(ismob(target)) - touch_mob(target) - if(isturf(target)) - touch_turf(target) - if(isobj(target)) - touch_obj(target) - return - -/datum/reagents/proc/touch_mob(var/mob/target) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_mob(target) - - update_total() - -/datum/reagents/proc/touch_turf(var/turf/target) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_turf(target) - - update_total() - -/datum/reagents/proc/touch_obj(var/obj/target) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_obj(target) - - update_total() - +//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally, +//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob(). +//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person), +//call the appropriate trans_to_*() proc. /datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + touch(target) //First, handle mere touch effects + if(ismob(target)) - //warning("[my_atom] is trying to transfer reagents to [target], which is a mob, using trans_to()") - //return trans_to_mob(target, amount, multiplier, copy) - return splash_mob(target, amount) + return splash_mob(target, amount, copy) if(isturf(target)) return trans_to_turf(target, amount, multiplier, copy) if(isobj(target)) return trans_to_obj(target, amount, multiplier, copy) return 0 +//Using this in case we want to differentiate splashing an atom from transferring reagents to it later down the road. +//For now it just calls trans_to. +/datum/reagents/proc/splash(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + trans_to(target, amount, multiplier, copy) + /datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1) if (!target || !target.reagents) return @@ -328,30 +313,55 @@ return F.trans_to(target, amount) // Let this proc check the atom's type -/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/clothes = 1) - var/perm = 0 - var/list/L = list("head" = THERMAL_PROTECTION_HEAD, "upper_torso" = THERMAL_PROTECTION_UPPER_TORSO, "lower_torso" = THERMAL_PROTECTION_LOWER_TORSO, "legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT, "feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT, "arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT, "hands" = THERMAL_PROTECTION_HAND_LEFT + THERMAL_PROTECTION_HAND_RIGHT) - if(clothes) - for(var/obj/item/clothing/C in target.get_equipped_items()) - if(C.permeability_coefficient == 1 || C.body_parts_covered == 0) - continue - if(C.body_parts_covered & HEAD) - L["head"] *= C.permeability_coefficient - if(C.body_parts_covered & UPPER_TORSO) - L["upper_torso"] *= C.permeability_coefficient - if(C.body_parts_covered & LOWER_TORSO) - L["lower_torso"] *= C.permeability_coefficient - if(C.body_parts_covered & LEGS) - L["legs"] *= C.permeability_coefficient - if(C.body_parts_covered & FEET) - L["feet"] *= C.permeability_coefficient - if(C.body_parts_covered & ARMS) - L["arms"] *= C.permeability_coefficient - if(C.body_parts_covered & HANDS) - L["hands"] *= C.permeability_coefficient - for(var/t in L) - perm += L[t] - return trans_to_mob(target, amount, CHEM_TOUCH, perm) +// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. +// This does not handle transferring reagents to things. +// For example, splashing someone with water will get them wet and extinguish them if they are on fire, +// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. +/datum/reagents/proc/touch(var/atom/target) + if(ismob(target)) + touch_mob(target) + if(isturf(target)) + touch_turf(target) + if(isobj(target)) + touch_obj(target) + return + +/datum/reagents/proc/touch_mob(var/mob/target) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_mob(target, current.volume) + + update_total() + +/datum/reagents/proc/touch_turf(var/turf/target) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_turf(target, current.volume) + + update_total() + +/datum/reagents/proc/touch_obj(var/obj/target) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_obj(target, current.volume) + + update_total() + +// Attempts to place a reagent on the mob's skin. +// Reagents are not guaranteed to transfer to the target. +// Do not call this directly, call trans_to() instead. +/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/copy = 0) + var/perm = 1 + if(isliving(target)) //will we ever even need to tranfer reagents to non-living mobs? + var/mob/living/L = target + perm = L.reagent_permeability() + return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy) /datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder... if(!target || !istype(target)) @@ -393,18 +403,7 @@ return trans_to_holder(target.reagents, amount, multiplier, copy) -/datum/reagents/proc/metabolize(var/alien, var/location) - if(!iscarbon(my_atom)) - return - var/mob/living/carbon/C = my_atom - if(!C || !istype(C)) - return - for(var/datum/reagent/current in reagent_list) - current.on_mob_life(C, alien, location) - update_total() - /* Atom reagent creation - use it all the time */ /atom/proc/create_reagents(var/max_vol) - reagents = new/datum/reagents(max_vol) - reagents.my_atom = src + reagents = new/datum/reagents(max_vol, src) diff --git a/code/modules/reagents/Chemistry-Metabolism.dm b/code/modules/reagents/Chemistry-Metabolism.dm new file mode 100644 index 0000000000..74ef2d4730 --- /dev/null +++ b/code/modules/reagents/Chemistry-Metabolism.dm @@ -0,0 +1,21 @@ +/datum/reagents/metabolism + var/metabolism_class //CHEM_TOUCH, CHEM_INGEST, or CHEM_BLOOD + var/mob/living/carbon/parent + +/datum/reagents/metabolism/New(var/max = 100, mob/living/carbon/parent_mob, var/met_class) + ..(max, parent_mob) + + metabolism_class = met_class + if(istype(parent_mob)) + parent = parent_mob + +/datum/reagents/metabolism/proc/metabolize() + + var/metabolism_type = 0 //non-human mobs + if(ishuman(parent)) + var/mob/living/carbon/human/H = parent + metabolism_type = H.species.reagent_tag + + for(var/datum/reagent/current in reagent_list) + current.on_mob_life(parent, metabolism_type, metabolism_class) + update_total() \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/Chemistry-Readme.dm index 399e856bf3..9a49d409e0 100644 --- a/code/modules/reagents/Chemistry-Readme.dm +++ b/code/modules/reagents/Chemistry-Readme.dm @@ -88,7 +88,12 @@ About the Holder: Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead. touch(var/atom/target) - Not recommended to use. Calls touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type. + When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. + This does not handle transferring reagents to things. + For example, splashing someone with water will get them wet and extinguish them if they are on fire, + even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. + Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type. + Not recommended to use this directly, since trans_to() calls it before attempting to transfer. touch_mob(var/mob/target) Calls each reagent's touch_mob(target). @@ -100,13 +105,18 @@ About the Holder: Calls each reagent's touch_obj(target). trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - Checks the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy). + The general proc for applying reagents to things externally (as opposed to directly injected into the contents). + It first calls touch, then the appropriate trans_to_*() or splash_mob(). + If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc. + + Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy). trans_id_to(var/atom/target, var/id, var/amount = 1) Transfers [amount] of [id] to [target]. Returns amount transferred. splash_mob(var/mob/target, var/amount = 1, var/clothes = 1) Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin. + Don't call this directly. Call apply_to() instead. trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection. diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index b223a48684..d77f7b412f 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -36,13 +36,14 @@ /datum/reagent/proc/remove_self(var/amount) // Shortcut holder.remove_reagent(id, amount) -/datum/reagent/proc/touch_mob(var/mob/M) // This doesn't apply to being splashed - this is for, e.g. extinguishers and sprays. The difference is that reagent is not on the mob - it's in another object. +// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing. +/datum/reagent/proc/touch_mob(var/mob/M, var/amount) return -/datum/reagent/proc/touch_obj(var/obj/O) // Acid melting, cleaner cleaning, etc +/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc return -/datum/reagent/proc/touch_turf(var/turf/T) // Cleaner cleaning, lube lubbing, etc, all go here +/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here return /datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob. diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index c7afddee39..2d32761ba6 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -55,6 +55,19 @@ M.adjustToxLoss(removed) if(dose > 15) M.adjustToxLoss(removed) + if(data && data["viruses"]) + for(var/datum/disease/D in data["viruses"]) + if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS) + continue + if(D.spread_type in list(CONTACT_FEET, CONTACT_HANDS, CONTACT_GENERAL)) + M.contract_disease(D) + if(data && data["virus2"]) + var/list/vlist = data["virus2"] + if(vlist.len) + for(var/ID in vlist) + var/datum/disease2/disease/V = vlist[ID] + if(V.spreadtype == "Contact") + infect_virus2(M, V.getcopy()) /datum/reagent/blood/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_MACHINE) @@ -63,13 +76,15 @@ for(var/datum/disease/D in data["viruses"]) if(D.spread_type == SPECIAL || D.spread_type == NON_CONTAGIOUS) continue - M.contract_disease(D) + if(D.spread_type in list(CONTACT_FEET, CONTACT_HANDS, CONTACT_GENERAL)) + M.contract_disease(D) if(data && data["virus2"]) var/list/vlist = data["virus2"] if(vlist.len) for(var/ID in vlist) var/datum/disease2/disease/V = vlist[ID] - infect_virus2(M, V.getcopy()) + if(V.spreadtype == "Contact") + infect_virus2(M, V.getcopy()) if(data && data["antibodies"]) M.antibodies |= data["antibodies"] @@ -157,6 +172,17 @@ if(!cube.wrapped) cube.Expand() +/datum/reagent/water/touch_mob(var/mob/living/L, var/amount) + if(istype(L)) + var/needed = L.fire_stacks * 10 + if(amount > needed) + L.fire_stacks = 0 + L.ExtinguishMob() + remove_self(needed) + else + L.adjust_fire_stacks(-(amount / 10)) + remove_self(amount) + /datum/reagent/water/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) if(istype(M, /mob/living/carbon/slime)) var/mob/living/carbon/slime/S = M @@ -167,15 +193,6 @@ ++S.Discipline if(dose == removed) S.visible_message("[S]'s flesh sizzles where the water touches it!", "Your flesh burns in the water!") - var/needed = M.fire_stacks * 10 - if(volume > needed) - M.fire_stacks = 0 - M.ExtinguishMob() - remove_self(needed) - else - M.adjust_fire_stacks(-(volume / 10)) - remove_self(volume) - return /datum/reagent/fuel name = "Welding fuel" @@ -197,5 +214,7 @@ /datum/reagent/fuel/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustToxLoss(2 * removed) -/datum/reagent/fuel/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) // Splashing people with welding fuel to make them easy to ignite! - M.adjust_fire_stacks(0.1 * removed) +/datum/reagent/fuel/touch_mob(var/mob/living/L, var/amount) + if(istype(L)) + L.adjust_fire_stacks(amount / 10) // Splashing people with welding fuel to make them easy to ignite! + diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm index a751b9df7e..7a882fa94e 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm @@ -100,9 +100,9 @@ glass_name = "glass of ethanol" glass_desc = "A well-known alcohol with a variety of applications." -/datum/reagent/ethanol/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - M.adjust_fire_stacks(removed / 15) - return +/datum/reagent/ethanol/touch_mob(var/mob/living/L, var/amount) + if(istype(L)) + L.adjust_fire_stacks(amount / 15) /datum/reagent/ethanol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustToxLoss(removed * 2 * toxicity) @@ -327,7 +327,7 @@ return if(volume < meltdose) // Not enough to melt anything - M.take_organ_damage(removed * power * 0.2) + M.take_organ_damage(0, removed * power * 0.2) //burn damage, since it causes chemical burns. Acid doesn't make bones shatter, like brute trauma would. return if(!M.unacidable && removed > 0) if(istype(M, /mob/living/carbon/human) && volume >= meltdose) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm index 51c86f1b52..09790d82c2 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm @@ -67,10 +67,7 @@ /datum/reagent/paint/touch_mob(var/mob/M) if(istype(M) && !istype(M, /mob/dead)) //painting ghosts: not allowed - M.color = color - -/datum/reagent/paint/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - M.color = color + M.color = color //maybe someday change this to paint only clothes and exposed body parts for human mobs. /datum/reagent/paint/get_data() return color @@ -258,9 +255,9 @@ remove_self(5) return -/datum/reagent/thermite/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - M.adjust_fire_stacks(removed * 0.2) - return +/datum/reagent/thermite/touch_mob(var/mob/living/L, var/amount) + if(istype(L)) + L.adjust_fire_stacks(amount / 5) /datum/reagent/thermite/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.adjustFireLoss(3 * removed) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 264e9183f8..8817db3618 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -46,9 +46,12 @@ strength = 30 touch_met = 5 +/datum/reagent/toxin/phoron/touch_mob(var/mob/living/L, var/amount) + if(istype(L)) + L.adjust_fire_stacks(amount / 5) + /datum/reagent/toxin/phoron/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - ..() - M.adjust_fire_stacks(removed / 5) + M.take_organ_damage(0, removed * 0.1) //being splashed directly with phoron causes minor chemical burns if(prob(50)) M.pl_effects() @@ -500,7 +503,7 @@ /datum/reagent/nanites/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) if(prob(10)) - M.contract_disease(new /datum/disease/robotic_transformation(0), 1) + M.contract_disease(new /datum/disease/robotic_transformation(0), 1) //What /datum/reagent/nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) M.contract_disease(new /datum/disease/robotic_transformation(0), 1) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 140cab11dd..3972213048 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -72,7 +72,7 @@ msg_admin_attack("[user.name] ([user.ckey]) splashed [target.name] ([target.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (JMP)") user.visible_message("[target] has been splashed with something by [user]!", "You splash the solution onto [target].") - reagents.splash_mob(target, reagents.total_volume) + reagents.splash(target, reagents.total_volume) return 1 /obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user) diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 5c69abb6b9..bc9f4c4243 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -64,7 +64,7 @@ return else - trans = reagents.trans_to(target, amount_per_transfer_from_this) + trans = reagents.splash(target, amount_per_transfer_from_this) //sprinkling reagents on generic non-mobs user << "You transfer [trans] units of the solution." else // Taking from something diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index e6b1308603..7e289a45f3 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -78,7 +78,7 @@ //The reagents in the bottle splash all over the target, thanks for the idea Nodrak if(reagents) user.visible_message("The contents of the [src] splash all over [target]!") - reagents.splash_mob(target, reagents.total_volume) + reagents.splash(target, reagents.total_volume) //Finally, smash the bottle. This kills (qdel) the bottle. src.smash(target, user) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index b7e7f948d5..23a440da59 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -481,7 +481,7 @@ /obj/item/weapon/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) ..() new/obj/effect/decal/cleanable/egg_smudge(src.loc) - src.reagents.trans_to(hit_atom, reagents.total_volume) + src.reagents.splash(hit_atom, reagents.total_volume) src.visible_message("\red [src.name] has been squashed.","\red You hear a smack.") qdel(src) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 836b500df3..26f58fb471 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -88,7 +88,7 @@ if(reagents.total_volume) user << "You splash the solution onto [target]." - reagents.trans_to(target, reagents.total_volume) + reagents.splash(target, reagents.total_volume) return attackby(obj/item/weapon/W as obj, mob/user as mob) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 79247f8252..662099a716 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -53,7 +53,7 @@ /obj/item/weapon/reagent_containers/spray/proc/Spray_at(atom/A as mob|obj, mob/user as mob, proximity) if (A.density && proximity) A.visible_message("[usr] sprays [A] with [src].") - reagents.trans_to(A, amount_per_transfer_from_this) + reagents.splash(A, amount_per_transfer_from_this) else spawn(0) var/obj/effect/effect/water/chempuff/D = new/obj/effect/effect/water/chempuff(get_turf(src)) @@ -88,7 +88,7 @@ return if(isturf(usr.loc)) usr << "You empty \the [src] onto the floor." - reagents.trans_to(usr.loc, reagents.total_volume) + reagents.splash(usr.loc, reagents.total_volume) //space cleaner /obj/item/weapon/reagent_containers/spray/cleaner diff --git a/config/example/config.txt b/config/example/config.txt index 7648a51a88..41b70c1193 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -174,6 +174,10 @@ GUEST_BAN ## set a server location for world reboot. Don't include the byond://, just give the address and port. #SERVER server.net:port +## set a server URL for the IRC bot to use; like SERVER, don't include the byond:// +## Unlike SERVER, this one shouldn't break auto-reconnect +#SERVERURL server.net:port + ## forum address # FORUMURL http://example.com @@ -241,6 +245,9 @@ USEALIENWHITELIST ## Uncomment to enable sending data to the IRC bot. #USE_IRC_BOT +## Uncomment if the IRC bot requires using world.Export() instead of nudge.py/libnudge +#IRC_BOT_EXPORT + ## Host where the IRC bot is hosted. Port 45678 needs to be open. #IRC_BOT_HOST localhost diff --git a/html/changelog.html b/html/changelog.html index b22bd9778e..37f48b6886 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -88,6 +88,16 @@