mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-19 11:58:39 +01:00
Shell May Cry: A comprehensive rework of synthetics. (#20721)
https://www.youtube.com/watch?v=9mPvZ96pHJI A pull request commissioned by the Synthetic Lore Team to comprehensively rework synthetics (read: IPCs) and how they work in Aurora. The objective is to make IPCs as unique as possible from humans, upgrading the robotic feel and atmosphere, while also preserving a good sense of balance in-game. Key features: - A comprehensive expansion of synthetic organs, all of which now fulfill a purpose: hydraulics, cooling units, power systems, actuators, diagnostics units. - Customizable organs with benefits and drawbacks, such as with cooling units and power systems. - Unique ways to repair the organs and more involved steps. - Unique damage mechanics - every organ has wiring and electronics which affect its functioning, and they are defended by plating which provides natural armour. - Improved and immersive diagnostics. - Unique features, benefits, and drawbacks for every IPC frame. - A rework of the positronic brain, which can be either destroyed or shut down, alongside effects caused by low integrity. - A rework of how EMPs affect IPC organs. - Non-binary damage states for each organ. To-do: - [x] Finish the unique features for each frame. - [x] Look into if mechanical synthskin is possible. - [x] Power system. - [x] Posibrain mechanics. - [ ] Passive cooling expansion. - [x] EMP mechanics. - [x] Repair mechanics. - [x] Mob weight mechanics. - [ ] Gurney for heavy mobs. - [x] New augments. - [ ] IPC tag scanning and flashing. --------- Signed-off-by: Werner <1331699+Arrow768@users.noreply.github.com> Co-authored-by: Matt Atlas <liermattia@gmail.com> Co-authored-by: Geeves <22774890+Geevies@users.noreply.github.com> Co-authored-by: Werner <1331699+Arrow768@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
/datum/tgui_module/ipc_diagnostic
|
||||
var/mob/patient
|
||||
|
||||
/datum/tgui_module/ipc_diagnostic/New(mob/user, mob/target)
|
||||
. = ..()
|
||||
patient = target
|
||||
|
||||
/datum/tgui_module/ipc_diagnostic/Destroy(force)
|
||||
patient = null
|
||||
return ..()
|
||||
|
||||
/datum/tgui_module/ipc_diagnostic/ui_interact(var/mob/user, var/datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "DiagnosticsUnit", "Diagnostics Unit", 400, 600)
|
||||
ui.open()
|
||||
|
||||
/datum/tgui_module/ipc_diagnostic/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["broken"] = FALSE
|
||||
|
||||
if(isipc(patient))
|
||||
var/mob/living/carbon/human/ipc = patient
|
||||
var/datum/species/machine/machine_species = ipc.species // need to manually set to ipc species because of machine_ui_theme
|
||||
var/obj/item/organ/internal/machine/internal_diagnostics/diagnostics = ipc.internal_organs_by_name[BP_DIAGNOSTICS_SUITE]
|
||||
if(!istype(diagnostics))
|
||||
data["broken"] = TRUE
|
||||
|
||||
data["patient_name"] = ipc.real_name
|
||||
data["broken"] = diagnostics.is_broken()
|
||||
data["integrity"] = diagnostics.get_integrity()
|
||||
data["temp"] = round(convert_k2c(ipc.bodytemperature))
|
||||
data["machine_ui_theme"] = machine_species.machine_ui_theme
|
||||
|
||||
data["organs"] = list()
|
||||
for(var/obj/item/organ/internal/organ in ipc.internal_organs)
|
||||
var/list/organ_data = list()
|
||||
|
||||
// this check is here first so we can avoid useless calculations in case the organ isn't visible from the diag suite
|
||||
if(istype(organ, /obj/item/organ/internal/machine))
|
||||
var/obj/item/organ/internal/machine/machine_organ = organ
|
||||
if(!machine_organ.diagnostics_suite_visible)
|
||||
continue
|
||||
|
||||
organ_data["wiring_status"] = edit_organ_status(machine_organ.wiring.get_status(), diagnostics)
|
||||
organ_data["plating_status"] = edit_organ_status(machine_organ.plating.get_status(), diagnostics)
|
||||
organ_data["electronics_status"] = edit_organ_status(machine_organ.electronics.get_status(), diagnostics)
|
||||
organ_data["diagnostics_info"] = machine_organ.get_diagnostics_info()
|
||||
|
||||
organ_data["name"] = organ.name
|
||||
organ_data["desc"] = organ.desc
|
||||
organ_data["damage"] = edit_organ_status(organ.damage, diagnostics)
|
||||
organ_data["max_damage"] = organ.max_damage
|
||||
|
||||
data["organs"] += list(organ_data)
|
||||
|
||||
data["robolimb_self_repair_cap"] = ROBOLIMB_SELF_REPAIR_CAP
|
||||
data["limbs"] = list()
|
||||
for(var/obj/item/organ/external/limb in ipc.organs)
|
||||
if(limb.brute_dam || limb.burn_dam)
|
||||
data["limbs"] += list(list("name" = limb.name, "brute_damage" = edit_organ_status(limb.brute_dam, diagnostics), "burn_damage" = edit_organ_status(limb.burn_dam, diagnostics), "max_damage" = limb.max_damage))
|
||||
|
||||
var/obj/item/organ/internal/machine/power_core/C = ipc.internal_organs_by_name[BP_CELL]
|
||||
if(C)
|
||||
data["charge_percent"] = C.percent()
|
||||
|
||||
var/datum/component/synthetic_endoskeleton/endoskeleton = ipc.GetComponent(/datum/component/synthetic_endoskeleton)
|
||||
if(istype(endoskeleton))
|
||||
data["endoskeleton_damage"] = endoskeleton.damage
|
||||
data["endoskeleton_max_damage"] = endoskeleton.max_damage
|
||||
|
||||
var/datum/component/armor/synthetic/synth_armor = ipc.GetComponent(/datum/component/armor/synthetic)
|
||||
if(istype(synth_armor))
|
||||
data["armor_data"] = list()
|
||||
var/list/armor_damage = synth_armor.get_visible_damage()
|
||||
for(var/key in armor_damage)
|
||||
data["armor_data"] += list(list("key" = key, "status" = armor_damage[key]))
|
||||
|
||||
return data
|
||||
|
||||
/**
|
||||
* Edits a status number based on the diagnostics unit's status.
|
||||
* The more damaged the diagnostics unit, the more errant a reading may be.
|
||||
*/
|
||||
/datum/tgui_module/ipc_diagnostic/proc/edit_organ_status(number, obj/item/organ/internal/machine/internal_diagnostics/diagnostics)
|
||||
if(!diagnostics)
|
||||
// what the hell are we doing here
|
||||
return 0
|
||||
|
||||
var/integrity = diagnostics.get_integrity()
|
||||
if(integrity > IPC_INTEGRITY_THRESHOLD_LOW)
|
||||
return number
|
||||
|
||||
var/variancy = (100 / integrity * rand(1, (100 / integrity * 10)))
|
||||
var/sign = prob(variancy) ? pick(1, -1) : 1
|
||||
var/random_number = sign * (rand(1, 100 / integrity))
|
||||
|
||||
return number + (sign * rand(1, variancy) + random_number)
|
||||
@@ -0,0 +1,88 @@
|
||||
/datum/tgui_module/neural_configuration
|
||||
var/mob/living/carbon/human/owner
|
||||
|
||||
/datum/tgui_module/neural_configuration/New(mob/user, mob/target)
|
||||
. = ..()
|
||||
if(!isipc(target))
|
||||
log_debug("Neural configuration created without IPC target!")
|
||||
qdel(src)
|
||||
owner = target
|
||||
|
||||
/datum/tgui_module/neural_configuration/Destroy(force)
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/datum/tgui_module/neural_configuration/ui_interact(var/mob/user, var/datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "NeuralConfiguration", "Neural Configuration", 400, 400)
|
||||
ui.open()
|
||||
|
||||
/datum/tgui_module/neural_configuration/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/obj/item/organ/internal/machine/posibrain/posibrain = owner.internal_organs_by_name[BP_BRAIN]
|
||||
if(istype(posibrain))
|
||||
data["neural_coherence"] = posibrain.damage
|
||||
data["max_neural_coherence"] = posibrain.max_damage
|
||||
data["owner_real_name"] = posibrain.owner.real_name
|
||||
data["firewall"] = posibrain.firewall
|
||||
data["p2p_communication"] = posibrain.p2p_communication_allowed
|
||||
|
||||
var/obj/item/organ/internal/machine/access_port/port = owner.internal_organs_by_name[BP_ACCESS_PORT]
|
||||
if(istype(port) && !port.is_broken())
|
||||
data["port"] = TRUE
|
||||
if(port.access_cable && istype(port.access_cable.target, /obj/item/organ/internal/machine/access_port))
|
||||
var/obj/item/organ/internal/machine/access_port/other_port = port.access_cable.target
|
||||
if(isipc(other_port.owner))
|
||||
var/mob/living/carbon/human/connected_ipc = other_port.owner
|
||||
data["port_connected"] = connected_ipc.real_name
|
||||
if(other_port && !other_port.is_broken())
|
||||
data["port_can_communicate"] = TRUE
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/neural_configuration/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
switch(action)
|
||||
if("toggle_firewall")
|
||||
var/obj/item/organ/internal/machine/posibrain/posibrain = owner.internal_organs_by_name[BP_BRAIN]
|
||||
if(istype(posibrain))
|
||||
posibrain.toggle_firewall()
|
||||
. = TRUE
|
||||
|
||||
if("toggle_p2p")
|
||||
var/obj/item/organ/internal/machine/posibrain/posibrain = owner.internal_organs_by_name[BP_BRAIN]
|
||||
if(istype(posibrain))
|
||||
posibrain.toggle_p2p()
|
||||
. = TRUE
|
||||
|
||||
if("talk_p2p")
|
||||
var/obj/item/organ/internal/machine/access_port/port = owner.internal_organs_by_name[BP_ACCESS_PORT]
|
||||
if(istype(port) && !port.is_broken())
|
||||
if(port.access_cable && istype(port.access_cable.target, /obj/item/organ/internal/machine/access_port))
|
||||
var/obj/item/organ/internal/machine/access_port/other_port = port.access_cable.target
|
||||
if(isipc(other_port.owner))
|
||||
var/mob/living/carbon/human/connected_ipc = other_port.owner
|
||||
if(other_port && !other_port.is_broken())
|
||||
if(connected_ipc.client)
|
||||
var/obj/item/organ/internal/machine/posibrain/other_posibrain = connected_ipc.internal_organs_by_name[BP_BRAIN]
|
||||
if(!other_posibrain.p2p_communication_allowed)
|
||||
to_chat(owner, SPAN_MACHINE_WARNING("[connected_ipc.real_name]'s Virtual Communication ports are not open."))
|
||||
return
|
||||
|
||||
var/message = sanitize_tg(tgui_input_text(owner, "Enter a peer-to-peer message to send to [connected_ipc.real_name].", "Virtual Communication", max_length = MAX_MESSAGE_LEN))
|
||||
// re-do all the checks just in case. bit ass but oh well
|
||||
if(message && !port.is_broken() && (port.access_cable.target && port.access_cable.target == connected_ipc && !other_port.is_broken()))
|
||||
var/p2p_message = SPAN_ITALIC("Virtual Communication, ") + SPAN_BOLD("[owner.real_name] transmits: ") + SPAN_MACHINE_WARNING(message)
|
||||
to_chat(connected_ipc, p2p_message)
|
||||
log_say("VIRTUAL COMMUNICATION: [owner]/[owner.client.ckey] to [connected_ipc]/[connected_ipc.client.ckey]: [message]")
|
||||
. = TRUE
|
||||
else
|
||||
to_chat(owner, SPAN_WARNING("That posibrain seems to be in deep sleep."))
|
||||
. = FALSE
|
||||
else
|
||||
to_chat(owner, SPAN_WARNING("The other port isn't responding at all!"))
|
||||
. = FALSE
|
||||
|
||||
if(.)
|
||||
sound_to(owner, 'sound/effects/neural_config.ogg')
|
||||
@@ -64,3 +64,14 @@ GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new)
|
||||
if(ismech(src_object))
|
||||
return UI_INTERACTIVE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/default_can_use_topic(src_object)
|
||||
. = ..()
|
||||
|
||||
var/obj/item/organ/internal/machine/wireless_access/access_point = internal_organs_by_name[BP_WIRELESS_ACCESS]
|
||||
if(istype(access_point))
|
||||
// Just like robots, these IPCs can interact with anything they can see.
|
||||
var/list/clientviewlist = getviewsize(client.view)
|
||||
if(get_dist(src, src_object) <= min(clientviewlist[1], clientviewlist[2]))
|
||||
return UI_INTERACTIVE
|
||||
return UI_DISABLED // Otherwise they can keep the UI open.
|
||||
|
||||
Reference in New Issue
Block a user