diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 7f360633..d5f1a77a 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -162,11 +162,14 @@ Implants;
if(M.client)
clients++
if(ishuman(M))
+ var/mob/living/carbon/human/H = M
if(!M.stat)
surviving_humans++
if(M.loc && M.loc.loc && M.loc.loc.type in escape_locations)
escaped_humans++
- var/mob/living/carbon/human/H = M
+ if (istype(H.species, /datum/species/machine))
+ var/datum/species/machine/machine = H.species
+ machine.update_tag(H, H.client)
if (H.species)
switch (H.species.name)
if ("Human")
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 8058315d..0db5f5e0 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -61,6 +61,9 @@
msg += "[src.name]!\n"
+ if (species && species.has_organ["ipc tag"] && internal_organs_by_name["ipc tag"])
+ msg += "[t_He] [t_is] wearing a tag designating them as an Integrated Positronic Chassis/Shell.\n"
+
//uniform
if(w_uniform && !skipjumpsuit)
//Ties
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index cb8ab473..e122d35a 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -610,6 +610,7 @@ See code\modules\mob\new_player\preferences_setup.dm for where it's used.
"radiator" = /datum/organ/internal/machine/radiator,
"chemical containment" = /datum/organ/internal/machine/bladder,
"diagnosis unit" = /datum/organ/internal/machine/diagnosis_unit,
+ "ipc tag" = /datum/organ/internal/machine/ipc_tag
)
/datum/species/machine/create_organs(var/mob/living/carbon/human/H)
..()
@@ -618,6 +619,54 @@ See code\modules\mob\new_player\preferences_setup.dm for where it's used.
if (isnull(brain_datum.machine_brain_type))
brain_datum.machine_brain_type="Posibrain"
+/datum/species/machine/proc/check_tag(var/mob/living/carbon/human/new_machine, var/client/player)
+ if (!new_machine || !player)
+ return
+
+ establish_db_connection()
+
+ if (dbcon.IsConnected())
+ var/datum/organ/internal/machine/ipc_tag/tag = new_machine.internal_organs_by_name["ipc tag"]
+
+ var/status = 0
+ var/list/query_details = list(":ckey" = player.ckey, ":character_name" = player.prefs.real_name)
+ var/DBQuery/query = dbcon.NewQuery("SELECT tag_status FROM ss13_ipc_tracking WHERE player_ckey = :ckey AND character_name = :character_name")
+ query.Execute(query_details)
+
+ if (query.NextRow())
+ status = text2num(query.item[1])
+ else
+ var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO ss13_ipc_tracking (player_ckey, character_name) VALUES (:ckey, :character_name)")
+ log_query.Execute(query_details)
+
+ if (!status)
+ new_machine.internal_organs_by_name.Remove("ipc tag")
+ new_machine.internal_organs.Remove(tag)
+ del(tag)
+
+/datum/species/machine/proc/update_tag(var/mob/living/carbon/human/target, var/client/player)
+ if (!target || !player)
+ return
+
+ establish_db_connection()
+
+ if (dbcon.IsConnected())
+ var/status = 0
+ var/sql_status = 0
+ if (target.internal_organs_by_name["ipc tag"])
+ status = 1
+
+ var/list/query_details = list(":ckey" = player.ckey, ":character_name" = target.real_name)
+ var/DBQuery/query = dbcon.NewQuery("SELECT tag_status FROM ss13_ipc_tracking WHERE player_ckey = :ckey AND character_name = :character_name")
+ query.Execute(query_details)
+
+ if (query.NextRow())
+ sql_status = text2num(query.item[1])
+ if (sql_status == status)
+ return
+
+ var/DBQuery/update_query = dbcon.NewQuery("UPDATE ss13_ipc_tracking SET tag_status = :status WHERE player_ckey = :ckey AND character_name = :character_name")
+ update_query.Execute(query_details)
/datum/species/bug
name = "Vaurca"
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index 8f836208..24579278 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -206,6 +206,12 @@
icon_state_broken = "bladder_broken"
organ_type = new /obj/item/organ/machine/bladder()
+/obj/item/robot_parts/robot_component/ipc_tag
+ name = "IPC tag"
+ icon_state = "tag"
+ icon_state_broken = "tag_broken"
+ organ_type = new /obj/item/organ/machine/ipc_tag()
+
//
//Robotic Component Analyser, basically a health analyser for robots
//
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 5032ffae..cb6e60e9 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -404,6 +404,10 @@
if(is_species_whitelisted(chosen_species) || has_admin_rights())
new_character = new(loc, client.prefs.species)
+ if (istype(chosen_species, /datum/species/machine))
+ var/datum/species/machine/chose_machine = chosen_species
+ chose_machine.check_tag(new_character, client)
+
if(!new_character)
new_character = new(loc)
diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/organ_alien.dm
index 39f63f81..956a13a8 100644
--- a/code/modules/organs/organ_alien.dm
+++ b/code/modules/organs/organ_alien.dm
@@ -228,36 +228,53 @@
/datum/organ/internal/machine
removed_type = /obj/item/organ/machine
+ robotic = 2
/datum/organ/internal/machine/process()
return
+/obj/item/organ/machine
+ robotic = 2
+
/datum/organ/internal/machine/radiator
name = "internal cooling unit"
parent_organ = "chest"
- robotic = 2
min_bruised_damage = 15
min_broken_damage = 40
removed_type = /obj/item/organ/machine/radiator
+ var/seized = 0
+
+/datum/organ/internal/machine/radiator/process()
+ if (seized && owner.internal_organs_by_name["diagnosis_unit"])
+ var/datum/organ/internal/machine/diagnosis_unit/diagnosis_unit = owner.internal_organs_by_name["diagnosis_unit"]
+ seized = diagnosis_unit.overload
+
+/datum/organ/internal/machine/radiator/is_broken()
+ if (seized)
+ return 1
+
+ ..()
/obj/item/organ/machine/radiator
name = "internal cooling unit"
icon_state = "radiator"
organ_tag = "radiator"
organ_type = /datum/organ/internal/machine/radiator
- robotic = 2
/obj/item/organ/machine/radiator/exposed_to_the_world()
var/obj/item/robot_parts/robot_component/radiator/Radiator = new(src.loc)
if(organ_data.damage)
Radiator.brute = organ_data.damage
+ if (organ_data)
+ var/datum/organ/internal/machine/radiator/old_radiator = organ_data
+ if (old_radiator.seized)
+ Radiator.desc += " It looks seized."
del(src)
return Radiator
/datum/organ/internal/machine/bladder
name = "chemical containment"
parent_organ = "groin"
- robotic = 2
removed_type = /obj/item/organ/machine/bladder
/datum/organ/internal/machine/bladder/process()
@@ -290,7 +307,6 @@
icon_state = "bladder"
organ_tag = "chemical containment"
organ_type = /datum/organ/internal/machine/bladder
- robotic = 2
/obj/item/organ/machine/bladder/replaced(var/mob/living/carbon/human/target)
if(istype(target) && (target.species.flags & IS_SYNTHETIC))
@@ -318,15 +334,25 @@
/datum/organ/internal/machine/diagnosis_unit
name = "diagnosis unit"
parent_organ = "head"
- robotic = 2
removed_type = /obj/item/organ/machine/diagnosis_unit
+ var/overload = 0
+
+/datum/organ/internal/machine/diagnosis_unit/process()
+ if (!overload)
+ return
+
+ if (owner.internal_organs_by_name["radiator"])
+ var/datum/organ/internal/machine/radiator/radiator = owner.internal_organs_by_name["radiator"]
+ radiator.seized = 1
+
+ var/list/pain_messages = list("ERROR: damage detected!", "System failure detected!", "Runtime errors present! System failure imminent!", "Software integrity compromised!", "Hardware malfunction detected!")
+ owner.custom_pain(pick(pain_messages), 1, 1)
/obj/item/organ/machine/diagnosis_unit
name = "diagnosis unit"
icon_state = "diagnosis_unit"
organ_tag = "diagnosis unit"
organ_type = /datum/organ/internal/machine/diagnosis_unit
- robotic = 2
/obj/item/organ/machine/diagnosis_unit/exposed_to_the_world()
var/obj/item/robot_parts/robot_component/diagnosis_unit/Diagnosis_unit = new(src.loc)
@@ -348,6 +374,30 @@
del(src)
return Eyes
+/datum/organ/internal/machine/ipc_tag
+ name = "IPC tag"
+ parent_organ = "head"
+ removed_type = /obj/item/organ/machine/ipc_tag
+
+/obj/item/organ/machine/ipc_tag
+ name = "IPC tag"
+ organ_tag = "ipc_tag"
+ organ_type = /datum/organ/internal/machine/ipc_tag
+
+/obj/item/organ/machine/ipc_tag/removed(var/mob/living/carbon/human/target, var/mob/living/user)
+ ..()
+
+ if (istype(target) && target.internal_organs_by_name["diagnosis_unit"])
+ var/datum/organ/internal/machine/diagnosis_unit/diagnosis_unit = target.internal_organs_by_name["diagnosis_unit"]
+ diagnosis_unit.overload = 1
+
+/obj/item/organ/machine/ipc_tag/exposed_to_the_world()
+ var/obj/item/robot_parts/robot_component/ipc_tag/tag = new(src.loc)
+ if (organ_data.damage)
+ tag.brute = organ_data.damage
+ del(src)
+ return tag
+
/obj/item/organ/vaurca/neuralsocket
name = "neural socket"
organ_tag = "neural socket"
@@ -371,5 +421,6 @@
organ_tag = "tracheae"
icon = 'icons/mob/alien_organs.dmi'
icon_state = "tracheae"
+
/obj/item/organ/vaurca/tracheae/removed()
return
diff --git a/code/modules/organs/pain.dm b/code/modules/organs/pain.dm
index 49cc2073..e6ae1eb0 100644
--- a/code/modules/organs/pain.dm
+++ b/code/modules/organs/pain.dm
@@ -53,10 +53,10 @@ mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0
// message is the custom message to be displayed
// flash_strength is 0 for weak pain flash, 1 for strong pain flash
-mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength)
+mob/living/carbon/human/proc/custom_pain(var/message, var/flash_strength, var/override_no_pain = 0)
if(stat >= 1) return
- if(species && species.flags & NO_PAIN) return
+ if(species && species.flags & NO_PAIN && !override_no_pain) return
if(reagents.has_reagent("tramadol"))
return
@@ -127,4 +127,4 @@ mob/living/carbon/human/proc/handle_pain()
toxDamageMessage = "Your body aches all over, it's driving you mad."
if(toxDamageMessage && prob(toxMessageProb))
- src.custom_pain(toxDamageMessage, getToxLoss() >= 15)
\ No newline at end of file
+ src.custom_pain(toxDamageMessage, getToxLoss() >= 15)