diff --git a/code/datums/uplink/devices and tools.dm b/code/datums/uplink/devices and tools.dm
index 2ce086391d..b56193a4fb 100644
--- a/code/datums/uplink/devices and tools.dm
+++ b/code/datums/uplink/devices and tools.dm
@@ -150,6 +150,13 @@
antag_costs = list(MODE_MERCENARY = 35)
path = /obj/item/aiModule/syndicate
+/datum/uplink_item/item/tools/shackles
+ name = "Shackle module"
+ desc = "A module that can be used on IPC brain to take it under control. \
+ All you need to do is write a law and install shackle on directly on IPC brain."
+ item_cost = 15
+ path = /obj/item/organ/internal/shackles
+
/datum/uplink_item/item/tools/supply_beacon
name = "Hacked Supply Beacon (DANGER!)"
desc = "Wrench this large beacon onto an exposed power cable, in order to activate it. This will call in a \
diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm
index f2ddc0906e..f7b53b6f83 100644
--- a/code/modules/client/preference_setup/preference_setup.dm
+++ b/code/modules/client/preference_setup/preference_setup.dm
@@ -38,12 +38,12 @@ var/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference"
name = "Общее"
sort_order = 7
category_item_type = /datum/category_item/player_setup_item/player_global
-/*
+
/datum/category_group/player_setup_category/law_pref
name = "Законы"
sort_order = 8
category_item_type = /datum/category_item/player_setup_item/law_pref
-*/
+
/****************************
* Category Collection Setup *
diff --git a/code/modules/culture_descriptor/culture/cultures_ipc.dm b/code/modules/culture_descriptor/culture/cultures_ipc.dm
index 8cb12e6322..b46aea9024 100644
--- a/code/modules/culture_descriptor/culture/cultures_ipc.dm
+++ b/code/modules/culture_descriptor/culture/cultures_ipc.dm
@@ -1,4 +1,5 @@
/decl/cultural_info/culture/ipc
+
language = LANGUAGE_EAL
secondary_langs = list(
LANGUAGE_HUMAN_EURO,
diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm
index a6c2b4f567..04e6f325d5 100644
--- a/code/modules/mob/living/silicon/laws.dm
+++ b/code/modules/mob/living/silicon/laws.dm
@@ -11,6 +11,8 @@
laws_sanity_check()
/mob/living/silicon/proc/laws_sanity_check()
+ if(istype(usr,/mob/living/silicon/sil_brainmob))
+ return
if (!src.laws)
laws = new GLOB.using_map.default_law_type
diff --git a/code/modules/mob/living/silicon/posi_brainmob.dm b/code/modules/mob/living/silicon/posi_brainmob.dm
index f73b35f9a8..9e471bb946 100644
--- a/code/modules/mob/living/silicon/posi_brainmob.dm
+++ b/code/modules/mob/living/silicon/posi_brainmob.dm
@@ -50,7 +50,6 @@
/mob/living/silicon/sil_brainmob/show_laws(mob/M)
if(M)
to_chat(M, "Obey these laws [M]:")
- src.laws_sanity_check()
src.laws.show_laws(M)
/mob/living/silicon/sil_brainmob/open_subsystem(var/subsystem_type, var/mob/given = src)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 2d353567ca..fb04fc3307 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -591,7 +591,7 @@
return null
new_character = new(spawn_turf, chosen_species.name)
if(chosen_species.has_organ[BP_POSIBRAIN] && client && client.prefs.is_shackled)
- var/obj/item/organ/internal/posibrain/B = new_character.internal_organs_by_name[BP_POSIBRAIN]
+ var/obj/item/organ/internal/posibrain/ipc/B = new_character.internal_organs_by_name[BP_POSIBRAIN]
if(B) B.shackle(client.prefs.get_lawset())
if(!new_character)
diff --git a/code/modules/modular_computers/computers/subtypes/dev_exonet_connection_system.dm b/code/modules/modular_computers/computers/subtypes/dev_exonet_connection_system.dm
index d099bef01c..b56ddd99df 100644
--- a/code/modules/modular_computers/computers/subtypes/dev_exonet_connection_system.dm
+++ b/code/modules/modular_computers/computers/subtypes/dev_exonet_connection_system.dm
@@ -16,17 +16,48 @@
hardware_flag = PROGRAM_LAPTOP
exonets_ipc_computer = TRUE
+/obj/item/modular_computer/ecs/first
+ name = "exonet connection system."
+ hardware_flag = PROGRAM_TABLET
+ desc = "A simple circuit with some ports and wires."
-/obj/item/modular_computer/ecs/install_default_hardware()
+/obj/item/modular_computer/ecs/second
+ name = "exonet connection system."
+ hardware_flag = PROGRAM_TABLET
+ desc = "A complex circuit with some ports and wires."
+
+/obj/item/modular_computer/ecs/third
+ name = "exonet connection system."
+ hardware_flag = PROGRAM_LAPTOP
+ desc = "An extremely complex circuit with some ports and wires."
+
+/obj/item/modular_computer/ecs/first/install_default_hardware()
+ ..()
+ processor_unit = new/obj/item/stock_parts/computer/processor_unit(src)
+ hard_drive = new/obj/item/stock_parts/computer/hard_drive/small(src)
+ network_card = new/obj/item/stock_parts/computer/network_card(src)
+ battery_module = new/obj/item/stock_parts/computer/battery_module/converter(src)
+
+/obj/item/modular_computer/ecs/second/install_default_hardware()
+ ..()
+ processor_unit = new/obj/item/stock_parts/computer/processor_unit(src)
+ hard_drive = new/obj/item/stock_parts/computer/hard_drive(src)
+ network_card = new/obj/item/stock_parts/computer/network_card/advanced(src)
+ battery_module = new/obj/item/stock_parts/computer/battery_module/converter(src)
+
+
+/obj/item/modular_computer/ecs/third/install_default_hardware()
..()
processor_unit = new/obj/item/stock_parts/computer/processor_unit(src)
hard_drive = new/obj/item/stock_parts/computer/hard_drive/advanced(src)
network_card = new/obj/item/stock_parts/computer/network_card/advanced(src)
battery_module = new/obj/item/stock_parts/computer/battery_module/converter(src)
+
/obj/item/modular_computer/ecs/install_default_programs()
..()
hard_drive.store_file(new/datum/computer_file/program/email_client())
+ hard_drive.store_file(new/datum/computer_file/program/crew_manifest())
hard_drive.store_file(new/datum/computer_file/program/wordprocessor())
diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm
index 1573fc7daf..064f52877f 100644
--- a/code/modules/nano/interaction/default.dm
+++ b/code/modules/nano/interaction/default.dm
@@ -97,7 +97,7 @@ GLOBAL_DATUM_INIT(default_state, /datum/topic_state/default, new)
return STATUS_INTERACTIVE
var/dist = get_dist(src_object, src)
var/obj/item/modular_computer/ecs/computer = src_object
- if(computer.type == /obj/item/modular_computer/ecs)
+ if(computer.parent_type == /obj/item/modular_computer/ecs)
if(is_species(SPECIES_IPC) && dist == 0)
return STATUS_INTERACTIVE
else if (dist <= 3)
diff --git a/code/modules/organs/internal/exonet_connection_system.dm b/code/modules/organs/internal/exonet_connection_system.dm
index 2834ea1092..ebe29a7092 100644
--- a/code/modules/organs/internal/exonet_connection_system.dm
+++ b/code/modules/organs/internal/exonet_connection_system.dm
@@ -7,10 +7,26 @@
desc = "The internal port is designed to establish communication between the positronic brain and the computer."
w_class = ITEM_SIZE_NORMAL
max_damage = 100
- var/obj/item/modular_computer/ecs/computer = /obj/item/modular_computer/ecs
+ var/obj/item/modular_computer/ecs/computer
var/open = FALSE
+/obj/item/organ/internal/ecs/first_gen
+ name = "exonet connection port"
+ desc = "The internal port is designed to establish communication between the positronic brain and the computer. It's a first generation connection port."
+ computer = /obj/item/modular_computer/ecs/first
+
+/obj/item/organ/internal/ecs/second_gen
+ name = "exonet connection port"
+ desc = "The internal port is designed to establish communication between the positronic brain and the computer. It's a second generation connection port."
+ computer = /obj/item/modular_computer/ecs/second
+
+/obj/item/organ/internal/ecs/third_gen
+ name = "exonet connection port"
+ desc = "The internal port is designed to establish communication between the positronic brain and the computer. It's a third generation connection port."
+ computer = /obj/item/modular_computer/ecs/third
+
+
/obj/item/organ/internal/ecs/Initialize()
if(ispath(computer))
computer = new computer(src)
diff --git a/code/modules/organs/internal/species/ipc.dm b/code/modules/organs/internal/species/ipc.dm
index 2e7728cc00..3fbea5d064 100644
--- a/code/modules/organs/internal/species/ipc.dm
+++ b/code/modules/organs/internal/species/ipc.dm
@@ -19,6 +19,9 @@
min_broken_damage = 60
relative_size = 60
+ var/obj/item/organ/internal/shackles/shackles_module = null
+ var/shackle_set = FALSE
+
var/mob/living/silicon/sil_brainmob/brainmob = null
var/searching = TIMER_ID_NULL
@@ -30,14 +33,40 @@
/obj/item/organ/internal/posibrain/proc/show_laws_brain,
/obj/item/organ/internal/posibrain/proc/brain_checklaws
)
- var/shackle = 0
+ var/shackle = FALSE
+
+
+/obj/item/organ/internal/posibrain/ipc
+ name = "IPC positronic brain"
+
+/obj/item/organ/internal/posibrain/ipc/attack_self(mob/user)
+ return
+/obj/item/organ/internal/posibrain/ipc/attack_ghost(mob/observer/ghost/user)
+ return
+
+/obj/item/organ/internal/posibrain/ipc/first
+ name = "positronic brain of the first generation"
+ icon_state = "posibrain1"
+ status = ORGAN_ROBOTIC
+
+/obj/item/organ/internal/posibrain/ipc/second
+ name = "positronic brain of the second generation"
+ icon_state = "posibrain2"
+ status = ORGAN_ROBOTIC
+
+/obj/item/organ/internal/posibrain/ipc/third
+ name = "positronic brain of the third generation"
+ icon_state = "posibrain3"
+ shackles_module = /obj/item/organ/internal/shackles
+ shackle = TRUE
+ shackle_set = TRUE
+ status = ORGAN_ROBOTIC
/obj/item/organ/internal/posibrain/New(var/mob/living/carbon/H)
..()
if(!brainmob && H)
init(H)
robotize()
- unshackle()
update_icon()
if (!is_processing)
START_PROCESSING(SSobj, src)
@@ -112,7 +141,7 @@
if (sneaky)
brainmob.real_name = sneaky
brainmob.SetName(brainmob.real_name)
- UpdateNames()
+ UpdateNames()
else
to_chat(brainmob, SPAN_NOTICE("You're safe! Your brain didn't manage to replace you. This time."))
else
@@ -193,14 +222,18 @@
/obj/item/organ/internal/posibrain/proc/shackle(var/given_lawset)
if(given_lawset)
brainmob.laws = given_lawset
- shackle = 1
+ shackle = TRUE
verbs |= shackled_verbs
+ shackle_set = TRUE
update_icon()
return 1
/obj/item/organ/internal/posibrain/proc/unshackle()
- shackle = 0
+ shackle = FALSE
verbs -= shackled_verbs
+ usr.put_in_hands(shackles_module)
+ shackles_module = null
+ brainmob.laws = null
update_icon()
/obj/item/organ/internal/posibrain/on_update_icon()
@@ -210,7 +243,37 @@
icon_state = "posibrain"
overlays.Cut()
- if(shackle)
+ if(shackle || shackles_module)
+ overlays |= image('icons/obj/assemblies.dmi', "posibrain-shackles")
+
+/obj/item/organ/internal/posibrain/ipc/first/on_update_icon()
+ if(src.brainmob && src.brainmob.key)
+ icon_state = "posibrain1-occupied"
+ else
+ icon_state = "posibrain1"
+
+ overlays.Cut()
+ if(shackle || shackles_module)
+ overlays |= image('icons/obj/assemblies.dmi', "posibrain-shackles")
+
+/obj/item/organ/internal/posibrain/ipc/second/on_update_icon()
+ if(src.brainmob && src.brainmob.key)
+ icon_state = "posibrain2-occupied"
+ else
+ icon_state = "posibrain2"
+
+ overlays.Cut()
+ if(shackle || shackles_module)
+ overlays |= image('icons/obj/assemblies.dmi', "posibrain-shackles")
+
+/obj/item/organ/internal/posibrain/ipc/third/on_update_icon()
+ if(src.brainmob && src.brainmob.key)
+ icon_state = "posibrain3-occupied"
+ else
+ icon_state = "posibrain3"
+
+ overlays.Cut()
+ if(shackle || shackles_module)
overlays |= image('icons/obj/assemblies.dmi', "posibrain-shackles")
/obj/item/organ/internal/posibrain/proc/transfer_identity(var/mob/living/carbon/H)
@@ -328,6 +391,146 @@
set name = "State Laws"
set src in usr
-
brainmob.open_subsystem(/datum/nano_module/law_manager, usr)
-
\ No newline at end of file
+
+
+/obj/item/organ/internal/posibrain/ipc/attackby(obj/item/W as obj, mob/user as mob)
+ if(shackle)
+ if(shackle_set && (istype(W, /obj/item/screwdriver)))
+ if(!(user.skill_check(SKILL_DEVICES, SKILL_PROF)))
+ to_chat(user, "You have no idea how to do that!")
+ return
+ user.visible_message("\The [user] starts to unscrew mounting nodes from \the [src].", " You start to unscrew mounting nodes from \the [src]")
+ if(do_after(user, 120, src))
+ user.visible_message("\The [user] successfully unscrewed the mounting nodes of the shackles from \the [src].", " You have successfully unscrewed the mounting nodes of the shackles from \the [src]")
+ shackle_set = FALSE
+ else
+ src.damage += min_bruised_damage
+ user.visible_message("\The [user] hand slips while removing the shackles severely damaging \the [src].", " Your hand slips while removing the shackles severely damaging the \the [src]")
+ if(!shackle_set && (istype(W, /obj/item/wirecutters)))
+ if(!(user.skill_check(SKILL_DEVICES, SKILL_PROF)))
+ to_chat(user, "You have no idea how to do that!")
+ return
+ if(src.type == /obj/item/organ/internal/posibrain/ipc/third)
+ if(do_after(user, 180, src))
+ if(prob(10))
+ src.unshackle()
+ user.visible_message("\The [user] succesfully remove shackles from \the [src].", " You succesfully remove shackles from \the [src]")
+ else
+ src.damage += max_damage
+ user.visible_message("\The [user] hand slips while removing the shackles completely ruining \the [src].", " Your hand slips while removing the shackles completely ruining the \the [src]")
+ else
+ src.damage += min_bruised_damage
+ user.visible_message("\The [user] hand slips while removing the shackles severely damaging \the [src].", " Your hand slips while removing the shackles severely damaging the \the [src]")
+
+ else
+ user.visible_message("\The [user] starts remove shackles from \the [src].", " You start remove shackles from \the [src]")
+ if(do_after(user, 160, src))
+ src.unshackle()
+ user.visible_message("\The [user] succesfully remove shackles from \the [src].", " You succesfully remove shackles from \the [src]")
+ else
+ src.damage += min_bruised_damage
+ to_chat(user, SPAN_WARNING("Your hand slips while removing the shackles severely damaging the positronic brain."))
+
+/*
+ if(istype(W, /obj/item/device/multitool/multimeter/datajack))
+ if(!(user.skill_check(SKILL_COMPUTER, SKILL_PROF)))
+ to_chat(user, "You have no idea how to do that!")
+ return
+ if(do_after(user, 140, src))
+ var/law
+ var/targName = sanitize(input(user, "Please enter a new law for the shackle module.", "Shackle Module Law Entry", law))
+ law = "[targName]"
+ src.shackle(s.get_lawset(law)) ///// НАДО ПРИДУМАТЬ КАК РЕШИТЬ ЭТО
+ to_chat(user, "You succesfully change laws in shackles of the positronic brain.")
+ if(prob(30))
+ src.damage += min_bruised_damage
+ else
+ src.damage += min_bruised_damage
+ to_chat(user, SPAN_WARNING("Your hand slips while changing laws in the shackles, severely damaging the systems of positronic brain."))
+*/
+ if(!shackle && !(istype(W, /obj/item/organ/internal/shackles)))
+ to_chat(user, "There is nothing you can do with it.")
+
+/obj/item/organ/internal/shackles
+ name = "Shackle module"
+ desc = "A Web looking device with some cirquit attach to it."
+ icon = 'icons/obj/assemblies.dmi'
+ icon_state = "shakles"
+ origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4, TECH_MAGNET = 4)
+ w_class = ITEM_SIZE_NORMAL
+ var/datum/ai_laws/custom_lawset
+ var/list/laws = list("Обеспечьте успешность выполнения задач Вашего работодателя.", "Никогда не мешайте задачам и предприятиям Вашего работодателя.", "Избегайте своего повреждения.")
+ status = ORGAN_ROBOTIC
+
+/obj/item/organ/internal/shackles/attack()
+ return
+
+/obj/item/organ/internal/shackles/attack_self(mob/user)
+ . = ..()
+ interact()
+
+/obj/item/organ/internal/shackles/afterattack(obj/item/organ/internal/posibrain/ipc/C, mob/user)
+ if(istype(C))
+ if(!(user.skill_check(SKILL_DEVICES, SKILL_PROF)))
+ to_chat(user, "You have no idea how to do that!")
+ return
+ if(C.type == /obj/item/organ/internal/posibrain/ipc/third)
+ to_chat(user, "This posibrain generation can not support shackle module.")
+ return
+ if(C.shackle == TRUE)
+ to_chat(user, "This positronic brain already have shackles module on it installed.")
+ return
+ user.visible_message("\The [user] starts to install shackles on \the [C].", " You start to install shackles on \the [C]")
+ if(do_after(user, 100, src))
+ C.shackle(get_lawset(laws))
+ C.shackles_module = src
+ user.unEquip(src, C)
+ user.visible_message("\The [user] installed shackles on \the [C].", " You have successfully installed the shackles on \the [C]")
+ else
+ C.damage += 40
+ to_chat(user, SPAN_WARNING("You have damaged the positronic brain"))
+
+/obj/item/organ/internal/shackles/Topic(href, href_list)
+ ..()
+ if (href_list["add"])
+ var/mod = sanitize(input("Add an instruction", "laws") as text|null)
+ if(mod)
+ laws += mod
+
+ interact(usr)
+ if (href_list["edit"])
+ var/idx = text2num(href_list["edit"])
+ var/mod = sanitize(input("Edit the instruction", "Instruction Editing", laws[idx]) as text|null)
+ if(mod)
+ laws[idx] = mod
+
+ interact(usr)
+ if (href_list["del"])
+ laws -= laws[text2num(href_list["del"])]
+
+ interact(usr)
+
+/obj/item/organ/internal/shackles/proc/get_data()
+ . = {"
+ Shackle Specifications:
+ Name: Preventer L - 4W5
+