mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
[MODULAR] Moves Synth Code to it's Own Module, Code Quality Pass, Minor EMP Nerf (#18193)
* Fucking synth code * Fucking surgery code * Fucking organs * Fucking organs pt. 2 * Me being dumb part 1, cause I forgot I was testing stuff with this * Stupid readmes. * Stupid APC code * Me being stupid part 2: Electric Boogaloo * Fucking changes * Fucking synth code * FUCK * Fucking commas * UNDEFINE, NERD * Fucking defines * Don't forget reagents. * Blood overlay restore, and revert a change I made without realizing the indirect consequences. * HOW
This commit is contained in:
@@ -6,3 +6,6 @@
|
||||
|
||||
#define DEFAULT_SYNTH_PART_COLOR "#746c6a"
|
||||
#define DEFAULT_SYNTH_SCREEN_COLOR "#b99b3a"
|
||||
|
||||
#define SYNTH_ORGAN_LIGHT_EMP_DAMAGE 20
|
||||
#define SYNTH_ORGAN_HEAVY_EMP_DAMAGE 30
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/obj/item/bodypart/arm/left/robot/l_arm
|
||||
organic_render = FALSE
|
||||
|
||||
/obj/item/bodypart/arm/right/robot/r_arm
|
||||
organic_render = FALSE
|
||||
|
||||
/obj/item/bodypart/leg/left/robot/l_leg
|
||||
organic_render = FALSE
|
||||
|
||||
/obj/item/bodypart/leg/right/robot/r_leg
|
||||
organic_render = FALSE
|
||||
|
||||
/obj/item/bodypart/chest/robot/chest
|
||||
organic_render = FALSE
|
||||
|
||||
/obj/item/bodypart/head/robot/head
|
||||
organic_render = FALSE
|
||||
@@ -1,239 +0,0 @@
|
||||
#define SYNTH_EMP_BRAIN_DAMAGE_HEAVY 36
|
||||
#define SYNTH_EMP_BRAIN_DAMAGE_LIGHT 12
|
||||
#define SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM 75
|
||||
|
||||
/obj/item/organ/internal/brain/synth
|
||||
name = "positronic brain carcass"
|
||||
slot = ORGAN_SLOT_BRAIN
|
||||
zone = BODY_ZONE_CHEST
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves. It has an IPC serial number engraved on the top. It is usually slotted into the chest of synthetic crewmembers."
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "posibrain-ipc"
|
||||
|
||||
/obj/item/organ/internal/brain/synth/Insert(mob/living/carbon/user, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE)
|
||||
..()
|
||||
if(user.stat == DEAD && ishuman(user))
|
||||
var/mob/living/carbon/human/user_human = user
|
||||
if(user_human?.dna?.species && (REVIVES_BY_HEALING in user_human.dna.species.species_traits))
|
||||
if(user_human.health > 50)
|
||||
user_human.revive(FALSE)
|
||||
|
||||
/obj/item/organ/internal/brain/synth/emp_act(severity)
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, SYNTH_EMP_BRAIN_DAMAGE_HEAVY, SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM)
|
||||
to_chat(owner, span_warning("Alert: Rampant system corruption in central processing unit."))
|
||||
if(2)
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, SYNTH_EMP_BRAIN_DAMAGE_LIGHT, SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM)
|
||||
to_chat(owner, span_warning("Alert: System corruption in central processing unit."))
|
||||
|
||||
/obj/item/organ/internal/stomach/synth
|
||||
name = "synth power cell"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "stomach-ipc"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
zone = "chest"
|
||||
slot = "stomach"
|
||||
desc = "A specialised cell, for synthetic use only. Has a low-power mode. Without this, synthetics are unable to stay powered."
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/stomach/synth/emp_act(severity)
|
||||
. = ..()
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.nutrition = 50
|
||||
to_chat(owner, span_warning("Alert: Detected severe battery discharge!"))
|
||||
if(2)
|
||||
owner.nutrition = 250
|
||||
to_chat(owner, span_warning("Alert: Minor battery discharge!"))
|
||||
|
||||
/obj/item/organ/internal/ears/synth
|
||||
name = "auditory sensors"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "ears-ipc"
|
||||
desc = "A pair of microphones intended to be installed in an IPC head, that grant the ability to hear."
|
||||
zone = BODY_ZONE_HEAD
|
||||
slot = ORGAN_SLOT_EARS
|
||||
gender = PLURAL
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/ears/synth/emp_act(severity)
|
||||
. = ..()
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.set_jitter_if_lower(60 SECONDS)
|
||||
owner.set_dizzy_if_lower(60 SECONDS)
|
||||
owner.Knockdown(80)
|
||||
deaf = 30
|
||||
to_chat(owner, span_warning("Your system reports a complete lack of input from your auditory sensors."))
|
||||
if(2)
|
||||
owner.set_jitter_if_lower(30 SECONDS)
|
||||
owner.set_dizzy_if_lower(30 SECONDS)
|
||||
owner.Knockdown(40)
|
||||
to_chat(owner, span_warning("Your system reports anomalous feedback from your auditory sensors."))
|
||||
|
||||
/obj/item/organ/internal/tongue/synth
|
||||
name = "synthetic voicebox"
|
||||
desc = "A voice synthesizer that allows synths to communicate with lifeforms. Tuned to sound less agressive than robotic voiceboxes."
|
||||
status = ORGAN_ROBOTIC
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "tongue-ipc"
|
||||
say_mod = "beeps"
|
||||
modifies_speech = TRUE
|
||||
taste_sensitivity = 25 // not as good as an organic tongue
|
||||
maxHealth = 100 //RoboTongue!
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/tongue/synth/handle_speech(datum/source, list/speech_args)
|
||||
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
|
||||
|
||||
/obj/item/organ/internal/eyes/synth
|
||||
name = "optical sensors"
|
||||
icon_state = "cybernetic_eyeballs"
|
||||
desc = "A very basic set of optical sensors with no extra vision modes or functions."
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/eyes/synth/emp_act(severity)
|
||||
. = ..()
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
to_chat(owner, span_warning("Electromagnetic interference clouds your optics with static."))
|
||||
owner.flash_act(visual = 1)
|
||||
if(severity == EMP_HEAVY)
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_EYES, 20)
|
||||
|
||||
/obj/item/organ/internal/lungs/synth
|
||||
name = "heat sink"
|
||||
desc = "A device that transfers generated heat to a fluid medium to cool it down. Required to keep your synthetics cool-headed. It's shape resembles lungs." //Purposefully left the 'fluid medium' ambigious for interpretation of the character, whether it be air or fluid cooling
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "lungs-ipc"
|
||||
safe_nitro_min = 0
|
||||
safe_nitro_max = 0
|
||||
safe_co2_min = 0
|
||||
safe_co2_max = 0
|
||||
safe_plasma_min = 0
|
||||
safe_plasma_max = 0
|
||||
safe_oxygen_min = 0 //What are you doing man, dont breathe with those!
|
||||
safe_oxygen_max = 0
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/lungs/synth/emp_act(severity)
|
||||
. = ..()
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
switch(severity)
|
||||
if(1)
|
||||
to_chat(owner, span_warning("Alert: Critical cooling system failure!"))
|
||||
owner.adjust_bodytemperature(100*TEMPERATURE_DAMAGE_COEFFICIENT)
|
||||
if(2)
|
||||
owner.adjust_bodytemperature(30*TEMPERATURE_DAMAGE_COEFFICIENT)
|
||||
|
||||
/obj/item/organ/internal/heart/synth
|
||||
name = "hydraulic pump engine"
|
||||
desc = "An electronic device that handles the hydraulic pumps, powering one's robotic limbs. Without this, synthetics are unable to move."
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
status = ORGAN_ROBOTIC
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "heart-ipc"
|
||||
|
||||
/obj/item/organ/internal/liver/synth
|
||||
name = "reagent processing unit"
|
||||
desc = "An electronic device that processes the beneficial chemicals for the synthetic user."
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
status = ORGAN_ROBOTIC
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "liver-ipc"
|
||||
filterToxins = FALSE //We dont filter them, we're immune to them
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/power_cord
|
||||
name = "power cord implant"
|
||||
desc = "An internal power cord. Useful if you run on elecricity. Not so much otherwise."
|
||||
contents = newlist(/obj/item/apc_powercord)
|
||||
zone = "l_arm"
|
||||
|
||||
/obj/item/apc_powercord
|
||||
name = "power cord"
|
||||
desc = "An internal power cord. Useful if you run on electricity. Not so much otherwise."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "wire1"
|
||||
|
||||
/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
|
||||
return ..()
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/machinery/power/apc/target_apc = target
|
||||
var/mob/living/carbon/human/ipc = user
|
||||
var/obj/item/organ/internal/stomach/synth/cell = locate(/obj/item/organ/internal/stomach/synth) in ipc.internal_organs
|
||||
if(!cell)
|
||||
to_chat(ipc, span_warning("You try to siphon energy from the [target_apc], but your power cell is gone! How are you still standing?"))
|
||||
return
|
||||
|
||||
if(target_apc.cell && target_apc.cell.charge > 0)
|
||||
if(ipc.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(user, span_warning("You are already fully charged!"))
|
||||
return
|
||||
else
|
||||
powerdraw_loop(target_apc, ipc)
|
||||
return
|
||||
|
||||
to_chat(user, span_warning("There is no charge to draw from that APC."))
|
||||
|
||||
#define SYNTH_CHARGE_MAX 150
|
||||
#define SYNTH_CHARGE_MIN 50
|
||||
#define SYNTH_CHARGE_PER_NUTRITION 10
|
||||
#define SYNTH_CHARGE_DELAY_PER_100 10
|
||||
|
||||
/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/target_apc, mob/living/carbon/human/user)
|
||||
user.visible_message(span_notice("[user] inserts a power connector into the [target_apc]."), span_notice("You begin to draw power from the [target_apc]."))
|
||||
|
||||
while(TRUE)
|
||||
var/power_needed = NUTRITION_LEVEL_WELL_FED - user.nutrition // How much charge do we need in total?
|
||||
// Do we even need anything?
|
||||
if(power_needed <= 0)
|
||||
to_chat(user, span_notice("You are fully charged."))
|
||||
break
|
||||
|
||||
// Is the APC almost empty?
|
||||
if(target_apc.cell.percent() < 10)
|
||||
to_chat(user, span_warning("[target_apc]'s emergency power is active."))
|
||||
break
|
||||
|
||||
// Calculate how much to draw this cycle
|
||||
var/power_use = clamp(power_needed, SYNTH_CHARGE_MIN, SYNTH_CHARGE_MAX)
|
||||
power_use = clamp(power_use, 0, target_apc.cell.charge)
|
||||
// Are we able to draw anything?
|
||||
if(power_use == 0)
|
||||
to_chat(user, span_warning("[target_apc] lacks the power to charge you."))
|
||||
break
|
||||
|
||||
// Calculate the delay.
|
||||
var/power_delay = (power_use / 100) * SYNTH_CHARGE_DELAY_PER_100
|
||||
// Attempt to run a charging cycle.
|
||||
if(!do_after(user, power_delay, target = target_apc))
|
||||
break
|
||||
|
||||
// Use the power and increase nutrition.
|
||||
target_apc.cell.use(power_use)
|
||||
user.nutrition += power_use / SYNTH_CHARGE_PER_NUTRITION
|
||||
do_sparks(1, FALSE, target_apc)
|
||||
|
||||
user.visible_message(span_notice("[user] unplugs from the [target_apc]."), span_notice("You unplug from the [target_apc]."))
|
||||
|
||||
#undef SYNTH_CHARGE_MAX
|
||||
#undef SYNTH_CHARGE_MIN
|
||||
#undef SYNTH_CHARGE_PER_NUTRITION
|
||||
#undef SYNTH_CHARGE_DELAY_PER_100
|
||||
|
||||
#undef SYNTH_EMP_BRAIN_DAMAGE_HEAVY
|
||||
#undef SYNTH_EMP_BRAIN_DAMAGE_LIGHT
|
||||
#undef SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM
|
||||
@@ -1,132 +0,0 @@
|
||||
//Almost copypaste of tend wounds, with some changes
|
||||
/datum/surgery/robot_healing
|
||||
steps = list(/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/pry_off_plating,
|
||||
/datum/surgery_step/cut_wires,
|
||||
/datum/surgery_step/robot_heal,
|
||||
/datum/surgery_step/mechanic_close)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
replaced_by = /datum/surgery
|
||||
requires_bodypart_type = BODYTYPE_ROBOTIC
|
||||
surgery_flags = SURGERY_IGNORE_CLOTHES | SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB
|
||||
var/healing_step_type
|
||||
var/antispam = FALSE
|
||||
|
||||
/datum/surgery/robot_healing/New(surgery_target, surgery_location, surgery_bodypart)
|
||||
..()
|
||||
if(healing_step_type)
|
||||
steps = list(/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/pry_off_plating,
|
||||
/datum/surgery_step/cut_wires,
|
||||
healing_step_type,
|
||||
/datum/surgery_step/mechanic_close)
|
||||
|
||||
/datum/surgery_step/robot_heal
|
||||
name = "repair body (welder/cable)"
|
||||
implements = list(TOOL_WELDER = 100, /obj/item/stack/cable_coil = 100)
|
||||
repeatable = TRUE
|
||||
time = 25
|
||||
var/healsbrute = FALSE
|
||||
var/healsburn = FALSE
|
||||
var/brutehealing = 0
|
||||
var/burnhealing = 0
|
||||
var/missinghpbonus = 0 //heals an extra point of damager per X missing damage of type (burn damage for burn healing, brute for brute). Smaller Number = More Healing!
|
||||
|
||||
/datum/surgery_step/robot_heal/tool_check(mob/user, obj/item/tool)
|
||||
if(implement_type == TOOL_WELDER && !tool.tool_use_check(user, 1))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/robot_heal/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/woundtype
|
||||
if(implement_type == TOOL_WELDER)
|
||||
healsbrute = TRUE
|
||||
healsburn = FALSE
|
||||
woundtype = "dents"
|
||||
else
|
||||
healsbrute = FALSE
|
||||
healsburn = TRUE
|
||||
woundtype = "wiring"
|
||||
|
||||
if(istype(surgery,/datum/surgery/robot_healing))
|
||||
var/datum/surgery/robot_healing/the_surgery = surgery
|
||||
if(!the_surgery.antispam)
|
||||
display_results(user, target, span_notice("You attempt to fix some of [target]'s [woundtype]."),
|
||||
span_notice("[user] attempts to fix some of [target]'s [woundtype]."),
|
||||
span_notice("[user] attempts to fix some of [target]'s [woundtype]."))
|
||||
|
||||
/datum/surgery_step/robot_heal/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
|
||||
if(..())
|
||||
while((healsbrute && target.getBruteLoss() && tool.tool_use_check(user,1)) || (healsburn && target.getFireLoss() && tool))
|
||||
if(!..())
|
||||
break
|
||||
|
||||
/datum/surgery_step/robot_heal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/umsg = "You succeed in fixing some of [target]'s damage" //no period, add initial space to "addons"
|
||||
var/tmsg = "[user] fixes some of [target]'s damage" //see above
|
||||
var/urhealedamt_brute = 0
|
||||
if(healsbrute)
|
||||
urhealedamt_brute = brutehealing
|
||||
tool.use_tool(target, user, 0, volume=50, amount=1)
|
||||
var/urhealedamt_burn = 0
|
||||
if(healsburn)
|
||||
var/obj/item/stack/cable_coil/cable = tool
|
||||
urhealedamt_burn = burnhealing
|
||||
if(!cable.amount)
|
||||
return
|
||||
cable.use(1)
|
||||
if(missinghpbonus)
|
||||
if(target.stat != DEAD)
|
||||
urhealedamt_brute += round((target.getBruteLoss()/ missinghpbonus),0.1)
|
||||
urhealedamt_burn += round((target.getFireLoss()/ missinghpbonus),0.1)
|
||||
else //less healing bonus for the dead since they're expected to have lots of damage to begin with (to make TW into defib not TOO simple)
|
||||
urhealedamt_brute += round((target.getBruteLoss()/ (missinghpbonus*5)),0.1)
|
||||
urhealedamt_burn += round((target.getFireLoss()/ (missinghpbonus*5)),0.1)
|
||||
if(!get_location_accessible(target, target_zone))
|
||||
urhealedamt_brute *= 0.55
|
||||
urhealedamt_burn *= 0.55
|
||||
umsg += " as best as you can while they have clothing on"
|
||||
tmsg += " as best as they can while [target] has clothing on"
|
||||
target.heal_bodypart_damage(urhealedamt_brute,urhealedamt_burn, 0, BODYTYPE_ROBOTIC)
|
||||
display_results(user, target, span_notice("[umsg]."),
|
||||
"[tmsg].",
|
||||
"[tmsg].")
|
||||
if(istype(surgery, /datum/surgery/robot_healing))
|
||||
var/datum/surgery/robot_healing/the_surgery = surgery
|
||||
the_surgery.antispam = TRUE
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/robot_heal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_warning("You screwed up!"),
|
||||
span_warning("[user] screws up!"),
|
||||
span_notice("[user] fixes some of [target]'s damage."), TRUE)
|
||||
var/urdamageamt_brute = 0
|
||||
if(healsbrute)
|
||||
urdamageamt_brute = brutehealing * 0.8
|
||||
var/urdamageamt_burn = 0
|
||||
if(healsburn)
|
||||
urdamageamt_burn = burnhealing * 0.8
|
||||
if(missinghpbonus)
|
||||
urdamageamt_brute += round((target.getBruteLoss()/ (missinghpbonus*2)),0.1)
|
||||
urdamageamt_burn += round((target.getFireLoss()/ (missinghpbonus*2)),0.1)
|
||||
|
||||
target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn)
|
||||
return FALSE
|
||||
|
||||
/***************************TYPES***************************/
|
||||
/datum/surgery/robot_healing/basic
|
||||
name = "Repair robotic limbs (basic)"
|
||||
healing_step_type = /datum/surgery_step/robot_heal/basic
|
||||
desc = "A surgical procedure that provides repairs and maintenance to robotic limbs. Is slightly more efficient when the patient is severely damaged."
|
||||
replaced_by = null
|
||||
|
||||
/***************************STEPS***************************/
|
||||
|
||||
/datum/surgery_step/robot_heal/basic
|
||||
name = "repair damage"
|
||||
brutehealing = 10
|
||||
burnhealing = 10
|
||||
missinghpbonus = 15
|
||||
time = 10
|
||||
@@ -0,0 +1,29 @@
|
||||
https://github.com/Skyrat-SS13/Skyrat-tg/pull/18193, plus many others, which I can't find easily.
|
||||
|
||||
## Synths
|
||||
|
||||
Module ID: SYNTHS
|
||||
|
||||
### Description:
|
||||
|
||||
Adds in a roundstart robotic race. Currently in a very sad state, and is being worked on by RimiNosha at the moment.
|
||||
|
||||
### TG Proc/File Changes:
|
||||
|
||||
- Will fill out as I discover what edits were made to acommodate these.
|
||||
|
||||
### Modular Overrides:
|
||||
|
||||
- Will fill out as I discover what edits were made to acommodate these.
|
||||
|
||||
### Defines:
|
||||
|
||||
- Will fill out as I discover what defines were made to acommodate these.
|
||||
|
||||
### Included files that are not contained in this module:
|
||||
|
||||
- N/A
|
||||
|
||||
### Credits:
|
||||
Nerevar - Initial code, I think. Correct this file if wrong.
|
||||
RimiNosha - Updating the code and adding various QoL features.
|
||||
@@ -0,0 +1,69 @@
|
||||
#define SYNTH_EMP_BRAIN_DAMAGE 20
|
||||
#define SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM 75
|
||||
#define SYNTH_BRAIN_WAKE_THRESHOLD 50
|
||||
#define SYNTH_BRAIN_DAMAGE_MESSAGE_INTERVAL 20 SECONDS
|
||||
|
||||
/obj/item/organ/internal/brain/synth
|
||||
name = "compact positronic brain"
|
||||
slot = ORGAN_SLOT_BRAIN
|
||||
zone = BODY_ZONE_CHEST
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves. It has an IPC serial number engraved on the top. It is usually slotted into the chest of synthetic crewmembers."
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "posibrain-ipc"
|
||||
/// The last time (in ticks) a message about brain damage was sent. Don't touch.
|
||||
var/last_message_time = 0
|
||||
|
||||
/obj/item/organ/internal/brain/synth/Insert(mob/living/carbon/user, special = FALSE, drop_if_replaced = TRUE, no_id_transfer = FALSE)
|
||||
. = ..()
|
||||
|
||||
if(user.stat != DEAD || !ishuman(user))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/user_human = user
|
||||
if(user_human?.dna?.species && (REVIVES_BY_HEALING in user_human.dna.species.species_traits) && user_human.health > SYNTH_BRAIN_WAKE_THRESHOLD)
|
||||
user_human.revive(FALSE)
|
||||
|
||||
/obj/item/organ/internal/brain/synth/emp_act(severity)
|
||||
// This value is the protection value!
|
||||
. = ..()
|
||||
|
||||
// If EMP protected, or light EMPed, don't emp_act.
|
||||
if(. & EMP_PROTECT_SELF || severity != EMP_HEAVY)
|
||||
return
|
||||
|
||||
applyOrganDamage(SYNTH_EMP_BRAIN_DAMAGE, SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM)
|
||||
|
||||
/obj/item/organ/internal/brain/synth/applyOrganDamage(damage_amount, maximumm, required_organtype)
|
||||
. = ..()
|
||||
|
||||
if(owner && damage > 0 && (world.time - last_message_time) > SYNTH_BRAIN_DAMAGE_MESSAGE_INTERVAL)
|
||||
last_message_time = world.time
|
||||
|
||||
if(damage > BRAIN_DAMAGE_SEVERE)
|
||||
to_chat(owner, span_warning("Alert: Severe corruption in central processing unit."))
|
||||
return
|
||||
|
||||
if(damage > BRAIN_DAMAGE_MILD)
|
||||
to_chat(owner, span_warning("Alert: Minor corruption in central processing unit."))
|
||||
|
||||
/obj/item/organ/internal/brain/synth/circuit
|
||||
name = "compact AI circuit"
|
||||
desc = "A compact and extremely complex circuit, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. It is usually slotted into the chest of synthetic crewmembers."
|
||||
icon = 'modular_skyrat/master_files/icons/obj/alt_silicon_brains.dmi'
|
||||
icon_state = "circuit-occupied"
|
||||
inhand_icon_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
|
||||
|
||||
/obj/item/organ/internal/brain/synth/mmi
|
||||
name = "compact man-machine interface"
|
||||
desc = "A compact man-machine interface, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. Unfortunately, the brain seems to be permanently attached to the circuitry, and it seems relatively sensitive to it's environment. It is usually slotted into the chest of synthetic crewmembers."
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "mmi-ipc"
|
||||
|
||||
#undef SYNTH_EMP_BRAIN_DAMAGE
|
||||
#undef SYNTH_EMP_BRAIN_DAMAGE_MAXIMUM
|
||||
#undef SYNTH_BRAIN_WAKE_THRESHOLD
|
||||
#undef SYNTH_BRAIN_DAMAGE_MESSAGE_INTERVAL
|
||||
@@ -0,0 +1,40 @@
|
||||
#define SYNTH_BAD_EFFECT_DURATION 30 SECONDS
|
||||
#define SYNTH_DEAF_STACKS 30
|
||||
#define SYNTH_KNOCKDOWN_POWER 40
|
||||
#define SYNTH_HEAVY_EMP_MULTIPLIER 2
|
||||
|
||||
/obj/item/organ/internal/ears/synth
|
||||
name = "auditory sensors"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "ears-ipc"
|
||||
desc = "A pair of microphones intended to be installed in an IPC head, that grant the ability to hear."
|
||||
zone = BODY_ZONE_HEAD
|
||||
slot = ORGAN_SLOT_EARS
|
||||
gender = PLURAL
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/ears/synth/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
|
||||
switch(severity)
|
||||
if(EMP_HEAVY)
|
||||
owner.set_jitter_if_lower(SYNTH_BAD_EFFECT_DURATION * SYNTH_HEAVY_EMP_MULTIPLIER)
|
||||
owner.set_dizzy_if_lower(SYNTH_BAD_EFFECT_DURATION * SYNTH_HEAVY_EMP_MULTIPLIER)
|
||||
owner.Knockdown(SYNTH_KNOCKDOWN_POWER * SYNTH_HEAVY_EMP_MULTIPLIER)
|
||||
adjustEarDamage(SYNTH_ORGAN_HEAVY_EMP_DAMAGE, SYNTH_DEAF_STACKS)
|
||||
to_chat(owner, span_warning("Your system reports a complete lack of input from your auditory sensors."))
|
||||
|
||||
if(EMP_LIGHT)
|
||||
owner.set_jitter_if_lower(SYNTH_BAD_EFFECT_DURATION)
|
||||
owner.set_dizzy_if_lower(SYNTH_BAD_EFFECT_DURATION)
|
||||
owner.Knockdown(SYNTH_KNOCKDOWN_POWER)
|
||||
to_chat(owner, span_warning("Your system reports anomalous feedback from your auditory sensors."))
|
||||
|
||||
#undef SYNTH_BAD_EFFECT_DURATION
|
||||
#undef SYNTH_DEAF_STACKS
|
||||
#undef SYNTH_KNOCKDOWN_POWER
|
||||
#undef SYNTH_HEAVY_EMP_MULTIPLIER
|
||||
@@ -0,0 +1,21 @@
|
||||
/obj/item/organ/internal/eyes/synth
|
||||
name = "optical sensors"
|
||||
icon_state = "cybernetic_eyeballs"
|
||||
desc = "A very basic set of optical sensors with no extra vision modes or functions."
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/eyes/synth/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
|
||||
to_chat(owner, span_warning("Electromagnetic interference clouds your optics with static."))
|
||||
owner.flash_act(visual = TRUE)
|
||||
|
||||
switch(severity)
|
||||
if(EMP_LIGHT)
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_EYES, SYNTH_ORGAN_LIGHT_EMP_DAMAGE)
|
||||
if(EMP_HEAVY)
|
||||
owner.adjustOrganLoss(ORGAN_SLOT_EYES, SYNTH_ORGAN_HEAVY_EMP_DAMAGE)
|
||||
@@ -0,0 +1,7 @@
|
||||
/obj/item/organ/internal/heart/synth
|
||||
name = "hydraulic pump engine"
|
||||
desc = "An electronic device that handles the hydraulic pumps, powering one's robotic limbs. Without this, synthetics are unable to move."
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
status = ORGAN_ROBOTIC
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "heart-ipc"
|
||||
@@ -0,0 +1,8 @@
|
||||
/obj/item/organ/internal/liver/synth
|
||||
name = "reagent processing unit"
|
||||
desc = "An electronic device that processes the beneficial chemicals for the synthetic user."
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
status = ORGAN_ROBOTIC
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "liver-ipc"
|
||||
filterToxins = FALSE //We dont filter them, we're immune to them
|
||||
@@ -0,0 +1,35 @@
|
||||
#define SYNTH_LIGHT_EMP_TEMPERATURE_POWER 30
|
||||
#define SYNTH_HEAVY_EMP_TEMPERATURE_POWER 100
|
||||
|
||||
/obj/item/organ/internal/lungs/synth
|
||||
name = "heat sink"
|
||||
desc = "A device that transfers generated heat to a fluid medium to cool it down. Required to keep your synthetics cool-headed. It's shape resembles lungs." //Purposefully left the 'fluid medium' ambigious for interpretation of the character, whether it be air or fluid cooling
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "lungs-ipc"
|
||||
safe_nitro_min = 0
|
||||
safe_nitro_max = 0
|
||||
safe_co2_min = 0
|
||||
safe_co2_max = 0
|
||||
safe_plasma_min = 0
|
||||
safe_plasma_max = 0
|
||||
safe_oxygen_min = 0 //What are you doing man, dont breathe with those!
|
||||
safe_oxygen_max = 0
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/lungs/synth/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
|
||||
switch(severity)
|
||||
if(EMP_HEAVY)
|
||||
to_chat(owner, span_warning("Alert: Critical cooling system failure!"))
|
||||
owner.adjust_bodytemperature(SYNTH_HEAVY_EMP_TEMPERATURE_POWER * TEMPERATURE_DAMAGE_COEFFICIENT)
|
||||
|
||||
if(EMP_LIGHT)
|
||||
owner.adjust_bodytemperature(SYNTH_LIGHT_EMP_TEMPERATURE_POWER * TEMPERATURE_DAMAGE_COEFFICIENT)
|
||||
|
||||
#undef SYNTH_LIGHT_EMP_TEMPERATURE_POWER
|
||||
#undef SYNTH_HEAVY_EMP_TEMPERATURE_POWER
|
||||
@@ -0,0 +1,101 @@
|
||||
#define SYNTH_CHARGE_MAX 150
|
||||
#define SYNTH_CHARGE_MIN 50
|
||||
#define SYNTH_CHARGE_PER_NUTRITION 10
|
||||
#define SYNTH_CHARGE_DELAY_PER_100 10
|
||||
#define SYNTH_DRAW_NUTRITION_BUFFER 30
|
||||
#define SYNTH_APC_MINIMUM_PERCENT 20
|
||||
|
||||
/obj/item/organ/internal/cyberimp/arm/power_cord
|
||||
name = "power cord implant"
|
||||
desc = "An internal power cord. Useful if you run on elecricity. Not so much otherwise."
|
||||
contents = newlist(/obj/item/apc_powercord)
|
||||
zone = "l_arm"
|
||||
|
||||
/obj/item/apc_powercord
|
||||
name = "power cord"
|
||||
desc = "An internal power cord. Useful if you run on electricity. Not so much otherwise."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "wire1"
|
||||
|
||||
/obj/item/apc_powercord/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
if(!istype(target, /obj/machinery/power/apc) || !ishuman(user) || !proximity_flag)
|
||||
return ..()
|
||||
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/machinery/power/apc/target_apc = target
|
||||
var/mob/living/carbon/human/ipc = user
|
||||
var/obj/item/organ/internal/stomach/synth/cell = ipc.internal_organs_slot[ORGAN_SLOT_STOMACH]
|
||||
|
||||
if(!cell)
|
||||
to_chat(ipc, span_warning("You try to siphon energy from the [target_apc], but you have no stomach! How are you still standing?"))
|
||||
return
|
||||
|
||||
if(!istype(cell))
|
||||
to_chat(ipc, span_warning("You plug into the APC, but nothing happens! It seems you don't have a cell to charge!"))
|
||||
return
|
||||
|
||||
if(target_apc.cell && target_apc.cell.percent() < SYNTH_APC_MINIMUM_PERCENT)
|
||||
to_chat(user, span_warning("There is no charge to draw from that APC."))
|
||||
return
|
||||
|
||||
if(ipc.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
to_chat(user, span_warning("You are already fully charged!"))
|
||||
return
|
||||
|
||||
powerdraw_loop(target_apc, ipc)
|
||||
|
||||
/**
|
||||
* Runs a loop to charge a synth cell (stomach) via powercord from an APC.
|
||||
*
|
||||
* Stops when:
|
||||
* - The user is full.
|
||||
* - The APC has less than 20% charge.
|
||||
* - The APC has machine power turned off.
|
||||
* - The APC is unable to provide charge for any other reason.
|
||||
* - The user moves, or anything else that can happen to interrupt a do_after.
|
||||
*
|
||||
* Arguments:
|
||||
* * target_apc - The APC to drain.
|
||||
* * user - The carbon draining the APC.
|
||||
*/
|
||||
/obj/item/apc_powercord/proc/powerdraw_loop(obj/machinery/power/apc/target_apc, mob/living/carbon/human/user)
|
||||
user.visible_message(span_notice("[user] inserts a power connector into the [target_apc]."), span_notice("You begin to draw power from the [target_apc]."))
|
||||
|
||||
while(TRUE)
|
||||
var/power_needed = NUTRITION_LEVEL_WELL_FED - user.nutrition // How much charge do we need in total?
|
||||
// Do we even need anything?
|
||||
if(power_needed <= SYNTH_CHARGE_MIN * 2) // Times two to make sure minimum draw is always lower than this margin to prevent potential needless loops.
|
||||
to_chat(user, span_notice("You are fully charged."))
|
||||
break
|
||||
|
||||
// Is the APC not charging equipment? And yes, synths are gonna be treated as equipment. Deal with it.
|
||||
if(target_apc.cell.percent() < SYNTH_APC_MINIMUM_PERCENT) // 20%, to prevent synths from overstepping and murdering power for department machines and potentially doors.
|
||||
to_chat(user, span_warning("[target_apc]'s power is too low to charge you."))
|
||||
break
|
||||
|
||||
// Calculate how much to draw this cycle
|
||||
var/power_use = clamp(power_needed, SYNTH_CHARGE_MIN, SYNTH_CHARGE_MAX)
|
||||
power_use = clamp(power_use, 0, target_apc.cell.charge)
|
||||
// Are we able to draw anything?
|
||||
if(power_use <= 0)
|
||||
to_chat(user, span_warning("[target_apc] lacks the power to charge you."))
|
||||
break
|
||||
|
||||
// Calculate the delay.
|
||||
var/power_delay = (power_use / 100) * SYNTH_CHARGE_DELAY_PER_100
|
||||
// Attempt to run a charging cycle.
|
||||
if(!do_after(user, power_delay, target = target_apc))
|
||||
break
|
||||
|
||||
// Use the power and increase nutrition.
|
||||
target_apc.cell.use(power_use)
|
||||
|
||||
user.nutrition += power_use / SYNTH_CHARGE_PER_NUTRITION
|
||||
do_sparks(1, FALSE, target_apc)
|
||||
|
||||
user.visible_message(span_notice("[user] unplugs from the [target_apc]."), span_notice("You unplug from the [target_apc]."))
|
||||
|
||||
#undef SYNTH_CHARGE_MAX
|
||||
#undef SYNTH_CHARGE_MIN
|
||||
#undef SYNTH_CHARGE_PER_NUTRITION
|
||||
#undef SYNTH_CHARGE_DELAY_PER_100
|
||||
+3
-15
@@ -1,3 +1,5 @@
|
||||
// Don't know of a better place to put these. They're technically related to synths, so they're going here.
|
||||
|
||||
/obj/item/mmi/posibrain/circuit
|
||||
name = "compact AI circuit"
|
||||
desc = "A compact circuit, perfectly dimensioned to fit in the same slot as a cyborg's positronic brain."
|
||||
@@ -15,24 +17,10 @@
|
||||
new_mob_message = span_notice("The compact AI circuit chimes quietly.")
|
||||
recharge_message = span_warning("The compact AI circuit isn't ready to activate again yet! Give it some time to recharge.")
|
||||
|
||||
/obj/item/organ/internal/brain/synth/circuit
|
||||
name = "compact AI circuit"
|
||||
desc = "A compact and extremely complex circuit, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. It is usually slotted into the chest of synthetic crewmembers."
|
||||
icon = 'modular_skyrat/master_files/icons/obj/alt_silicon_brains.dmi'
|
||||
icon_state = "circuit-occupied"
|
||||
inhand_icon_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
|
||||
|
||||
/obj/item/organ/internal/brain/synth/mmi
|
||||
name = "compact man-machine interface"
|
||||
desc = "A compact man-machine interface, perfectly dimensioned to fit in the same slot as a synthetic-compatible positronic brain. Unfortunately, the brain seems to be permanently attached to the circuitry, and it seems relatively sensitive to it's environment. It is usually slotted into the chest of synthetic crewmembers."
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "mmi-ipc"
|
||||
|
||||
// CODE THAT ACTUALLY APPLIES THE BRAINS.
|
||||
// See modular_skyrat/master_files/code/modules/client/preferences/brain.dm for Synth/IPC application.
|
||||
|
||||
/// Returns a type to use based off of a given preference value (ORGAN_PREF_POSI_BRAIN, ORGAN_PREF_MMI_BRAIN and ORGAN_PREF_CIRCUIT_BRAIN), and if they're a cyborg or not.
|
||||
/mob/living/proc/prefs_get_brain_to_use(value, is_cyborg = FALSE)
|
||||
switch(value)
|
||||
if(ORGAN_PREF_POSI_BRAIN)
|
||||
@@ -0,0 +1,31 @@
|
||||
#define SYNTH_STOMACH_LIGHT_EMP_CHARGE_LOSS 50
|
||||
#define SYNTH_STOMACH_HEAVY_EMP_CHARGE_LOSS 150
|
||||
|
||||
/obj/item/organ/internal/stomach/synth
|
||||
name = "synth power cell"
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "stomach-ipc"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
zone = "chest"
|
||||
slot = "stomach"
|
||||
desc = "A specialised cell, for synthetic use only. Has a low-power mode. Without this, synthetics are unable to stay powered."
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/stomach/synth/emp_act(severity)
|
||||
. = ..()
|
||||
|
||||
if(!owner || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
|
||||
switch(severity)
|
||||
if(EMP_HEAVY)
|
||||
owner.nutrition = max(0, owner.nutrition - SYNTH_STOMACH_HEAVY_EMP_CHARGE_LOSS)
|
||||
to_chat(owner, span_warning("Alert: Severe battery discharge!"))
|
||||
|
||||
if(EMP_LIGHT)
|
||||
owner.nutrition = max(0, owner.nutrition - SYNTH_STOMACH_LIGHT_EMP_CHARGE_LOSS)
|
||||
to_chat(owner, span_warning("Alert: Minor battery discharge!"))
|
||||
|
||||
#undef SYNTH_STOMACH_LIGHT_EMP_CHARGE_LOSS
|
||||
#undef SYNTH_STOMACH_HEAVY_EMP_CHARGE_LOSS
|
||||
@@ -0,0 +1,14 @@
|
||||
/obj/item/organ/internal/tongue/synth
|
||||
name = "synthetic voicebox"
|
||||
desc = "A voice synthesizer that allows synths to communicate with lifeforms. Tuned to sound less agressive than robotic voiceboxes."
|
||||
status = ORGAN_ROBOTIC
|
||||
icon = 'modular_skyrat/master_files/icons/obj/surgery.dmi'
|
||||
icon_state = "tongue-ipc"
|
||||
say_mod = "beeps"
|
||||
modifies_speech = TRUE
|
||||
taste_sensitivity = 25 // not as good as an organic tongue
|
||||
maxHealth = 100 //RoboTongue!
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/internal/tongue/synth/handle_speech(datum/source, list/speech_args)
|
||||
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// I cannot wait to get rid of this. This is so many levels of awful wrapped into one.
|
||||
/obj/item/reagent_containers/blood/oil
|
||||
blood_type = "Oil"
|
||||
unique_blood = /datum/reagent/fuel/oil
|
||||
+8
-8
@@ -1,3 +1,6 @@
|
||||
#define NANITE_SLURRY_ORGANIC_PURGE_RATE 4
|
||||
#define NANITE_SLURRY_ORGANIC_VOMIT_CHANCE 25
|
||||
|
||||
/datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs
|
||||
process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC //Let's not cripple synth ops
|
||||
|
||||
@@ -10,9 +13,7 @@
|
||||
/datum/reagent/medicine/leporazine
|
||||
process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC
|
||||
|
||||
//REAGENTS FOR SYNTHS
|
||||
#define NANITE_SLURRY_ORGANIC_PURGE_RATE 4
|
||||
#define NANITE_SLURRY_ORGANIC_VOMIT_CHANCE 25
|
||||
// REAGENTS FOR SYNTHS
|
||||
|
||||
/datum/reagent/medicine/system_cleaner
|
||||
name = "System Cleaner"
|
||||
@@ -25,13 +26,13 @@
|
||||
|
||||
/datum/reagent/medicine/system_cleaner/on_mob_life(mob/living/carbon/affected_mob, delta_time, times_fired)
|
||||
affected_mob.adjustToxLoss(-2 * REM * delta_time, 0)
|
||||
. = 1
|
||||
var/remove_amount = 1 * REM * delta_time;
|
||||
for(var/thing in affected_mob.reagents.reagent_list)
|
||||
var/datum/reagent/reagent = thing
|
||||
if(reagent != src)
|
||||
affected_mob.reagents.remove_reagent(reagent.type, remove_amount)
|
||||
..()
|
||||
return TRUE
|
||||
|
||||
/datum/reagent/medicine/liquid_solder
|
||||
name = "Liquid Solder"
|
||||
@@ -45,7 +46,7 @@
|
||||
affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3 * REM * delta_time)
|
||||
if(prob(10))
|
||||
affected_mob.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/datum/reagent/medicine/nanite_slurry
|
||||
name = "Nanite Slurry"
|
||||
@@ -65,7 +66,7 @@
|
||||
/datum/reagent/medicine/nanite_slurry/on_mob_life(mob/living/carbon/affected_mob, delta_time)
|
||||
var/heal_amount = healing * REM * delta_time
|
||||
affected_mob.heal_bodypart_damage(heal_amount, heal_amount, required_bodytype = BODYTYPE_ROBOTIC)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/datum/reagent/medicine/nanite_slurry/overdose_process(mob/living/carbon/affected_mob, delta_time, times_fired)
|
||||
if(affected_mob.mob_biotypes & MOB_ROBOTIC)
|
||||
@@ -74,8 +75,7 @@
|
||||
affected_mob.reagents.remove_reagent(type, NANITE_SLURRY_ORGANIC_PURGE_RATE) //gets removed from organics very fast
|
||||
if(prob(NANITE_SLURRY_ORGANIC_VOMIT_CHANCE))
|
||||
affected_mob.vomit(vomit_type = VOMIT_NANITE)
|
||||
..()
|
||||
. = 1
|
||||
return TRUE
|
||||
|
||||
#undef NANITE_SLURRY_ORGANIC_PURGE_RATE
|
||||
#undef NANITE_SLURRY_ORGANIC_VOMIT_CHANCE
|
||||
+6
-6
@@ -2,7 +2,7 @@
|
||||
name = "Synthetic Humanoid"
|
||||
id = SPECIES_SYNTH
|
||||
say_mod = "beeps"
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
inherent_biotypes = MOB_ROBOTIC | MOB_HUMANOID
|
||||
inherent_traits = list(
|
||||
TRAIT_CAN_STRIP,
|
||||
TRAIT_ADVANCEDTOOLUSER,
|
||||
@@ -39,11 +39,6 @@
|
||||
)
|
||||
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT
|
||||
reagent_flags = PROCESS_SYNTHETIC
|
||||
burnmod = 1.3 // Every 0.1% is 10% above the base.
|
||||
brutemod = 1.3
|
||||
coldmod = 1.2
|
||||
heatmod = 2
|
||||
siemens_coeff = 1.4 //Not more because some shocks will outright crit you, which is very unfun
|
||||
payday_modifier = 0.75 // Matches the rest of the pay penalties the non-human crew have
|
||||
species_language_holder = /datum/language_holder/machine
|
||||
mutant_organs = list(/obj/item/organ/internal/cyberimp/arm/power_cord)
|
||||
@@ -65,6 +60,11 @@
|
||||
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/robot/synth,
|
||||
)
|
||||
digitigrade_customization = DIGITIGRADE_OPTIONAL
|
||||
burnmod = 1.3 // Every 0.1 is 10% above the base.
|
||||
brutemod = 1.3
|
||||
coldmod = 1.2
|
||||
heatmod = 2 // TWO TIMES DAMAGE FROM BEING TOO HOT?! WHAT?! No wonder lava is literal instant death for us.
|
||||
siemens_coeff = 1.4 // Not more because some shocks will outright crit you, which is very unfun
|
||||
/// The innate action that synths get, if they've got a screen selected on species being set.
|
||||
var/datum/action/innate/monitor_change/screen
|
||||
/// This is the screen that is given to the user after they get revived. On death, their screen is temporarily set to BSOD before it turns off, hence the need for this var.
|
||||
+50
-29
@@ -2,16 +2,21 @@
|
||||
/datum/surgery_step/cut_wires
|
||||
name = "cut wires"
|
||||
implements = list(
|
||||
TOOL_WIRECUTTER = 100,
|
||||
TOOL_SCALPEL = 75,
|
||||
TOOL_WIRECUTTER = 100,
|
||||
TOOL_SCALPEL = 75,
|
||||
/obj/item/knife = 50,
|
||||
/obj/item = 10) // 10% success with any sharp item.
|
||||
time = 24
|
||||
/obj/item = 10,
|
||||
) // 10% success with any sharp item.
|
||||
time = 2.4 SECONDS
|
||||
|
||||
/datum/surgery_step/cut_wires/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to cut loose wires in [target]'s [parse_zone(target_zone)]..."),
|
||||
"[user] begins to cut loose wires in [target]'s [parse_zone(target_zone)].",
|
||||
"[user] begins to cut loose wires in [target]'s [parse_zone(target_zone)].")
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to cut loose wires in [target]'s [parse_zone(target_zone)]..."),
|
||||
"[user] begins to cut loose wires in [target]'s [parse_zone(target_zone)].",
|
||||
"[user] begins to cut loose wires in [target]'s [parse_zone(target_zone)].",
|
||||
)
|
||||
|
||||
/datum/surgery_step/cut_wires/tool_check(mob/user, obj/item/tool)
|
||||
if(implement_type == /obj/item && !tool.get_sharpness())
|
||||
@@ -23,24 +28,30 @@
|
||||
name = "pry off plating"
|
||||
implements = list(
|
||||
TOOL_CROWBAR = 100,
|
||||
TOOL_HEMOSTAT = 10)
|
||||
time = 24
|
||||
TOOL_HEMOSTAT = 10,
|
||||
)
|
||||
time = 2.4 SECONDS
|
||||
|
||||
/datum/surgery_step/pry_off_plating/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
do_sparks(rand(5, 9), FALSE, target.loc)
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/pry_off_plating/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to pry off [target]'s [parse_zone(target_zone)] plating..."),
|
||||
"[user] begins to pry off [target]'s [parse_zone(target_zone)] plating.",
|
||||
"[user] begins to pry off [target]'s [parse_zone(target_zone)] plating.")
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to pry off [target]'s [parse_zone(target_zone)] plating..."),
|
||||
"[user] begins to pry off [target]'s [parse_zone(target_zone)] plating.",
|
||||
"[user] begins to pry off [target]'s [parse_zone(target_zone)] plating.",
|
||||
)
|
||||
|
||||
//weld plating
|
||||
/datum/surgery_step/weld_plating
|
||||
name = "weld plating"
|
||||
implements = list(
|
||||
TOOL_WELDER = 100)
|
||||
time = 24
|
||||
TOOL_WELDER = 100,
|
||||
)
|
||||
time = 2.4 SECONDS
|
||||
|
||||
/datum/surgery_step/weld_plating/tool_check(mob/user, obj/item/tool)
|
||||
if(implement_type == TOOL_WELDER && !tool.use_tool(user, user, 0, volume=50, amount=1))
|
||||
@@ -48,15 +59,19 @@
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/weld_plating/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to weld [target]'s [parse_zone(target_zone)] plating..."),
|
||||
"[user] begins to weld [target]'s [parse_zone(target_zone)] plating.",
|
||||
"[user] begins to weld [target]'s [parse_zone(target_zone)] plating.")
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to weld [target]'s [parse_zone(target_zone)] plating..."),
|
||||
"[user] begins to weld [target]'s [parse_zone(target_zone)] plating.",
|
||||
"[user] begins to weld [target]'s [parse_zone(target_zone)] plating.",
|
||||
)
|
||||
|
||||
//replace wires
|
||||
/datum/surgery_step/replace_wires
|
||||
name = "replace wires"
|
||||
implements = list(/obj/item/stack/cable_coil = 100)
|
||||
time = 24
|
||||
time = 2.4 SECONDS
|
||||
var/cableamount = 5
|
||||
|
||||
/datum/surgery_step/replace_wires/tool_check(mob/user, obj/item/tool)
|
||||
@@ -68,20 +83,24 @@
|
||||
|
||||
/datum/surgery_step/replace_wires/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/obj/item/stack/cable_coil/coil = tool
|
||||
if(coil && !(coil.get_amount()<cableamount)) //failproof
|
||||
if(coil && !(coil.get_amount() < cableamount)) //failproof
|
||||
coil.use(cableamount)
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/replace_wires/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to replace [target]'s [parse_zone(target_zone)] wiring..."),
|
||||
"[user] begins to replace [target]'s [parse_zone(target_zone)] wiring.",
|
||||
"[user] begins to replace [target]'s [parse_zone(target_zone)] wiring.")
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to replace [target]'s [parse_zone(target_zone)] wiring..."),
|
||||
"[user] begins to replace [target]'s [parse_zone(target_zone)] wiring.",
|
||||
"[user] begins to replace [target]'s [parse_zone(target_zone)] wiring.",
|
||||
)
|
||||
|
||||
//add plating
|
||||
/datum/surgery_step/add_plating
|
||||
name = "add plating"
|
||||
implements = list(/obj/item/stack/sheet/iron = 100)
|
||||
time = 24
|
||||
time = 2.4 SECONDS
|
||||
var/ironamount = 5
|
||||
|
||||
/datum/surgery_step/add_plating/tool_check(mob/user, obj/item/tool)
|
||||
@@ -93,11 +112,13 @@
|
||||
|
||||
/datum/surgery_step/add_plating/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/obj/item/stack/sheet/iron/plat = tool
|
||||
if(plat && !(plat.get_amount()<ironamount)) //failproof
|
||||
plat.use(ironamount)
|
||||
return TRUE
|
||||
return plat?.use(ironamount)
|
||||
|
||||
/datum/surgery_step/add_plating/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to add plating to [target]'s [parse_zone(target_zone)]..."),
|
||||
"[user] begins to add plating to [target]'s [parse_zone(target_zone)].",
|
||||
"[user] begins to add plating to [target]'s [parse_zone(target_zone)].")
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to add plating to [target]'s [parse_zone(target_zone)]..."),
|
||||
"[user] begins to add plating to [target]'s [parse_zone(target_zone)].",
|
||||
"[user] begins to add plating to [target]'s [parse_zone(target_zone)].",
|
||||
)
|
||||
+32
-16
@@ -1,12 +1,13 @@
|
||||
/datum/surgery/robot_brain_surgery
|
||||
name = "Reset Posibrain Logic (Brain Surgery)"
|
||||
steps = list(
|
||||
/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/mechanic_unwrench,
|
||||
/datum/surgery_step/pry_off_plating,
|
||||
/datum/surgery_step/prepare_electronics,
|
||||
/datum/surgery_step/fix_robot_brain,
|
||||
/datum/surgery_step/mechanic_close)
|
||||
/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/mechanic_unwrench,
|
||||
/datum/surgery_step/pry_off_plating,
|
||||
/datum/surgery_step/prepare_electronics,
|
||||
/datum/surgery_step/fix_robot_brain,
|
||||
/datum/surgery_step/mechanic_close,
|
||||
)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_HEAD)
|
||||
@@ -24,35 +25,50 @@
|
||||
time = 12 SECONDS //long and complicated
|
||||
|
||||
/datum/surgery/robot_brain_surgery/can_start(mob/user, mob/living/carbon/target, obj/item/tool)
|
||||
var/obj/item/organ/internal/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(!B)
|
||||
return FALSE
|
||||
return TRUE
|
||||
var/obj/item/organ/internal/brain/brain = target.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
return !!brain
|
||||
|
||||
/datum/surgery_step/fix_robot_brain/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to clear system corruption from [target]'s posibrain..."),
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to clear system corruption from [target]'s posibrain..."),
|
||||
"[user] begins to fix [target]'s posibrain.",
|
||||
"[user] begins to perform surgery on [target]'s posibrain.")
|
||||
"[user] begins to perform surgery on [target]'s posibrain.",
|
||||
)
|
||||
|
||||
/datum/surgery_step/fix_robot_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You succeed in clearing system corruption from [target]'s posibrain."),
|
||||
display_results(user,
|
||||
target,
|
||||
span_notice("You succeed in clearing system corruption from [target]'s posibrain."),
|
||||
"[user] successfully fixes [target]'s posibrain!",
|
||||
"[user] completes the surgery on [target]'s posibrain.")
|
||||
"[user] completes the surgery on [target]'s posibrain.",
|
||||
)
|
||||
|
||||
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
|
||||
target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
|
||||
|
||||
target.setOrganLoss(ORGAN_SLOT_BRAIN, target.getOrganLoss(ORGAN_SLOT_BRAIN) - 60) //we set damage in this case in order to clear the "failing" flag
|
||||
target.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY) //Lobotomy tier fix cause you can't clone this!
|
||||
|
||||
if(target.getOrganLoss(ORGAN_SLOT_BRAIN) > NONE)
|
||||
to_chat(user, "[target]'s posibrain still has some lasting system damage that can be cleared.")
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/surgery_step/fix_robot_brain/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(target.getorganslot(ORGAN_SLOT_BRAIN))
|
||||
display_results(user, target, span_warning("You screw up, fragmenting their data!"),
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_warning("You screw up, fragmenting their data!"),
|
||||
span_warning("[user] screws up, causing damage to the circuits!"),
|
||||
"[user] completes the surgery on [target]'s posibrain.")
|
||||
"[user] completes the surgery on [target]'s posibrain.",
|
||||
)
|
||||
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 60)
|
||||
target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
|
||||
else
|
||||
user.visible_message(span_warning("[user] suddenly notices that the posibrain [user.p_they()] [user.p_were()] working on is not there anymore."), span_warning("You suddenly notice that the posibrain you were working on is not there anymore."))
|
||||
|
||||
return FALSE
|
||||
+51
-30
@@ -1,15 +1,16 @@
|
||||
/datum/surgery/positronic_restoration
|
||||
name = "Posibrain Reboot (Revival)"
|
||||
steps = list(
|
||||
/datum/surgery_step/mechanic_unwrench,
|
||||
/datum/surgery_step/pry_off_plating/fullbody,
|
||||
/datum/surgery_step/cut_wires/fullbody,
|
||||
/datum/surgery_step/replace_wires/fullbody,
|
||||
/datum/surgery_step/prepare_electronics,
|
||||
/datum/surgery_step/add_plating/fullbody,
|
||||
/datum/surgery_step/weld_plating/fullbody,
|
||||
/datum/surgery_step/finalize_positronic_restoration,
|
||||
/datum/surgery_step/mechanic_close)
|
||||
/datum/surgery_step/mechanic_unwrench,
|
||||
/datum/surgery_step/pry_off_plating/fullbody,
|
||||
/datum/surgery_step/cut_wires/fullbody,
|
||||
/datum/surgery_step/replace_wires/fullbody,
|
||||
/datum/surgery_step/prepare_electronics,
|
||||
/datum/surgery_step/add_plating/fullbody,
|
||||
/datum/surgery_step/weld_plating/fullbody,
|
||||
/datum/surgery_step/finalize_positronic_restoration,
|
||||
/datum/surgery_step/mechanic_close,
|
||||
)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
@@ -17,53 +18,67 @@
|
||||
desc = "A surgical procedure that reboots a positronic brain."
|
||||
|
||||
/datum/surgery/robot_chassis_restoration/can_start(mob/user, mob/living/carbon/target)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(target.stat != DEAD)
|
||||
return FALSE
|
||||
if(target.suiciding)
|
||||
return FALSE
|
||||
var/obj/item/organ/internal/brain/target_brain = target.getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(!target_brain)
|
||||
if(!..() || target.stat != DEAD || target.suiciding || !target.getorganslot(ORGAN_SLOT_BRAIN))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/pry_off_plating/fullbody
|
||||
time = 12 SECONDS
|
||||
|
||||
/datum/surgery_step/pry_off_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to pry open compromised panels on [target]'s braincase..."),
|
||||
span_notice("[user] begins to pry open compromised panels on [target]'s braincase."))
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to pry open compromised panels on [target]'s braincase..."),
|
||||
span_notice("[user] begins to pry open compromised panels on [target]'s braincase."),
|
||||
)
|
||||
|
||||
/datum/surgery_step/cut_wires/fullbody
|
||||
time = 12 SECONDS
|
||||
|
||||
/datum/surgery_step/cut_wires/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to trim [target]'s nonfunctional wires..."),
|
||||
span_notice("[user] begins to cut [target]'s loose wires."))
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to trim [target]'s nonfunctional wires..."),
|
||||
span_notice("[user] begins to cut [target]'s loose wires."),
|
||||
)
|
||||
|
||||
/datum/surgery_step/weld_plating/fullbody
|
||||
time = 12 SECONDS
|
||||
|
||||
/datum/surgery_step/weld_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to slice compromised panels from [target]'s braincase..."),
|
||||
span_notice("[user] begins to slice compromised panels from [target]'s braincase."))
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to slice compromised panels from [target]'s braincase..."),
|
||||
span_notice("[user] begins to slice compromised panels from [target]'s braincase."),
|
||||
)
|
||||
|
||||
/datum/surgery_step/replace_wires/fullbody
|
||||
time = 7 SECONDS
|
||||
cableamount = 15
|
||||
|
||||
/datum/surgery_step/replace_wires/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to replace [target]'s wiring..."),
|
||||
span_notice("[user] begins to replace [target]'s wiring."))
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to replace [target]'s wiring..."),
|
||||
span_notice("[user] begins to replace [target]'s wiring."),
|
||||
)
|
||||
|
||||
/datum/surgery_step/add_plating/fullbody
|
||||
time = 12 SECONDS
|
||||
ironamount = 15
|
||||
|
||||
/datum/surgery_step/add_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to add new panels to [target]'s braincase..."),
|
||||
span_notice("[user] begins to add new panels to [target]'s braincase."))
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to add new panels to [target]'s braincase..."),
|
||||
span_notice("[user] begins to add new panels to [target]'s braincase."),
|
||||
)
|
||||
|
||||
/datum/surgery_step/finalize_positronic_restoration
|
||||
name = "finalize positronic restoration (multitool)"
|
||||
@@ -74,15 +89,21 @@
|
||||
time = 12 SECONDS
|
||||
|
||||
/datum/surgery_step/finalize_positronic_restoration/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, span_notice("You begin to force a reboot in [target]'s posibrain..."),
|
||||
span_notice("[user] begins to force a reboot in [target]'s posibrain."))
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You begin to force a reboot in [target]'s posibrain..."),
|
||||
span_notice("[user] begins to force a reboot in [target]'s posibrain."),
|
||||
)
|
||||
|
||||
target.notify_ghost_cloning("Someone is trying to reboot your posibrain.", source = target)
|
||||
|
||||
/datum/surgery_step/finalize_positronic_restoration/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
target.cure_husk()
|
||||
target.grab_ghost()
|
||||
target.updatehealth()
|
||||
target.setOrganLoss(ORGAN_SLOT_BRAIN, target.getOrganLoss(ORGAN_SLOT_BRAIN) - 200)
|
||||
target.setOrganLoss(ORGAN_SLOT_BRAIN, NONE)
|
||||
|
||||
if(target.revive())
|
||||
target.emote("chime")
|
||||
target.visible_message(span_notice("...[target] reactivates, their chassis coming online!"))
|
||||
@@ -0,0 +1,176 @@
|
||||
#define DAMAGE_ROUNDING 0.1
|
||||
#define FAIL_DAMAGE_MULTIPLIER 0.8
|
||||
#define FINAL_STEP_HEAL_MULTIPLIER 0.55
|
||||
|
||||
//Almost copypaste of tend wounds, with some changes
|
||||
/datum/surgery/robot_healing
|
||||
steps = list(
|
||||
/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/pry_off_plating,
|
||||
/datum/surgery_step/cut_wires,
|
||||
/datum/surgery_step/robot_heal,
|
||||
/datum/surgery_step/mechanic_close,
|
||||
)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
replaced_by = /datum/surgery
|
||||
requires_bodypart_type = BODYTYPE_ROBOTIC
|
||||
surgery_flags = SURGERY_IGNORE_CLOTHES | SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB
|
||||
|
||||
/// The step to use in the 4th surgery step.
|
||||
var/healing_step_type
|
||||
/// If true, doesn't send the surgery preop message. Set during surgery.
|
||||
var/surgery_preop_message_sent = FALSE
|
||||
|
||||
/datum/surgery/robot_healing/New(surgery_target, surgery_location, surgery_bodypart)
|
||||
..()
|
||||
if(healing_step_type)
|
||||
steps = list(
|
||||
/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/pry_off_plating,
|
||||
/datum/surgery_step/cut_wires,
|
||||
healing_step_type,
|
||||
/datum/surgery_step/mechanic_close,
|
||||
)
|
||||
|
||||
/datum/surgery_step/robot_heal
|
||||
name = "repair body (welder/cable)"
|
||||
implements = list(TOOL_WELDER = 100, /obj/item/stack/cable_coil = 100)
|
||||
repeatable = TRUE
|
||||
time = 25
|
||||
|
||||
/// If this surgery is healing brute damage. Set during operation steps.
|
||||
var/heals_brute = FALSE
|
||||
/// If this surgery is healing burn damage. Set during operation steps.
|
||||
var/heals_burn = FALSE
|
||||
/// How much healing the sugery gives.
|
||||
var/brute_heal_amount = 0
|
||||
/// How much healing the sugery gives.
|
||||
var/burn_heal_amount = 0
|
||||
/// Heals an extra point of damage per X missing damage of type (burn damage for burn healing, brute for brute). Smaller number = more healing!
|
||||
var/missing_health_bonus = 0
|
||||
|
||||
/datum/surgery_step/robot_heal/tool_check(mob/user, obj/item/tool)
|
||||
if(implement_type == TOOL_WELDER && !tool.tool_use_check(user, 1))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/robot_heal/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/woundtype
|
||||
if(implement_type == TOOL_WELDER)
|
||||
heals_brute = TRUE
|
||||
heals_burn = FALSE
|
||||
woundtype = "dents"
|
||||
else
|
||||
heals_brute = FALSE
|
||||
heals_burn = TRUE
|
||||
woundtype = "wiring"
|
||||
|
||||
if(!istype(surgery, /datum/surgery/robot_healing))
|
||||
return
|
||||
|
||||
var/datum/surgery/robot_healing/the_surgery = surgery
|
||||
if(the_surgery.surgery_preop_message_sent)
|
||||
return
|
||||
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_notice("You attempt to fix some of [target]'s [woundtype]."),
|
||||
span_notice("[user] attempts to fix some of [target]'s [woundtype]."),
|
||||
span_notice("[user] attempts to fix some of [target]'s [woundtype]."),
|
||||
)
|
||||
|
||||
/datum/surgery_step/robot_heal/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
|
||||
if(..())
|
||||
while((heals_brute && target.getBruteLoss() && tool.tool_use_check(user, 1)) || (heals_burn && target.getFireLoss() && tool))
|
||||
if(!..())
|
||||
break
|
||||
|
||||
/datum/surgery_step/robot_heal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/self_message = "You succeed in fixing some of [target]'s damage" //no period, add initial space to "addons"
|
||||
var/other_message = "[user] fixes some of [target]'s damage" //see above
|
||||
var/healed_brute = 0
|
||||
|
||||
if(heals_brute)
|
||||
healed_brute = brute_heal_amount
|
||||
tool.use_tool(target, user, 0, volume = 50, amount=1)
|
||||
|
||||
var/healed_burn = 0
|
||||
if(heals_burn)
|
||||
var/obj/item/stack/cable_coil/cable = tool
|
||||
healed_burn = burn_heal_amount
|
||||
if(!cable.amount)
|
||||
return
|
||||
|
||||
cable.use(1)
|
||||
|
||||
if(missing_health_bonus)
|
||||
if(target.stat != DEAD)
|
||||
healed_brute += round((target.getBruteLoss() / missing_health_bonus), DAMAGE_ROUNDING)
|
||||
healed_burn += round((target.getFireLoss() / missing_health_bonus), DAMAGE_ROUNDING)
|
||||
|
||||
else //less healing bonus for the dead since they're expected to have lots of damage to begin with (to make TW into defib not TOO simple)
|
||||
healed_brute += round((target.getBruteLoss() / (missing_health_bonus * 5)), DAMAGE_ROUNDING)
|
||||
healed_burn += round((target.getFireLoss() / (missing_health_bonus * 5)), DAMAGE_ROUNDING)
|
||||
|
||||
if(!get_location_accessible(target, target_zone))
|
||||
healed_brute *= FINAL_STEP_HEAL_MULTIPLIER
|
||||
healed_burn *= FINAL_STEP_HEAL_MULTIPLIER
|
||||
self_message += " as best as you can while they have clothing on"
|
||||
other_message += " as best as they can while [target] has clothing on"
|
||||
|
||||
target.heal_bodypart_damage(healed_brute, healed_burn, 0, BODYTYPE_ROBOTIC)
|
||||
display_results(user, target, span_notice("[self_message]."), "[other_message].", "[other_message].")
|
||||
|
||||
if(istype(surgery, /datum/surgery/robot_healing))
|
||||
var/datum/surgery/robot_healing/the_surgery = surgery
|
||||
the_surgery.surgery_preop_message_sent = TRUE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/robot_heal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(
|
||||
user,
|
||||
target,
|
||||
span_warning("You screwed up!"),
|
||||
span_warning("[user] screws up!"),
|
||||
span_notice("[user] fixes some of [target]'s damage."),
|
||||
TRUE,
|
||||
)
|
||||
|
||||
var/brute_damage = 0
|
||||
if(heals_brute)
|
||||
brute_damage = brute_heal_amount * FAIL_DAMAGE_MULTIPLIER
|
||||
|
||||
var/burn_damage = 0
|
||||
if(heals_burn)
|
||||
burn_damage = burn_heal_amount * FAIL_DAMAGE_MULTIPLIER
|
||||
|
||||
if(missing_health_bonus)
|
||||
brute_damage += round((target.getBruteLoss() / (missing_health_bonus * 2)), DAMAGE_ROUNDING)
|
||||
burn_damage += round((target.getFireLoss() / (missing_health_bonus * 2)), DAMAGE_ROUNDING)
|
||||
|
||||
target.take_bodypart_damage(brute_damage, burn_damage)
|
||||
return FALSE
|
||||
|
||||
/***************************TYPES***************************/
|
||||
/datum/surgery/robot_healing/basic
|
||||
name = "Repair robotic limbs (basic)"
|
||||
healing_step_type = /datum/surgery_step/robot_heal/basic
|
||||
desc = "A surgical procedure that provides repairs and maintenance to robotic limbs. Is slightly more efficient when the patient is severely damaged."
|
||||
replaced_by = null
|
||||
|
||||
/***************************STEPS***************************/
|
||||
|
||||
/datum/surgery_step/robot_heal/basic
|
||||
name = "repair damage"
|
||||
brute_heal_amount = 10
|
||||
burn_heal_amount = 10
|
||||
missing_health_bonus = 15
|
||||
time = 10
|
||||
|
||||
#undef DAMAGE_ROUNDING
|
||||
#undef FAIL_DAMAGE_MULTIPLIER
|
||||
#undef FINAL_STEP_HEAL_MULTIPLIER
|
||||
+22
-15
@@ -5129,7 +5129,6 @@
|
||||
#include "modular_skyrat\master_files\code\game\objects\items\stacks\sheets\sheet_types.dm"
|
||||
#include "modular_skyrat\master_files\code\game\objects\items\storage\backpack.dm"
|
||||
#include "modular_skyrat\master_files\code\game\objects\items\storage\boxes.dm"
|
||||
#include "modular_skyrat\master_files\code\game\objects\items\storage\pill_bottles.dm"
|
||||
#include "modular_skyrat\master_files\code\game\objects\items\tools\weldingtool.dm"
|
||||
#include "modular_skyrat\master_files\code\game\objects\structures\railings.dm"
|
||||
#include "modular_skyrat\master_files\code\game\objects\structures\sauna_oven.dm"
|
||||
@@ -5258,9 +5257,7 @@
|
||||
#include "modular_skyrat\master_files\code\modules\projectiles\guns\gun.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\projectiles\guns\ballistic\automatic.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\projectiles\guns\ballistic\revolver.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\reagents\blood_pack.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\reagents\bottle.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\reagents\pill.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\reagents\chemistry\colors.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\reagents\withdrawal\generic_addictions.dm"
|
||||
#include "modular_skyrat\master_files\code\modules\research\designs\biogenerator_designs.dm"
|
||||
@@ -5521,7 +5518,6 @@
|
||||
#include "modular_skyrat\modules\bodyparts\code\teshari_bodyparts.dm"
|
||||
#include "modular_skyrat\modules\bodyparts\code\vox_bodyparts.dm"
|
||||
#include "modular_skyrat\modules\bodyparts\code\xenohybrid_bodyparts.dm"
|
||||
#include "modular_skyrat\modules\bodyparts\code\robotic\_mutant_robotic_bodyparts.dm"
|
||||
#include "modular_skyrat\modules\bongs\code\bong.dm"
|
||||
#include "modular_skyrat\modules\borg_buffs\code\robot.dm"
|
||||
#include "modular_skyrat\modules\borg_buffs\code\snack_dispensor.dm"
|
||||
@@ -5801,33 +5797,22 @@
|
||||
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\vox.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\vulpkanin.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\xeno.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\robotic\prefsmenu.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\robotic\screen.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\mob\living\carbon\human\species\robotic\synthetic.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\mob\living\simple_mob\examine.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\alcohol_reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\drink_reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\drinks.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\food_reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\medicine_reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\other_reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\pyrotechnic_reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\reagents\toxin_reagents.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\reagents\chemistry\recipes\medicine.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\mechanic_steps.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\robot_brain_surgery.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\robot_chassis_restoration.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\robot_healing.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\bodyparts\_bodyparts.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\bodyparts\robot_bodyparts.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\bodyparts\robot_parts.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\ears.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\eyes.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\genitals.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\organ.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\silicon_alt_brains.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\synth.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\tails.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\vox.dm"
|
||||
#include "modular_skyrat\modules\customization\modules\surgery\organs\wings.dm"
|
||||
@@ -6499,6 +6484,28 @@
|
||||
#include "modular_skyrat\modules\supermatter_surge\code\supermatter_surge.dm"
|
||||
#include "modular_skyrat\modules\Syndie_edits\code\area.dm"
|
||||
#include "modular_skyrat\modules\Syndie_edits\code\syndie_edits.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\brain.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\ears.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\eyes.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\heart.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\limbs.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\liver.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\lungs.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\power_cord.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\silicon_alt_brains.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\stomach.dm"
|
||||
#include "modular_skyrat\modules\synths\code\bodyparts\tongue.dm"
|
||||
#include "modular_skyrat\modules\synths\code\reagents\blood_pack.dm"
|
||||
#include "modular_skyrat\modules\synths\code\reagents\pill.dm"
|
||||
#include "modular_skyrat\modules\synths\code\reagents\pill_bottles.dm"
|
||||
#include "modular_skyrat\modules\synths\code\reagents\reagents.dm"
|
||||
#include "modular_skyrat\modules\synths\code\species\prefsmenu.dm"
|
||||
#include "modular_skyrat\modules\synths\code\species\screen.dm"
|
||||
#include "modular_skyrat\modules\synths\code\species\synthetic.dm"
|
||||
#include "modular_skyrat\modules\synths\code\surgery\mechanic_steps.dm"
|
||||
#include "modular_skyrat\modules\synths\code\surgery\robot_brain_surgery.dm"
|
||||
#include "modular_skyrat\modules\synths\code\surgery\robot_chassis_restoration.dm"
|
||||
#include "modular_skyrat\modules\synths\code\surgery\robot_healing.dm"
|
||||
#include "modular_skyrat\modules\tableflip\code\flipped_table.dm"
|
||||
#include "modular_skyrat\modules\tagline\code\world.dm"
|
||||
#include "modular_skyrat\modules\teshari\code\_clothing_defines.dm"
|
||||
|
||||
Reference in New Issue
Block a user