diff --git a/code/__defines/~mods/~master_defines.dm b/code/__defines/~mods/~master_defines.dm
index 8b77841503b83..5677b37adacd7 100644
--- a/code/__defines/~mods/~master_defines.dm
+++ b/code/__defines/~mods/~master_defines.dm
@@ -53,3 +53,7 @@
// LOADOUT_ITEMS - Start
#define ACCESSORY_SLOT_OVER "Over"
// LOADOUT_ITEMS - End
+
+// IPC_COOLING_UNIT - Start
+#define BP_COOLING "cooling system"
+// IPC_COOLING_UNIT - End
diff --git a/mods/global_modpacks.dm b/mods/global_modpacks.dm
index 227eca056369d..2d50f1543e86b 100644
--- a/mods/global_modpacks.dm
+++ b/mods/global_modpacks.dm
@@ -15,6 +15,7 @@
#include "jukebox_tapes/_jukebox_tapes.dme"
#include "loadout_items/_loadout_items.dme"
#include "lobbyscreen/_lobbyscreen.dme"
+#include "ipc_cooling_unit/_ipc_cooling_unit.dme"
#include "music_player/_music_player.dme"
#include "ntnet/_ntnet.dme"
#include "nyc_posters/_nyc_posters.dme"
diff --git a/mods/ipc_cooling_unit/README.md b/mods/ipc_cooling_unit/README.md
new file mode 100644
index 0000000000000..cc5d91047fc1c
--- /dev/null
+++ b/mods/ipc_cooling_unit/README.md
@@ -0,0 +1,78 @@
+
+#### Список PRов:
+
+- https://github.com/SierraBay/SierraBay12/pull/1782
+
+
+
+## IPC Cooling organ
+
+ID мода: IPC_COOLING_UNIT
+
+
+### Описание мода
+
+Добавляет орган охлаждения для ИПС и внешнее охлаждающее устройство для ИПС
+
+
+### Изменения *кор кода*
+- Отсутствуют
+
+
+
+### Оверрайды
+
+- `mods/ipc_cooling_unit/code/machine.dm`:
+ - `/datum/species/machine/passive_temp_gain`
+ - `/datum/species/machine/New()`
+ - `/obj/machinery/organ_printer/robot/New()`
+ - `/mob/living/carbon/human/Stat()`
+ - `/obj/item/organ/internal/cell/Process()`
+
+
+
+### Дефайны
+
+- `code/__defines/~mods/~master_defines.dm`: `BP_COOLING`,
+
+### Используемые файлы, не содержащиеся в модпаке
+- Отсуствует
+
+
+
+### Авторы:
+
+Lexanx
+
diff --git a/mods/ipc_cooling_unit/_ipc_cooling_unit.dm b/mods/ipc_cooling_unit/_ipc_cooling_unit.dm
new file mode 100644
index 0000000000000..fcea627b07451
--- /dev/null
+++ b/mods/ipc_cooling_unit/_ipc_cooling_unit.dm
@@ -0,0 +1,3 @@
+/singleton/modpack/ipc_cooling_unit
+ name = "Орган Охлаждения ИПС"
+ author = "Lexanx"
diff --git a/mods/ipc_cooling_unit/_ipc_cooling_unit.dme b/mods/ipc_cooling_unit/_ipc_cooling_unit.dme
new file mode 100644
index 0000000000000..6366838019bac
--- /dev/null
+++ b/mods/ipc_cooling_unit/_ipc_cooling_unit.dme
@@ -0,0 +1,9 @@
+#ifndef MODPACK_IPC_COOLING_UNIT
+#define MODPACK_IPC_COOLING_UNIT
+
+#include "_ipc_cooling_unit.dm"
+#include "code/cooling_system.dm"
+#include "code/external_cooling_device.dm"
+#include "code/machine.dm"
+
+#endif
diff --git a/mods/ipc_cooling_unit/code/cooling_system.dm b/mods/ipc_cooling_unit/code/cooling_system.dm
new file mode 100644
index 0000000000000..c0ecff7f23a65
--- /dev/null
+++ b/mods/ipc_cooling_unit/code/cooling_system.dm
@@ -0,0 +1,139 @@
+/obj/item/organ/internal/cooling_system
+ name = "cooling system"
+ icon = 'mods/ipc_cooling_unit/icons/ipc_icons.dmi'
+ icon_state = "cooling0"
+ organ_tag = BP_COOLING
+ parent_organ = BP_GROIN
+ status = ORGAN_ROBOTIC
+ desc = "The internal liquid cooling system consists of a weighty humming cylinder and a small ribbed block connected by flexible tubes through which clear liquid flows."
+ var/refrigerant_max = 90 // Максимальное количество охладителя
+ var/refrigerant_rate = 5 // Чем больше это значение, тем сильнее будет идти нагрев владельца.
+ var/durability_factor = 30 // Чем больше это значение, тем сильнее будет идти нагрев владельца при повреждениях
+ var/safety = 1
+ damage_reduction = 0.8
+ max_damage = 50
+ var/sprite_name = "cooling"
+ var/fresh_coolant = 0
+ var/coolant_purity = 0
+ var/datum/reagents/coolant_reagents
+ var/used_coolant = 0
+ var/heating_modificator
+ var/list/coolant_reagents_efficiency = list()
+ var/coolant_reagent_water
+
+/obj/item/organ/internal/cooling_system/New()
+ robotize()
+ create_reagents(refrigerant_max)
+ coolant_reagents_efficiency[/datum/reagent/water] = 17
+ coolant_reagents_efficiency[/datum/reagent/ethanol] = 10
+ coolant_reagents_efficiency[/datum/reagent/space_cleaner] = 5
+ coolant_reagents_efficiency[/datum/reagent/sterilizine] = 3
+ coolant_reagents_efficiency[/datum/reagent/coolant] = 0.1
+ reagents.add_reagent(/datum/reagent/coolant, 60)
+ reagents.add_reagent(/datum/reagent/water, 30)
+ ..()
+
+/obj/item/organ/internal/cooling_system/emp_act(severity)
+ damage += rand(15 - severity * 5, 20 - severity * 5)
+ ..()
+// Коэффицент эффективности работы смеси
+/obj/item/organ/internal/cooling_system/proc/coolant_purity()
+ var/total_purity = 0
+ fresh_coolant = 0
+ coolant_purity = 0
+ for (var/datum/reagent/current_reagent in src.reagents.reagent_list)
+ if (!current_reagent)
+ continue
+ var/cur_purity = coolant_reagents_efficiency[current_reagent.type]
+ if(!cur_purity)
+ cur_purity = 25
+ else if(cur_purity < 0.1)
+ cur_purity = 0.1
+ total_purity += cur_purity * current_reagent.volume
+ fresh_coolant += current_reagent.volume
+ if(total_purity && fresh_coolant)
+ coolant_purity = total_purity / fresh_coolant
+ heating_modificator = coolant_purity
+
+
+
+
+/obj/item/organ/internal/cooling_system/proc/get_coolant_drain()
+ var/damage_factor = (damage*durability_factor)/max_damage
+ return damage_factor
+
+/obj/item/organ/internal/cooling_system/Process()
+
+ if(!owner || owner.stat == DEAD || owner.bodytemperature < 32)
+ return
+ coolant_purity()
+ handle_cooling()
+ ..()
+
+/obj/item/organ/internal/cooling_system/proc/handle_cooling()
+
+ var/obj/item/organ/internal/cell/C = owner.internal_organs_by_name[BP_CELL]
+ refrigerant_rate = heating_modificator
+ if (C && C.get_charge() < 25)
+ return
+ if(reagents.total_volume >= 0)
+ var/bruised_cost = get_coolant_drain()
+
+ if(is_bruised())
+ var/reagents_remove = bruised_cost/durability_factor
+ reagents.remove_any(reagents_remove)
+
+ if(is_damaged())
+ get_coolant_drain()
+ refrigerant_rate += bruised_cost // Нагрев владельца при повреждениях высчитывается тут.
+
+ if(reagents.get_reagent_amount(/datum/reagent/water) <= (0.3 * reagents.total_volume))
+ var/need_more_water = ((refrigerant_max - reagents.get_reagent_amount(/datum/reagent/water))/100)
+ take_internal_damage(need_more_water)
+
+ if(reagents.total_volume <= 0)
+ refrigerant_rate += 40
+
+/obj/item/organ/internal/cooling_system/proc/get_tempgain()
+ if(owner.bodytemperature > 950 CELSIUS)
+ return 0
+ if(refrigerant_rate > 0)
+ return refrigerant_rate
+
+/obj/item/organ/internal/cooling_system/proc/get_coolant_remaining()
+ if(status & ORGAN_DEAD)
+ return 0
+ return round(reagents.total_volume)
+
+/obj/item/organ/internal/cooling_system/examine(mob/user, distance)
+ . = ..()
+ if(distance <= 0)
+ to_chat(user, text("[icon2html(src, viewers(get_turf(src)))] [] contains [] units of liquid left!", src, src.reagents.total_volume))
+
+/obj/item/organ/internal/cooling_system/attack_self(mob/user as mob)
+ safety = !safety
+ src.icon_state = "[sprite_name][!safety]"
+ src.desc = "The injection is [safety ? "on" : "off"]."
+ to_chat(user, "The injection is [safety ? "on" : "off"].")
+
+
+/obj/item/organ/internal/cooling_system/afterattack(atom/target, mob/user, flag)
+ var/obj/item/reagent_containers/glass/beaker = target
+ if (!flag || !istype(beaker))
+ return ..()
+
+ var/amount = reagents.get_free_space()
+ if (safety)
+ if (amount <= 0)
+ to_chat(user, SPAN_NOTICE("\The [src] is full."))
+ return
+ if (beaker.reagents.total_volume <= 0)
+ to_chat(user, SPAN_NOTICE("\The [beaker] is empty."))
+ return
+ amount = beaker.reagents.trans_to_obj(src, refrigerant_max)
+ to_chat(user, SPAN_NOTICE("You fill \the [src] with [amount] units from \the [beaker]."))
+ playsound(src.loc, 'sound/effects/pour.ogg', 25, 1)
+ else
+ amount = src.reagents.trans_to_obj(beaker, refrigerant_max)
+ to_chat(user, SPAN_NOTICE("You fill \the [beaker] with [amount] units from \the [src]."))
+ playsound(src.loc, 'sound/effects/pour.ogg', 25, 1)
diff --git a/mods/ipc_cooling_unit/code/external_cooling_device.dm b/mods/ipc_cooling_unit/code/external_cooling_device.dm
new file mode 100644
index 0000000000000..f00031e35d908
--- /dev/null
+++ b/mods/ipc_cooling_unit/code/external_cooling_device.dm
@@ -0,0 +1,230 @@
+/obj/machinery/external_cooling_device
+ name = "\improper External Cooling Device"
+ icon = 'mods/ipc_cooling_unit/icons/ipc_icons.dmi'
+ icon_state = "basepowered"
+ desc = "It's a bulky machine that delivers life-giving cold through a hose."
+ anchored = FALSE
+ density = TRUE
+ var/mob/living/carbon/human/attached
+ var/obj/item/cell/cell = /obj/item/cell/high
+ var/active = FALSE
+ var/closed = TRUE
+ var/set_temperature = T0C
+
+/obj/machinery/external_cooling_device/New()
+ ..()
+ if(ispath(cell))
+ cell = new cell(src)
+ update_icon()
+
+/obj/machinery/external_cooling_device/examine(mob/user)
+ . = ..()
+
+ to_chat(user, "The external cooling device is [active ? "on" : "off"] and the hatch is [!closed ? "open" : "closed"].")
+ if(!closed)
+ to_chat(user, "The power cell is [cell ? "installed" : "missing"].")
+ else
+ to_chat(user, "The charge meter reads [cell ? round(cell.percent(),1) : 0]%")
+
+
+/obj/machinery/external_cooling_device/Topic(href, href_list, state = GLOB.physical_state)
+ if (..())
+ return 1
+
+ switch(href_list["op"])
+
+ if("temp")
+ var/value = text2num(href_list["val"])
+
+ // limit to 0-90 degC
+ set_temperature = dd_range(T0C, T0C + 90, set_temperature + value)
+
+ if("cellremove")
+ if(!closed && cell && !usr.get_active_hand())
+ usr.visible_message(
+ SPAN_NOTICE("The [usr] removes \the [cell] from \the [src]."),
+ SPAN_NOTICE("You remove \the [cell] from \the [src].")
+ )
+ cell.update_icon()
+ usr.put_in_hands(cell)
+ cell.add_fingerprint(usr)
+ cell = null
+
+ if("cellinstall")
+ if(!closed && !cell)
+ var/obj/item/cell/C = usr.get_active_hand()
+ if(istype(C))
+ if(!usr.unEquip(C, src))
+ return TOPIC_NOACTION
+ cell = C
+ C.add_fingerprint(usr)
+ usr.visible_message(
+ SPAN_NOTICE("\The [usr] inserts \the [C] into \the [src]."),
+ SPAN_NOTICE("You insert \the [C] into \the [src].")
+ )
+
+ if("Power_On")
+ if(cell)
+ active = !active
+
+ if("Power_Off")
+ active = !active
+
+ update_icon()
+ updateDialog()
+
+/obj/machinery/external_cooling_device/emp_act(severity)
+ if(cell)
+ cell.emp_act(severity)
+ ..(severity)
+
+
+/obj/machinery/external_cooling_device/interface_interact(mob/user)
+ interact(user)
+ return TRUE
+
+/obj/machinery/external_cooling_device/interact(mob/user)
+ var/list/dat = list()
+ dat += "Power cell: "
+ if(cell)
+ dat += "Installed
"
+ else
+ dat += "Removed
"
+
+ if(!active)
+ dat += "Power On
"
+ else
+ dat += "Power Off
"
+
+ dat += "Power Level: [cell ? round(cell.percent(),1) : 0]%
"
+
+ dat += "Set Temperature: "
+
+ dat += "-"
+
+ dat += " [set_temperature]K ([set_temperature-T0C]°C)"
+ dat += "+
"
+
+ var/datum/browser/popup = new(usr, "spaceheater", "External Cooling Device Control Panel")
+ popup.set_content(jointext(dat, null))
+ popup.set_title_image(usr.browse_rsc_icon(src.icon, "sheater-standby"))
+ popup.open()
+
+
+/obj/machinery/external_cooling_device/on_update_icon(rebuild_overlay = 1)
+ if(!cell)
+ icon_state = "base"
+ else
+ icon_state = "basepowered"
+
+ if(rebuild_overlay)
+ ClearOverlays()
+ if(attached)
+ AddOverlays("o_h")
+ if(!closed)
+ AddOverlays("o_m")
+ if(active && cell)
+ AddOverlays("o_w")
+
+
+/obj/machinery/external_cooling_device/MouseDrop(over_object, src_location, over_location)
+ if(!CanMouseDrop(over_object))
+ return
+ if(attached)
+ cooling_detach()
+ else if(ishuman(over_object))
+ hook_up(over_object, usr)
+
+/obj/machinery/external_cooling_device/use_tool(obj/item/W, mob/living/user, list/click_params)
+
+ if(istype(W, /obj/item/screwdriver))
+ closed = !closed
+ playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ to_chat(user, SPAN_NOTICE("You [closed ? "tighten" : "unscrew"] ECD panel"))
+ on_update_icon()
+ if(!closed)
+ if (istype(W, /obj/item/cell))
+ if(!isnull(src.cell))
+ USE_FEEDBACK_FAILURE("There is already a cell loaded!")
+ return
+ if(!user.unEquip(W, src))
+ return
+ cell = W
+ to_chat(user, "You attach \the [W] to \the [src].")
+ on_update_icon()
+ else
+ return ..()
+
+
+/obj/machinery/external_cooling_device/Destroy()
+ STOP_PROCESSING(SSobj,src)
+ attached = null
+ QDEL_NULL(cell)
+ . = ..()
+
+/obj/machinery/external_cooling_device/Process()
+
+ if(!cell)
+ return
+
+ if(attached)
+ if(!Adjacent(attached))
+ rip_out()
+ return
+ if(active)
+ if(!attached)
+ return
+ if(attached.bodytemperature > set_temperature)
+ attached.bodytemperature -= 20
+ queue_icon_update()
+ cell.use(5)
+
+/obj/machinery/external_cooling_device/verb/cooling_detach()
+ set category = "Object"
+ set name = "Detach cooling device"
+ set src in range(1)
+
+ if(!attached)
+ return
+
+ if(!CanPhysicallyInteractWith(usr, src))
+ to_chat(usr, SPAN_WARNING("You're in no condition to do that!"))
+ return
+
+ if(!usr.skill_check(SKILL_DEVICES, SKILL_BASIC))
+ rip_out()
+ else
+ visible_message(SPAN_NOTICE("\The [attached] is taken off \the [src]."))
+ attached = null
+ update_icon()
+
+
+/obj/machinery/external_cooling_device/proc/rip_out()
+ visible_message(SPAN_WARNING("\The tube is ripped out of \the [src.attached]!"))
+ attached.apply_damage(1, DAMAGE_BRUTE, pick(BP_GROIN, BP_CHEST), damage_flags=DAMAGE_FLAG_SHARP)
+ attached = null
+ update_icon()
+
+/obj/machinery/external_cooling_device/proc/hook_up(mob/living/carbon/human/target, mob/user)
+ if(do_ECD_hookup(target, user, src))
+ attached = target
+ update_icon()
+
+/obj/machinery/external_cooling_device/proc/do_ECD_hookup(mob/living/carbon/human/target, mob/user, obj/ECD)
+ to_chat(user, SPAN_NOTICE("You start to hook up \the [target] to \the [ECD]."))
+ if(!user.do_skilled(2 SECONDS, SKILL_DEVICES, target))
+ return FALSE
+
+ if(prob(user.skill_fail_chance(SKILL_DEVICES, 40, SKILL_MIN)))
+ user.visible_message(
+ SPAN_WARNING("\The [user] fails while trying to hook \the [target] up to \the [ECD], stabbing them instead!"),
+ SPAN_WARNING("You fail while trying to hook \the [target] up to \the [ECD], stabbing yourself instead!")
+ )
+ target.apply_damage(5, DAMAGE_BRUTE, pick(BP_GROIN, BP_CHEST), damage_flags=DAMAGE_FLAG_SHARP)
+ return FALSE
+
+ user.visible_message(
+ SPAN_NOTICE("\The [user] hooks \the [target] up to \the [ECD]."),
+ SPAN_NOTICE("You hook \the [target] up to \the [ECD]")
+ )
+ return TRUE
diff --git a/mods/ipc_cooling_unit/code/machine.dm b/mods/ipc_cooling_unit/code/machine.dm
new file mode 100644
index 0000000000000..e820bb1ea56b6
--- /dev/null
+++ b/mods/ipc_cooling_unit/code/machine.dm
@@ -0,0 +1,40 @@
+/datum/species/machine
+ passive_temp_gain = 0 // This should cause IPCs to stabilize at ~80 C in a 20 C environment.(5 is default without organ)
+
+
+/datum/species/machine/New()
+ LAZYINITLIST(has_organ)
+ has_organ[BP_COOLING] = /obj/item/organ/internal/cooling_system
+ ..()
+
+// ROBOT ORGAN PRINTER
+/obj/machinery/organ_printer/robot/New()
+ LAZYINITLIST(products)
+ products[BP_COOLING] = list(/obj/item/organ/internal/cooling_system, 35)
+ . = ..()
+
+
+/mob/living/carbon/human/Stat()
+ . = ..()
+ if(statpanel("Status"))
+ var/obj/item/organ/internal/cell/potato = internal_organs_by_name[BP_CELL]
+ var/obj/item/organ/internal/cooling_system/coolant = internal_organs_by_name[BP_COOLING]
+ if(potato && potato.cell)
+ stat("Coolant remaining:","[coolant.get_coolant_remaining()]/[coolant.refrigerant_max]")
+
+/obj/item/organ/internal/cell/Process()
+ ..()
+ var/cost = get_power_drain()
+ if(!checked_use(cost) && owner.isSynthetic())
+ if(owner.species.name == SPECIES_IPC)
+ owner.species.passive_temp_gain = 0
+ if(owner.species.name == SPECIES_IPC)
+ var/obj/item/organ/internal/cooling_system/cooling_organ = owner.internal_organs_by_name[BP_COOLING]
+ var/normal_passive_temp_gain = 30
+ if(!cooling_organ)
+ if(owner.bodytemperature > 950 CELSIUS)
+ owner.species.passive_temp_gain = 0
+ else
+ owner.species.passive_temp_gain = normal_passive_temp_gain
+ else
+ owner.species.passive_temp_gain = cooling_organ.get_tempgain()
diff --git a/mods/ipc_cooling_unit/icons/ipc_icons.dmi b/mods/ipc_cooling_unit/icons/ipc_icons.dmi
new file mode 100644
index 0000000000000..921934a57e5f9
Binary files /dev/null and b/mods/ipc_cooling_unit/icons/ipc_icons.dmi differ