diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index b303d7d31f4..bded06b1947 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -112,11 +112,14 @@ "[user] unfastens \the [src].", \ "\blue You have unfastened \the [src].", \ "You hear ratchet.") - new /obj/item/pipe(loc, make_from=src) + var/obj/item/P = new /obj/item/pipe(loc, make_from=src) for (var/obj/machinery/meter/meter in T) if (meter.target == src) new /obj/item/pipe_meter(T) del(meter) + if(P) + transfer_fingerprints_to(P) + P.add_fingerprint(user) qdel(src) return 1 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 136f78203df..9462083757e 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1385,38 +1385,55 @@ var/global/list/common_tools = list( return 1 return 0 -proc/is_hot(obj/item/W as obj) - switch(W.type) - if(/obj/item/weapon/weldingtool) - var/obj/item/weapon/weldingtool/WT = W - if(WT.isOn()) - return 3800 - else - return 0 - if(/obj/item/weapon/lighter) - if(W:lit) - return 1500 - else - return 0 - if(/obj/item/weapon/match) - if(W:lit) - return 1000 - else - return 0 - if(/obj/item/clothing/mask/cigarette) - if(W:lit) - return 1000 - else - return 0 - if(/obj/item/weapon/pickaxe/plasmacutter) +/proc/is_hot(obj/item/W as obj) + if(istype(W, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/O = W + if(O.isOn()) return 3800 - if(/obj/item/weapon/melee/energy) + else + return 0 + if(istype(W, /obj/item/weapon/lighter)) + var/obj/item/weapon/lighter/O = W + if(O.lit) + return 1500 + else + return 0 + if(istype(W, /obj/item/weapon/match)) + var/obj/item/weapon/match/O = W + if(O.lit == 1) + return 1000 + else + return 0 + if(istype(W, /obj/item/clothing/mask/cigarette)) + var/obj/item/clothing/mask/cigarette/O = W + if(O.lit) + return 1000 + else + return 0 + if(istype(W, /obj/item/candle)) + var/obj/item/candle/O = W + if(O.lit) + return 1000 + else + return 0 + if(istype(W, /obj/item/device/flashlight/flare)) + var/obj/item/device/flashlight/flare/O = W + if(O.on) + return 1000 + else + return 0 + if(istype(W, /obj/item/weapon/pickaxe/plasmacutter)) + return 3800 + if(istype(W, /obj/item/weapon/melee/energy)) + var/obj/item/weapon/melee/energy/O = W + if(O.active) return 3500 else return 0 - - return 0 - + if(istype(W, /obj/item/device/assembly/igniter)) + return 1000 + else + return 0 //Whether or not the given item counts as sharp in terms of dealing damage /proc/is_sharp(obj/O as obj) diff --git a/code/datums/cargoprofile.dm b/code/datums/cargoprofile.dm index bf331bae619..90b7930937b 100644 --- a/code/datums/cargoprofile.dm +++ b/code/datums/cargoprofile.dm @@ -245,7 +245,7 @@ id = "trash" //Note that this filters out blueprints because they are a paper item. Do NOT throw out the station blueprints unless you be trollin'. blacklist = null - whitelist = list(/obj/item/trash,/obj/item/toy,/obj/item/weapon/ectoplasm,/obj/item/weapon/bananapeel,/obj/item/weapon/broken_bottle,/obj/item/weapon/bikehorn, + whitelist = list(/obj/item/trash,/obj/item/toy,/obj/item/weapon/reagent_containers/food/snacks/ectoplasm,/obj/item/weapon/bananapeel,/obj/item/weapon/broken_bottle,/obj/item/weapon/bikehorn, /obj/item/weapon/cigbutt,/obj/item/weapon/contraband,/obj/item/weapon/corncob,/obj/item/weapon/paper,/obj/item/weapon/shard, /obj/item/weapon/sord,/obj/item/weapon/photo,/obj/item/weapon/folder, /obj/item/areaeditor/blueprints,/obj/item/weapon/contraband,/obj/item/weapon/kitchen,/obj/item/weapon/book,/obj/item/clothing/mask/facehugger) diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index eb9cca9ec93..c8e76fa8ac9 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -829,13 +829,6 @@ origin_tech = "magnets=3;materials=3;bluespace=2" m_amt = 50 -/obj/item/weapon/ectoplasm - name = "ectoplasm" - desc = "spooky" - gender = PLURAL - icon = 'icons/obj/wizard.dmi' - icon_state = "ectoplasm" - /obj/item/weapon/research//Makes testing much less of a pain -Sieve name = "research" icon = 'icons/obj/stock_parts.dmi' diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 21e66517422..acf9f023c91 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -411,8 +411,9 @@ Buildable meters // no conflicts found var/pipefailtext = "\red There's nothing to connect this pipe section to!" //(with how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment)" + var/obj/machinery/atmospherics/machineReference = null //If somebody wants to overhaul that switch statement below, be my guest. Easier to set a reference here and then transfer logs after the switch statement. - switch(pipe_type) + switch(pipe_type) //What kind of heartless person thought of doing this? if(PIPE_SIMPLE_STRAIGHT, PIPE_SIMPLE_BENT) var/obj/machinery/atmospherics/pipe/simple/P = new( src.loc ) P.pipe_color = color @@ -431,6 +432,8 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P + if(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT) var/obj/machinery/atmospherics/pipe/simple/hidden/supply/P = new( src.loc ) @@ -450,6 +453,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT) var/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers/P = new( src.loc ) @@ -469,6 +473,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_UNIVERSAL) var/obj/machinery/atmospherics/pipe/simple/hidden/universal/P = new( src.loc ) @@ -488,6 +493,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_HE_STRAIGHT, PIPE_HE_BENT) var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/P = new ( src.loc ) @@ -507,6 +513,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_CONNECTOR) // connector var/obj/machinery/atmospherics/portables_connector/C = new( src.loc ) @@ -521,6 +528,7 @@ Buildable meters if (C.node) C.node.initialize() C.node.build_network() + machineReference = C if(PIPE_MANIFOLD) //manifold @@ -545,6 +553,7 @@ Buildable meters if (M.node3) M.node3.initialize() M.node3.build_network() + machineReference = M if(PIPE_SUPPLY_MANIFOLD) //manifold var/obj/machinery/atmospherics/pipe/manifold/hidden/supply/M = new( src.loc ) @@ -568,6 +577,7 @@ Buildable meters if (M.node3) M.node3.initialize() M.node3.build_network() + machineReference = M if(PIPE_SCRUBBERS_MANIFOLD) //manifold var/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers/M = new( src.loc ) @@ -591,6 +601,7 @@ Buildable meters if (M.node3) M.node3.initialize() M.node3.build_network() + machineReference = M if(PIPE_MANIFOLD4W) //4-way manifold var/obj/machinery/atmospherics/pipe/manifold4w/M = new( src.loc ) @@ -617,6 +628,7 @@ Buildable meters if (M.node4) M.node4.initialize() M.node4.build_network() + machineReference = M if(PIPE_SUPPLY_MANIFOLD4W) //4-way manifold var/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply/M = new( src.loc ) @@ -644,6 +656,7 @@ Buildable meters if (M.node4) M.node4.initialize() M.node4.build_network() + machineReference = M if(PIPE_SCRUBBERS_MANIFOLD4W) //4-way manifold var/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers/M = new( src.loc ) @@ -671,6 +684,7 @@ Buildable meters if (M.node4) M.node4.initialize() M.node4.build_network() + machineReference = M if(PIPE_JUNCTION) var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/P = new ( src.loc ) @@ -690,6 +704,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_UVENT) //unary vent var/obj/machinery/atmospherics/unary/vent_pump/V = new( src.loc ) @@ -704,6 +719,7 @@ Buildable meters if (V.node) V.node.initialize() V.node.build_network() + machineReference = V if(PIPE_MVALVE) //manual valve @@ -724,6 +740,7 @@ Buildable meters // world << "[V.node2.name] is connected to valve, forcing it to update its nodes." V.node2.initialize() V.node2.build_network() + machineReference = V if(PIPE_PUMP) //gas pump var/obj/machinery/atmospherics/binary/pump/P = new(src.loc) @@ -741,6 +758,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_GAS_FILTER) //gas filter var/obj/machinery/atmospherics/trinary/filter/P = new(src.loc) @@ -761,6 +779,7 @@ Buildable meters if (P.node3) P.node3.initialize() P.node3.build_network() + machineReference = P if(PIPE_GAS_MIXER) //gas mixer var/obj/machinery/atmospherics/trinary/mixer/P = new(src.loc) @@ -781,6 +800,7 @@ Buildable meters if (P.node3) P.node3.initialize() P.node3.build_network() + machineReference = P if(PIPE_GAS_FILTER_M) //gas filter mirrored var/obj/machinery/atmospherics/trinary/filter/m_filter/P = new(src.loc) @@ -801,6 +821,7 @@ Buildable meters if (P.node3) P.node3.initialize() P.node3.build_network() + machineReference = P if(PIPE_GAS_MIXER_T) //gas mixer-t var/obj/machinery/atmospherics/trinary/mixer/t_mixer/P = new(src.loc) @@ -821,6 +842,7 @@ Buildable meters if (P.node3) P.node3.initialize() P.node3.build_network() + machineReference = P if(PIPE_GAS_MIXER_M) //gas mixer mirrored var/obj/machinery/atmospherics/trinary/mixer/m_mixer/P = new(src.loc) @@ -841,6 +863,7 @@ Buildable meters if (P.node3) P.node3.initialize() P.node3.build_network() + machineReference = P if(PIPE_SCRUBBER) //scrubber var/obj/machinery/atmospherics/unary/vent_scrubber/S = new(src.loc) @@ -855,6 +878,7 @@ Buildable meters if (S.node) S.node.initialize() S.node.build_network() + machineReference = S if(PIPE_INSULATED_STRAIGHT, PIPE_INSULATED_BENT) var/obj/machinery/atmospherics/pipe/simple/insulated/P = new( src.loc ) @@ -873,6 +897,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_MTVALVE) //manual t-valve var/obj/machinery/atmospherics/tvalve/V = new(src.loc) @@ -893,6 +918,7 @@ Buildable meters if (V.node3) V.node3.initialize() V.node3.build_network() + machineReference = V if(PIPE_CAP) var/obj/machinery/atmospherics/pipe/cap/C = new(src.loc) @@ -903,6 +929,7 @@ Buildable meters if(C.node) C.node.initialize() C.node.build_network() + machineReference = C if(PIPE_SUPPLY_CAP) var/obj/machinery/atmospherics/pipe/cap/hidden/supply/C = new(src.loc) @@ -913,6 +940,7 @@ Buildable meters if(C.node) C.node.initialize() C.node.build_network() + machineReference = C if(PIPE_SCRUBBERS_CAP) var/obj/machinery/atmospherics/pipe/cap/hidden/scrubbers/C = new(src.loc) @@ -923,6 +951,7 @@ Buildable meters if(C.node) C.node.initialize() C.node.build_network() + machineReference = C if(PIPE_PASSIVE_GATE) //passive gate var/obj/machinery/atmospherics/binary/passive_gate/P = new(src.loc) @@ -940,6 +969,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_VOLUME_PUMP) //volume pump var/obj/machinery/atmospherics/binary/volume_pump/P = new(src.loc) @@ -957,6 +987,7 @@ Buildable meters if (P.node2) P.node2.initialize() P.node2.build_network() + machineReference = P if(PIPE_HEAT_EXCHANGE) // heat exchanger var/obj/machinery/atmospherics/unary/heat_exchanger/C = new( src.loc ) @@ -971,6 +1002,8 @@ Buildable meters if (C.node) C.node.initialize() C.node.build_network() + machineReference = C + ///// Z-Level stuff /* if(PIPE_UP) var/obj/machinery/atmospherics/pipe/zpipe/up/P = new(src.loc) @@ -1005,24 +1038,30 @@ Buildable meters P.node2.initialize() P.node2.build_network()*/ ///// Z-Level stuff + if(PIPE_OMNI_MIXER) var/obj/machinery/atmospherics/omni/mixer/P = new(loc) var/turf/T = P.loc P.level = T.intact ? 2 : 1 P.initialize() P.build_network() + machineReference = P if(PIPE_OMNI_FILTER) var/obj/machinery/atmospherics/omni/filter/P = new(loc) var/turf/T = P.loc P.level = T.intact ? 2 : 1 P.initialize() P.build_network() + machineReference = P playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) user.visible_message( \ "[user] fastens the [src].", \ "\blue You have fastened the [src].", \ "You hear ratchet.") + if(machineReference) + transfer_fingerprints_to(machineReference) + machineReference.add_fingerprint(user) del(src) // remove the pipe item return diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index a9eb9e4a217..b18b86aae71 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -204,4 +204,26 @@ /obj/structure/flora/kirbyplants/dead name = "RD's potted plant" desc = "A gift from the botanical staff, presented after the RD's reassignment. There's a tag on it that says \"Y'all come back now, y'hear?\"\nIt doesn't look very healthy..." - icon_state = "plant-25" \ No newline at end of file + icon_state = "plant-25" + +//a rock is flora according to where the icon file is +//and now these defines +/obj/structure/flora/rock + name = "rock" + desc = "a rock" + icon_state = "rock1" + icon = 'icons/obj/flora/rocks.dmi' + anchored = 1 + +/obj/structure/flora/rock/New() + ..() + icon_state = "rock[rand(1,5)]" + +/obj/structure/flora/rock/pile + name = "rocks" + desc = "some rocks" + icon_state = "rockpile1" + +/obj/structure/flora/rock/pile/New() + ..() + icon_state = "rockpile[rand(1,5)]" \ No newline at end of file diff --git a/code/game/turfs/unsimulated/floor.dm b/code/game/turfs/unsimulated/floor.dm index 1d391eee1c1..74cd160a86b 100644 --- a/code/game/turfs/unsimulated/floor.dm +++ b/code/game/turfs/unsimulated/floor.dm @@ -21,4 +21,11 @@ M.start_pulling(t) else step(user.pulling, get_dir(user.pulling.loc, src)) - return \ No newline at end of file + return + +/turf/unsimulated/floor/grass + icon_state = "grass1" + +/turf/unsimulated/floor/grass/New() + ..() + icon_state = "grass[rand(1,4)]" \ No newline at end of file diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 076b05d2187..fcf047784aa 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -143,7 +143,8 @@ var/list/admin_verbs_debug = list( /client/proc/callproc_datum, /client/proc/toggledebuglogs, /client/proc/qdel_toggle, // /vg/ - /client/proc/gc_dump_hdl + /client/proc/gc_dump_hdl, + /client/proc/debugNatureMapGenerator ) var/list/admin_verbs_possess = list( /proc/possess, diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 03a0e99437b..c5d1c020564 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -165,7 +165,6 @@ icon_state = "reactiveoff" item_state = "reactiveoff" blood_overlay_type = "armor" - slowdown = 1 icon_action_button = "reactiveoff" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index cec48a49a99..10d74c98f0f 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -177,7 +177,7 @@ /datum/recipe/microwave/ghostburger items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/weapon/ectoplasm //where do you even find this stuff + /obj/item/weapon/reagent_containers/food/snacks/ectoplasm //where do you even find this stuff ) result = /obj/item/weapon/reagent_containers/food/snacks/ghostburger diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index a5bd0ecc58b..a63f834fe7c 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -1032,7 +1032,7 @@ proc/populate_seed_list() products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans) plant_icon = "soybean" harvest_repeat = 1 - chems = list("nutriment" = list(1,20)) + chems = list("nutriment" = list(1,20), "soybeanoil" = list(1,20)) lifespan = 25 maturation = 4 diff --git a/code/modules/mining/surprises/tg.dm b/code/modules/mining/surprises/tg.dm index cadebb94841..0fc8eb9dd65 100644 --- a/code/modules/mining/surprises/tg.dm +++ b/code/modules/mining/surprises/tg.dm @@ -54,7 +54,7 @@ /obj/item/toy/crayon/red=2, /obj/effect/decal/cleanable/blood=4, /obj/structure/table/woodentable=2, - /obj/item/weapon/ectoplasm=3 + /obj/item/weapon/reagent_containers/food/snacks/ectoplasm=3 ) flags = CONTIGUOUS_WALLS | CONTIGUOUS_FLOORS diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index dfa3cb878b9..809844ea3b7 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -222,6 +222,17 @@ message = "[src] makes a strong noise." m_type = 2 + if ("burp") + if(miming) + message = "[src] opens their mouth rather obnoxiously." + m_type = 1 + else + if (!muzzled) + message = "[src] burps." + m_type = 2 + else + message = "[src] makes a peculiar noise." + m_type = 2 if ("clap") if (!src.restrained()) message = "[src] claps." diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index bffd95bbd5c..a865ffb63f5 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -32,8 +32,6 @@ timeofdeath = 0 /mob/living/carbon/human/getBrainLoss() - if(species && species.flags & NO_INTORGANS) - return var/res = brainloss var/obj/item/organ/brain/sponge = internal_organs_by_name["brain"] if(!sponge) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 8431b334c75..02256eeb652 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -172,16 +172,16 @@ emp_act return 1 if(wear_suit && istype(wear_suit, /obj/item/)) var/obj/item/I = wear_suit - if(I.IsShield() && (prob(35))) + if(I.IsShield() && (prob(50))) visible_message("\red The reactive teleport system flings [src] clear of [attack_text]!") var/list/turfs = new/list() - for(var/turf/T in orange(6)) + for(var/turf/T in orange(6, src)) if(istype(T,/turf/space)) continue if(T.density) continue if(T.x>world.maxx-6 || T.x<6) continue if(T.y>world.maxy-6 || T.y<6) continue turfs += T - if(!turfs.len) turfs += pick(/turf in orange(6)) + if(!turfs.len) turfs += pick(/turf in orange(6, src)) var/turf/picked = pick(turfs) if(!isturf(picked)) return if(buckled) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 132f11bcd08..94f4a93d38b 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1623,6 +1623,10 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc var/client/C = src.client if(C && C.prefs.sound & SOUND_HEARTBEAT) //disable heartbeat by pref var/obj/item/organ/heart/H = internal_organs_by_name["heart"] + + if(!H) //H.status will runtime if there is no H (obviously) + return + if(H.status & ORGAN_ROBOT) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people. if(shock_stage >= 10 || istype(get_turf(src), /turf/space)) //PULSE_THREADY - maximum value for pulse, currently it 5. @@ -1641,9 +1645,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc if(pulse == PULSE_NONE) return - if(!H) - return - if(pulse >= PULSE_2FAST || shock_stage >= 10 || istype(get_turf(src), /turf/space)) //PULSE_THREADY - maximum value for pulse, currently it 5. //High pulse value corresponds to a fast rate of heartbeat. diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index c54c1329707..0d637fc6c78 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -35,7 +35,7 @@ /mob/living/simple_animal/construct/Die() ..() - new /obj/item/weapon/ectoplasm (src.loc) + new /obj/item/weapon/reagent_containers/food/snacks/ectoplasm (src.loc) for(var/mob/M in viewers(src, null)) if((M.client && !( M.blinded ))) M.show_message("\red [src] collapses in a shattered heap. ") diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm index 6abf37ba978..417e4d99f3e 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/undead.dm @@ -68,7 +68,7 @@ invisibility = pick(0,60,60,invisibility) ..() /mob/living/simple_animal/hostile/retaliate/ghost/Die() - new /obj/item/weapon/ectoplasm(loc) + new /obj/item/weapon/reagent_containers/food/snacks/ectoplasm(loc) del src return diff --git a/code/modules/mob/living/simple_animal/pony.dm b/code/modules/mob/living/simple_animal/pony.dm index 7680e8ee42a..edd3480cc23 100644 --- a/code/modules/mob/living/simple_animal/pony.dm +++ b/code/modules/mob/living/simple_animal/pony.dm @@ -28,7 +28,7 @@ Life() ..() if(stat == 2) - new /obj/item/weapon/ectoplasm (src.loc) + new /obj/item/weapon/reagent_containers/food/snacks/ectoplasm (src.loc) for(var/mob/M in viewers(src, null)) if((M.client && !( M.blinded ))) M.show_message("\red [src] lets out a contented sigh as their form unwinds. ") diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 779692028ec..aa1a9509b5a 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -31,7 +31,7 @@ Life() ..() if(stat == 2) - new /obj/item/weapon/ectoplasm (src.loc) + new /obj/item/weapon/reagent_containers/food/snacks/ectoplasm (src.loc) for(var/mob/M in viewers(src, null)) if((M.client && !( M.blinded ))) M.show_message("\red [src] lets out a contented sigh as their form unwinds. ") diff --git a/code/modules/procedural mapping/mapGenerator.dm b/code/modules/procedural mapping/mapGenerator.dm new file mode 100644 index 00000000000..9a304e5c57a --- /dev/null +++ b/code/modules/procedural mapping/mapGenerator.dm @@ -0,0 +1,122 @@ + +/datum/mapGenerator + + //Map information + var/list/map = list() + var/turf/bottomLeft = null + var/turf/topRight = null + + //mapGeneratorModule information + var/list/modules = list() + +/datum/mapGenerator/New() + ..() + initialiseModules() + +//Defines the region the map represents, sets map, bottomLeft, topRight +//Returns the map +/datum/mapGenerator/proc/defineRegion(var/turf/Start, var/turf/End) + if(!checkRegion(Start, End)) + return 0 + + if(!Start || !End) + return 0 + bottomLeft = Start + topRight = End + + map = block(bottomLeft,topRight) + return map + + +//Checks for and Rejects bad region coordinates +//Returns 1/0 +/datum/mapGenerator/proc/checkRegion(var/turf/Start, var/turf/End) + . = 1 + + if(!Start || !End) + return 0 //Just bail + + if(Start.x > world.maxx || End.x > world.maxx) + . = 0 + if(Start.y > world.maxy || End.y > world.maxy) + . = 0 + if(Start.z > world.maxz || End.z > world.maxz) + . = 0 + + +//Requests the mapGeneratorModule(s) to (re)generate +/datum/mapGenerator/proc/generate() + set background = 1 //this can get beefy + + syncModules() + if(!modules || !modules.len) + return + for(var/datum/mapGeneratorModule/mod in modules) + mod.generate() + + +//Requests the mapGeneratorModule(s) to (re)generate this one turf +/datum/mapGenerator/proc/generateOneTurf(var/turf/T) + if(!T) + return + syncModules() + if(!modules || !modules.len) + return + for(var/datum/mapGeneratorModule/mod in modules) + mod.place(T) + + +//Replaces all paths in the module list with actual module datums +/datum/mapGenerator/proc/initialiseModules() + for(var/path in modules) + if(ispath(path)) + modules.Remove(path) + modules |= new path + syncModules() + + +//Sync mapGeneratorModule(s) to mapGenerator +/datum/mapGenerator/proc/syncModules() + for(var/datum/mapGeneratorModule/mod in modules) + mod.sync(src) + + + +/////////////////////////// +// HERE BE DEBUG DRAGONS // +/////////////////////////// + +/client/proc/debugNatureMapGenerator() + set name = "Test Nature Map Generator" + set category = "Debug" + + var/datum/mapGenerator/nature/N = new() + var/startInput = input(usr,"Start turf of Map, (X;Y;Z)", "Map Gen Settings", "1;1;1") as text + var/endInput = input(usr,"End turf of Map (X;Y;Z)", "Map Gen Settings", "[world.maxx];[world.maxy];[mob ? mob.z : 1]") as text + //maxx maxy and current z so that if you fuck up, you only fuck up one entire z level instead of the entire universe + if(!startInput || !endInput) + src << "Missing Input" + return + + var/list/startCoords = text2list(startInput, ";") + var/list/endCoords = text2list(endInput, ";") + if(!startCoords || !endCoords) + src << "Invalid Coords" + src << "Start Input: [startInput]" + src << "End Input: [endInput]" + return + + var/turf/Start = locate(text2num(startCoords[1]),text2num(startCoords[2]),text2num(startCoords[3])) + var/turf/End = locate(text2num(endCoords[1]),text2num(endCoords[2]),text2num(endCoords[3])) + if(!Start || !End) + src << "Invalid Turfs" + src << "Start Coords: [startCoords[1]] - [startCoords[2]] - [startCoords[3]]" + src << "End Coords: [endCoords[1]] - [endCoords[2]] - [endCoords[3]]" + return + + src << "Defining Region" + N.defineRegion(Start, End) + src << "Region Defined" + src << "Generating Region" + N.generate() + src << "Generated Region" diff --git a/code/modules/procedural mapping/mapGeneratorModule.dm b/code/modules/procedural mapping/mapGeneratorModule.dm new file mode 100644 index 00000000000..458f11cd969 --- /dev/null +++ b/code/modules/procedural mapping/mapGeneratorModule.dm @@ -0,0 +1,101 @@ + +#define CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible +#define CLUSTER_CHECK_ATOMS 2 //Don't let atoms cluster, based on clusterMin and clusterMax as guides +#define CLUSTER_CHECK_TURFS 4 //Don't let turfs cluster, based on clusterMin and clusterMax as guides +#define CLUSTER_CHECK_ALL 6 //Don't let anything cluster, based on clusterMind and clusterMax as guides + +/datum/mapGeneratorModule + var/datum/mapGenerator/mother = null + var/list/spawnableAtoms = list() + var/list/spawnableTurfs = list() + var/clusterMax = 5 + var/clusterMin = 1 + var/clusterCheckFlags = CLUSTER_CHECK_ALL + + +//Syncs the module up with it's mother +/datum/mapGeneratorModule/proc/sync(var/datum/mapGenerator/mum) + mother = null + if(mum) + mother = mum + + +//Generates it's spawnable atoms and turfs +/datum/mapGeneratorModule/proc/generate() + if(!mother) + return + var/list/map = mother.map + for(var/turf/T in map) + place(T) + + +//Place a spawnable atom or turf on this turf +/datum/mapGeneratorModule/proc/place(var/turf/T) + if(!T) + return 0 + + var/clustering = 0 + + //Turfs don't care whether atoms can be placed here + for(var/turfPath in spawnableTurfs) + if(clusterCheckFlags & CLUSTER_CHECK_TURFS) + if(clusterMax && clusterMin) + clustering = rand(clusterMin,clusterMax) + if(locate(/atom/movable) in range(clustering, T)) + continue + if(prob(spawnableTurfs[turfPath])) + T.ChangeTurf(turfPath) + + //Atoms DO care whether atoms can be placed here + if(checkPlaceAtom(T)) + for(var/atomPath in spawnableAtoms) + if(clusterCheckFlags & CLUSTER_CHECK_ATOMS) + if(clusterMax && clusterMin) + clustering = rand(clusterMin,clusterMax) + if(locate(/atom/movable) in range(clustering, T)) + continue + if(prob(spawnableAtoms[atomPath])) + new atomPath (T) + + . = 1 + + +//Checks and Rejects dense turfs +/datum/mapGeneratorModule/proc/checkPlaceAtom(var/turf/T) + . = 1 + if(!T) + return 0 + if(T.density) + . = 0 + for(var/atom/A in T) + if(A.density) + . = 0 + break + + +/////////////////////////////////////////////////////////// +// PREMADE BASE TEMPLATES // +// Appropriate settings for usable types // +// Not usable types themselves, use them as parent types // +// Seriously, don't use these on their own, just parents // +/////////////////////////////////////////////////////////// +//The /atom and /turf examples are just so these compile, replace those with your typepaths in your subtypes. + +//Settings appropriate for a turf that covers the entire map region, eg a fill colour on a bottom layer in a graphics program. +//Should only have one of these in your mapGenerator unless you want to waste CPU +/datum/mapGeneratorModule/bottomLayer + clusterCheckFlags = CLUSTER_CHECK_NONE + spawnableAtoms = list()//Recommended: No atoms. + spawnableTurfs = list(/turf = 100) + +//Settings appropriate for turfs/atoms that cover SOME of the map region, sometimes referred to as a splatter layer. +/datum/mapGeneratorModule/splatterLayer + clusterCheckFlags = CLUSTER_CHECK_ALL + spawnableAtoms = list(/atom = 30) + spawnableTurfs = list(/turf = 30) + +//Settings appropriate for turfs/atoms that cover a lot of the map region, eg a dense forest. +/datum/mapGeneratorModule/denseLayer + clusterCheckFlags = CLUSTER_CHECK_NONE + spawnableAtoms = list(/atom = 75) + spawnableTurfs = list(/turf = 75) \ No newline at end of file diff --git a/code/modules/procedural mapping/mapGeneratorModules/nature.dm b/code/modules/procedural mapping/mapGeneratorModules/nature.dm new file mode 100644 index 00000000000..742141f6fdf --- /dev/null +++ b/code/modules/procedural mapping/mapGeneratorModules/nature.dm @@ -0,0 +1,37 @@ + +//Contents exist primarily for the nature generator test type. + + +//Pine Trees +/datum/mapGeneratorModule/pineTrees + spawnableAtoms = list(/obj/structure/flora/tree/pine = 30) + +//Dead Trees +/datum/mapGeneratorModule/deadTrees + spawnableAtoms = list(/obj/structure/flora/tree/dead = 10) + +//Random assortment of bushes +/datum/mapGeneratorModule/randBushes + spawnableAtoms = list() + +/datum/mapGeneratorModule/randBushes/New() + ..() + spawnableAtoms = typesof(/obj/structure/flora/ausbushes) + for(var/i in spawnableAtoms) + spawnableAtoms[i] = 20 + + +//Random assortment of rocks and rockpiles +/datum/mapGeneratorModule/randRocks + spawnableAtoms = list(/obj/structure/flora/rock = 40, /obj/structure/flora/rock/pile = 20) + + +//Grass turfs +/datum/mapGeneratorModule/bottomLayer/grassTurfs + spawnableTurfs = list(/turf/unsimulated/floor/grass = 100) + + +//Grass tufts with a high spawn chance +/datum/mapGeneratorModule/denseLayer/grassTufts + spawnableTurfs = list() + spawnableAtoms = list(/obj/structure/flora/ausbushes/grassybush = 75) \ No newline at end of file diff --git a/code/modules/procedural mapping/mapGeneratorReadme.dm b/code/modules/procedural mapping/mapGeneratorReadme.dm new file mode 100644 index 00000000000..95fa449624e --- /dev/null +++ b/code/modules/procedural mapping/mapGeneratorReadme.dm @@ -0,0 +1,130 @@ + +/* +by RemieRichards + +////////////////////////////// +// CODER INFORMATIVE README // +////////////////////////////// +(See below for Mapper Friendly Readme) + +mapGenerator: + Desc: a mapGenerator is a master datum that collects + and syncs all mapGeneratorModules in it's modules list + + defineRegion(var/list/startList, var/list/endList) + Example: defineRegion(locate(1,1,1),locate(5,5,5)) + Desc: Sets the bounds of the mapGenerator's "map" + + checkRegion(var/turf/Start, var/turf/End) + Example: checkRegion(locate(1,1,1), locate(5,5,5)) + Desc: Checks if a rectangle between Start's coords and End's coords is valid + Existing Calls: mapGenerator/defineRegion() + + generate() + Example: generate() + Desc: Orders all mapGeneratorModules in the modules list to generate() + + generateOneTurf(var/turf/T) + Example: generateOneTurf(locate(1,1,1)) + Desc: Orders all mapGeneratorModules in the modules list to place(T) on this turf + + initialiseModules() + Example: initialiseModules() + Desc: Replaces all typepaths in the modules list with actual /datum/mapGenerator/Module types + Existing Calls: mapGenerator/New() + + syncModules() + Example: syncModules() + Desc: Sets the Mother variable on all mapGeneratorModules in the modules list to this mapGenerator + Existing Calls: initialiseModules(),generate(),generateOneTurf() + + +mapGeneratorModule + Desc: a mapGeneratorModule has spawnableAtoms and spawnableTurfs lists + which it will generate on turfs in it's mother's map based on cluster variables + + sync(var/datum/mapGenerator/mum) + Example: sync(a_mapGenerator_as_a_variable) + Desc: Sets the Mother variable to the mum argument + Existing Calls: mapGenerator/syncModules() + + generate() + Example: generate() + Desc: Calls place(T) on all turfs in it's mother's map + Existing Calls: mapGenerator/generate() + + place(var/turf/T) + Example: place(locate(1,1,1)) + Desc: Run this mapGeneratorModule's effects on this turf (Spawning atoms, Changing turfs) + Existing Calls: mapGenerator/generate(), mapGenerator/generateOneTurf() + + checkPlaceAtom(var/turf/T) + Example: checkPlace(locate(1,1,1)) + Desc: Checks if the turf is valid for placing atoms + Existing Calls: place() + + + +//////////////////////////// +// MAPPER FRIENDLY README // +//////////////////////////// + +Simple Workflow: + + 1. Define a/some mapGeneratorModule(s) to your liking, choosing atoms and turfs to spawn + #Note: I chose to split Turfs and Atoms off into seperate modules, but this is NOT required. + #Note: A mapGeneratorModule may have turfs AND atoms, so long as each is in it's appropriate list + + 2. Define a mapGenerator type who's modules list contains the typepath(s) of all the module(s) you wish to use + #Note: The order of the typepaths in the modules list is the order they will happen in, this is important for clusterCheckFlags. + + 3. Take notes of the Bottom Left and Top Right turfs of your rectangular "map"'s coordinates + #Note: X,Y AND Z, Yes you can created 3D "maps" by having differing Z coords + + 4. Create the mapGenerator type you created + + 5. Call yourMapGeneratorType.defineRegion(locate(X,Y,Z), locate(X,Y,Z)) + #Note: The above X/Y/Zs are the coordinates of the start and end turfs, the locate() simply finds the turf for the code + + 6. Call yourMapGeneratorType.generate(), this will cause all the modules in the generator to build within the map bounds + +Option Suggestions: + + * Have seperate modules for Turfs and Atoms, this is not enforced, but it is how I have structured my nature example. + * If your map doesn't look quite to your liking, simply jiggle with the variables on your modules and the type probabilities + * You can mix and map premade areas with the procedural generation, for example mapping an entire flat land but having code generate just the grass tufts + + +Using the Modules list + + Simply think of it like each module is a layer in a graphics editing program! + To help you do this templates such as /mapGeneratorModule/bottomLayer have been provided with appropriate default settings. + These are located near the bottom of mapGeneratorModule.dm + you would order your list left to right, top to bottom, e.g: + modules = list(bottomLayer,nextLayer,nextNextLayer) etc. + + +Variable Breakdown (For Mappers): + + mapGenerator + map - INTERNAL, do not touch + bottomLeft - INTERNAL, do not touch + topRight - INTERNAL, do not touch + modules - A list of typepaths of mapGeneratorModules + + mapGeneratorModule + mother - INTERNAL, do not touch + spawnableAtoms - A list of typepaths and their probability to spawn, eg: spawnableAtoms = list(/obj/structure/flora/tree/pine = 30) + spawnableTurfs - A list of typepaths and their probability to spawn, eg: spawnableTurfs = list(/turf/unsimulated/floor/grass = 100) + clusterMax - The max range to check for something being "too close" for this atom/turf to spawn, the true value is random between clusterMin and clusterMax + clusterMin - The min range to check for something being "too close" for this atom/turf to spawn, the true value is random between clusterMin and clusterMax + clusterCheckFlags - A Bitfield that controls how the cluster checks work. + + clusterCheckFlags flags: + CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible + CLUSTER_CHECK_ATOMS 2 //Don't let atoms cluster, based on clusterMin and clusterMax as guides + CLUSTER_CHECK_TURFS 4 //Don't let turfs cluster, based on clusterMin and clusterMax as guides + CLUSTER_CHECK_ALL 6 //Don't let anything cluster, based on clusterMind and clusterMax as guides + + +*/ \ No newline at end of file diff --git a/code/modules/procedural mapping/mapGenerators/nature.dm b/code/modules/procedural mapping/mapGenerators/nature.dm new file mode 100644 index 00000000000..0300de38211 --- /dev/null +++ b/code/modules/procedural mapping/mapGenerators/nature.dm @@ -0,0 +1,10 @@ + +//Exists primarily as a test type. + +/datum/mapGenerator/nature + modules = list(/datum/mapGeneratorModule/pineTrees, \ + /datum/mapGeneratorModule/deadTrees, \ + /datum/mapGeneratorModule/randBushes, \ + /datum/mapGeneratorModule/randRocks, \ + /datum/mapGeneratorModule/bottomLayer/grassTurfs, \ + /datum/mapGeneratorModule/denseLayer/grassTufts) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 748282e346d..09d27ee57dc 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -2094,6 +2094,12 @@ datum description = "The fatty, still liquid part of milk. Why don't you mix this with sum scotch, eh?" color = "#DFD7AF" // rgb: 223, 215, 175 + chocolate_milk + name = "Chocolate milk" + id ="chocolate_milk" + description = "Chocolate-flavored milk, tastes like being a kid again." + color = "#85432C" + hot_coco name = "Hot Chocolate" id = "hot_coco" @@ -2383,6 +2389,7 @@ datum var/confused_adj = 2 var/slur_start = 65 //amount absorbed after which mob starts slurring var/confused_start = 130 //amount absorbed after which mob starts confusing directions + var/vomit_start = 180 //amount absorbed after which mob starts vomitting var/blur_start = 260 //amount absorbed after which mob starts getting blurred vision var/pass_out = 325 //amount absorbed after which mob starts passing out @@ -2416,6 +2423,9 @@ datum if(d >= blur_start) M.eye_blurry = max(M.eye_blurry, 10/sober_str) M:drowsyness = max(M:drowsyness, 0) + if(d >= vomit_start) + if(prob(8)) + M.fakevomit() if(d >= pass_out) M:paralysis = max(M:paralysis, 20/sober_str) M:drowsyness = max(M:drowsyness, 30/sober_str) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index a3591a943c1..b90620e69f6 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -979,6 +979,14 @@ datum required_reagents = list("water" = 5, "coco" = 1) result_amount = 5 + chocolate_milk + name = "Chocolate Milk" + id = "chocolate_milk" + result = "chocolate_milk" + required_reagents = list("chocolate" = 1, "milk" = 1) + result_amount = 2 + mix_message = "The mixture turns a nice brown color." + coffee name = "Coffee" id = "coffee" diff --git a/code/modules/reagents/newchem/food.dm b/code/modules/reagents/newchem/food.dm index 52be1d5848a..0ac2019e031 100644 --- a/code/modules/reagents/newchem/food.dm +++ b/code/modules/reagents/newchem/food.dm @@ -139,6 +139,12 @@ datum/reagent/chocolate/on_mob_life(var/mob/living/M as mob) ..() return +datum/reagent/chocolate/reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 5) + new /obj/item/weapon/reagent_containers/food/snacks/reagentchocolatebar(T) + return + /datum/reagent/mugwort name = "Mugwort" id = "mugwort" @@ -220,6 +226,27 @@ datum/reagent/msg/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) ..() return +/datum/reagent/cheese + name = "Cheese" + id = "cheese" + description = "Some cheese. Pour it out to make it solid." + reagent_state = SOLID + color = "#FFFF00" + +datum/reagent/cheese/reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 5) + new /obj/item/weapon/reagent_containers/food/snacks/cheesewedge(T) + return + +/datum/chemical_reaction/cheese + name = "weird_cheese" + id = "weird_cheese" + result = "weird_cheese" + required_reagents = list("vomit" = 1, "milk" = 1) + result_amount = 1 + mix_message = "The mixture curdles up." + /datum/reagent/fake_cheese name = "Cheese substitute" id = "fake_cheese" @@ -227,6 +254,27 @@ datum/reagent/msg/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) reagent_state = LIQUID color = "#B2B139" +/datum/reagent/weird_cheese + name = "Weird cheese" + id = "weird_cheese" + description = "Hell, I don't even know if this IS cheese. Whatever it is, it ain't normal. If you want to, pour it out to make it solid." + reagent_state = SOLID + color = "#50FF00" + +datum/reagent/weird_cheese/reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 5) + new /obj/item/weapon/reagent_containers/food/snacks/weirdcheesewedge(T) + return + +/datum/chemical_reaction/weird_cheese + name = "Weird cheese" + id = "weird_cheese" + result = "weird_cheese" + required_reagents = list("green_vomit" = 1, "milk" = 1) + result_amount = 1 + mix_message = "The disgusting mixture sloughs together horribly, emitting a foul stench." + datum/reagent/beans name = "Refried beans" id = "beans" @@ -241,5 +289,208 @@ datum/reagent/beans/on_mob_life(var/mob/living/M as mob) ..() return +/datum/reagent/bread + name = "Bread" + id = "bread" + description = "Bread! Yep, bread." + reagent_state = SOLID + color = "#9C5013" + +datum/reagent/bread/reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 5) + new /obj/item/weapon/reagent_containers/food/snacks/breadslice(T) + return + +/datum/reagent/vomit + name = "Vomit" + id = "vomit" + description = "Looks like someone lost their lunch. And then collected it. Yuck." + reagent_state = LIQUID + color = "#FFFF00" + +datum/reagent/vomit/reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 5) + new /obj/effect/decal/cleanable/vomit(T) + playsound(T, 'sound/effects/splat.ogg', 50, 1, -3) + return + +/datum/reagent/greenvomit + name = "Green vomit" + id = "green_vomit" + description = "Whoa, that can't be natural. That's horrible." + reagent_state = LIQUID + color = "#78FF74" + +datum/reagent/greenvomit/reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 5) + new /obj/effect/decal/cleanable/vomit/green(T) + playsound(T, 'sound/effects/splat.ogg', 50, 1, -3) + return +/datum/reagent/ectoplasm + name = "Ectoplasm" + id = "ectoplasm" + description = "A bizarre gelatinous substance supposedly derived from ghosts." + reagent_state = LIQUID + color = "#8EAE7B" + +datum/reagent/ectoplasm/reaction_mob(var/mob/M, var/method=TOUCH, var/volume) + if(!istype(M, /mob/living)) + return + if(method == INGEST) + var/spooky_eat = pick("Ugh, why did you eat that? Your mouth feels haunted. Haunted with bad flavors.", "Ugh, why did you eat that? It has the texture of ham aspic. From the 1950s. Left out in the sun.", "Ugh, why did you eat that? It tastes like a ghost fart.", "Ugh, why did you eat that? It tastes like flavor died.") + M << "[spooky_eat]" + +/datum/reagent/ectoplasm/on_mob_life(var/mob/living/M as mob) + var/spooky_message = pick("You notice something moving out of the corner of your eye, but nothing is there...", "Your eyes twitch, you feel like something you can't see is here...", "You've got the heebie-jeebies.", "You feel uneasy.", "You shudder as if cold...", "You feel something gliding across your back...") + if(prob(5)) + M << "[spooky_message]" + ..() + return + +datum/reagent/ectoplasm/reaction_turf(var/turf/T, var/volume) + src = null + if(volume >= 10) + new /obj/item/weapon/reagent_containers/food/snacks/ectoplasm(T) + return + +/datum/reagent/soybeanoil + name = "Space-soybean oil " + id = "soybeanoil" + description = "An oil derived from extra-terrestrial soybeans." + reagent_state = LIQUID + color = "#B1B0B0" + +/datum/reagent/soybeanoil/on_mob_life(var/mob/living/M as mob) + if(prob(5)) + M.reagents.add_reagent("porktonium",5) + ..() + return + +/datum/reagent/hydrogenated_soybeanoil + name = "Partially hydrogenated space-soybean oil" + id = "hydrogenated_soybeanoil" + description = "An oil derived from extra-terrestrial soybeans, with additional hydrogen atoms added to convert it into a saturated form." + reagent_state = LIQUID + color = "#B1B0B0" + +/datum/reagent/hydrogenated_soybeanoil/on_mob_life(var/mob/living/M as mob) + if(prob(8)) + M.reagents.add_reagent("porktonium",5) + ..() + return + +/datum/chemical_reaction/hydrogenated_soybeanoil + name = "Partially hydrogenated space-soybean oil" + id = "hydrogenated_soybeanoil" + result = "hydrogenated_soybeanoil" + required_reagents = list("soybeanoil" = 1, "hydrogen" = 1) + result_amount = 2 + required_temp = 520 + mix_message = "The mixture emits a burnt, oily smell." + +/datum/reagent/meatslurry + name = "Meat Slurry" + id = "meatslurry" + description = "A paste comprised of highly-processed organic material. Uncomfortably similar to deviled ham spread." + reagent_state = LIQUID + color = "#EBD7D7" + +/datum/chemical_reaction/meatslurry + name = "Meat Slurry" + id = "meatslurry" + result = "meatslurry" + required_reagents = list("corn_starch" = 1, "blood" = 1) + result_amount = 2 + mix_message = "The mixture congeals into a bloody mass." + +/datum/reagent/mashedpotatoes + name = "Mashed potatoes" + id = "mashedpotatoes" + description = "A starchy food paste made from boiled potatoes." + reagent_state = SOLID + color = "#D6D9C1" + +/datum/reagent/gravy + name = "Gravy" + id = "gravy" + description = "A savory sauce made from a simple meat-dripping roux and milk." + reagent_state = LIQUID + color = "#B4641B" + +/datum/chemical_reaction/gravy + name = "Gravy" + id = "gravy" + result = "gravy" + required_reagents = list("porktonium" = 1, "corn_starch" = 1, "milk" = 1) + result_amount = 3 + required_temp = 374 + mix_message = "The substance thickens and takes on a meaty odor." + +/datum/reagent/beff + name = "Beff" + id = "beff" + description = "An advanced blend of mechanically-recovered meat and textured synthesized protein product notable for its unusual crystalline grain when sliced." + reagent_state = SOLID + color = "#AC7E67" + +/datum/reagent/beff/on_mob_life(var/mob/living/M as mob) + if(prob(5)) + M.reagents.add_reagent("porktonium",5) + if(prob(5)) + M.reagents.add_reagent(pick("blood", "corn_syrup", "synthflesh", "hydrogenated_soybeanoil"), 0.8) + if(prob(5)) + M.emote("groan") + if(prob(2)) + M << "You feel sick." + ..() + return + +/datum/chemical_reaction/beff + name = "Beff" + id = "beff" + result = "beff" + required_reagents = list("hydrogenated_soybeanoil" = 2, "meatslurry" = 1, "plasma" = 1) + result_amount = 4 + mix_message = "The mixture solidifies, taking a crystalline appearance." + +/datum/reagent/pepperoni + name = "Pepperoni" + id = "pepperoni" + description = "An Italian-American variety of salami usually made from beef and pork" + reagent_state = SOLID + color = "#AC7E67" + +datum/reagent/pepperoni/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) + if(method == TOUCH) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + + if(H.wear_mask) + H << "The pepperoni bounces off your mask!" + return + + if(H.head) + H << "Your mask protects you from the errant pepperoni!" + return + + if(prob(50)) + M.adjustBruteLoss(1) + playsound(M, 'sound/effects/woodhit.ogg', 50, 1, -1) + M << "A slice of pepperoni slaps you!" + else + M.emote("burp") + M << "My goodness, that was tasty!" + + +/datum/chemical_reaction/pepperoni + name = "Pepperoni" + id = "pepperoni" + result = "pepperoni" + required_reagents = list("beff" = 1, "saltpetre" = 1, "synthflesh" = 1) + result_amount = 2 + mix_message = "The beff and the synthflesh combine to form a smoky red log." \ No newline at end of file diff --git a/code/modules/reagents/newchem/pyro.dm b/code/modules/reagents/newchem/pyro.dm index c76df7af21f..4314b831422 100644 --- a/code/modules/reagents/newchem/pyro.dm +++ b/code/modules/reagents/newchem/pyro.dm @@ -262,6 +262,7 @@ result = "smoke_powder" required_reagents = list("stabilizing_agent" = 1, "potassium" = 1, "sugar" = 1, "phosphorus" = 1) result_amount = 1 + mix_message = "The mixture sets into a greyish powder!" /datum/chemical_reaction/smoke name = "smoke" @@ -269,6 +270,7 @@ result = null required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) result_amount = 1 + mix_message = "The mixture quickly turns into a pall of smoke!" var/forbidden_reagents = list("sugar", "phosphorus", "potassium") //Do not transfer this stuff through smoke. /datum/chemical_reaction/smoke/on_reaction(var/datum/reagents/holder, var/created_volume) diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index 1f3539c18ba..3785259d5d7 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -130,6 +130,15 @@ return + attackby(var/obj/item/I, mob/user as mob, params) + if(istype(I, /obj/item/clothing/mask/cigarette)) //ciggies are weird + return + if(is_hot(I)) + if(src.reagents) + src.reagents.chem_temp += 15 + user << "You heat [src] with [I]." + src.reagents.handle_reactions() + examine() set src in view() ..() diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 4b2c250b4ee..c4a75cbe7d2 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -392,6 +392,18 @@ reagents.add_reagent("coco", 2) bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/reagentchocolatebar //for reagent chocolate + name = "Chocolate Bar" + desc = "A plain chocolate bar. Is it dark chocolate, milk chocolate? Who knows!" + icon_state = "chocolatebar" + filling_color = "#7D5F46" + + New() + ..() + reagents.add_reagent("sugar", 10) + reagents.add_reagent("chocolate",10) + bitesize = 2 + /obj/item/weapon/reagent_containers/food/snacks/chocolateegg name = "Chocolate Egg" desc = "Such sweet, fattening food." @@ -2576,7 +2588,18 @@ filling_color = "#FFF700" bitesize = 2 - +/obj/item/weapon/reagent_containers/food/snacks/weirdcheesewedge + name = "Weird Cheese" + desc = "Some kind of... gooey, messy, gloopy thing. Similar to cheese, but only in the looser sense of the word." + icon_state = "weirdcheesewedge" + filling_color = "#00FF33" + bitesize = 2 + New() + ..() + reagents.add_reagent("mercury", 5) + reagents.add_reagent("mindbreaker", 5) + reagents.add_reagent("ethanol", 5) + reagents.add_reagent("weird_cheese", 5) /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake name = "Birthday Cake" @@ -2604,7 +2627,7 @@ icon_state = "Some plain old Earthen bread." icon_state = "bread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice - slices_num = 5 + slices_num = 6 filling_color = "#FFE396" New() @@ -2620,6 +2643,9 @@ filling_color = "#D27332" bitesize = 2 + New() + ..() + reagents.add_reagent("bread", 5) /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread name = "Cream Cheese Bread" @@ -3334,3 +3360,11 @@ ..() reagents.add_reagent("nutriment", 3) +/obj/item/weapon/reagent_containers/food/snacks/ectoplasm + name = "ectoplasm" + desc = "A luminescent blob of what scientists refer to as 'ghost goo'." + icon = 'icons/obj/wizard.dmi' + icon_state = "ectoplasm" + New() + ..() + reagents.add_reagent("ectoplasm", 10) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm deleted file mode 100644 index b9d5c648e59..00000000000 --- a/code/modules/reagents/reagent_containers/glass.dm +++ /dev/null @@ -1,361 +0,0 @@ - - //////////////////////////////////////////////////////////////////////////////// - /// (Mixing)Glass. - //////////////////////////////////////////////////////////////////////////////// - /obj/item/weapon/reagent_containers/glass - name = " " - var/base_name = " " - desc = " " - icon = 'icons/obj/chemical.dmi' - icon_state = "null" - item_state = "null" - amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(5,10,15,25,30,50) - volume = 50 - flags = OPENCONTAINER - - var/label_text = "" - // the fucking asshole who designed this can go die in a fire - Iamgoofball - var/list/can_be_placed_into = list( - /obj/machinery/chem_master/, - /obj/machinery/chem_heater/, - /obj/machinery/chem_dispenser/, - /obj/machinery/reagentgrinder, - /obj/structure/table, - /obj/structure/closet, - /obj/structure/sink, - /obj/item/weapon/storage, - /obj/machinery/atmospherics/unary/cryo_cell, - /obj/machinery/dna_scannernew, - /obj/item/weapon/grenade/chem_grenade, - /obj/machinery/bot/medbot, - /obj/item/weapon/storage/secure/safe, - /obj/machinery/iv_drip, - /obj/machinery/disease2/incubator, - /obj/machinery/disposal, - /obj/machinery/apiary, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/hostile/retaliate/goat, - /obj/machinery/computer/centrifuge, - /obj/machinery/sleeper, - /obj/machinery/smartfridge/, - // /obj/machinery/biogenerator, - /obj/machinery/portable_atmospherics/hydroponics, - /obj/machinery/constructable_frame) - - New() - ..() - base_name = name - - examine() - set src in view() - ..() - if (!(usr in view(2)) && usr!=src.loc) return - usr << "\blue It contains:" - if(reagents && reagents.reagent_list.len) - usr << "\blue [src.reagents.total_volume] units of liquid." - else - usr << "\blue Nothing." - if (!is_open_container()) - usr << "\blue Airtight lid seals it completely." - - attack_self() - ..() - if (is_open_container()) - usr << "You put the lid on \the [src]." - flags ^= OPENCONTAINER - else - usr << "You take the lid off \the [src]." - flags |= OPENCONTAINER - update_icon() - - afterattack(obj/target, mob/user, proximity) - if(!proximity) return - if (!is_open_container()) - return - - for(var/type in src.can_be_placed_into) - if(istype(target, type)) - return - - if(ismob(target) && target.reagents && reagents.total_volume) - user << "\blue You splash the solution onto [target]." - - var/mob/living/M = target - var/list/injected = list() - for(var/datum/reagent/R in src.reagents.reagent_list) - injected += R.name - var/contained = english_list(injected) - M.attack_log += text("\[[time_stamp()]\] Has been splashed with [src.name] by [user.name] ([user.ckey]). Reagents: [contained]") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to splash [M.name] ([M.key]). Reagents: [contained]") - if(M.ckey) - msg_admin_attack("[user.name] ([user.ckey]) splashed [M.name] ([M.key]) with [src.name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (JMP)") - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\red [] has been splashed with something by []!", target, user), 1) - src.reagents.reaction(target, TOUCH) - spawn(5) src.reagents.clear_reagents() - return - else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - - if(!target.reagents.total_volume && target.reagents) - user << "\red [target] is empty." - return - - if(reagents.total_volume >= reagents.maximum_volume) - user << "\red [src] is full." - return - - var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) - user << "\blue You fill [src] with [trans] units of the contents of [target]." - - else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. - if(!reagents.total_volume) - user << "\red [src] is empty." - return - - if(target.reagents.total_volume >= target.reagents.maximum_volume) - user << "\red [target] is full." - return - - if(istype(target, /obj/item/weapon/reagent_containers)) - var/obj/item/weapon/reagent_containers/RC = target - for(var/bad_reg in RC.banned_reagents) - if(reagents.has_reagent(bad_reg, 1)) //Message is a bit "Game-y" but I can't think up a better one. - user << "A chemical in [src] is far too dangerous to transfer to [RC]!" - return - - // /vg/: Logging transfers of bad things - if(target.reagents_to_log.len) - var/list/badshit=list() - for(var/bad_reagent in target.reagents_to_log) - if(reagents.has_reagent(bad_reagent)) - badshit += reagents_to_log[bad_reagent] - if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" - message_admins("[user.name] ([user.ckey]) added [reagents.get_reagent_ids(1)] to \a [target] with [src].[hl] (JMP)") - log_game("[user.name] ([user.ckey]) added [reagents.get_reagent_ids(1)] to \a [target] with [src].") - - var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) - user << "\blue You transfer [trans] units of the solution to [target]." - - else if(istype(target, /obj/machinery/bunsen_burner)) - return - - else if(istype(target, /obj/machinery/radiocarbon_spectrometer)) - return - - else if(reagents.total_volume) - user << "\blue You splash the solution onto [target]." - src.reagents.reaction(target, TOUCH) - spawn(5) src.reagents.clear_reagents() - return - - attackby(obj/item/weapon/W as obj, mob/user as mob, params) - ..() - if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) - var/tmp_label = sanitize(input(user, "Enter a label for [src.name]","Label",src.label_text)) - if(length(tmp_label) > 10) - user << "\red The label can be at most 10 characters long." - else - user << "\blue You set the label to \"[tmp_label]\"." - src.label_text = tmp_label - src.update_name_label() - - proc/update_name_label() - if(src.label_text == "") - src.name = src.base_name - else - src.name = "[src.base_name] ([src.label_text])" - - /obj/item/weapon/reagent_containers/glass/beaker - name = "beaker" - desc = "A beaker. Can hold up to 50 units." - icon = 'icons/obj/chemical.dmi' - icon_state = "beaker" - item_state = "beaker" - m_amt = 0 - g_amt = 500 - - on_reagent_change() - update_icon() - - pickup(mob/user) - ..() - update_icon() - - dropped(mob/user) - ..() - update_icon() - - attack_hand() - ..() - update_icon() - - update_icon() - overlays.Cut() - - if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") - - var/percent = round((reagents.total_volume / volume) * 100) - switch(percent) - if(0 to 9) filling.icon_state = "[icon_state]-10" - if(10 to 24) filling.icon_state = "[icon_state]10" - if(25 to 49) filling.icon_state = "[icon_state]25" - if(50 to 74) filling.icon_state = "[icon_state]50" - if(75 to 79) filling.icon_state = "[icon_state]75" - if(80 to 90) filling.icon_state = "[icon_state]80" - if(91 to INFINITY) filling.icon_state = "[icon_state]100" - - filling.icon += mix_color_from_reagents(reagents.reagent_list) - overlays += filling - - if (!is_open_container()) - var/image/lid = image(icon, src, "lid_[initial(icon_state)]") - overlays += lid - - /obj/item/weapon/reagent_containers/glass/beaker/large - name = "large beaker" - desc = "A large beaker. Can hold up to 100 units." - icon_state = "beakerlarge" - g_amt = 2500 - volume = 100 - amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(5,10,15,25,30,50,100) - flags = OPENCONTAINER - - /obj/item/weapon/reagent_containers/glass/beaker/vial - name = "vial" - desc = "A small glass vial. Can hold up to 25 units." - icon_state = "vial" - g_amt = 250 - volume = 25 - amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(5,10,15,25) - flags = OPENCONTAINER - - /obj/item/weapon/reagent_containers/glass/beaker/noreact - name = "cryostasis beaker" - desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." - icon_state = "beakernoreact" - g_amt = 500 - volume = 50 - amount_per_transfer_from_this = 10 - flags = OPENCONTAINER | NOREACT - - /obj/item/weapon/reagent_containers/glass/beaker/bluespace - name = "bluespace beaker" - desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." - icon_state = "beakerbluespace" - g_amt = 5000 - volume = 300 - amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(5,10,15,25,30,50,100,300) - flags = OPENCONTAINER - - /obj/item/weapon/reagent_containers/glass/beaker/cryoxadone - New() - ..() - reagents.add_reagent("cryoxadone", 30) - update_icon() - - /obj/item/weapon/reagent_containers/glass/beaker/sulphuric - New() - ..() - reagents.add_reagent("sacid", 50) - update_icon() - - /obj/item/weapon/reagent_containers/glass/beaker/slime - New() - ..() - reagents.add_reagent("slimejelly", 50) - update_icon() - - /obj/item/weapon/reagent_containers/glass/bucket - desc = "It's a bucket." - name = "bucket" - icon = 'icons/obj/janitor.dmi' - icon_state = "bucket" - item_state = "bucket" - m_amt = 200 - g_amt = 0 - w_class = 3.0 - amount_per_transfer_from_this = 20 - possible_transfer_amounts = list(5,10,15,25,30,50,80,100,120) - volume = 120 - flags = OPENCONTAINER - - attackby(var/obj/D, mob/user as mob, params) - if(isprox(D)) - user << "You add [D] to [src]." - del(D) - user.put_in_hands(new /obj/item/weapon/bucket_sensor) - user.unEquip(src) - qdel(src) - - ..() - - /obj/item/weapon/reagent_containers/glass/beaker/vial - name = "vial" - desc = "Small glass vial. Looks fragile." - icon_state = "vial" - g_amt = 500 - volume = 15 - amount_per_transfer_from_this = 5 - possible_transfer_amounts = list(1,5,15) - flags = OPENCONTAINER - - /* - /obj/item/weapon/reagent_containers/glass/blender_jug - name = "Blender Jug" - desc = "A blender jug, part of a blender." - icon = 'icons/obj/kitchen.dmi' - icon_state = "blender_jug_e" - volume = 100 - - on_reagent_change() - switch(src.reagents.total_volume) - if(0) - icon_state = "blender_jug_e" - if(1 to 75) - icon_state = "blender_jug_h" - if(76 to 100) - icon_state = "blender_jug_f" - - /obj/item/weapon/reagent_containers/glass/canister //not used apparantly - desc = "It's a canister. Mainly used for transporting fuel." - name = "canister" - icon = 'icons/obj/tank.dmi' - icon_state = "canister" - item_state = "canister" - m_amt = 300 - g_amt = 0 - w_class = 4.0 - - amount_per_transfer_from_this = 20 - possible_transfer_amounts = list(10,20,30,60) - volume = 120 - - /obj/item/weapon/reagent_containers/glass/dispenser - name = "reagent glass" - desc = "A reagent glass." - icon = 'icons/obj/chemical.dmi' - icon_state = "beaker0" - amount_per_transfer_from_this = 10 - flags = OPENCONTAINER - - /obj/item/weapon/reagent_containers/glass/dispenser/surfactant - name = "reagent glass (surfactant)" - icon_state = "liquid" - - New() - ..() - reagents.add_reagent("fluorosurfactant", 20) - - */ - \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm new file mode 100644 index 00000000000..e6fcbe43fe6 --- /dev/null +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -0,0 +1,367 @@ +//////////////////////////////////////////////////////////////////////////////// +/// (Mixing)Glass. +//////////////////////////////////////////////////////////////////////////////// +/obj/item/weapon/reagent_containers/glass + name = " " + var/base_name = " " + desc = " " + icon = 'icons/obj/chemical.dmi' + icon_state = "null" + item_state = "null" + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(5,10,15,25,30,50) + volume = 50 + flags = OPENCONTAINER + + var/label_text = "" + // the fucking asshole who designed this can go die in a fire - Iamgoofball + var/list/can_be_placed_into = list( + /obj/machinery/chem_master/, + /obj/machinery/chem_heater/, + /obj/machinery/chem_dispenser/, + /obj/machinery/reagentgrinder, + /obj/structure/table, + /obj/structure/closet, + /obj/structure/sink, + /obj/item/weapon/storage, + /obj/machinery/atmospherics/unary/cryo_cell, + /obj/machinery/dna_scannernew, + /obj/item/weapon/grenade/chem_grenade, + /obj/machinery/bot/medbot, + /obj/item/weapon/storage/secure/safe, + /obj/machinery/iv_drip, + /obj/machinery/disease2/incubator, + /obj/machinery/disposal, + /obj/machinery/apiary, + /mob/living/simple_animal/cow, + /mob/living/simple_animal/hostile/retaliate/goat, + /obj/machinery/computer/centrifuge, + /obj/machinery/sleeper, + /obj/machinery/smartfridge/, +// /obj/machinery/biogenerator, + /obj/machinery/portable_atmospherics/hydroponics, + /obj/machinery/constructable_frame) + + New() + ..() + base_name = name + + examine() + set src in view() + ..() + if (!(usr in view(2)) && usr!=src.loc) return + usr << "\blue It contains:" + if(reagents && reagents.reagent_list.len) + usr << "\blue [src.reagents.total_volume] units of liquid." + else + usr << "\blue Nothing." + if (!is_open_container()) + usr << "\blue Airtight lid seals it completely." + + attack_self() + ..() + if (is_open_container()) + usr << "You put the lid on \the [src]." + flags ^= OPENCONTAINER + else + usr << "You take the lid off \the [src]." + flags |= OPENCONTAINER + update_icon() + + afterattack(obj/target, mob/user, proximity) + if(!proximity) return + if (!is_open_container()) + return + + for(var/type in src.can_be_placed_into) + if(istype(target, type)) + return + + if(ismob(target) && target.reagents && reagents.total_volume) + user << "\blue You splash the solution onto [target]." + + var/mob/living/M = target + var/list/injected = list() + for(var/datum/reagent/R in src.reagents.reagent_list) + injected += R.name + var/contained = english_list(injected) + M.attack_log += text("\[[time_stamp()]\] Has been splashed with [src.name] by [user.name] ([user.ckey]). Reagents: [contained]") + user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to splash [M.name] ([M.key]). Reagents: [contained]") + if(M.ckey) + msg_admin_attack("[user.name] ([user.ckey]) splashed [M.name] ([M.key]) with [src.name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (JMP)") + if(!iscarbon(user)) + M.LAssailant = null + else + M.LAssailant = user + + for(var/mob/O in viewers(world.view, user)) + O.show_message(text("\red [] has been splashed with something by []!", target, user), 1) + src.reagents.reaction(target, TOUCH) + spawn(5) src.reagents.clear_reagents() + return + else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. + + if(!target.reagents.total_volume && target.reagents) + user << "\red [target] is empty." + return + + if(reagents.total_volume >= reagents.maximum_volume) + user << "\red [src] is full." + return + + var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) + user << "\blue You fill [src] with [trans] units of the contents of [target]." + + else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. + if(!reagents.total_volume) + user << "\red [src] is empty." + return + + if(target.reagents.total_volume >= target.reagents.maximum_volume) + user << "\red [target] is full." + return + + if(istype(target, /obj/item/weapon/reagent_containers)) + var/obj/item/weapon/reagent_containers/RC = target + for(var/bad_reg in RC.banned_reagents) + if(reagents.has_reagent(bad_reg, 1)) //Message is a bit "Game-y" but I can't think up a better one. + user << "A chemical in [src] is far too dangerous to transfer to [RC]!" + return + + // /vg/: Logging transfers of bad things + if(target.reagents_to_log.len) + var/list/badshit=list() + for(var/bad_reagent in target.reagents_to_log) + if(reagents.has_reagent(bad_reagent)) + badshit += reagents_to_log[bad_reagent] + if(badshit.len) + var/hl="\red ([english_list(badshit)]) \black" + message_admins("[user.name] ([user.ckey]) added [reagents.get_reagent_ids(1)] to \a [target] with [src].[hl] (JMP)") + log_game("[user.name] ([user.ckey]) added [reagents.get_reagent_ids(1)] to \a [target] with [src].") + + var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) + user << "\blue You transfer [trans] units of the solution to [target]." + + else if(istype(target, /obj/machinery/bunsen_burner)) + return + + else if(istype(target, /obj/machinery/radiocarbon_spectrometer)) + return + + else if(reagents.total_volume) + user << "\blue You splash the solution onto [target]." + src.reagents.reaction(target, TOUCH) + spawn(5) src.reagents.clear_reagents() + return + + + attackby(var/obj/item/I, mob/user as mob, params) + if(istype(I, /obj/item/clothing/mask/cigarette)) //ciggies are weird + return + if(is_hot(I)) + if(src.reagents) + src.reagents.chem_temp += 15 + user << "You heat [src] with [I]." + src.reagents.handle_reactions() + if(istype(I, /obj/item/weapon/pen) || istype(I, /obj/item/device/flashlight/pen)) + var/tmp_label = sanitize(input(user, "Enter a label for [src.name]","Label",src.label_text)) + if(length(tmp_label) > 10) + user << "\red The label can be at most 10 characters long." + else + user << "\blue You set the label to \"[tmp_label]\"." + src.label_text = tmp_label + src.update_name_label() + + + proc/update_name_label() + if(src.label_text == "") + src.name = src.base_name + else + src.name = "[src.base_name] ([src.label_text])" + +/obj/item/weapon/reagent_containers/glass/beaker + name = "beaker" + desc = "A beaker. Can hold up to 50 units." + icon = 'icons/obj/chemical.dmi' + icon_state = "beaker" + item_state = "beaker" + m_amt = 0 + g_amt = 500 + + on_reagent_change() + update_icon() + + pickup(mob/user) + ..() + update_icon() + + dropped(mob/user) + ..() + update_icon() + + attack_hand() + ..() + update_icon() + + update_icon() + overlays.Cut() + + if(reagents.total_volume) + var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10") + + var/percent = round((reagents.total_volume / volume) * 100) + switch(percent) + if(0 to 9) filling.icon_state = "[icon_state]-10" + if(10 to 24) filling.icon_state = "[icon_state]10" + if(25 to 49) filling.icon_state = "[icon_state]25" + if(50 to 74) filling.icon_state = "[icon_state]50" + if(75 to 79) filling.icon_state = "[icon_state]75" + if(80 to 90) filling.icon_state = "[icon_state]80" + if(91 to INFINITY) filling.icon_state = "[icon_state]100" + + filling.icon += mix_color_from_reagents(reagents.reagent_list) + overlays += filling + + if (!is_open_container()) + var/image/lid = image(icon, src, "lid_[initial(icon_state)]") + overlays += lid + +/obj/item/weapon/reagent_containers/glass/beaker/large + name = "large beaker" + desc = "A large beaker. Can hold up to 100 units." + icon_state = "beakerlarge" + g_amt = 2500 + volume = 100 + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(5,10,15,25,30,50,100) + flags = OPENCONTAINER + +/obj/item/weapon/reagent_containers/glass/beaker/vial + name = "vial" + desc = "A small glass vial. Can hold up to 25 units." + icon_state = "vial" + g_amt = 250 + volume = 25 + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(5,10,15,25) + flags = OPENCONTAINER + +/obj/item/weapon/reagent_containers/glass/beaker/noreact + name = "cryostasis beaker" + desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." + icon_state = "beakernoreact" + g_amt = 500 + volume = 50 + amount_per_transfer_from_this = 10 + flags = OPENCONTAINER | NOREACT + +/obj/item/weapon/reagent_containers/glass/beaker/bluespace + name = "bluespace beaker" + desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." + icon_state = "beakerbluespace" + g_amt = 5000 + volume = 300 + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(5,10,15,25,30,50,100,300) + flags = OPENCONTAINER + +/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone + New() + ..() + reagents.add_reagent("cryoxadone", 30) + update_icon() + +/obj/item/weapon/reagent_containers/glass/beaker/sulphuric + New() + ..() + reagents.add_reagent("sacid", 50) + update_icon() + +/obj/item/weapon/reagent_containers/glass/beaker/slime + New() + ..() + reagents.add_reagent("slimejelly", 50) + update_icon() + +/obj/item/weapon/reagent_containers/glass/bucket + desc = "It's a bucket." + name = "bucket" + icon = 'icons/obj/janitor.dmi' + icon_state = "bucket" + item_state = "bucket" + m_amt = 200 + g_amt = 0 + w_class = 3.0 + amount_per_transfer_from_this = 20 + possible_transfer_amounts = list(5,10,15,25,30,50,80,100,120) + volume = 120 + flags = OPENCONTAINER + + attackby(var/obj/D, mob/user as mob, params) + if(isprox(D)) + user << "You add [D] to [src]." + del(D) + user.put_in_hands(new /obj/item/weapon/bucket_sensor) + user.unEquip(src) + qdel(src) + else + ..() + +/obj/item/weapon/reagent_containers/glass/beaker/vial + name = "vial" + desc = "Small glass vial. Looks fragile." + icon_state = "vial" + g_amt = 500 + volume = 15 + amount_per_transfer_from_this = 5 + possible_transfer_amounts = list(1,5,15) + flags = OPENCONTAINER + +/* +/obj/item/weapon/reagent_containers/glass/blender_jug + name = "Blender Jug" + desc = "A blender jug, part of a blender." + icon = 'icons/obj/kitchen.dmi' + icon_state = "blender_jug_e" + volume = 100 + + on_reagent_change() + switch(src.reagents.total_volume) + if(0) + icon_state = "blender_jug_e" + if(1 to 75) + icon_state = "blender_jug_h" + if(76 to 100) + icon_state = "blender_jug_f" + +/obj/item/weapon/reagent_containers/glass/canister //not used apparantly + desc = "It's a canister. Mainly used for transporting fuel." + name = "canister" + icon = 'icons/obj/tank.dmi' + icon_state = "canister" + item_state = "canister" + m_amt = 300 + g_amt = 0 + w_class = 4.0 + + amount_per_transfer_from_this = 20 + possible_transfer_amounts = list(10,20,30,60) + volume = 120 + +/obj/item/weapon/reagent_containers/glass/dispenser + name = "reagent glass" + desc = "A reagent glass." + icon = 'icons/obj/chemical.dmi' + icon_state = "beaker0" + amount_per_transfer_from_this = 10 + flags = OPENCONTAINER + +/obj/item/weapon/reagent_containers/glass/dispenser/surfactant + name = "reagent glass (surfactant)" + icon_state = "liquid" + + New() + ..() + reagents.add_reagent("fluorosurfactant", 20) + +*/ diff --git a/icons/obj/flora/rocks.dmi b/icons/obj/flora/rocks.dmi index a1f6a0df0a9..b03c866fd75 100644 Binary files a/icons/obj/flora/rocks.dmi and b/icons/obj/flora/rocks.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index d7cae5cecd6..abdfc3456b4 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/paradise.dme b/paradise.dme index 56ca0c6a5d3..f4bdc02c04c 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1423,6 +1423,11 @@ #include "code\modules\power\singularity\particle_accelerator\particle_control.dm" #include "code\modules\power\singularity\particle_accelerator\particle_emitter.dm" #include "code\modules\power\singularity\particle_accelerator\particle_power.dm" +#include "code\modules\procedural mapping\mapGenerator.dm" +#include "code\modules\procedural mapping\mapGeneratorModule.dm" +#include "code\modules\procedural mapping\mapGeneratorReadme.dm" +#include "code\modules\procedural mapping\mapGeneratorModules\nature.dm" +#include "code\modules\procedural mapping\mapGenerators\nature.dm" #include "code\modules\projectiles\ammunition.dm" #include "code\modules\projectiles\gun.dm" #include "code\modules\projectiles\projectile.dm" @@ -1487,7 +1492,7 @@ #include "code\modules\reagents\reagent_containers\dropper.dm" #include "code\modules\reagents\reagent_containers\drugs.dm" #include "code\modules\reagents\reagent_containers\food.dm" -#include "code\modules\reagents\reagent_containers\glass.dm" +#include "code\modules\reagents\reagent_containers\glass_containers.dm" #include "code\modules\reagents\reagent_containers\hypospray.dm" #include "code\modules\reagents\reagent_containers\pill.dm" #include "code\modules\reagents\reagent_containers\robodropper.dm"