From e771c6230acb6280194d637125e6efd908479d25 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 18 Jan 2024 15:46:01 -0500
Subject: [PATCH 001/113] jesus christ forgive me for this shitcode
---
code/_onclick/item_attack.dm | 17 ++-
.../living/carbon/xenomorph/XenoAttacks.dm | 4 +-
.../mob/living/carbon/xenomorph/Xenomorph.dm | 5 +
code/modules/surgery/surgery_initiator.dm | 57 ++++++--
code/modules/surgery/surgery_procedure.dm | 11 +-
code/modules/surgery/xeno.dm | 129 ++++++++++++++++++
colonialmarines.dme | 1 +
7 files changed, 206 insertions(+), 18 deletions(-)
create mode 100644 code/modules/surgery/xeno.dm
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index c6052da33199..41829bd8d648 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -66,10 +66,25 @@
if(!(user in viewers(M, null)))
showname = "."
+ if(isxeno(M) && M.stat == DEAD)
+ var/datum/surgery/current_surgery = M.active_surgeries[user.zone_selected]
+ if(current_surgery)
+ to_chat(user, "we are here000000")
+ if(current_surgery.attempt_next_step(user, src))
+ to_chat(user, "we are here 2oh")
+ return FALSE //Cancel attack.
+ to_chat(user, "we are here 2uh")
+ else
+ to_chat(user, "we are here 2")
+ if(initiate_surgery_moment(src, M, "head" , user))
+ to_chat(user, "got true")
+ return FALSE
+ to_chat(user, "got false")
+
if (user.a_intent == INTENT_HELP && ((user.client?.prefs && user.client?.prefs?.toggle_prefs & TOGGLE_HELP_INTENT_SAFETY) || (user.mob_flags & SURGERY_MODE_ON)))
playsound(loc, 'sound/effects/pop.ogg', 25, 1)
user.visible_message(SPAN_NOTICE("[M] has been poked with [src][showname]"),\
- SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src]."), null, 4)
+ SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src].LORD"), null, 4)
return FALSE
diff --git a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
index 6361ff595b10..911c4af56309 100644
--- a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
+++ b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
@@ -49,10 +49,10 @@
backpack.open(M)
return
if(stat == DEAD)
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens."), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens.DED"), \
SPAN_WARNING("You poke \the [src], but nothing happens."), null, 5, CHAT_TYPE_FLUFF_ACTION)
else
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src]."), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src].WA"), \
SPAN_WARNING("You poke \the [src]."), null, 5, CHAT_TYPE_FLUFF_ACTION)
if(INTENT_GRAB)
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index cc0c12bd1cc8..73da4f0afbe7 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -256,6 +256,9 @@
var/life_daze_reduction = -1.5
var/life_slow_reduction = -1.5
+ //Research organ harvesting.
+ var/organ_removed = FALSE
+
//////////////////////////////////////////////////////////////////
//
@@ -690,6 +693,8 @@
if(iff_tag)
. += SPAN_NOTICE("It has an IFF tag sticking out of its carapace.")
+ if(organ_removed)
+ . += "It seems to have its organ removed."
/mob/living/carbon/xenomorph/Destroy()
GLOB.living_xeno_list -= src
diff --git a/code/modules/surgery/surgery_initiator.dm b/code/modules/surgery/surgery_initiator.dm
index 08b4dbdfed60..9e3315e8940e 100644
--- a/code/modules/surgery/surgery_initiator.dm
+++ b/code/modules/surgery/surgery_initiator.dm
@@ -6,8 +6,9 @@
/proc/initiate_surgery_moment(obj/item/tool, mob/living/carbon/target, obj/limb/affecting, mob/living/user)
if(!tool && !(affecting.status & LIMB_UNCALIBRATED_PROSTHETIC))
+ to_chat(user, SPAN_WARNING("You can't perform surgery hggggggggggggggere!"))
return FALSE
-
+ to_chat(user, tool)
var/target_zone = user.zone_selected
var/list/available_surgeries = list()
var/list/valid_steps = list() //Steps that could be performed, if we had the right tool.
@@ -20,51 +21,74 @@
if(!istype(T) || !T.supports_surgery)
if(tool.flags_item & CAN_DIG_SHRAPNEL) //Both shrapnel removal and prosthetic repair shouldn't be affected by being on the dropship.
tool.dig_out_shrapnel_check(target, user)
+ to_chat(user, SPAN_WARNING("You can't peasdasdrform surgery here!"))
return TRUE //Otherwise you get 'poked' by the knife.
if(HAS_TRAIT(tool, TRAIT_TOOL_BLOWTORCH) && affecting)
+ to_chat(user, SPAN_WARNING("You can't perform saaaaaaaaaaaaaaaasurgery here!"))
return FALSE
if(!(tool.type in SURGERY_TOOLS_NO_INIT_MSG))
to_chat(user, SPAN_WARNING("You can't perform surgery under these bad conditions!"))
+ to_chat(user, SPAN_WARNING("You can't perform suggggggggggrgery here!"))
return FALSE
if(user.action_busy) //already doing an action
+ to_chat(user, SPAN_WARNING("You can't perform surgerasdasdasdasdasdy here!"))
return FALSE
for(var/datum/surgery/surgeryloop as anything in GLOB.surgeries_by_zone_and_depth[target_zone][target.incision_depths[target_zone]])
//Skill check.
if((target.mob_flags & EASY_SURGERY) ? !skillcheck(user, SKILL_SURGERY, SKILL_SURGERY_NOVICE) : !skillcheck(user, SKILL_SURGERY, surgeryloop.required_surgery_skill))
+ to_chat(user, SPAN_WARNING("You can't perform surgery heraaaaaaaaaaaaaaaaaaaaaaaae!"))
continue
+ to_chat(user, surgeryloop)
//Lying and self-surgery checks.
if(surgeryloop.lying_required && !target.lying)
+ to_chat(user, "lying check failed as [surgeryloop]")
continue
if(!surgeryloop.self_operable && target == user)
+ to_chat(user, "selfop fail [surgeryloop]")
continue
-
+ to_chat(user, "starting lspecies [surgeryloop]")
//Species check.
if(!is_type_in_typecache(target, GLOB.surgical_patient_types["[surgeryloop]"]))
+ to_chat(user, "mobcheck failed [surgeryloop]")
continue
-
+ to_chat(user, "starting limbcheck [surgeryloop]")
//Limb checks.
+ to_chat(user,"0")
if(affecting)
+ to_chat(user,"1")
if(surgeryloop.requires_bodypart)
+ to_chat(user,"2")
if(affecting.status & LIMB_DESTROYED)
+ to_chat(user,"3")
+ to_chat(user, "m [surgeryloop] asdadas")
continue
else
- if(!(affecting.status & LIMB_DESTROYED))
- continue
- if(affecting.parent && affecting.parent.status & LIMB_DESTROYED)
- continue
+ if(ishuman(target))
+ to_chat(user,"4")
+ if(!(affecting.status & LIMB_DESTROYED) && ishuman(target))
+ to_chat(user, "ma [surgeryloop]")
+ continue
+ to_chat(user,"5")
+ if(affecting.parent && affecting.parent.status & LIMB_DESTROYED && ishuman(target))
+ to_chat(user, "mk failed [surgeryloop]")
+ continue
+ to_chat(user,"6")
if(surgeryloop.requires_bodypart_type && !(affecting.status & surgeryloop.requires_bodypart_type))
+ to_chat(user, "mobcheck failed [surgeryloop]")
continue
else if(surgeryloop.requires_bodypart) //mob with no limb in surgery zone when we need a limb
+ to_chat(user, "FUCK FUCK FUCK")
continue
-
+ to_chat(user,"8")
+ to_chat(user, "Limbcheck passed for [surgeryloop]")
//Surgery-specific requirements.
if(!surgeryloop.can_start(user, target, affecting, tool))
+ to_chat(user, "this kekw")
continue
-
//Tool checks.
var/datum/surgery_step/current_step = GLOB.surgery_step_list[surgeryloop.steps[1]]
@@ -74,14 +98,17 @@
var/datum/surgery_step/next_step = GLOB.surgery_step_list[surgeryloop.steps[2]]
if(!next_step.tool_check(user, tool, surgeryloop))
valid_steps += next_step
+ to_chat(user, "Limbr [surgeryloop]")
continue
else
+ to_chat(user, "Limbcheck for [surgeryloop]")
continue
-
+ to_chat(user, "m AAAAAAAAA[surgeryloop]")
available_surgeries[surgeryloop.name] = surgeryloop //Add it to the list.
-
+ to_chat(user, "m [available_surgeries]")
if(!length(available_surgeries))
if(!tool)
+ to_chat(user, "Limbcheck passaaaaasFFFFFFFFFFssssssed for")
return FALSE
if(target.incision_depths[target_zone] == SURGERY_DEPTH_SURFACE ? is_surgery_init_tool(tool) : is_surgery_tool(tool))
@@ -91,13 +118,15 @@
return FALSE
if(!length(valid_steps))
+ to_chat(user, "Limbcheck passaaaaasssssssed for")
var/limbname = affecting?.status & LIMB_DESTROYED ? "the stump of [target]'s [affecting.display_name]" : "[target]'s [parse_zone(target_zone)]"
if(target.incision_depths[target_zone] != SURGERY_DEPTH_SURFACE)
to_chat(user, SPAN_WARNING("You don't know of any operations you could perform in the [target.incision_depths[target_zone]] incision on [limbname]."))
else
to_chat(user, SPAN_WARNING("You don't know of any operations you could begin on [limbname]."))
+ to_chat(user, SPAN_WARNING("You can't perform surgery rfrfrfrfrfrfrfrhere!"))
return FALSE
-
+ to_chat(user, "mSTARTING surgeryloop]")
var/hint_msg
for(var/datum/surgery_step/current_step as anything in valid_steps)
if(hint_msg)
@@ -108,12 +137,14 @@
else
hint_msg = "You can't [current_step.desc] with \the [tool]"
to_chat(user, SPAN_WARNING("[hint_msg]."))
+ to_chat(user, SPAN_WARNING("You cana1231231231232131222aasdd't perform surgery here!"))
return FALSE
var/datum/surgery/surgeryinstance
if(length(available_surgeries) == 1)
surgeryinstance = available_surgeries[available_surgeries[1]]
else
+ to_chat(user, "mama [available_surgeries[1]]")
surgeryinstance = available_surgeries[tgui_input_list(user, "Begin which procedure?", "Surgery", sortList(available_surgeries))]
//we check that the surgery is still doable after the input() wait.
if(!surgeryinstance || QDELETED(user) || user.is_mob_incapacitated() || !user.Adjacent(target) || tool != user.get_active_hand() || target_zone != user.zone_selected)
@@ -146,7 +177,7 @@
return TRUE
if(!surgeryinstance.can_start(user, target, affecting, tool))
return TRUE
-
+ to_chat(user, "Limbcheck pass2222aaaaasssssssed for")
var/datum/surgery/procedure = new surgeryinstance.type(target, target_zone, affecting)
#ifdef DEBUG_SURGERY_INIT
message_admins("[procedure.name] started.")
diff --git a/code/modules/surgery/surgery_procedure.dm b/code/modules/surgery/surgery_procedure.dm
index 1e11516a8079..64863a59fb06 100644
--- a/code/modules/surgery/surgery_procedure.dm
+++ b/code/modules/surgery/surgery_procedure.dm
@@ -69,10 +69,12 @@
///Used on attackby and attackhand; TRUE means it stops the attack there, FALSE means it performs an item/open hand attack. CHECK OPENHAND ATTACK IS BLOCKED PROPERLY
/datum/surgery/proc/attempt_next_step(mob/user, obj/item/tool, repeating)
+ to_chat(user, "-1")
if(step_in_progress)
if(!user.action_busy) //Otherwise, assume it's the same person.
to_chat(user, SPAN_WARNING("Someone is already performing surgery on [target]'s [affected_limb.display_name]!"))
return FALSE
+
return TRUE //So that you don't poke them with a tool you're already using.
if(user.action_busy)
@@ -88,12 +90,13 @@
to_chat(user, SPAN_WARNING("You need to set [target] down before you can operate on \him!"))
else
to_chat(user, SPAN_WARNING("You can't operate on [target], \he is being carried by [target.pulledby]!"))
+ to_chat(user, "we are here 222")
return FALSE
if(lying_required && !target.lying)
to_chat(user, SPAN_WARNING("[user == target ? "You need" : "[target] needs"] to be lying down for this operation!"))
return FALSE
-
+ to_chat(user, "we are here")
if(user == target)
if(!self_operable)
to_chat(user, SPAN_WARNING("You can't perform this operation on yourself!"))
@@ -102,14 +105,16 @@
to_chat(user, SPAN_WARNING("You can't perform surgery on the same \
[user.zone_selected == "r_hand"||user.zone_selected == "l_hand" ? "hand":"arm"] you're using!"))
return FALSE
-
+ to_chat(user, "2")
var/datum/surgery_step/current_step = GLOB.surgery_step_list[steps[status]]
if(current_step)
+ to_chat(user, "we are hersteasae")
if(current_step.attempt_step(user, target, user.zone_selected, tool, src, repeating)) //First, try this step.
return TRUE
var/datum/surgery_step/next_step
if(current_step.skip_step_criteria(user, target, user.zone_selected, tool, src) && status < length(steps)) //If that doesn't work but the step is optional and not the last in the list, try the next step.
next_step = GLOB.surgery_step_list[steps[status + 1]]
+ to_chat(user, "we are her12312312312313131231kkakkake")
if(next_step.attempt_step(user, target, user.zone_selected, tool, src, skipped = TRUE))
return TRUE
if(tool && is_surgery_tool(tool)) //Just because you used the wrong tool doesn't mean you meant to whack the patient with it...
@@ -117,6 +122,8 @@
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool], or [next_step.desc]."))
else
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool]."))
+ to_chat(user, "we are here 22")
return FALSE //...but you might be wanting to use it on them anyway. If on help intent, the help-intent safety will apply for this attack.
+ to_chat(user, "we are here 2")
return FALSE
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
new file mode 100644
index 000000000000..eeb4bac701fe
--- /dev/null
+++ b/code/modules/surgery/xeno.dm
@@ -0,0 +1,129 @@
+
+//Research stuff to extract stuff from xenomorphs for goodies. In other words, to extract usefull material that could be used to upgrade marines and etc. doesnt add anything of kind
+
+/datum/surgery/xenomorph
+ name = "Experimental Harvesting Surgery"
+ invasiveness = list(SURGERY_DEPTH_SURFACE)
+ required_surgery_skill = SKILL_SURGERY_NOVICE
+ possible_locs = list("head")
+ target_mobtypes = list(/mob/living/carbon/xenomorph)
+ steps = list(
+ /datum/surgery_step/xenomorph/cut_exoskeleton,
+ /datum/surgery_step/xenomorph/open_exoskeleton,
+ ///datum/surgery_step/xenomorph/severe_connections
+ )
+ lying_required = FALSE
+ requires_bodypart_type = NONE
+ requires_bodypart = FALSE
+
+/datum/surgery/xenomorph/can_start(mob/user, mob/living/carbon/xenomorph/patient, obj/limb/L, obj/item/tool)
+ if(patient.stat == DEAD && !patient.organ_removed)
+ return TRUE
+ return FALSE
+
+/datum/surgery_step/xenomorph/cut_exoskeleton
+ name = "Cut Exoskeleton Carapace"
+ desc = "Cut the carapace open."
+ tools = SURGERY_TOOLS_SEVER_BONE
+ time = 4 SECONDS
+ preop_sound = 'sound/handling/clothingrustle1.ogg'
+ success_sound = 'sound/handling/bandage.ogg'
+ failure_sound = 'sound/surgery/organ2.ogg'
+
+/datum/surgery_step/xenomorph/cut_exoskeleton/preop(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/circular_saw)
+ user.affected_message(target,
+ SPAN_NOTICE("You start to cut [target.caste_type] carapace apart using \the [tool], carefully, with barely any acid."),
+ SPAN_NOTICE("[user] starts to cut Your carapace apart using \the [tool], carefully, with barely any acid."),
+ SPAN_NOTICE("[user] starts to cut [target.caste_type] carapace. \the [tool], carefully, with barely any acid."))
+ if(user.head && !(user.head.flags_inventory & COVEREYES))
+ var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
+ user_eye.take_damage(rand(1,2), FALSE)
+ to_chat(user, SPAN_DANGER("Some acid gets into your eyes!"))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You start to [pick("smash", "crack", "break")] [target.caste_type] carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
+ SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] Your carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
+ SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] [target.caste_type] carapace with \the [tool], Recklessly, with acid splashing him!"))
+ if(user.head && !(user.head.flags_inventory & COVEREYES))
+ var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
+ user_eye.take_damage(rand(3,5), FALSE)
+ to_chat(user, SPAN_DANGER("Lots of acid gets into your eyes!"))
+ user.emote("pain")
+ user.apply_damage(rand(10,25),BURN)
+
+/datum/surgery_step/xenomorph/cut_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/circular_saw)
+ user.affected_message(target,
+ SPAN_NOTICE("You succesfully cut through [target.caste_type] carapace apart using \the [tool]."),
+ SPAN_NOTICE("[user] Succesfully cuts through Your carapace. \the [tool]."),
+ SPAN_NOTICE("[user] Succesfully cuts [target.caste_type] carapace. \the [tool]."))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You succesfully destroy [target.caste_type] carapace into bits and pieces apart using \the [tool]."),
+ SPAN_NOTICE("[user] succesfully destroys Your carapace into bits and pieces apart using \the [tool]."),,
+ SPAN_NOTICE("[user] Succesfully destroys [target.caste_type] carapace into bits and pieces apart using \the [tool]."))
+
+/datum/surgery_step/xenomorph/cut_exoskeleton/failure(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/circular_saw)
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, failing to cut [target.caste_type] carapace apart using \the [tool]!"),
+ SPAN_WARNING("[user] hand slips, failing to cut Your carapace apart using \the [tool]!"),
+ SPAN_WARNING("[user] hand slips, failing to cut [target.caste_type] carapace using \the [tool]!"))
+ else
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, failing to destroy [target.caste_type] carapace into bits and pieces apart using \the [tool]."),
+ SPAN_WARNING("[user] hand slips, failing to destroy Your carapace into bits and pieces using \the [tool]."),
+ SPAN_WARNING("[user] hand slips, failing to destroy [target.caste_type] carapace into bits and pieces using \the [tool]."))
+
+/datum/surgery_step/xenomorph/open_exoskeleton
+ name = "Pry exoskeleton open"
+ desc = "Open the exoskeleton in the opening."
+ tools = SURGERY_TOOLS_PRY_ENCASED
+ time = 3 SECONDS
+ preop_sound = 'sound/surgery/retractor1.ogg'
+ success_sound = 'sound/surgery/retractor2.ogg'
+ failure_sound = 'sound/surgery/organ1.ogg'
+
+/datum/surgery_step/xenomorph/open_exoskeleton/preop(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ user.affected_message(target,
+ SPAN_NOTICE("You start to pry [target.caste_type] carapace open using \the [tool], slowly"),
+ SPAN_NOTICE("[user] starts to pry Your carapace open with \the [tool] very carefully"),
+ SPAN_NOTICE("[user] starts to pry [target.caste_type] carapace open with \the [tool] very carefully"))
+
+/datum/surgery_step/xenomorph/open_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/retractor)
+ user.affected_message(target,
+ SPAN_NOTICE("You hold [target.caste_type] carapace and exoskeleton open using \the [tool], exposing [target.caste_type] vital organs"),
+ SPAN_NOTICE("[user] Holds Your carapace and exoskeleton open with \the [tool], exposing [target.caste_type] vital organs "),
+ SPAN_NOTICE("[user] Holds [target.caste_type] carapace and exoskeleton open with \the [tool], exposing [target.caste_type] vital organs "))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You Hold [target.caste_type] carapace open using \the [tool] like a medieval doctor, exposing [target.caste_type] vital organs"),
+ SPAN_NOTICE("[user] starts to open Your carapace with \the [tool] very carefully"),
+ SPAN_NOTICE("[user] starts to open [target.caste_type] carapace with \the [tool] very carefully"))
+
+/datum/surgery_step/xenomorph/open_exoskeleton/failure(mob/living/carbon/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
+ SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
+ SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"))
+ user.apply_damage(rand(5, 15), BURN)
+/*
+/datum/surgery_step/xenomorph/severe_connections
+ name = "Severe organ connections"
+ desc = "Detach tubes and connections from organ."
+ tools = list(
+ /obj/item/tool/surgery/scalpel = SURGERY_TOOL_MULT_IDEAL,
+ /obj/item/tool/surgery/scalpel/pict_system = SURGERY_TOOL_MULT_IDEAL,
+ /obj/item/attachable/bayonet = SURGERY_TOOL_MULT_SUBSTITUTE,
+ /obj/item/tool/kitchen/knife = SURGERY_TOOL_MULT_SUBSTITUTE,
+ /obj/item/shard = SURGERY_TOOL_MULT_AWFUL,
+ ) //shamelessly taken from embryo code
+ time = 5 SECONDS
+ preop_sound = 'sound/surgery/scalpel1.ogg'
+ success_sound = 'sound/surgery/scalpel2.ogg'
+ failure_sound = 'sound/surgery/organ2.ogg'
+
+/datum/surgery_step/xenomorph/remove_organ
+*/
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 43a250b7b091..e6aff3abae6a 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -2203,6 +2203,7 @@
#include "code\modules\surgery\surgery_steps.dm"
#include "code\modules\surgery\surgery_toggle.dm"
#include "code\modules\surgery\tendwounds.dm"
+#include "code\modules\surgery\xeno.dm"
#include "code\modules\teleporters\teleporter.dm"
#include "code\modules\teleporters\teleporter_admin_verbs.dm"
#include "code\modules\teleporters\teleporter_console.dm"
From 0234eb1e92279cdcfb41e19dfc186431b168fe79 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 18 Jan 2024 15:54:31 -0500
Subject: [PATCH 002/113] Revert "jesus christ forgive me for this shitcode"
This reverts commit e771c6230acb6280194d637125e6efd908479d25.
---
code/_onclick/item_attack.dm | 17 +--
.../living/carbon/xenomorph/XenoAttacks.dm | 4 +-
.../mob/living/carbon/xenomorph/Xenomorph.dm | 5 -
code/modules/surgery/surgery_initiator.dm | 57 ++------
code/modules/surgery/surgery_procedure.dm | 11 +-
code/modules/surgery/xeno.dm | 129 ------------------
colonialmarines.dme | 1 -
7 files changed, 18 insertions(+), 206 deletions(-)
delete mode 100644 code/modules/surgery/xeno.dm
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 41829bd8d648..c6052da33199 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -66,25 +66,10 @@
if(!(user in viewers(M, null)))
showname = "."
- if(isxeno(M) && M.stat == DEAD)
- var/datum/surgery/current_surgery = M.active_surgeries[user.zone_selected]
- if(current_surgery)
- to_chat(user, "we are here000000")
- if(current_surgery.attempt_next_step(user, src))
- to_chat(user, "we are here 2oh")
- return FALSE //Cancel attack.
- to_chat(user, "we are here 2uh")
- else
- to_chat(user, "we are here 2")
- if(initiate_surgery_moment(src, M, "head" , user))
- to_chat(user, "got true")
- return FALSE
- to_chat(user, "got false")
-
if (user.a_intent == INTENT_HELP && ((user.client?.prefs && user.client?.prefs?.toggle_prefs & TOGGLE_HELP_INTENT_SAFETY) || (user.mob_flags & SURGERY_MODE_ON)))
playsound(loc, 'sound/effects/pop.ogg', 25, 1)
user.visible_message(SPAN_NOTICE("[M] has been poked with [src][showname]"),\
- SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src].LORD"), null, 4)
+ SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src]."), null, 4)
return FALSE
diff --git a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
index 911c4af56309..6361ff595b10 100644
--- a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
+++ b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
@@ -49,10 +49,10 @@
backpack.open(M)
return
if(stat == DEAD)
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens.DED"), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens."), \
SPAN_WARNING("You poke \the [src], but nothing happens."), null, 5, CHAT_TYPE_FLUFF_ACTION)
else
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src].WA"), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src]."), \
SPAN_WARNING("You poke \the [src]."), null, 5, CHAT_TYPE_FLUFF_ACTION)
if(INTENT_GRAB)
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 73da4f0afbe7..cc0c12bd1cc8 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -256,9 +256,6 @@
var/life_daze_reduction = -1.5
var/life_slow_reduction = -1.5
- //Research organ harvesting.
- var/organ_removed = FALSE
-
//////////////////////////////////////////////////////////////////
//
@@ -693,8 +690,6 @@
if(iff_tag)
. += SPAN_NOTICE("It has an IFF tag sticking out of its carapace.")
- if(organ_removed)
- . += "It seems to have its organ removed."
/mob/living/carbon/xenomorph/Destroy()
GLOB.living_xeno_list -= src
diff --git a/code/modules/surgery/surgery_initiator.dm b/code/modules/surgery/surgery_initiator.dm
index 9e3315e8940e..08b4dbdfed60 100644
--- a/code/modules/surgery/surgery_initiator.dm
+++ b/code/modules/surgery/surgery_initiator.dm
@@ -6,9 +6,8 @@
/proc/initiate_surgery_moment(obj/item/tool, mob/living/carbon/target, obj/limb/affecting, mob/living/user)
if(!tool && !(affecting.status & LIMB_UNCALIBRATED_PROSTHETIC))
- to_chat(user, SPAN_WARNING("You can't perform surgery hggggggggggggggere!"))
return FALSE
- to_chat(user, tool)
+
var/target_zone = user.zone_selected
var/list/available_surgeries = list()
var/list/valid_steps = list() //Steps that could be performed, if we had the right tool.
@@ -21,74 +20,51 @@
if(!istype(T) || !T.supports_surgery)
if(tool.flags_item & CAN_DIG_SHRAPNEL) //Both shrapnel removal and prosthetic repair shouldn't be affected by being on the dropship.
tool.dig_out_shrapnel_check(target, user)
- to_chat(user, SPAN_WARNING("You can't peasdasdrform surgery here!"))
return TRUE //Otherwise you get 'poked' by the knife.
if(HAS_TRAIT(tool, TRAIT_TOOL_BLOWTORCH) && affecting)
- to_chat(user, SPAN_WARNING("You can't perform saaaaaaaaaaaaaaaasurgery here!"))
return FALSE
if(!(tool.type in SURGERY_TOOLS_NO_INIT_MSG))
to_chat(user, SPAN_WARNING("You can't perform surgery under these bad conditions!"))
- to_chat(user, SPAN_WARNING("You can't perform suggggggggggrgery here!"))
return FALSE
if(user.action_busy) //already doing an action
- to_chat(user, SPAN_WARNING("You can't perform surgerasdasdasdasdasdy here!"))
return FALSE
for(var/datum/surgery/surgeryloop as anything in GLOB.surgeries_by_zone_and_depth[target_zone][target.incision_depths[target_zone]])
//Skill check.
if((target.mob_flags & EASY_SURGERY) ? !skillcheck(user, SKILL_SURGERY, SKILL_SURGERY_NOVICE) : !skillcheck(user, SKILL_SURGERY, surgeryloop.required_surgery_skill))
- to_chat(user, SPAN_WARNING("You can't perform surgery heraaaaaaaaaaaaaaaaaaaaaaaae!"))
continue
- to_chat(user, surgeryloop)
//Lying and self-surgery checks.
if(surgeryloop.lying_required && !target.lying)
- to_chat(user, "lying check failed as [surgeryloop]")
continue
if(!surgeryloop.self_operable && target == user)
- to_chat(user, "selfop fail [surgeryloop]")
continue
- to_chat(user, "starting lspecies [surgeryloop]")
+
//Species check.
if(!is_type_in_typecache(target, GLOB.surgical_patient_types["[surgeryloop]"]))
- to_chat(user, "mobcheck failed [surgeryloop]")
continue
- to_chat(user, "starting limbcheck [surgeryloop]")
+
//Limb checks.
- to_chat(user,"0")
if(affecting)
- to_chat(user,"1")
if(surgeryloop.requires_bodypart)
- to_chat(user,"2")
if(affecting.status & LIMB_DESTROYED)
- to_chat(user,"3")
- to_chat(user, "m [surgeryloop] asdadas")
continue
else
- if(ishuman(target))
- to_chat(user,"4")
- if(!(affecting.status & LIMB_DESTROYED) && ishuman(target))
- to_chat(user, "ma [surgeryloop]")
- continue
- to_chat(user,"5")
- if(affecting.parent && affecting.parent.status & LIMB_DESTROYED && ishuman(target))
- to_chat(user, "mk failed [surgeryloop]")
- continue
- to_chat(user,"6")
+ if(!(affecting.status & LIMB_DESTROYED))
+ continue
+ if(affecting.parent && affecting.parent.status & LIMB_DESTROYED)
+ continue
if(surgeryloop.requires_bodypart_type && !(affecting.status & surgeryloop.requires_bodypart_type))
- to_chat(user, "mobcheck failed [surgeryloop]")
continue
else if(surgeryloop.requires_bodypart) //mob with no limb in surgery zone when we need a limb
- to_chat(user, "FUCK FUCK FUCK")
continue
- to_chat(user,"8")
- to_chat(user, "Limbcheck passed for [surgeryloop]")
+
//Surgery-specific requirements.
if(!surgeryloop.can_start(user, target, affecting, tool))
- to_chat(user, "this kekw")
continue
+
//Tool checks.
var/datum/surgery_step/current_step = GLOB.surgery_step_list[surgeryloop.steps[1]]
@@ -98,17 +74,14 @@
var/datum/surgery_step/next_step = GLOB.surgery_step_list[surgeryloop.steps[2]]
if(!next_step.tool_check(user, tool, surgeryloop))
valid_steps += next_step
- to_chat(user, "Limbr [surgeryloop]")
continue
else
- to_chat(user, "Limbcheck for [surgeryloop]")
continue
- to_chat(user, "m AAAAAAAAA[surgeryloop]")
+
available_surgeries[surgeryloop.name] = surgeryloop //Add it to the list.
- to_chat(user, "m [available_surgeries]")
+
if(!length(available_surgeries))
if(!tool)
- to_chat(user, "Limbcheck passaaaaasFFFFFFFFFFssssssed for")
return FALSE
if(target.incision_depths[target_zone] == SURGERY_DEPTH_SURFACE ? is_surgery_init_tool(tool) : is_surgery_tool(tool))
@@ -118,15 +91,13 @@
return FALSE
if(!length(valid_steps))
- to_chat(user, "Limbcheck passaaaaasssssssed for")
var/limbname = affecting?.status & LIMB_DESTROYED ? "the stump of [target]'s [affecting.display_name]" : "[target]'s [parse_zone(target_zone)]"
if(target.incision_depths[target_zone] != SURGERY_DEPTH_SURFACE)
to_chat(user, SPAN_WARNING("You don't know of any operations you could perform in the [target.incision_depths[target_zone]] incision on [limbname]."))
else
to_chat(user, SPAN_WARNING("You don't know of any operations you could begin on [limbname]."))
- to_chat(user, SPAN_WARNING("You can't perform surgery rfrfrfrfrfrfrfrhere!"))
return FALSE
- to_chat(user, "mSTARTING surgeryloop]")
+
var/hint_msg
for(var/datum/surgery_step/current_step as anything in valid_steps)
if(hint_msg)
@@ -137,14 +108,12 @@
else
hint_msg = "You can't [current_step.desc] with \the [tool]"
to_chat(user, SPAN_WARNING("[hint_msg]."))
- to_chat(user, SPAN_WARNING("You cana1231231231232131222aasdd't perform surgery here!"))
return FALSE
var/datum/surgery/surgeryinstance
if(length(available_surgeries) == 1)
surgeryinstance = available_surgeries[available_surgeries[1]]
else
- to_chat(user, "mama [available_surgeries[1]]")
surgeryinstance = available_surgeries[tgui_input_list(user, "Begin which procedure?", "Surgery", sortList(available_surgeries))]
//we check that the surgery is still doable after the input() wait.
if(!surgeryinstance || QDELETED(user) || user.is_mob_incapacitated() || !user.Adjacent(target) || tool != user.get_active_hand() || target_zone != user.zone_selected)
@@ -177,7 +146,7 @@
return TRUE
if(!surgeryinstance.can_start(user, target, affecting, tool))
return TRUE
- to_chat(user, "Limbcheck pass2222aaaaasssssssed for")
+
var/datum/surgery/procedure = new surgeryinstance.type(target, target_zone, affecting)
#ifdef DEBUG_SURGERY_INIT
message_admins("[procedure.name] started.")
diff --git a/code/modules/surgery/surgery_procedure.dm b/code/modules/surgery/surgery_procedure.dm
index 64863a59fb06..1e11516a8079 100644
--- a/code/modules/surgery/surgery_procedure.dm
+++ b/code/modules/surgery/surgery_procedure.dm
@@ -69,12 +69,10 @@
///Used on attackby and attackhand; TRUE means it stops the attack there, FALSE means it performs an item/open hand attack. CHECK OPENHAND ATTACK IS BLOCKED PROPERLY
/datum/surgery/proc/attempt_next_step(mob/user, obj/item/tool, repeating)
- to_chat(user, "-1")
if(step_in_progress)
if(!user.action_busy) //Otherwise, assume it's the same person.
to_chat(user, SPAN_WARNING("Someone is already performing surgery on [target]'s [affected_limb.display_name]!"))
return FALSE
-
return TRUE //So that you don't poke them with a tool you're already using.
if(user.action_busy)
@@ -90,13 +88,12 @@
to_chat(user, SPAN_WARNING("You need to set [target] down before you can operate on \him!"))
else
to_chat(user, SPAN_WARNING("You can't operate on [target], \he is being carried by [target.pulledby]!"))
- to_chat(user, "we are here 222")
return FALSE
if(lying_required && !target.lying)
to_chat(user, SPAN_WARNING("[user == target ? "You need" : "[target] needs"] to be lying down for this operation!"))
return FALSE
- to_chat(user, "we are here")
+
if(user == target)
if(!self_operable)
to_chat(user, SPAN_WARNING("You can't perform this operation on yourself!"))
@@ -105,16 +102,14 @@
to_chat(user, SPAN_WARNING("You can't perform surgery on the same \
[user.zone_selected == "r_hand"||user.zone_selected == "l_hand" ? "hand":"arm"] you're using!"))
return FALSE
- to_chat(user, "2")
+
var/datum/surgery_step/current_step = GLOB.surgery_step_list[steps[status]]
if(current_step)
- to_chat(user, "we are hersteasae")
if(current_step.attempt_step(user, target, user.zone_selected, tool, src, repeating)) //First, try this step.
return TRUE
var/datum/surgery_step/next_step
if(current_step.skip_step_criteria(user, target, user.zone_selected, tool, src) && status < length(steps)) //If that doesn't work but the step is optional and not the last in the list, try the next step.
next_step = GLOB.surgery_step_list[steps[status + 1]]
- to_chat(user, "we are her12312312312313131231kkakkake")
if(next_step.attempt_step(user, target, user.zone_selected, tool, src, skipped = TRUE))
return TRUE
if(tool && is_surgery_tool(tool)) //Just because you used the wrong tool doesn't mean you meant to whack the patient with it...
@@ -122,8 +117,6 @@
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool], or [next_step.desc]."))
else
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool]."))
- to_chat(user, "we are here 22")
return FALSE //...but you might be wanting to use it on them anyway. If on help intent, the help-intent safety will apply for this attack.
- to_chat(user, "we are here 2")
return FALSE
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
deleted file mode 100644
index eeb4bac701fe..000000000000
--- a/code/modules/surgery/xeno.dm
+++ /dev/null
@@ -1,129 +0,0 @@
-
-//Research stuff to extract stuff from xenomorphs for goodies. In other words, to extract usefull material that could be used to upgrade marines and etc. doesnt add anything of kind
-
-/datum/surgery/xenomorph
- name = "Experimental Harvesting Surgery"
- invasiveness = list(SURGERY_DEPTH_SURFACE)
- required_surgery_skill = SKILL_SURGERY_NOVICE
- possible_locs = list("head")
- target_mobtypes = list(/mob/living/carbon/xenomorph)
- steps = list(
- /datum/surgery_step/xenomorph/cut_exoskeleton,
- /datum/surgery_step/xenomorph/open_exoskeleton,
- ///datum/surgery_step/xenomorph/severe_connections
- )
- lying_required = FALSE
- requires_bodypart_type = NONE
- requires_bodypart = FALSE
-
-/datum/surgery/xenomorph/can_start(mob/user, mob/living/carbon/xenomorph/patient, obj/limb/L, obj/item/tool)
- if(patient.stat == DEAD && !patient.organ_removed)
- return TRUE
- return FALSE
-
-/datum/surgery_step/xenomorph/cut_exoskeleton
- name = "Cut Exoskeleton Carapace"
- desc = "Cut the carapace open."
- tools = SURGERY_TOOLS_SEVER_BONE
- time = 4 SECONDS
- preop_sound = 'sound/handling/clothingrustle1.ogg'
- success_sound = 'sound/handling/bandage.ogg'
- failure_sound = 'sound/surgery/organ2.ogg'
-
-/datum/surgery_step/xenomorph/cut_exoskeleton/preop(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
- if(tool_type == /obj/item/tool/surgery/circular_saw)
- user.affected_message(target,
- SPAN_NOTICE("You start to cut [target.caste_type] carapace apart using \the [tool], carefully, with barely any acid."),
- SPAN_NOTICE("[user] starts to cut Your carapace apart using \the [tool], carefully, with barely any acid."),
- SPAN_NOTICE("[user] starts to cut [target.caste_type] carapace. \the [tool], carefully, with barely any acid."))
- if(user.head && !(user.head.flags_inventory & COVEREYES))
- var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
- user_eye.take_damage(rand(1,2), FALSE)
- to_chat(user, SPAN_DANGER("Some acid gets into your eyes!"))
- else
- user.affected_message(target,
- SPAN_NOTICE("You start to [pick("smash", "crack", "break")] [target.caste_type] carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
- SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] Your carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
- SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] [target.caste_type] carapace with \the [tool], Recklessly, with acid splashing him!"))
- if(user.head && !(user.head.flags_inventory & COVEREYES))
- var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
- user_eye.take_damage(rand(3,5), FALSE)
- to_chat(user, SPAN_DANGER("Lots of acid gets into your eyes!"))
- user.emote("pain")
- user.apply_damage(rand(10,25),BURN)
-
-/datum/surgery_step/xenomorph/cut_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
- if(tool_type == /obj/item/tool/surgery/circular_saw)
- user.affected_message(target,
- SPAN_NOTICE("You succesfully cut through [target.caste_type] carapace apart using \the [tool]."),
- SPAN_NOTICE("[user] Succesfully cuts through Your carapace. \the [tool]."),
- SPAN_NOTICE("[user] Succesfully cuts [target.caste_type] carapace. \the [tool]."))
- else
- user.affected_message(target,
- SPAN_NOTICE("You succesfully destroy [target.caste_type] carapace into bits and pieces apart using \the [tool]."),
- SPAN_NOTICE("[user] succesfully destroys Your carapace into bits and pieces apart using \the [tool]."),,
- SPAN_NOTICE("[user] Succesfully destroys [target.caste_type] carapace into bits and pieces apart using \the [tool]."))
-
-/datum/surgery_step/xenomorph/cut_exoskeleton/failure(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
- if(tool_type == /obj/item/tool/surgery/circular_saw)
- user.affected_message(target,
- SPAN_WARNING("Your hand slips, failing to cut [target.caste_type] carapace apart using \the [tool]!"),
- SPAN_WARNING("[user] hand slips, failing to cut Your carapace apart using \the [tool]!"),
- SPAN_WARNING("[user] hand slips, failing to cut [target.caste_type] carapace using \the [tool]!"))
- else
- user.affected_message(target,
- SPAN_WARNING("Your hand slips, failing to destroy [target.caste_type] carapace into bits and pieces apart using \the [tool]."),
- SPAN_WARNING("[user] hand slips, failing to destroy Your carapace into bits and pieces using \the [tool]."),
- SPAN_WARNING("[user] hand slips, failing to destroy [target.caste_type] carapace into bits and pieces using \the [tool]."))
-
-/datum/surgery_step/xenomorph/open_exoskeleton
- name = "Pry exoskeleton open"
- desc = "Open the exoskeleton in the opening."
- tools = SURGERY_TOOLS_PRY_ENCASED
- time = 3 SECONDS
- preop_sound = 'sound/surgery/retractor1.ogg'
- success_sound = 'sound/surgery/retractor2.ogg'
- failure_sound = 'sound/surgery/organ1.ogg'
-
-/datum/surgery_step/xenomorph/open_exoskeleton/preop(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
- user.affected_message(target,
- SPAN_NOTICE("You start to pry [target.caste_type] carapace open using \the [tool], slowly"),
- SPAN_NOTICE("[user] starts to pry Your carapace open with \the [tool] very carefully"),
- SPAN_NOTICE("[user] starts to pry [target.caste_type] carapace open with \the [tool] very carefully"))
-
-/datum/surgery_step/xenomorph/open_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
- if(tool_type == /obj/item/tool/surgery/retractor)
- user.affected_message(target,
- SPAN_NOTICE("You hold [target.caste_type] carapace and exoskeleton open using \the [tool], exposing [target.caste_type] vital organs"),
- SPAN_NOTICE("[user] Holds Your carapace and exoskeleton open with \the [tool], exposing [target.caste_type] vital organs "),
- SPAN_NOTICE("[user] Holds [target.caste_type] carapace and exoskeleton open with \the [tool], exposing [target.caste_type] vital organs "))
- else
- user.affected_message(target,
- SPAN_NOTICE("You Hold [target.caste_type] carapace open using \the [tool] like a medieval doctor, exposing [target.caste_type] vital organs"),
- SPAN_NOTICE("[user] starts to open Your carapace with \the [tool] very carefully"),
- SPAN_NOTICE("[user] starts to open [target.caste_type] carapace with \the [tool] very carefully"))
-
-/datum/surgery_step/xenomorph/open_exoskeleton/failure(mob/living/carbon/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
- user.affected_message(target,
- SPAN_WARNING("Your hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
- SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
- SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"))
- user.apply_damage(rand(5, 15), BURN)
-/*
-/datum/surgery_step/xenomorph/severe_connections
- name = "Severe organ connections"
- desc = "Detach tubes and connections from organ."
- tools = list(
- /obj/item/tool/surgery/scalpel = SURGERY_TOOL_MULT_IDEAL,
- /obj/item/tool/surgery/scalpel/pict_system = SURGERY_TOOL_MULT_IDEAL,
- /obj/item/attachable/bayonet = SURGERY_TOOL_MULT_SUBSTITUTE,
- /obj/item/tool/kitchen/knife = SURGERY_TOOL_MULT_SUBSTITUTE,
- /obj/item/shard = SURGERY_TOOL_MULT_AWFUL,
- ) //shamelessly taken from embryo code
- time = 5 SECONDS
- preop_sound = 'sound/surgery/scalpel1.ogg'
- success_sound = 'sound/surgery/scalpel2.ogg'
- failure_sound = 'sound/surgery/organ2.ogg'
-
-/datum/surgery_step/xenomorph/remove_organ
-*/
diff --git a/colonialmarines.dme b/colonialmarines.dme
index e6aff3abae6a..43a250b7b091 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -2203,7 +2203,6 @@
#include "code\modules\surgery\surgery_steps.dm"
#include "code\modules\surgery\surgery_toggle.dm"
#include "code\modules\surgery\tendwounds.dm"
-#include "code\modules\surgery\xeno.dm"
#include "code\modules\teleporters\teleporter.dm"
#include "code\modules\teleporters\teleporter_admin_verbs.dm"
#include "code\modules\teleporters\teleporter_console.dm"
From b181704cebdfb53b2936a87c473cc3e571754b88 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 18 Jan 2024 16:01:41 -0500
Subject: [PATCH 003/113] Revert "Revert "jesus christ forgive me for this
shitcode""
This reverts commit 0234eb1e92279cdcfb41e19dfc186431b168fe79.
---
code/_onclick/item_attack.dm | 17 ++-
.../living/carbon/xenomorph/XenoAttacks.dm | 4 +-
.../mob/living/carbon/xenomorph/Xenomorph.dm | 6 +
code/modules/surgery/surgery_initiator.dm | 56 ++++++--
code/modules/surgery/surgery_procedure.dm | 11 +-
code/modules/surgery/xeno.dm | 129 ++++++++++++++++++
colonialmarines.dme | 1 +
7 files changed, 206 insertions(+), 18 deletions(-)
create mode 100644 code/modules/surgery/xeno.dm
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 8d77920a59cc..4d77a7113048 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -68,10 +68,25 @@
if(!(user in viewers(M, null)))
showname = "."
+ if(isxeno(M) && M.stat == DEAD)
+ var/datum/surgery/current_surgery = M.active_surgeries[user.zone_selected]
+ if(current_surgery)
+ to_chat(user, "we are here000000")
+ if(current_surgery.attempt_next_step(user, src))
+ to_chat(user, "we are here 2oh")
+ return FALSE //Cancel attack.
+ to_chat(user, "we are here 2uh")
+ else
+ to_chat(user, "we are here 2")
+ if(initiate_surgery_moment(src, M, "head" , user))
+ to_chat(user, "got true")
+ return FALSE
+ to_chat(user, "got false")
+
if (user.a_intent == INTENT_HELP && ((user.client?.prefs && user.client?.prefs?.toggle_prefs & TOGGLE_HELP_INTENT_SAFETY) || (user.mob_flags & SURGERY_MODE_ON)))
playsound(loc, 'sound/effects/pop.ogg', 25, 1)
user.visible_message(SPAN_NOTICE("[M] has been poked with [src][showname]"),\
- SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src]."), null, 4)
+ SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src].LORD"), null, 4)
return FALSE
diff --git a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
index 39866eb53798..ebd720cd1685 100644
--- a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
+++ b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
@@ -49,10 +49,10 @@
backpack.open(M)
return
if(stat == DEAD)
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens."), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens.DED"), \
SPAN_WARNING("You poke \the [src], but nothing happens."), null, 5, CHAT_TYPE_FLUFF_ACTION)
else
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src]."), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src].WA"), \
SPAN_WARNING("You poke \the [src]."), null, 5, CHAT_TYPE_FLUFF_ACTION)
if(INTENT_GRAB)
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 3f83451a6386..209b35bd85a4 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -249,6 +249,9 @@
// Life reduction variables.
var/life_slow_reduction = -1.5
+ //Research organ harvesting.
+ var/organ_removed = FALSE
+
//////////////////////////////////////////////////////////////////
//
@@ -263,6 +266,7 @@
// an easily modularizable way. So, here you go.
//
//////////////////////////////////////////////////////////////////
+
var/tunnel = FALSE
/// for check on lurker invisibility
var/stealth = FALSE
@@ -666,6 +670,8 @@
if(iff_tag)
. += SPAN_NOTICE("It has an IFF tag sticking out of its carapace.")
+ if(organ_removed)
+ . += "It seems to have its organ removed."
/mob/living/carbon/xenomorph/Destroy()
GLOB.living_xeno_list -= src
diff --git a/code/modules/surgery/surgery_initiator.dm b/code/modules/surgery/surgery_initiator.dm
index 706b28d0e94e..46118e140b96 100644
--- a/code/modules/surgery/surgery_initiator.dm
+++ b/code/modules/surgery/surgery_initiator.dm
@@ -6,8 +6,9 @@
/proc/initiate_surgery_moment(obj/item/tool, mob/living/carbon/target, obj/limb/affecting, mob/living/user)
if(!tool && !(affecting.status & LIMB_UNCALIBRATED_PROSTHETIC))
+ to_chat(user, SPAN_WARNING("You can't perform surgery hggggggggggggggere!"))
return FALSE
-
+ to_chat(user, tool)
var/target_zone = user.zone_selected
var/list/available_surgeries = list()
var/list/valid_steps = list() //Steps that could be performed, if we had the right tool.
@@ -20,11 +21,14 @@
if(!istype(T) || !T.supports_surgery)
if(tool.flags_item & CAN_DIG_SHRAPNEL) //Both shrapnel removal and prosthetic repair shouldn't be affected by being on the dropship.
tool.dig_out_shrapnel_check(target, user)
+ to_chat(user, SPAN_WARNING("You can't peasdasdrform surgery here!"))
return TRUE //Otherwise you get 'poked' by the knife.
if(HAS_TRAIT(tool, TRAIT_TOOL_BLOWTORCH) && affecting)
+ to_chat(user, SPAN_WARNING("You can't perform saaaaaaaaaaaaaaaasurgery here!"))
return FALSE
if(!(tool.type in SURGERY_TOOLS_NO_INIT_MSG))
to_chat(user, SPAN_WARNING("You can't perform surgery under these bad conditions!"))
+ to_chat(user, SPAN_WARNING("You can't perform suggggggggggrgery here!"))
return FALSE
var/obj/limb/surgery_limb = target.get_limb(target_zone)
@@ -35,43 +39,62 @@
return
if(user.action_busy) //already doing an action
+ to_chat(user, SPAN_WARNING("You can't perform surgerasdasdasdasdasdy here!"))
return FALSE
for(var/datum/surgery/surgeryloop as anything in GLOB.surgeries_by_zone_and_depth[target_zone][target.incision_depths[target_zone]])
//Skill check.
if((target.mob_flags & EASY_SURGERY) ? !skillcheck(user, SKILL_SURGERY, SKILL_SURGERY_NOVICE) : !skillcheck(user, SKILL_SURGERY, surgeryloop.required_surgery_skill))
+ to_chat(user, SPAN_WARNING("You can't perform surgery heraaaaaaaaaaaaaaaaaaaaaaaae!"))
continue
+ to_chat(user, surgeryloop)
//Lying and self-surgery checks.
if(surgeryloop.lying_required && target.body_position != LYING_DOWN)
continue
if(!surgeryloop.self_operable && target == user)
+ to_chat(user, "selfop fail [surgeryloop]")
continue
-
+ to_chat(user, "starting lspecies [surgeryloop]")
//Species check.
if(!is_type_in_typecache(target, GLOB.surgical_patient_types["[surgeryloop]"]))
+ to_chat(user, "mobcheck failed [surgeryloop]")
continue
-
+ to_chat(user, "starting limbcheck [surgeryloop]")
//Limb checks.
+ to_chat(user,"0")
if(affecting)
+ to_chat(user,"1")
if(surgeryloop.requires_bodypart)
+ to_chat(user,"2")
if(affecting.status & LIMB_DESTROYED)
+ to_chat(user,"3")
+ to_chat(user, "m [surgeryloop] asdadas")
continue
else
- if(!(affecting.status & LIMB_DESTROYED))
- continue
- if(affecting.parent && affecting.parent.status & LIMB_DESTROYED)
- continue
+ if(ishuman(target))
+ to_chat(user,"4")
+ if(!(affecting.status & LIMB_DESTROYED) && ishuman(target))
+ to_chat(user, "ma [surgeryloop]")
+ continue
+ to_chat(user,"5")
+ if(affecting.parent && affecting.parent.status & LIMB_DESTROYED && ishuman(target))
+ to_chat(user, "mk failed [surgeryloop]")
+ continue
+ to_chat(user,"6")
if(surgeryloop.requires_bodypart_type && !(affecting.status & surgeryloop.requires_bodypart_type))
+ to_chat(user, "mobcheck failed [surgeryloop]")
continue
else if(surgeryloop.requires_bodypart) //mob with no limb in surgery zone when we need a limb
+ to_chat(user, "FUCK FUCK FUCK")
continue
-
+ to_chat(user,"8")
+ to_chat(user, "Limbcheck passed for [surgeryloop]")
//Surgery-specific requirements.
if(!surgeryloop.can_start(user, target, affecting, tool))
+ to_chat(user, "this kekw")
continue
-
//Tool checks.
var/datum/surgery_step/current_step = GLOB.surgery_step_list[surgeryloop.steps[1]]
@@ -81,14 +104,17 @@
var/datum/surgery_step/next_step = GLOB.surgery_step_list[surgeryloop.steps[2]]
if(!next_step.tool_check(user, tool, surgeryloop))
valid_steps += next_step
+ to_chat(user, "Limbr [surgeryloop]")
continue
else
+ to_chat(user, "Limbcheck for [surgeryloop]")
continue
-
+ to_chat(user, "m AAAAAAAAA[surgeryloop]")
available_surgeries[surgeryloop.name] = surgeryloop //Add it to the list.
-
+ to_chat(user, "m [available_surgeries]")
if(!length(available_surgeries))
if(!tool)
+ to_chat(user, "Limbcheck passaaaaasFFFFFFFFFFssssssed for")
return FALSE
if(target.incision_depths[target_zone] == SURGERY_DEPTH_SURFACE ? is_surgery_init_tool(tool) : is_surgery_tool(tool))
@@ -98,13 +124,15 @@
return FALSE
if(!length(valid_steps))
+ to_chat(user, "Limbcheck passaaaaasssssssed for")
var/limbname = affecting?.status & LIMB_DESTROYED ? "the stump of [target]'s [affecting.display_name]" : "[target]'s [parse_zone(target_zone)]"
if(target.incision_depths[target_zone] != SURGERY_DEPTH_SURFACE)
to_chat(user, SPAN_WARNING("You don't know of any operations you could perform in the [target.incision_depths[target_zone]] incision on [limbname]."))
else
to_chat(user, SPAN_WARNING("You don't know of any operations you could begin on [limbname]."))
+ to_chat(user, SPAN_WARNING("You can't perform surgery rfrfrfrfrfrfrfrhere!"))
return FALSE
-
+ to_chat(user, "mSTARTING surgeryloop]")
var/hint_msg
for(var/datum/surgery_step/current_step as anything in valid_steps)
if(hint_msg)
@@ -115,12 +143,14 @@
else
hint_msg = "You can't [current_step.desc] with \the [tool]"
to_chat(user, SPAN_WARNING("[hint_msg]."))
+ to_chat(user, SPAN_WARNING("You cana1231231231232131222aasdd't perform surgery here!"))
return FALSE
var/datum/surgery/surgeryinstance
if(length(available_surgeries) == 1)
surgeryinstance = available_surgeries[available_surgeries[1]]
else
+ to_chat(user, "mama [available_surgeries[1]]")
surgeryinstance = available_surgeries[tgui_input_list(user, "Begin which procedure?", "Surgery", sortList(available_surgeries))]
//we check that the surgery is still doable after the input() wait.
if(!surgeryinstance || QDELETED(user) || user.is_mob_incapacitated() || !user.Adjacent(target) || tool != user.get_active_hand() || target_zone != user.zone_selected)
@@ -159,7 +189,7 @@
return TRUE
if(!surgeryinstance.can_start(user, target, affecting, tool))
return TRUE
-
+ to_chat(user, "Limbcheck pass2222aaaaasssssssed for")
var/datum/surgery/procedure = new surgeryinstance.type(target, target_zone, affecting)
#ifdef DEBUG_SURGERY_INIT
message_admins("[procedure.name] started.")
diff --git a/code/modules/surgery/surgery_procedure.dm b/code/modules/surgery/surgery_procedure.dm
index 8620c557eb4b..f34371c21f02 100644
--- a/code/modules/surgery/surgery_procedure.dm
+++ b/code/modules/surgery/surgery_procedure.dm
@@ -69,10 +69,12 @@
///Used on attackby and attackhand; TRUE means it stops the attack there, FALSE means it performs an item/open hand attack. CHECK OPENHAND ATTACK IS BLOCKED PROPERLY
/datum/surgery/proc/attempt_next_step(mob/user, obj/item/tool, repeating)
+ to_chat(user, "-1")
if(step_in_progress)
if(!user.action_busy) //Otherwise, assume it's the same person.
to_chat(user, SPAN_WARNING("Someone is already performing surgery on [target]'s [affected_limb.display_name]!"))
return FALSE
+
return TRUE //So that you don't poke them with a tool you're already using.
if(user.action_busy)
@@ -88,12 +90,13 @@
to_chat(user, SPAN_WARNING("You need to set [target] down before you can operate on \him!"))
else
to_chat(user, SPAN_WARNING("You can't operate on [target], \he is being carried by [target.pulledby]!"))
+ to_chat(user, "we are here 222")
return FALSE
if(lying_required && target.body_position != LYING_DOWN)
to_chat(user, SPAN_WARNING("[user == target ? "You need" : "[target] needs"] to be lying down for this operation!"))
return FALSE
-
+ to_chat(user, "we are here")
if(user == target)
if(!self_operable)
to_chat(user, SPAN_WARNING("You can't perform this operation on yourself!"))
@@ -102,14 +105,16 @@
to_chat(user, SPAN_WARNING("You can't perform surgery on the same \
[user.zone_selected == "r_hand"||user.zone_selected == "l_hand" ? "hand":"arm"] you're using!"))
return FALSE
-
+ to_chat(user, "2")
var/datum/surgery_step/current_step = GLOB.surgery_step_list[steps[status]]
if(current_step)
+ to_chat(user, "we are hersteasae")
if(current_step.attempt_step(user, target, user.zone_selected, tool, src, repeating)) //First, try this step.
return TRUE
var/datum/surgery_step/next_step
if(current_step.skip_step_criteria(user, target, user.zone_selected, tool, src) && status < length(steps)) //If that doesn't work but the step is optional and not the last in the list, try the next step.
next_step = GLOB.surgery_step_list[steps[status + 1]]
+ to_chat(user, "we are her12312312312313131231kkakkake")
if(next_step.attempt_step(user, target, user.zone_selected, tool, src, skipped = TRUE))
return TRUE
if(tool && is_surgery_tool(tool)) //Just because you used the wrong tool doesn't mean you meant to whack the patient with it...
@@ -117,6 +122,8 @@
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool], or [next_step.desc]."))
else
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool]."))
+ to_chat(user, "we are here 22")
return FALSE //...but you might be wanting to use it on them anyway. If on help intent, the help-intent safety will apply for this attack.
+ to_chat(user, "we are here 2")
return FALSE
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
new file mode 100644
index 000000000000..eeb4bac701fe
--- /dev/null
+++ b/code/modules/surgery/xeno.dm
@@ -0,0 +1,129 @@
+
+//Research stuff to extract stuff from xenomorphs for goodies. In other words, to extract usefull material that could be used to upgrade marines and etc. doesnt add anything of kind
+
+/datum/surgery/xenomorph
+ name = "Experimental Harvesting Surgery"
+ invasiveness = list(SURGERY_DEPTH_SURFACE)
+ required_surgery_skill = SKILL_SURGERY_NOVICE
+ possible_locs = list("head")
+ target_mobtypes = list(/mob/living/carbon/xenomorph)
+ steps = list(
+ /datum/surgery_step/xenomorph/cut_exoskeleton,
+ /datum/surgery_step/xenomorph/open_exoskeleton,
+ ///datum/surgery_step/xenomorph/severe_connections
+ )
+ lying_required = FALSE
+ requires_bodypart_type = NONE
+ requires_bodypart = FALSE
+
+/datum/surgery/xenomorph/can_start(mob/user, mob/living/carbon/xenomorph/patient, obj/limb/L, obj/item/tool)
+ if(patient.stat == DEAD && !patient.organ_removed)
+ return TRUE
+ return FALSE
+
+/datum/surgery_step/xenomorph/cut_exoskeleton
+ name = "Cut Exoskeleton Carapace"
+ desc = "Cut the carapace open."
+ tools = SURGERY_TOOLS_SEVER_BONE
+ time = 4 SECONDS
+ preop_sound = 'sound/handling/clothingrustle1.ogg'
+ success_sound = 'sound/handling/bandage.ogg'
+ failure_sound = 'sound/surgery/organ2.ogg'
+
+/datum/surgery_step/xenomorph/cut_exoskeleton/preop(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/circular_saw)
+ user.affected_message(target,
+ SPAN_NOTICE("You start to cut [target.caste_type] carapace apart using \the [tool], carefully, with barely any acid."),
+ SPAN_NOTICE("[user] starts to cut Your carapace apart using \the [tool], carefully, with barely any acid."),
+ SPAN_NOTICE("[user] starts to cut [target.caste_type] carapace. \the [tool], carefully, with barely any acid."))
+ if(user.head && !(user.head.flags_inventory & COVEREYES))
+ var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
+ user_eye.take_damage(rand(1,2), FALSE)
+ to_chat(user, SPAN_DANGER("Some acid gets into your eyes!"))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You start to [pick("smash", "crack", "break")] [target.caste_type] carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
+ SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] Your carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
+ SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] [target.caste_type] carapace with \the [tool], Recklessly, with acid splashing him!"))
+ if(user.head && !(user.head.flags_inventory & COVEREYES))
+ var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
+ user_eye.take_damage(rand(3,5), FALSE)
+ to_chat(user, SPAN_DANGER("Lots of acid gets into your eyes!"))
+ user.emote("pain")
+ user.apply_damage(rand(10,25),BURN)
+
+/datum/surgery_step/xenomorph/cut_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/circular_saw)
+ user.affected_message(target,
+ SPAN_NOTICE("You succesfully cut through [target.caste_type] carapace apart using \the [tool]."),
+ SPAN_NOTICE("[user] Succesfully cuts through Your carapace. \the [tool]."),
+ SPAN_NOTICE("[user] Succesfully cuts [target.caste_type] carapace. \the [tool]."))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You succesfully destroy [target.caste_type] carapace into bits and pieces apart using \the [tool]."),
+ SPAN_NOTICE("[user] succesfully destroys Your carapace into bits and pieces apart using \the [tool]."),,
+ SPAN_NOTICE("[user] Succesfully destroys [target.caste_type] carapace into bits and pieces apart using \the [tool]."))
+
+/datum/surgery_step/xenomorph/cut_exoskeleton/failure(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/circular_saw)
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, failing to cut [target.caste_type] carapace apart using \the [tool]!"),
+ SPAN_WARNING("[user] hand slips, failing to cut Your carapace apart using \the [tool]!"),
+ SPAN_WARNING("[user] hand slips, failing to cut [target.caste_type] carapace using \the [tool]!"))
+ else
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, failing to destroy [target.caste_type] carapace into bits and pieces apart using \the [tool]."),
+ SPAN_WARNING("[user] hand slips, failing to destroy Your carapace into bits and pieces using \the [tool]."),
+ SPAN_WARNING("[user] hand slips, failing to destroy [target.caste_type] carapace into bits and pieces using \the [tool]."))
+
+/datum/surgery_step/xenomorph/open_exoskeleton
+ name = "Pry exoskeleton open"
+ desc = "Open the exoskeleton in the opening."
+ tools = SURGERY_TOOLS_PRY_ENCASED
+ time = 3 SECONDS
+ preop_sound = 'sound/surgery/retractor1.ogg'
+ success_sound = 'sound/surgery/retractor2.ogg'
+ failure_sound = 'sound/surgery/organ1.ogg'
+
+/datum/surgery_step/xenomorph/open_exoskeleton/preop(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ user.affected_message(target,
+ SPAN_NOTICE("You start to pry [target.caste_type] carapace open using \the [tool], slowly"),
+ SPAN_NOTICE("[user] starts to pry Your carapace open with \the [tool] very carefully"),
+ SPAN_NOTICE("[user] starts to pry [target.caste_type] carapace open with \the [tool] very carefully"))
+
+/datum/surgery_step/xenomorph/open_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/retractor)
+ user.affected_message(target,
+ SPAN_NOTICE("You hold [target.caste_type] carapace and exoskeleton open using \the [tool], exposing [target.caste_type] vital organs"),
+ SPAN_NOTICE("[user] Holds Your carapace and exoskeleton open with \the [tool], exposing [target.caste_type] vital organs "),
+ SPAN_NOTICE("[user] Holds [target.caste_type] carapace and exoskeleton open with \the [tool], exposing [target.caste_type] vital organs "))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You Hold [target.caste_type] carapace open using \the [tool] like a medieval doctor, exposing [target.caste_type] vital organs"),
+ SPAN_NOTICE("[user] starts to open Your carapace with \the [tool] very carefully"),
+ SPAN_NOTICE("[user] starts to open [target.caste_type] carapace with \the [tool] very carefully"))
+
+/datum/surgery_step/xenomorph/open_exoskeleton/failure(mob/living/carbon/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
+ SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
+ SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"))
+ user.apply_damage(rand(5, 15), BURN)
+/*
+/datum/surgery_step/xenomorph/severe_connections
+ name = "Severe organ connections"
+ desc = "Detach tubes and connections from organ."
+ tools = list(
+ /obj/item/tool/surgery/scalpel = SURGERY_TOOL_MULT_IDEAL,
+ /obj/item/tool/surgery/scalpel/pict_system = SURGERY_TOOL_MULT_IDEAL,
+ /obj/item/attachable/bayonet = SURGERY_TOOL_MULT_SUBSTITUTE,
+ /obj/item/tool/kitchen/knife = SURGERY_TOOL_MULT_SUBSTITUTE,
+ /obj/item/shard = SURGERY_TOOL_MULT_AWFUL,
+ ) //shamelessly taken from embryo code
+ time = 5 SECONDS
+ preop_sound = 'sound/surgery/scalpel1.ogg'
+ success_sound = 'sound/surgery/scalpel2.ogg'
+ failure_sound = 'sound/surgery/organ2.ogg'
+
+/datum/surgery_step/xenomorph/remove_organ
+*/
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 4df1bd2afb54..6fda30edf4cf 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -2296,6 +2296,7 @@
#include "code\modules\surgery\surgery_steps.dm"
#include "code\modules\surgery\surgery_toggle.dm"
#include "code\modules\surgery\tendwounds.dm"
+#include "code\modules\surgery\xeno.dm"
#include "code\modules\teleporters\teleporter.dm"
#include "code\modules\teleporters\teleporter_admin_verbs.dm"
#include "code\modules\teleporters\teleporter_console.dm"
From 557815375c98eca6c35eb1f1990e4cd92f787678 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Fri, 19 Jan 2024 07:26:45 -0500
Subject: [PATCH 004/113] AH
---
code/_onclick/item_attack.dm | 15 ---
.../mob/living/carbon/xenomorph/Xenomorph.dm | 1 +
.../living/carbon/xenomorph/damage_procs.dm | 8 ++
code/modules/organs/organ_objects.dm | 7 ++
code/modules/surgery/surgery_initiator.dm | 44 ++------
code/modules/surgery/surgery_procedure.dm | 8 --
code/modules/surgery/xeno.dm | 104 +++++++++++++++---
7 files changed, 113 insertions(+), 74 deletions(-)
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 4d77a7113048..80e97758669e 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -68,21 +68,6 @@
if(!(user in viewers(M, null)))
showname = "."
- if(isxeno(M) && M.stat == DEAD)
- var/datum/surgery/current_surgery = M.active_surgeries[user.zone_selected]
- if(current_surgery)
- to_chat(user, "we are here000000")
- if(current_surgery.attempt_next_step(user, src))
- to_chat(user, "we are here 2oh")
- return FALSE //Cancel attack.
- to_chat(user, "we are here 2uh")
- else
- to_chat(user, "we are here 2")
- if(initiate_surgery_moment(src, M, "head" , user))
- to_chat(user, "got true")
- return FALSE
- to_chat(user, "got false")
-
if (user.a_intent == INTENT_HELP && ((user.client?.prefs && user.client?.prefs?.toggle_prefs & TOGGLE_HELP_INTENT_SAFETY) || (user.mob_flags & SURGERY_MODE_ON)))
playsound(loc, 'sound/effects/pop.ogg', 25, 1)
user.visible_message(SPAN_NOTICE("[M] has been poked with [src][showname]"),\
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 209b35bd85a4..5c991dae7dfd 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -395,6 +395,7 @@
mutators.xeno = src
+
//Set caste stuff
if(caste_type && GLOB.xeno_datum_list[caste_type])
caste = GLOB.xeno_datum_list[caste_type]
diff --git a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
index 624c9df25f3e..9fada5e1f8ea 100644
--- a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
+++ b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm
@@ -16,6 +16,14 @@
return
programmer.visible_message(SPAN_NOTICE("[programmer] reprograms \the [src]'s IFF tag."), SPAN_NOTICE("You reprogram \the [src]'s IFF tag."), max_distance = 3)
return
+ if(stat == DEAD)
+ var/datum/surgery/current_surgery = active_surgeries[user.zone_selected]
+ if(current_surgery)
+ if(current_surgery.attempt_next_step(user, item))
+ return
+ else
+ if(initiate_surgery_moment(item, src, "head" , user))
+ return
if(item.type in SURGERY_TOOLS_PINCH)
if(!iff_tag)
to_chat(user, SPAN_WARNING("\The [src] doesn't have an IFF tag to remove."))
diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm
index d011933e4b2e..7f558f82562b 100644
--- a/code/modules/organs/organ_objects.dm
+++ b/code/modules/organs/organ_objects.dm
@@ -114,6 +114,13 @@
organ_tag = "liver"
organ_type = /datum/internal_organ/liver
+/obj/item/organ/heart/xeno
+ name = "Acidic Heart"
+ desc = "Acidic heart removed from a xenomorph. It spews droplets of acid every so often. Definetly not human heart."
+ icon_state = "heart-on"
+ organ_tag = "heart"
+ black_market_value = 60
+
//These are here so they can be printed out via the fabricator.
/obj/item/organ/heart/prosthetic
name = "circulatory pump"
diff --git a/code/modules/surgery/surgery_initiator.dm b/code/modules/surgery/surgery_initiator.dm
index 46118e140b96..642411df76c0 100644
--- a/code/modules/surgery/surgery_initiator.dm
+++ b/code/modules/surgery/surgery_initiator.dm
@@ -6,7 +6,7 @@
/proc/initiate_surgery_moment(obj/item/tool, mob/living/carbon/target, obj/limb/affecting, mob/living/user)
if(!tool && !(affecting.status & LIMB_UNCALIBRATED_PROSTHETIC))
- to_chat(user, SPAN_WARNING("You can't perform surgery hggggggggggggggere!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
to_chat(user, tool)
var/target_zone = user.zone_selected
@@ -21,14 +21,14 @@
if(!istype(T) || !T.supports_surgery)
if(tool.flags_item & CAN_DIG_SHRAPNEL) //Both shrapnel removal and prosthetic repair shouldn't be affected by being on the dropship.
tool.dig_out_shrapnel_check(target, user)
- to_chat(user, SPAN_WARNING("You can't peasdasdrform surgery here!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return TRUE //Otherwise you get 'poked' by the knife.
if(HAS_TRAIT(tool, TRAIT_TOOL_BLOWTORCH) && affecting)
- to_chat(user, SPAN_WARNING("You can't perform saaaaaaaaaaaaaaaasurgery here!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
if(!(tool.type in SURGERY_TOOLS_NO_INIT_MSG))
to_chat(user, SPAN_WARNING("You can't perform surgery under these bad conditions!"))
- to_chat(user, SPAN_WARNING("You can't perform suggggggggggrgery here!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
var/obj/limb/surgery_limb = target.get_limb(target_zone)
@@ -39,13 +39,13 @@
return
if(user.action_busy) //already doing an action
- to_chat(user, SPAN_WARNING("You can't perform surgerasdasdasdasdasdy here!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
for(var/datum/surgery/surgeryloop as anything in GLOB.surgeries_by_zone_and_depth[target_zone][target.incision_depths[target_zone]])
//Skill check.
if((target.mob_flags & EASY_SURGERY) ? !skillcheck(user, SKILL_SURGERY, SKILL_SURGERY_NOVICE) : !skillcheck(user, SKILL_SURGERY, surgeryloop.required_surgery_skill))
- to_chat(user, SPAN_WARNING("You can't perform surgery heraaaaaaaaaaaaaaaaaaaaaaaae!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
continue
to_chat(user, surgeryloop)
@@ -53,46 +53,27 @@
if(surgeryloop.lying_required && target.body_position != LYING_DOWN)
continue
if(!surgeryloop.self_operable && target == user)
- to_chat(user, "selfop fail [surgeryloop]")
continue
- to_chat(user, "starting lspecies [surgeryloop]")
//Species check.
if(!is_type_in_typecache(target, GLOB.surgical_patient_types["[surgeryloop]"]))
- to_chat(user, "mobcheck failed [surgeryloop]")
continue
- to_chat(user, "starting limbcheck [surgeryloop]")
//Limb checks.
- to_chat(user,"0")
if(affecting)
- to_chat(user,"1")
if(surgeryloop.requires_bodypart)
- to_chat(user,"2")
if(affecting.status & LIMB_DESTROYED)
- to_chat(user,"3")
- to_chat(user, "m [surgeryloop] asdadas")
continue
else
if(ishuman(target))
- to_chat(user,"4")
if(!(affecting.status & LIMB_DESTROYED) && ishuman(target))
- to_chat(user, "ma [surgeryloop]")
continue
- to_chat(user,"5")
if(affecting.parent && affecting.parent.status & LIMB_DESTROYED && ishuman(target))
- to_chat(user, "mk failed [surgeryloop]")
continue
- to_chat(user,"6")
if(surgeryloop.requires_bodypart_type && !(affecting.status & surgeryloop.requires_bodypart_type))
- to_chat(user, "mobcheck failed [surgeryloop]")
continue
else if(surgeryloop.requires_bodypart) //mob with no limb in surgery zone when we need a limb
- to_chat(user, "FUCK FUCK FUCK")
continue
- to_chat(user,"8")
- to_chat(user, "Limbcheck passed for [surgeryloop]")
//Surgery-specific requirements.
if(!surgeryloop.can_start(user, target, affecting, tool))
- to_chat(user, "this kekw")
continue
//Tool checks.
@@ -104,17 +85,12 @@
var/datum/surgery_step/next_step = GLOB.surgery_step_list[surgeryloop.steps[2]]
if(!next_step.tool_check(user, tool, surgeryloop))
valid_steps += next_step
- to_chat(user, "Limbr [surgeryloop]")
continue
else
- to_chat(user, "Limbcheck for [surgeryloop]")
continue
- to_chat(user, "m AAAAAAAAA[surgeryloop]")
available_surgeries[surgeryloop.name] = surgeryloop //Add it to the list.
- to_chat(user, "m [available_surgeries]")
if(!length(available_surgeries))
if(!tool)
- to_chat(user, "Limbcheck passaaaaasFFFFFFFFFFssssssed for")
return FALSE
if(target.incision_depths[target_zone] == SURGERY_DEPTH_SURFACE ? is_surgery_init_tool(tool) : is_surgery_tool(tool))
@@ -124,15 +100,13 @@
return FALSE
if(!length(valid_steps))
- to_chat(user, "Limbcheck passaaaaasssssssed for")
var/limbname = affecting?.status & LIMB_DESTROYED ? "the stump of [target]'s [affecting.display_name]" : "[target]'s [parse_zone(target_zone)]"
if(target.incision_depths[target_zone] != SURGERY_DEPTH_SURFACE)
to_chat(user, SPAN_WARNING("You don't know of any operations you could perform in the [target.incision_depths[target_zone]] incision on [limbname]."))
else
to_chat(user, SPAN_WARNING("You don't know of any operations you could begin on [limbname]."))
- to_chat(user, SPAN_WARNING("You can't perform surgery rfrfrfrfrfrfrfrhere!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
- to_chat(user, "mSTARTING surgeryloop]")
var/hint_msg
for(var/datum/surgery_step/current_step as anything in valid_steps)
if(hint_msg)
@@ -143,14 +117,13 @@
else
hint_msg = "You can't [current_step.desc] with \the [tool]"
to_chat(user, SPAN_WARNING("[hint_msg]."))
- to_chat(user, SPAN_WARNING("You cana1231231231232131222aasdd't perform surgery here!"))
+ to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
var/datum/surgery/surgeryinstance
if(length(available_surgeries) == 1)
surgeryinstance = available_surgeries[available_surgeries[1]]
else
- to_chat(user, "mama [available_surgeries[1]]")
surgeryinstance = available_surgeries[tgui_input_list(user, "Begin which procedure?", "Surgery", sortList(available_surgeries))]
//we check that the surgery is still doable after the input() wait.
if(!surgeryinstance || QDELETED(user) || user.is_mob_incapacitated() || !user.Adjacent(target) || tool != user.get_active_hand() || target_zone != user.zone_selected)
@@ -189,7 +162,6 @@
return TRUE
if(!surgeryinstance.can_start(user, target, affecting, tool))
return TRUE
- to_chat(user, "Limbcheck pass2222aaaaasssssssed for")
var/datum/surgery/procedure = new surgeryinstance.type(target, target_zone, affecting)
#ifdef DEBUG_SURGERY_INIT
message_admins("[procedure.name] started.")
diff --git a/code/modules/surgery/surgery_procedure.dm b/code/modules/surgery/surgery_procedure.dm
index f34371c21f02..1ec72ae77673 100644
--- a/code/modules/surgery/surgery_procedure.dm
+++ b/code/modules/surgery/surgery_procedure.dm
@@ -69,7 +69,6 @@
///Used on attackby and attackhand; TRUE means it stops the attack there, FALSE means it performs an item/open hand attack. CHECK OPENHAND ATTACK IS BLOCKED PROPERLY
/datum/surgery/proc/attempt_next_step(mob/user, obj/item/tool, repeating)
- to_chat(user, "-1")
if(step_in_progress)
if(!user.action_busy) //Otherwise, assume it's the same person.
to_chat(user, SPAN_WARNING("Someone is already performing surgery on [target]'s [affected_limb.display_name]!"))
@@ -90,13 +89,11 @@
to_chat(user, SPAN_WARNING("You need to set [target] down before you can operate on \him!"))
else
to_chat(user, SPAN_WARNING("You can't operate on [target], \he is being carried by [target.pulledby]!"))
- to_chat(user, "we are here 222")
return FALSE
if(lying_required && target.body_position != LYING_DOWN)
to_chat(user, SPAN_WARNING("[user == target ? "You need" : "[target] needs"] to be lying down for this operation!"))
return FALSE
- to_chat(user, "we are here")
if(user == target)
if(!self_operable)
to_chat(user, SPAN_WARNING("You can't perform this operation on yourself!"))
@@ -105,16 +102,13 @@
to_chat(user, SPAN_WARNING("You can't perform surgery on the same \
[user.zone_selected == "r_hand"||user.zone_selected == "l_hand" ? "hand":"arm"] you're using!"))
return FALSE
- to_chat(user, "2")
var/datum/surgery_step/current_step = GLOB.surgery_step_list[steps[status]]
if(current_step)
- to_chat(user, "we are hersteasae")
if(current_step.attempt_step(user, target, user.zone_selected, tool, src, repeating)) //First, try this step.
return TRUE
var/datum/surgery_step/next_step
if(current_step.skip_step_criteria(user, target, user.zone_selected, tool, src) && status < length(steps)) //If that doesn't work but the step is optional and not the last in the list, try the next step.
next_step = GLOB.surgery_step_list[steps[status + 1]]
- to_chat(user, "we are her12312312312313131231kkakkake")
if(next_step.attempt_step(user, target, user.zone_selected, tool, src, skipped = TRUE))
return TRUE
if(tool && is_surgery_tool(tool)) //Just because you used the wrong tool doesn't mean you meant to whack the patient with it...
@@ -122,8 +116,6 @@
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool], or [next_step.desc]."))
else
to_chat(user, SPAN_WARNING("You can't [current_step.desc] with \the [tool]."))
- to_chat(user, "we are here 22")
return FALSE //...but you might be wanting to use it on them anyway. If on help intent, the help-intent safety will apply for this attack.
- to_chat(user, "we are here 2")
return FALSE
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
index eeb4bac701fe..f92703145ea2 100644
--- a/code/modules/surgery/xeno.dm
+++ b/code/modules/surgery/xeno.dm
@@ -10,7 +10,8 @@
steps = list(
/datum/surgery_step/xenomorph/cut_exoskeleton,
/datum/surgery_step/xenomorph/open_exoskeleton,
- ///datum/surgery_step/xenomorph/severe_connections
+ /datum/surgery_step/xenomorph/severe_connections,
+ /datum/surgery_step/xenomorph/remove_organ
)
lying_required = FALSE
requires_bodypart_type = NONE
@@ -36,10 +37,6 @@
SPAN_NOTICE("You start to cut [target.caste_type] carapace apart using \the [tool], carefully, with barely any acid."),
SPAN_NOTICE("[user] starts to cut Your carapace apart using \the [tool], carefully, with barely any acid."),
SPAN_NOTICE("[user] starts to cut [target.caste_type] carapace. \the [tool], carefully, with barely any acid."))
- if(user.head && !(user.head.flags_inventory & COVEREYES))
- var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
- user_eye.take_damage(rand(1,2), FALSE)
- to_chat(user, SPAN_DANGER("Some acid gets into your eyes!"))
else
user.affected_message(target,
SPAN_NOTICE("You start to [pick("smash", "crack", "break")] [target.caste_type] carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
@@ -48,11 +45,11 @@
if(user.head && !(user.head.flags_inventory & COVEREYES))
var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
user_eye.take_damage(rand(3,5), FALSE)
- to_chat(user, SPAN_DANGER("Lots of acid gets into your eyes!"))
+ to_chat(user, SPAN_DANGER("Lots of acid gets into your eyes and on your skin!"))
user.emote("pain")
user.apply_damage(rand(10,25),BURN)
-/datum/surgery_step/xenomorph/cut_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+/datum/surgery_step/xenomorph/cut_exoskeleton/success(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
if(tool_type == /obj/item/tool/surgery/circular_saw)
user.affected_message(target,
SPAN_NOTICE("You succesfully cut through [target.caste_type] carapace apart using \the [tool]."),
@@ -64,7 +61,7 @@
SPAN_NOTICE("[user] succesfully destroys Your carapace into bits and pieces apart using \the [tool]."),,
SPAN_NOTICE("[user] Succesfully destroys [target.caste_type] carapace into bits and pieces apart using \the [tool]."))
-/datum/surgery_step/xenomorph/cut_exoskeleton/failure(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+/datum/surgery_step/xenomorph/cut_exoskeleton/failure(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
if(tool_type == /obj/item/tool/surgery/circular_saw)
user.affected_message(target,
SPAN_WARNING("Your hand slips, failing to cut [target.caste_type] carapace apart using \the [tool]!"),
@@ -80,18 +77,18 @@
name = "Pry exoskeleton open"
desc = "Open the exoskeleton in the opening."
tools = SURGERY_TOOLS_PRY_ENCASED
- time = 3 SECONDS
+ time = 2 SECONDS
preop_sound = 'sound/surgery/retractor1.ogg'
success_sound = 'sound/surgery/retractor2.ogg'
failure_sound = 'sound/surgery/organ1.ogg'
-/datum/surgery_step/xenomorph/open_exoskeleton/preop(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+/datum/surgery_step/xenomorph/open_exoskeleton/preop(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
user.affected_message(target,
SPAN_NOTICE("You start to pry [target.caste_type] carapace open using \the [tool], slowly"),
SPAN_NOTICE("[user] starts to pry Your carapace open with \the [tool] very carefully"),
SPAN_NOTICE("[user] starts to pry [target.caste_type] carapace open with \the [tool] very carefully"))
-/datum/surgery_step/xenomorph/open_exoskeleton/success(mob/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+/datum/surgery_step/xenomorph/open_exoskeleton/success(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
if(tool_type == /obj/item/tool/surgery/retractor)
user.affected_message(target,
SPAN_NOTICE("You hold [target.caste_type] carapace and exoskeleton open using \the [tool], exposing [target.caste_type] vital organs"),
@@ -103,13 +100,13 @@
SPAN_NOTICE("[user] starts to open Your carapace with \the [tool] very carefully"),
SPAN_NOTICE("[user] starts to open [target.caste_type] carapace with \the [tool] very carefully"))
-/datum/surgery_step/xenomorph/open_exoskeleton/failure(mob/living/carbon/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+/datum/surgery_step/xenomorph/open_exoskeleton/failure(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
user.affected_message(target,
SPAN_WARNING("Your hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"))
user.apply_damage(rand(5, 15), BURN)
-/*
+
/datum/surgery_step/xenomorph/severe_connections
name = "Severe organ connections"
desc = "Detach tubes and connections from organ."
@@ -120,10 +117,87 @@
/obj/item/tool/kitchen/knife = SURGERY_TOOL_MULT_SUBSTITUTE,
/obj/item/shard = SURGERY_TOOL_MULT_AWFUL,
) //shamelessly taken from embryo code
- time = 5 SECONDS
+ time = 4 SECONDS
preop_sound = 'sound/surgery/scalpel1.ogg'
success_sound = 'sound/surgery/scalpel2.ogg'
failure_sound = 'sound/surgery/organ2.ogg'
+/datum/surgery_step/xenomorph/severe_connections/preop(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ user.affected_message(target,
+ SPAN_NOTICE("You start to severe [target.caste_type] organ links using \the [tool], with confidence"),
+ SPAN_NOTICE("[user] start to severe Your organ links using \the [tool], with confidence"),
+ SPAN_NOTICE("[user] starts to severe [target.caste_type] organ links using \the [tool], with confidence"))
+
+/datum/surgery_step/xenomorph/severe_connections/success(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool_type == /obj/item/tool/surgery/retractor)
+ user.affected_message(target,
+ SPAN_NOTICE("You severed [target.caste_type] connections and links to vital organs using \the [tool]"),
+ SPAN_NOTICE("[user] severed Your connections and links to vital organs using \the [tool]"),
+ SPAN_NOTICE("[user] severed [target.caste_type] connections and links to vital organs using \the [tool]"))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You rip [target.caste_type] connections and links to vital organs apart using \the [tool]"),
+ SPAN_NOTICE("[user] rips Your connections and links to vital organs apart using \the [tool]"),
+ SPAN_NOTICE("[user] rips [target.caste_type] connections and links to vital organs apart using \the [tool]"))
+
+/datum/surgery_step/xenomorph/severe_connections/failure(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, damaging one of [target.caste_type] [pick("arteries", "viens")], gushing acid blood everywhere!"),
+ SPAN_WARNING("[user] hand slips, damaging one of Your [pick("arteries", "viens")], gushing acid blood everywhere!"),
+ SPAN_WARNING("[user] hand slips, damaging one of [target.caste_type] [pick("arteries", "viens")], gushing acid blood everywhere!"))
+ user.apply_damage(rand(5, 15), BURN)
+
/datum/surgery_step/xenomorph/remove_organ
-*/
+ name = "Take out the organ"
+ desc = "Grab a hold of it and pull the organ out."
+ accept_hand = TRUE
+ tools = list(
+ /obj/item/tool/surgery/hemostat = 1.5,
+ /obj/item/tool/wirecutters = SURGERY_TOOL_MULT_SUBOPTIMAL,
+ /obj/item/tool/kitchen/utensil/fork = SURGERY_TOOL_MULT_SUBSTITUTE
+ )//shamelessly taken from embryo code
+ time = 6 SECONDS
+ preop_sound = 'sound/surgery/scalpel1.ogg'
+ success_sound = 'sound/surgery/scalpel2.ogg'
+ failure_sound = 'sound/surgery/organ2.ogg'
+
+/datum/surgery_step/xenomorph/remove_organ/preop(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool)
+ user.affected_message(target,
+ SPAN_NOTICE("You start to get a firm grip on the [target.caste_type] organ using \the [tool] "),
+ SPAN_NOTICE("[user] start to get a firm grip on your insides using \the [tool]"),
+ SPAN_NOTICE("[user] starts to get a firm grip on the [target.caste_type] organ using \the [tool] "))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You start to get a firm grip on the [target.caste_type] organ"),
+ SPAN_NOTICE("[user] start to get a firm grip on your insides"),
+ SPAN_NOTICE("[user] starts to get a firm grip on the [target.caste_type] organ"))
+
+/datum/surgery_step/xenomorph/remove_organ/success(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool)
+ user.affected_message(target,
+ SPAN_NOTICE("You pulled the [target.caste_type] organ out using \the [tool]"),
+ SPAN_NOTICE("[user] pulled Your organ out using \the [tool]"),
+ SPAN_NOTICE("[user] pulled the [target.caste_type] organ out using \the [tool]"))
+ else
+ user.affected_message(target,
+ SPAN_NOTICE("You burn your hands as you pulled the [target.caste_type] organ out!"),
+ SPAN_NOTICE("[user] burns their hands as they pulled Your insides out!"),
+ SPAN_NOTICE("[user] burns their hands as they pulled the [target.caste_type] organ out"))
+ user.emote("pain")
+ if(user.hand)
+ user.apply_damage(15, BURN, "l_hand")
+ else
+ user.apply_damage(15, BURN, "r_hand")
+ //spawn organ here, hm, maybe a good idea to give all benos organs on init instead of spawning it here out of thin air
+ target.organ_removed = TRUE
+ var/obj/item/organ/heart/xeno/organ = new()
+ organ.forceMove(target.loc)
+
+/datum/surgery_step/xenomorph/remove_organ/failure(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
+ if(tool)
+ user.affected_message(target,
+ SPAN_NOTICE("You fail to pull the [target.caste_type] organ out using \the [tool]"),
+ SPAN_NOTICE("[user] pulled Your organ out using \the [tool]"),
+ SPAN_NOTICE("[user] pulled the [target.caste_type] organ out using \the [tool]"))
+
From b9ffd6be131e8ba81e2707b603437944ad2dc333 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Fri, 19 Jan 2024 09:39:45 -0500
Subject: [PATCH 005/113] organ changes
---
code/_onclick/item_attack.dm | 2 +-
code/modules/mob/living/carbon/xenomorph/Xenomorph.dm | 4 ++++
code/modules/organs/organ_objects.dm | 1 +
code/modules/surgery/xeno.dm | 3 +--
4 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 80e97758669e..8d77920a59cc 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -71,7 +71,7 @@
if (user.a_intent == INTENT_HELP && ((user.client?.prefs && user.client?.prefs?.toggle_prefs & TOGGLE_HELP_INTENT_SAFETY) || (user.mob_flags & SURGERY_MODE_ON)))
playsound(loc, 'sound/effects/pop.ogg', 25, 1)
user.visible_message(SPAN_NOTICE("[M] has been poked with [src][showname]"),\
- SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src].LORD"), null, 4)
+ SPAN_NOTICE("You poke [M == user ? "yourself":M] with [src]."), null, 4)
return FALSE
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 5c991dae7dfd..2f31e2821100 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -349,6 +349,10 @@
else if(hivenumber)
src.hivenumber = hivenumber
+ var/obj/item/organ/heart/xeno/organ = new() //give
+ organ.forceMove(src)
+ organ.research_value = tier
+
var/datum/hive_status/hive = GLOB.hive_datum[src.hivenumber]
if(hive)
diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm
index 7f558f82562b..18d59d71d28a 100644
--- a/code/modules/organs/organ_objects.dm
+++ b/code/modules/organs/organ_objects.dm
@@ -120,6 +120,7 @@
icon_state = "heart-on"
organ_tag = "heart"
black_market_value = 60
+ var/research_value = 1 //depending on the size and tier
//These are here so they can be printed out via the fabricator.
/obj/item/organ/heart/prosthetic
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
index f92703145ea2..82f9a899853e 100644
--- a/code/modules/surgery/xeno.dm
+++ b/code/modules/surgery/xeno.dm
@@ -189,9 +189,8 @@
user.apply_damage(15, BURN, "l_hand")
else
user.apply_damage(15, BURN, "r_hand")
- //spawn organ here, hm, maybe a good idea to give all benos organs on init instead of spawning it here out of thin air
target.organ_removed = TRUE
- var/obj/item/organ/heart/xeno/organ = new()
+ var/obj/item/organ/heart/xeno/organ = locate() in target
organ.forceMove(target.loc)
/datum/surgery_step/xenomorph/remove_organ/failure(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
From 2d8a5adbf5c451e5fd4bb418519f3152f79ae3b5 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Fri, 19 Jan 2024 09:43:01 -0500
Subject: [PATCH 006/113] mroe shit removed
---
code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm | 4 ++--
code/modules/surgery/surgery_initiator.dm | 2 --
code/modules/surgery/xeno.dm | 8 ++++----
3 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
index ebd720cd1685..39866eb53798 100644
--- a/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
+++ b/code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
@@ -49,10 +49,10 @@
backpack.open(M)
return
if(stat == DEAD)
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens.DED"), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens."), \
SPAN_WARNING("You poke \the [src], but nothing happens."), null, 5, CHAT_TYPE_FLUFF_ACTION)
else
- M.visible_message(SPAN_WARNING("\The [M] pokes \the [src].WA"), \
+ M.visible_message(SPAN_WARNING("\The [M] pokes \the [src]."), \
SPAN_WARNING("You poke \the [src]."), null, 5, CHAT_TYPE_FLUFF_ACTION)
if(INTENT_GRAB)
diff --git a/code/modules/surgery/surgery_initiator.dm b/code/modules/surgery/surgery_initiator.dm
index 642411df76c0..35c21c3ee3e2 100644
--- a/code/modules/surgery/surgery_initiator.dm
+++ b/code/modules/surgery/surgery_initiator.dm
@@ -105,7 +105,6 @@
to_chat(user, SPAN_WARNING("You don't know of any operations you could perform in the [target.incision_depths[target_zone]] incision on [limbname]."))
else
to_chat(user, SPAN_WARNING("You don't know of any operations you could begin on [limbname]."))
- to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
var/hint_msg
for(var/datum/surgery_step/current_step as anything in valid_steps)
@@ -117,7 +116,6 @@
else
hint_msg = "You can't [current_step.desc] with \the [tool]"
to_chat(user, SPAN_WARNING("[hint_msg]."))
- to_chat(user, SPAN_WARNING("You can't perform surgery here!"))
return FALSE
var/datum/surgery/surgeryinstance
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
index 82f9a899853e..cef98fd80358 100644
--- a/code/modules/surgery/xeno.dm
+++ b/code/modules/surgery/xeno.dm
@@ -24,7 +24,7 @@
/datum/surgery_step/xenomorph/cut_exoskeleton
name = "Cut Exoskeleton Carapace"
- desc = "Cut the carapace open."
+ desc = "cut the carapace open"
tools = SURGERY_TOOLS_SEVER_BONE
time = 4 SECONDS
preop_sound = 'sound/handling/clothingrustle1.ogg'
@@ -75,7 +75,7 @@
/datum/surgery_step/xenomorph/open_exoskeleton
name = "Pry exoskeleton open"
- desc = "Open the exoskeleton in the opening."
+ desc = "open the exoskeleton in the incision"
tools = SURGERY_TOOLS_PRY_ENCASED
time = 2 SECONDS
preop_sound = 'sound/surgery/retractor1.ogg'
@@ -109,7 +109,7 @@
/datum/surgery_step/xenomorph/severe_connections
name = "Severe organ connections"
- desc = "Detach tubes and connections from organ."
+ desc = "detach tubes and connections from organ"
tools = list(
/obj/item/tool/surgery/scalpel = SURGERY_TOOL_MULT_IDEAL,
/obj/item/tool/surgery/scalpel/pict_system = SURGERY_TOOL_MULT_IDEAL,
@@ -149,7 +149,7 @@
/datum/surgery_step/xenomorph/remove_organ
name = "Take out the organ"
- desc = "Grab a hold of it and pull the organ out."
+ desc = "grab a hold of it and pull the organ out"
accept_hand = TRUE
tools = list(
/obj/item/tool/surgery/hemostat = 1.5,
From 55d6ec0ba3753560ee34a8f36b68f08a416de495 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Fri, 19 Jan 2024 10:53:03 -0500
Subject: [PATCH 007/113] polising
---
code/modules/surgery/surgery_initiator.dm | 2 +-
code/modules/surgery/xeno.dm | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/code/modules/surgery/surgery_initiator.dm b/code/modules/surgery/surgery_initiator.dm
index 35c21c3ee3e2..e92c2728c318 100644
--- a/code/modules/surgery/surgery_initiator.dm
+++ b/code/modules/surgery/surgery_initiator.dm
@@ -63,7 +63,7 @@
if(affecting.status & LIMB_DESTROYED)
continue
else
- if(ishuman(target))
+ if(ishuman(target))//otherwise breaks when trying to op xeno
if(!(affecting.status & LIMB_DESTROYED) && ishuman(target))
continue
if(affecting.parent && affecting.parent.status & LIMB_DESTROYED && ishuman(target))
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
index cef98fd80358..e3cbd3d5c67f 100644
--- a/code/modules/surgery/xeno.dm
+++ b/code/modules/surgery/xeno.dm
@@ -40,8 +40,8 @@
else
user.affected_message(target,
SPAN_NOTICE("You start to [pick("smash", "crack", "break")] [target.caste_type] carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
- SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] Your carapace apart using \the [tool], Recklessly, with acid splashing on you!"),
- SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] [target.caste_type] carapace with \the [tool], Recklessly, with acid splashing him!"))
+ SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] Your carapace apart using \the [tool], Recklessly, with acid splashing all of the place!"),
+ SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] [target.caste_type] carapace with \the [tool], Recklessly, with acid splashing them!"))
if(user.head && !(user.head.flags_inventory & COVEREYES))
var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
user_eye.take_damage(rand(3,5), FALSE)
@@ -197,6 +197,6 @@
if(tool)
user.affected_message(target,
SPAN_NOTICE("You fail to pull the [target.caste_type] organ out using \the [tool]"),
- SPAN_NOTICE("[user] pulled Your organ out using \the [tool]"),
- SPAN_NOTICE("[user] pulled the [target.caste_type] organ out using \the [tool]"))
+ SPAN_NOTICE("[user] fails to pull Your organ out using \the [tool]"),
+ SPAN_NOTICE("[user] fails to pull the [target.caste_type] organ out using \the [tool]"))
From 33cddf77238e7555da19db61233d33ec855539bd Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Wed, 24 Jan 2024 18:10:45 -0500
Subject: [PATCH 008/113] waa
---
.../mob/living/carbon/xenomorph/Xenomorph.dm | 2 +-
.../chemical_research/xenomorph_analyzer.dm | 77 +++++++++++++++++++
colonialmarines.dme | 1 +
.../tgui/interfaces/XenomorphExtractor.jsx | 75 ++++++++++++++++++
4 files changed, 154 insertions(+), 1 deletion(-)
create mode 100644 code/modules/reagents/chemical_research/xenomorph_analyzer.dm
create mode 100644 tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 2f31e2821100..dd7a3bb63275 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -676,7 +676,7 @@
if(iff_tag)
. += SPAN_NOTICE("It has an IFF tag sticking out of its carapace.")
if(organ_removed)
- . += "It seems to have its organ removed."
+ . += "It seems to have its carapace cut open."
/mob/living/carbon/xenomorph/Destroy()
GLOB.living_xeno_list -= src
diff --git a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
new file mode 100644
index 000000000000..f94ab6aee4c6
--- /dev/null
+++ b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
@@ -0,0 +1,77 @@
+/obj/structure/machinery/xenoanalyzer
+ name = "Biomass Analyzer"
+ desc = "todo"
+ density = TRUE
+ anchored = TRUE
+ icon = 'icons/obj/structures/machinery/science_machines.dmi'
+ icon_state = "mixer0b" //for the time while no sprites
+ use_power = USE_POWER_NONE
+ wrenchable = FALSE
+ idle_power_usage = 40
+ var/biomass_points = 0 //most important thing in this
+ var/obj/item/organ/heart/xeno/organ = null
+
+/obj/structure/machinery/xenoanalyzer/attackby(obj/item/W, mob/user)
+ if(!skillcheck(user, SKILL_RESEARCH, SKILL_RESEARCH_TRAINED))
+ to_chat(user, SPAN_WARNING("You have no idea how to use this."))
+ return
+ if(!istype(W, /obj/item/organ/heart/xeno))
+ return
+ if(!do_after(user, 3 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC))
+ to_chat(user, SPAN_WARNING("You were interupted!"))
+ return
+ if(!user.drop_inv_item_to_loc(W, src))
+ return
+ to_chat(user, SPAN_NOTICE("You fed organ in the machine."))
+ organ = W
+
+/obj/structure/machinery/xenoanalyzer/ui_data(mob/user)
+ var/list/data = list()
+
+ data["points"] = biomass_points
+
+ if(organ)
+ data["organ"] = TRUE
+ else
+ data["organ"] = FALSE
+ return data
+
+
+/obj/structure/machinery/xenoanalyzer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ . = ..()
+ if(.)
+ return
+
+ switch(action)
+ if("eject_organ")
+ eject_biomass()
+ . = TRUE
+
+ if("process_organ")
+ process_organ()
+ . = TRUE
+
+/obj/structure/machinery/xenoanalyzer/proc/eject_biomass()
+ if(isnull(organ))
+ return
+ organ.forceMove(get_turf(src))
+ organ = null
+
+/obj/structure/machinery/xenoanalyzer/proc/process_organ()
+ if(isnull(organ))
+ return
+ playsound(src.loc, 'sound/machines/blender.ogg', 25, 1)
+ biomass_points += organ.research_value * 1000 //inflating values less goo
+ qdel(organ)
+ organ = null
+
+
+
+
+
+
+
+
+
+
+
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 6fda30edf4cf..72b504bef656 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -2214,6 +2214,7 @@
#include "code\modules\reagents\Chemistry-Vessel.dm"
#include "code\modules\reagents\chemical_research\Chemical-Research.dm"
#include "code\modules\reagents\chemical_research\generated_reagents.dm"
+#include "code\modules\reagents\chemical_research\xenomorph_analyzer.dm"
#include "code\modules\reagents\chemistry_machinery\acid_harness.dm"
#include "code\modules\reagents\chemistry_machinery\autodispenser.dm"
#include "code\modules\reagents\chemistry_machinery\centrifuge.dm"
diff --git a/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx b/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
new file mode 100644
index 000000000000..26155ef7a835
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
@@ -0,0 +1,75 @@
+import { useBackend } from '../backend';
+import { Section, Button, Stack, LabeledList, NoticeBox } from '../components';
+import { Window } from '../layouts';
+
+export const XenomorphExtractor = (_props, context) => {
+ const { act, data } = useBackend(context);
+
+ const { organ, points } = data;
+
+ const degraded = degradation >= 100;
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ {!organ && (
+
+ Recepticle is empty, analyzing is impossible!
+
+ )}
+ {!!disk && (
+
+ {sourceName}
+ {locus}
+
+ )}
+
+ {!!seed && (
+
+ {degraded && (
+ Genetic data too degraded to edit!
+ )}
+
+ {seed}
+
+ {!degraded ? degradation + '%' : '#!ERROR%'}
+
+
+
+
+
+ )}
+
+
+ );
+};
From 1c1feaa153c8bb8cd6a3887e81e220cedaaea51a Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Fri, 26 Jan 2024 15:57:40 -0500
Subject: [PATCH 009/113] ima kms
---
code/__DEFINES/misc.dm | 6 +
code/game/objects/items/old_research.dm | 112 ------------------
code/game/objects/items/research_upgrades.dm | 82 +++++++++++++
.../chemical_research/xenomorph_analyzer.dm | 32 ++++-
colonialmarines.dme | 2 +-
.../tgui/interfaces/XenomorphExtractor.jsx | 72 ++++++-----
6 files changed, 162 insertions(+), 144 deletions(-)
delete mode 100644 code/game/objects/items/old_research.dm
create mode 100644 code/game/objects/items/research_upgrades.dm
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index b195328264cd..2ab70bf39654 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -160,6 +160,12 @@
#define MATRIX_NVG 1
#define MATRIX_WIDE 2
+//autodoc upgrade via research
+#define AUTODOC_UPGRADE_IB 1
+#define AUTODOC_UPGRADE_BONEBREAK 2
+#define AUTODOC_UPGRADE_ORGAN 3
+#define AUTODOC_UPGRADE_LARVA 4
+
// Statistics defines
#define STATISTIC_XENO "xeno"
#define STATISTIC_HUMAN "human"
diff --git a/code/game/objects/items/old_research.dm b/code/game/objects/items/old_research.dm
deleted file mode 100644
index 7330baac5812..000000000000
--- a/code/game/objects/items/old_research.dm
+++ /dev/null
@@ -1,112 +0,0 @@
-/obj/item/XenoBio
- name = "An unidentified Alien Organ"
- desc = "Looking at it makes you want to vomit"
- icon = 'icons/obj/items/Marine_Research.dmi'
- icon_state = "biomass"
- black_market_value = 50
- //For all of them for now, until we have specific organs/more techs
-
-/obj/item/XenoBio/Resin
- name = "Alien Resin"
- desc = "A piece of alien Resin"
- icon_state = "biomass"
-
-
-/obj/item/XenoBio/Chitin
- name = "Alien Chitin"
- desc = "A chunk of alien Chitin"
- icon_state = "chitin-chunk"
-
-
-/obj/item/XenoBio/Blood
- name = "Alien Blood"
- desc = "A sample of alien Blood"
- icon_state = "blood-vial"
-
-
-
-
-
-
-
-
-// ======== ITEMS YOU CAN MAKE THAT ARE BADASS ======== //
-
-/obj/item/XenoItem
- name = "Strange Item"
- desc = "Some sort of fucked up item from the Weyland-Yutani brand 3D Biometric Printer... Probably should make a bug report if you got this..."
- icon_state = "chitin-chunk"
- icon = 'icons/obj/items/Marine_Research.dmi'
-
-/obj/item/XenoItem/ResinPaste
- name = "Resin Paste"
- desc = "This resin paste will fix a broken helmet. (Use by clicking the glue with the armor)."
- icon_state = "resin-glue"
- icon = 'icons/obj/items/Marine_Research.dmi'
-
-/obj/item/XenoItem/ResinPaste/afterattack(obj/item/clothing/head/helmet/marine/A as obj, mob/user as mob)
- if (!istype(A) || !istype(usr))
- to_chat(usr, "Doesn't work that way")
- return
- if (A.anti_hug >= 1)
- usr <<"This Helmet can't be further reinforced."
- return
- to_chat(usr, "You reinforce the Helmet...")
- A.anti_hug++
- user.temp_drop_inv_item(src)
- qdel(src)
- ..()
- return
-
-/obj/item/XenoItem/ChitinPlate
- name = "Chitin Plate"
- desc = "A plate of Chitin Armor that can be attached to your Marine Armor to make it stronger, but will also slow you down. (Use by clicking the plate with the armor)."
- icon_state = "chitin-armor"
- icon = 'icons/obj/items/Marine_Research.dmi'
-
-/obj/item/XenoItem/ChitinPlate/afterattack(obj/item/clothing/suit/storage/marine/A as obj, mob/user as mob)
- if (!istype(A) || !istype(usr))
- to_chat(usr, "Doesn't work that way...")
- return
- if (A.flags_marine_armor & ARMOR_IS_REINFORCED)
- usr <<"This armor is already reinforced."
- return
- to_chat(usr, "You reinforce the armor with some Chitin Plating...")
- A.armor_melee = 70
- A.armor_bullet = 90
- A.armor_laser = 7
- A.armor_energy = 40
- A.armor_bomb = 50
- A.armor_bio = 40
- A.armor_rad = 20
- A.slowdown++
- A.flags_marine_armor |= ARMOR_IS_REINFORCED
- user.temp_drop_inv_item(src)
- qdel(src)
- ..()
- return
-
-
-/obj/item/XenoItem/AntiAcid
- name = "Anti-Acid Spray"
- desc = "A spray that makes whatever it's used on unacidable. Single use."
- icon_state = "anti-acid"
- icon = 'icons/obj/items/Marine_Research.dmi'
-
-
-/obj/item/XenoItem/AntiAcid/afterattack(obj/A as obj, mob/user as mob, proximity)
- if (!isobj(A))
- to_chat(usr, "Doesn't work that way...")
- return
- if (A.unacidable == 1)
- to_chat(usr, "It's already resistant to acid...")
- return
- if (istype(A, /obj/structure/machinery/door))
- to_chat(usr, "It doesn't work on doors...")
- return
- to_chat(usr, "You spray [A] with the Anti-Acid spray making it unacidable...")
- A.unacidable = TRUE
- user.temp_drop_inv_item(src)
- qdel(src)
- ..()
- return
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
new file mode 100644
index 000000000000..541ccd18c42b
--- /dev/null
+++ b/code/game/objects/items/research_upgrades.dm
@@ -0,0 +1,82 @@
+//prop items
+/obj/item/XenoBio
+ name = "An unidentified Alien Organ"
+ desc = "Looking at it makes you want to vomit"
+ icon = 'icons/obj/items/Marine_Research.dmi'
+ icon_state = "biomass"
+ black_market_value = 50
+ //For all of them for now, until we have specific organs/more techs
+
+/obj/item/XenoBio/Resin
+ name = "Alien Resin"
+ desc = "A piece of alien Resin"
+ icon_state = "biomass"
+
+
+/obj/item/XenoBio/Chitin
+ name = "Alien Chitin"
+ desc = "A chunk of alien Chitin"
+ icon_state = "chitin-chunk"
+
+
+/obj/item/XenoBio/Blood
+ name = "Alien Blood"
+ desc = "A sample of alien Blood"
+ icon_state = "blood-vial"
+
+//prop items end
+
+
+
+//previously file holding left over stuff that never got finished from 8 years ago, it was boring though, so we change that.
+/obj/item/research_upgrades
+ name = "Research upgrade"
+ desc = "Somehow you got this, you shouldnt be able to, consider yourself special."
+ icon = 'icons/obj/items/disk.dmi'
+ icon_state = "datadisk1"
+ var/value = 0 //technology stored on this disk, goes through one to whatever levels of upgrades there are,
+ var/price = 1000 // initial price, multiplied by * price_increase at final checkout if there are better version
+ var/price_increase
+
+/obj/item/research_upgrades/proc/get_upgrade_desc(val) //we have to differ them SOMEHOW, so we do that, called if there are more versions of upgrades than one, basically a copypaste of examine text
+ return "This technology contains unknown data and forever will be..."
+
+/obj/item/research_upgrades/autodoc
+ name = "Research upgrade (AutoDoc)"
+ desc = "Research upgrade for AutoDoc, insert it in the recepticle located underneath certified AutoDoc Pod"
+ value = AUTODOC_UPGRADE_LARVA
+ price = 3000
+ //starting at internal bleeding repair, 2 for bone repair, 3 for organ repair/etc, and 4 for larva removal. They are not exclusive, that means if you get level 4, you still dont have level 2 and 3 & 1.
+ //set to final upgrade to show the amount of upgrades
+
+/obj/item/research_upgrades/autodoc/get_examine_text(mob/user)
+ . = ..()
+ switch(value)
+
+ if(AUTODOC_UPGRADE_IB)
+ . += "Labeling indicates that this disk contains data and statictics for stopping internal bleedings."
+ if(AUTODOC_UPGRADE_BONEBREAK)
+ . += "Labeling indicates that this disk contains data and statictics for fixating and mending broken bones."
+ if(AUTODOC_UPGRADE_ORGAN)
+ . += "Labeling indicates that this disk contains data and statictics for treating damaged organs."
+ if(AUTODOC_UPGRADE_LARVA)
+ . += "Labeling indicates that this disk contains data and statictics for extracting unknown parasites."
+
+/obj/item/research_upgrades/autodoc/get_upgrade_desc(val)
+ switch(val)
+
+ if(AUTODOC_UPGRADE_IB)
+ . += "Labeling indicates that this disk contains data and statictics for stopping internal bleedings."
+ if(AUTODOC_UPGRADE_BONEBREAK)
+ . += "Labeling indicates that this disk contains data and statictics for fixating and mending broken bones."
+ if(AUTODOC_UPGRADE_ORGAN)
+ . += "Labeling indicates that this disk contains data and statictics for treating damaged organs."
+ if(AUTODOC_UPGRADE_LARVA)
+ . += "Labeling indicates that this disk contains data and statictics for extracting unknown parasites."
+ return
+
+
+
+
+
+
diff --git a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
index f94ab6aee4c6..289e37980cf5 100644
--- a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
+++ b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
@@ -10,6 +10,16 @@
idle_power_usage = 40
var/biomass_points = 0 //most important thing in this
var/obj/item/organ/heart/xeno/organ = null
+ var/list/unlocked_tech = list()
+
+/obj/structure/machinery/xenoanalyzer/attack_hand(mob/user as mob)
+ tgui_interact(user)
+
+/obj/structure/machinery/xenoanalyzer/tgui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "XenomorphExtractor", name)
+ ui.open()
/obj/structure/machinery/xenoanalyzer/attackby(obj/item/W, mob/user)
if(!skillcheck(user, SKILL_RESEARCH, SKILL_RESEARCH_TRAINED))
@@ -27,7 +37,6 @@
/obj/structure/machinery/xenoanalyzer/ui_data(mob/user)
var/list/data = list()
-
data["points"] = biomass_points
if(organ)
@@ -36,6 +45,27 @@
data["organ"] = FALSE
return data
+/obj/structure/machinery/xenoanalyzer/ui_static_data(mob/user)
+ to_world("Oof")
+ var/list/static_data = list()
+ static_data["upgrades"] = list()
+ for(var/upgrade_type in typesof(/obj/item/research_upgrades))
+ var/obj/item/research_upgrades/upgrade = upgrade_type
+ var/upgrade_name = initial(upgrade.name)
+ var/upgrade_variations = initial(upgrade.value)
+ var/upgrade_price = initial(upgrade.price)
+ for(var/iteration in 1 to upgrade_variations)
+ to_world("loor")
+ to_world(upgrade_name)
+ to_world(iteration)
+ if(upgrade.value)
+ static_data["upgrades"] += list(list(
+ "name" = (capitalize_first_letters(upgrade_name) + " ([iteration])"),
+ "desc" = (upgrade.desc + upgrade.get_upgrade_desc(iteration)),
+ "vari" = iteration,
+ "cost" = upgrade_price
+ ))
+ return static_data
/obj/structure/machinery/xenoanalyzer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 72b504bef656..02f9b32dd89d 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -1060,10 +1060,10 @@
#include "code\game\objects\items\legcuffs.dm"
#include "code\game\objects\items\lightstick.dm"
#include "code\game\objects\items\misc.dm"
-#include "code\game\objects\items\old_research.dm"
#include "code\game\objects\items\ore.dm"
#include "code\game\objects\items\paint.dm"
#include "code\game\objects\items\pamphlets.dm"
+#include "code\game\objects\items\research_upgrades.dm"
#include "code\game\objects\items\shards.dm"
#include "code\game\objects\items\stock_parts.dm"
#include "code\game\objects\items\trash.dm"
diff --git a/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx b/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
index 26155ef7a835..ed88ef805ecb 100644
--- a/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
+++ b/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
@@ -1,13 +1,11 @@
import { useBackend } from '../backend';
-import { Section, Button, Stack, LabeledList, NoticeBox } from '../components';
+import { Section, Button, Stack, NoticeBox, Box, Flex, LabeledList } from '../components';
import { Window } from '../layouts';
export const XenomorphExtractor = (_props, context) => {
const { act, data } = useBackend(context);
- const { organ, points } = data;
-
- const degraded = degradation >= 100;
+ const { organ, points, upgrades } = data;
return (
@@ -27,12 +25,13 @@ export const XenomorphExtractor = (_props, context) => {
);
};
+
+const UpgradesDropdown = (props, context) => {
+ const { act, data } = useBackend(context);
+ const { upgrades } = data;
+
+
+ {upgrades.map((upgrades) => (
+
+ act(
+ 'produce'
+ // path: upgrades.path,
+ // cost: Equipment.cost,
+ )
+ }
+ />
+ }
+ />
+ ))}
+
+ ;
+ ;
+};
From fd68692eade93d783ff594e3d6e9cb7e3915c2be Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Sun, 28 Jan 2024 15:55:29 -0500
Subject: [PATCH 010/113] omfg kms
---
code/game/objects/items/research_upgrades.dm | 61 ++++++++-----
.../mob/living/carbon/xenomorph/Xenomorph.dm | 1 +
code/modules/organs/organ_objects.dm | 1 +
.../chemical_research/xenomorph_analyzer.dm | 59 ++++++++++---
code/modules/surgery/xeno.dm | 2 +-
.../tgui/interfaces/XenomorphExtractor.jsx | 88 ++++++++++---------
tools/build/build.js | 2 +-
7 files changed, 135 insertions(+), 79 deletions(-)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index 541ccd18c42b..320f4c538a52 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -35,17 +35,16 @@
icon = 'icons/obj/items/disk.dmi'
icon_state = "datadisk1"
var/value = 0 //technology stored on this disk, goes through one to whatever levels of upgrades there are,
- var/price = 1000 // initial price, multiplied by * price_increase at final checkout if there are better version
- var/price_increase
+ var/list/price = list(1000) // initial price, multiplied by * price_increase at final checkout if there are better version
-/obj/item/research_upgrades/proc/get_upgrade_desc(val) //we have to differ them SOMEHOW, so we do that, called if there are more versions of upgrades than one, basically a copypaste of examine text
- return "This technology contains unknown data and forever will be..."
+/obj/item/research_upgrades/proc/get_upgrade_desc(val, short = TRUE) //needed for those special cases like one below. only needed in cases where single disk can be many upgrades, otherwise use desc and name.
+ return "ERROR"
/obj/item/research_upgrades/autodoc
- name = "Research upgrade (AutoDoc)"
- desc = "Research upgrade for AutoDoc, insert it in the recepticle located underneath certified AutoDoc Pod"
+ name = "Research upgrade "
+ desc = "Research upgrade for AutoDoc, Technology on this disk is used "
value = AUTODOC_UPGRADE_LARVA
- price = 3000
+ price = list(3000, 5000, 8000, 10000)
//starting at internal bleeding repair, 2 for bone repair, 3 for organ repair/etc, and 4 for larva removal. They are not exclusive, that means if you get level 4, you still dont have level 2 and 3 & 1.
//set to final upgrade to show the amount of upgrades
@@ -54,29 +53,47 @@
switch(value)
if(AUTODOC_UPGRADE_IB)
- . += "Labeling indicates that this disk contains data and statictics for stopping internal bleedings."
+ . += "for stopping internal bleedings."
if(AUTODOC_UPGRADE_BONEBREAK)
- . += "Labeling indicates that this disk contains data and statictics for fixating and mending broken bones."
+ . += "for fixating and mending broken bones."
if(AUTODOC_UPGRADE_ORGAN)
- . += "Labeling indicates that this disk contains data and statictics for treating damaged organs."
+ . += "for treating damaged organs."
if(AUTODOC_UPGRADE_LARVA)
- . += "Labeling indicates that this disk contains data and statictics for extracting unknown parasites."
+ . += "for extracting unknown parasites."
+
+/obj/item/research_upgrades/autodoc/get_upgrade_desc(val, short = TRUE)
+ if(short)
+ switch(val)
+ if(AUTODOC_UPGRADE_IB)
+ . += "(Internal Bleedings)"
+ if(AUTODOC_UPGRADE_BONEBREAK)
+ . += "(Broken Bones)"
+ if(AUTODOC_UPGRADE_ORGAN)
+ . += "(Organ Treating)"
+ if(AUTODOC_UPGRADE_LARVA)
+ . += "(Unknown Parasites)"
+ else
+ switch(val)
+ if(AUTODOC_UPGRADE_IB)
+ . += "for stopping internal bleedings."
+ if(AUTODOC_UPGRADE_BONEBREAK)
+ . += "for fixating and mending broken bones."
+ if (AUTODOC_UPGRADE_ORGAN)
+ . += "for treating damaged organs"
+ if (AUTODOC_UPGRADE_LARVA)
+ . += "for extracting unknown parasites"
+ return
-/obj/item/research_upgrades/autodoc/get_upgrade_desc(val)
- switch(val)
+/obj/item/research_upgrades/sleeper
+ name = "Research upgrade (Sleeper)"
+ desc = "Research upgrade for Sleeper system, Technology on this disk is used on a sleeper to allow wider spectrum of chemicals to be administered "
+ value = 1
+ price = list(4000)
- if(AUTODOC_UPGRADE_IB)
- . += "Labeling indicates that this disk contains data and statictics for stopping internal bleedings."
- if(AUTODOC_UPGRADE_BONEBREAK)
- . += "Labeling indicates that this disk contains data and statictics for fixating and mending broken bones."
- if(AUTODOC_UPGRADE_ORGAN)
- . += "Labeling indicates that this disk contains data and statictics for treating damaged organs."
- if(AUTODOC_UPGRADE_LARVA)
- . += "Labeling indicates that this disk contains data and statictics for extracting unknown parasites."
+/obj/item/research_upgrades/sleeper/get_upgrade_desc(val, short = TRUE)
return
-
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index dd7a3bb63275..46fac05c3f63 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -352,6 +352,7 @@
var/obj/item/organ/heart/xeno/organ = new() //give
organ.forceMove(src)
organ.research_value = tier
+ organ.caste_origin = src.caste_type
var/datum/hive_status/hive = GLOB.hive_datum[src.hivenumber]
diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm
index 18d59d71d28a..0671b20de37e 100644
--- a/code/modules/organs/organ_objects.dm
+++ b/code/modules/organs/organ_objects.dm
@@ -121,6 +121,7 @@
organ_tag = "heart"
black_market_value = 60
var/research_value = 1 //depending on the size and tier
+ var/caste_origin // used for desc in xenoanalyzer
//These are here so they can be printed out via the fabricator.
/obj/item/organ/heart/prosthetic
diff --git a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
index 289e37980cf5..a1bb61b0d32b 100644
--- a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
+++ b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
@@ -10,7 +10,9 @@
idle_power_usage = 40
var/biomass_points = 0 //most important thing in this
var/obj/item/organ/heart/xeno/organ = null
- var/list/unlocked_tech = list()
+ var/busy = FALSE
+ var/caste_of_organ = null
+ var/list/different_upgrades = list()// used for items that are not research_upgrades. eg ammo
/obj/structure/machinery/xenoanalyzer/attack_hand(mob/user as mob)
tgui_interact(user)
@@ -34,6 +36,7 @@
return
to_chat(user, SPAN_NOTICE("You fed organ in the machine."))
organ = W
+ caste_of_organ = organ.caste_origin
/obj/structure/machinery/xenoanalyzer/ui_data(mob/user)
var/list/data = list()
@@ -41,6 +44,8 @@
if(organ)
data["organ"] = TRUE
+ data["caste"] = caste_of_organ
+ data["value"] = organ.research_value
else
data["organ"] = FALSE
return data
@@ -49,22 +54,26 @@
to_world("Oof")
var/list/static_data = list()
static_data["upgrades"] = list()
- for(var/upgrade_type in typesof(/obj/item/research_upgrades))
- var/obj/item/research_upgrades/upgrade = upgrade_type
- var/upgrade_name = initial(upgrade.name)
- var/upgrade_variations = initial(upgrade.value)
- var/upgrade_price = initial(upgrade.price)
+ for(var/upgrade_type in subtypesof(/obj/item/research_upgrades))
+ to_world("Ayo")
+ var/obj/item/research_upgrades/upgrade = new upgrade_type //cant call procs without creating it. doing so crashes the game.
+ var/upgrade_variations = upgrade.value
for(var/iteration in 1 to upgrade_variations)
- to_world("loor")
- to_world(upgrade_name)
- to_world(iteration)
if(upgrade.value)
+ to_world(upgrade)
+ var/upgrade_price = upgrade.price[iteration]
+ var/upgrade_name = (capitalize_first_letters(upgrade.name) + capitalize_first_letters(upgrade.get_upgrade_desc(iteration, TRUE) ))
+ var/upgrade_desc = (initial(upgrade.desc) + upgrade.get_upgrade_desc(iteration, FALSE))
+ to_world(upgrade_name)
static_data["upgrades"] += list(list(
- "name" = (capitalize_first_letters(upgrade_name) + " ([iteration])"),
- "desc" = (upgrade.desc + upgrade.get_upgrade_desc(iteration)),
+ "name" = upgrade_name,
+ "desc" = upgrade_desc,
"vari" = iteration,
- "cost" = upgrade_price
+ "cost" = upgrade_price,
+ "path" = upgrade_type
))
+ for(var/item in different_upgrades)
+
return static_data
/obj/structure/machinery/xenoanalyzer/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
@@ -80,6 +89,12 @@
if("process_organ")
process_organ()
. = TRUE
+ if("produce")
+ var/produce = text2path(params["paths"])
+ var/cost = text2num(params["cost"])
+ var/vari = text2num(params["varia"])
+ if(cost)
+ start_print_upgrade(produce, cost, usr, vari)
/obj/structure/machinery/xenoanalyzer/proc/eject_biomass()
if(isnull(organ))
@@ -91,10 +106,28 @@
if(isnull(organ))
return
playsound(src.loc, 'sound/machines/blender.ogg', 25, 1)
- biomass_points += organ.research_value * 1000 //inflating values less goo
+ biomass_points += organ.research_value * 1000 //inflatizng values less goo
qdel(organ)
organ = null
+/obj/structure/machinery/xenoanalyzer/proc/start_print_upgrade(produce_path, cost, mob/user, variation)
+ if (stat & NOPOWER)
+ icon_state = "drone_fab_nopower"
+ if(cost > biomass_points)
+ to_chat(user, SPAN_WARNING("[src] makes a worrying beep and flashes red, theres not enough data processed to build the requested upgrade!"))
+ return
+ else
+ icon_state = "mixer1b"
+ busy = TRUE
+ biomass_points -= cost
+ addtimer(CALLBACK(src, PROC_REF(print_upgrade), produce_path, variation), 5 SECONDS)
+
+
+/obj/structure/machinery/xenoanalyzer/proc/print_upgrade(produce_path, variation)
+ busy = FALSE
+ icon_state = "mixer0b"
+ var/obj/item/research_upgrades/upgrade = new produce_path(get_turf(src))
+ upgrade.value = variation
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
index e3cbd3d5c67f..3d8e28217dee 100644
--- a/code/modules/surgery/xeno.dm
+++ b/code/modules/surgery/xeno.dm
@@ -18,7 +18,7 @@
requires_bodypart = FALSE
/datum/surgery/xenomorph/can_start(mob/user, mob/living/carbon/xenomorph/patient, obj/limb/L, obj/item/tool)
- if(patient.stat == DEAD && !patient.organ_removed)
+ if(patient.stat == DEAD && !patient.organ_removed && !islarva(patient))
return TRUE
return FALSE
diff --git a/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx b/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
index ed88ef805ecb..708774334e25 100644
--- a/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
+++ b/tgui/packages/tgui/interfaces/XenomorphExtractor.jsx
@@ -1,14 +1,14 @@
import { useBackend } from '../backend';
-import { Section, Button, Stack, NoticeBox, Box, Flex, LabeledList } from '../components';
+import { Section, Button, Stack, NoticeBox, LabeledList, Flex, Box } from '../components';
import { Window } from '../layouts';
export const XenomorphExtractor = (_props, context) => {
const { act, data } = useBackend(context);
- const { organ, points, upgrades } = data;
+ const { organ, points, upgrades, path, caste, value } = data;
return (
-
+
@@ -16,7 +16,9 @@ export const XenomorphExtractor = (_props, context) => {
act('eject_organ')}
/>
@@ -25,13 +27,19 @@ export const XenomorphExtractor = (_props, context) => {
act('process_organ')}
/>
+
+ Biological Matter : {points}
+
- Biological Buffer: {points}
{!organ && (
@@ -40,10 +48,38 @@ export const XenomorphExtractor = (_props, context) => {
)}
-
-
-
-
+
+
+
+
+ {upgrades.map((upgrades) => (
+ {upgrades.name}}
+ buttons={
+
+
+ act('produce', {
+ paths: upgrades.path,
+ cost: upgrades.cost,
+ varia: upgrades.vari,
+ })
+ }
+ />
+
+ }
+ />
+ ))}
+
+
+
+
{!!organ && (
Biomass detected, Ready to process
@@ -53,35 +89,3 @@ export const XenomorphExtractor = (_props, context) => {
);
};
-
-const UpgradesDropdown = (props, context) => {
- const { act, data } = useBackend(context);
- const { upgrades } = data;
-
-
- {upgrades.map((upgrades) => (
-
- act(
- 'produce'
- // path: upgrades.path,
- // cost: Equipment.cost,
- )
- }
- />
- }
- />
- ))}
-
- ;
- ;
-};
diff --git a/tools/build/build.js b/tools/build/build.js
index c145ed391eb2..104adaffc57c 100644
--- a/tools/build/build.js
+++ b/tools/build/build.js
@@ -176,7 +176,7 @@ export const TguiTarget = new Juke.Target({
"tgui/.yarn/install-target",
"tgui/webpack.config.js",
"tgui/**/package.json",
- "tgui/packages/**/*.+(js|cjs|ts|tsx|scss)",
+ "tgui/packages/**/*.+(js|cjs|ts|tsx|jsx|scss)",
],
outputs: [
"tgui/public/tgui.bundle.css",
From 9c48fd5d299486eb621e55dc4f9210e7b74e5db9 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Mon, 29 Jan 2024 12:22:36 -0500
Subject: [PATCH 011/113] HOLY LORD THE AUTODOC CODE NEVER AGAIN
---
code/game/machinery/medical_pod/autodoc.dm | 53 +++++++++++++++++++
code/game/objects/items/research_upgrades.dm | 54 ++++++++++++++++++--
2 files changed, 103 insertions(+), 4 deletions(-)
diff --git a/code/game/machinery/medical_pod/autodoc.dm b/code/game/machinery/medical_pod/autodoc.dm
index 7049df4c661c..a5b116bcd16c 100644
--- a/code/game/machinery/medical_pod/autodoc.dm
+++ b/code/game/machinery/medical_pod/autodoc.dm
@@ -518,6 +518,22 @@
if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src]croaks: Closing surgical incision.");
close_encased(H,S.limb_ref)
close_incision(H,S.limb_ref)
+ if("larva")
+ if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src]beeps: Removing unknown parasites.");
+ if(!locate(/obj/item/alien_embryo) in occupant)
+ sleep(UNNEEDED_DELAY)
+ visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Procedure has been deemed unnecessary."); // >:)
+ surgery_todo_list -= S
+ continue
+ sleep(SCALPEL_MAX_DURATION + HEMOSTAT_MAX_DURATION + REMOVE_OBJECT_MAX_DURATION)
+ var/obj/item/alien_embryo/A = locate() in occupant
+ var/mob/living/carbon/xenomorph/larva/L = locate() in occupant
+ if(L)
+ L.forceMove(occupant.loc) //funny stealth larva bursts incoming
+ qdel(A)
+ else
+ A.forceMove(occupant.loc)
+ occupant.status_flags &= ~XENO_HOST
if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Procedure complete.");
surgery_todo_list -= S
@@ -590,6 +606,7 @@
unslashable = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 40
+ var/list/upgrades = list() // lists what kind of op we can get
/obj/structure/machinery/autodoc_console/Initialize()
. = ..()
@@ -629,6 +646,18 @@
/obj/structure/machinery/autodoc_console/process()
updateUsrDialog()
+/obj/structure/machinery/autodoc_console/attackby(obj/item/with, mob/user)
+ if(istype(with, /obj/item/research_upgrades/autodoc))
+ var/obj/item/research_upgrades/autodoc/upgrd = with
+ for(var/iter in upgrades)
+ if(iter == upgrd.value)
+ to_chat(user, SPAN_NOTICE("This data is already present in the [src]!"))
+ return
+ if(!user.drop_inv_item_to_loc(with, src))
+ return
+ to_chat(user, SPAN_NOTICE("You insert the data into the console, and the drive whirrs to life, reading the data"))
+ upgrades += upgrd.value
+
/obj/structure/machinery/autodoc_console/attack_hand(mob/living/user)
if(..())
return
@@ -700,6 +729,9 @@
if("eyes")
surgeryqueue["eyes"] = 1
dat += "Corrective Eye Surgery"
+ if("larva")
+ surgeryqueue["larva"] = 1
+ dat += "Experimental Parasite Surgery"
if(LIMB_SURGERY)
switch(A.surgery_procedure)
if("internal")
@@ -720,6 +752,7 @@
if("open")
surgeryqueue["open"] = 1
dat += "Close Open Incisions"
+
dat += "
"
dat += "
Begin Surgery - Refresh Menu - Clear Queue
"
@@ -743,6 +776,23 @@
if(isnull(surgeryqueue["toxin"]))
dat += "Bloodstream Toxin Removal
"
dat += "
"
+ if(upgrades.len > 0)
+ dat += "Orthopedic Surgeries"
+ dat += "
"
+ for(var/iter in upgrades)
+ switch(iter)
+ if(AUTODOC_UPGRADE_BONEBREAK)
+ if(isnull(surgeryqueue["broken"]))
+ dat += "Broken Bone Surgery
"
+ if(AUTODOC_UPGRADE_IB)
+ if(isnull(surgeryqueue["internal"]))
+ dat += "Internal Bleeding Surgery
"
+ if(AUTODOC_UPGRADE_ORGAN)
+ if(isnull(surgeryqueue["organdamage"]))
+ dat += "Organ Damage Treatment
"
+ if(AUTODOC_UPGRADE_LARVA)
+ if(isnull(surgeryqueue["larva"]))
+ dat += "Experimental Parasite Exctraction
"
else
dat += "The autodoc is empty."
dat += text("Close", user)
@@ -797,6 +847,9 @@
if(!needed)
N.fields["autodoc_manual"] += create_autodoc_surgery(null,ORGAN_SURGERY,"damage",1)
updateUsrDialog()
+ if(href_list["larva"])
+ if(locate(/obj/item/alien_embryo) in connected.occupant)
+ N.fields["autodoc_manual"] += create_autodoc_surgery("chest",ORGAN_SURGERY,"damage",0)
if(href_list["internal"])
for(var/obj/limb/L in connected.occupant.limbs)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index 320f4c538a52..d3abcee72977 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -34,14 +34,14 @@
desc = "Somehow you got this, you shouldnt be able to, consider yourself special."
icon = 'icons/obj/items/disk.dmi'
icon_state = "datadisk1"
- var/value = 0 //technology stored on this disk, goes through one to whatever levels of upgrades there are,
+ var/value = 0 //technology stored on this disk, goes through one to whatever levels of upgrades there are. 0 Excludes it from buying menu.
var/list/price = list(1000) // initial price, multiplied by * price_increase at final checkout if there are better version
/obj/item/research_upgrades/proc/get_upgrade_desc(val, short = TRUE) //needed for those special cases like one below. only needed in cases where single disk can be many upgrades, otherwise use desc and name.
return "ERROR"
/obj/item/research_upgrades/autodoc
- name = "Research upgrade "
+ name = "Research Upgrade "
desc = "Research upgrade for AutoDoc, Technology on this disk is used "
value = AUTODOC_UPGRADE_LARVA
price = list(3000, 5000, 8000, 10000)
@@ -85,14 +85,60 @@
return
/obj/item/research_upgrades/sleeper
- name = "Research upgrade (Sleeper)"
- desc = "Research upgrade for Sleeper system, Technology on this disk is used on a sleeper to allow wider spectrum of chemicals to be administered "
+ name = "Research Upgrade (Sleeper)"
+ desc = "Research upgrade for Sleeper system, Technology on this disk is used on a sleeper to allow wider spectrum of chemicals to be administered"
value = 1
price = list(4000)
/obj/item/research_upgrades/sleeper/get_upgrade_desc(val, short = TRUE)
return
+/obj/item/research_upgrades/credits
+ name = "Research Market (Credits)"
+ desc = "Research points disk for chemical synthesis, insert this into research computer to acquire two points" //need to balance this out somehow. either nerf passive income or remove grants from groundside
+ value = 1
+ price = list(3000)
+
+/obj/item/research_upgrades/packet
+ name = "Research Packet"
+ desc = "A sealed opaque packet containing whatever research marvel the nerds upstairs were brewing, you shouldnt be able to see this!"
+ value = 0
+ //icon = ***
+ //icon_state = ***
+ price = list(1000)
+ var/list/contains = null //the item(s) the packet inside has.
+ var/is_opened = FALSE //ripped open or not
+
+/obj/item/research_upgrades/packet/attack_self(mob/user)
+ . = ..()
+ playsound(src, "rip", 15, TRUE, 6)
+ if(isnull(contains) && !is_opened)
+ to_chat(user, SPAN_WARNING("The packet was empty, so you throw it out."))
+ qdel(src)
+ return
+ if(!is_opened)
+ var/thing_to_spawn = pick(contains)
+ var/obj/item/spawn_item = new thing_to_spawn
+ spawn_item.forceMove(get_turf(user))
+ is_opened = TRUE
+ desc += "This one seems to be already opened"
+ return
+
+
+/obj/item/research_upgrades/packet/attachment
+ name = "Research Packet (Attachment)"
+ desc = "An opaque sealed packet containing one random experimental gun attachment"
+ price = list(2000)
+ value = 1
+ contains = list()//need to add actual attachments(sprites ;-;) too, so many shit todo holy shit.
+
+/obj/item/research_upgrades/packet/attachment/attack_self(mob/user)
+ . = ..()
+ //icon_state = insert torn packet here
+ return
+
+
+
From 81bc3724b33fc2f7e9f2618bb274cb4077184eae Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Mon, 29 Jan 2024 13:34:53 -0500
Subject: [PATCH 012/113] someone really needs to move autodoc to tgui holy
moly
---
code/game/machinery/medical_pod/autodoc.dm | 44 +++++++++++-----------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/code/game/machinery/medical_pod/autodoc.dm b/code/game/machinery/medical_pod/autodoc.dm
index a5b116bcd16c..1472dd574ec3 100644
--- a/code/game/machinery/medical_pod/autodoc.dm
+++ b/code/game/machinery/medical_pod/autodoc.dm
@@ -392,6 +392,22 @@
H.sdisabilities &= ~DISABILITY_BLIND
E.heal_damage(E.damage)
E.eye_surgery_stage = 0
+ if("larva")
+ if(prob(99)) visible_message("[icon2html(src, viewers(src))] \The [src]beeps: Removing unknown parasites.");
+ if(!locate(/obj/item/alien_embryo) in occupant)
+ sleep(UNNEEDED_DELAY)
+ visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Procedure has been deemed unnecessary."); // >:)
+ surgery_todo_list -= S
+ continue
+ sleep(SCALPEL_MAX_DURATION + HEMOSTAT_MAX_DURATION + REMOVE_OBJECT_MAX_DURATION)
+ var/obj/item/alien_embryo/A = locate() in occupant
+ var/mob/living/carbon/xenomorph/larva/L = locate() in occupant
+ if(L)
+ L.forceMove(get_turf(occupant)) //funny stealth larva bursts incoming
+ qdel(A)
+ else
+ A.forceMove(get_turf(occupant))
+ occupant.status_flags &= ~XENO_HOST
if(LIMB_SURGERY)
@@ -518,22 +534,7 @@
if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src]croaks: Closing surgical incision.");
close_encased(H,S.limb_ref)
close_incision(H,S.limb_ref)
- if("larva")
- if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src]beeps: Removing unknown parasites.");
- if(!locate(/obj/item/alien_embryo) in occupant)
- sleep(UNNEEDED_DELAY)
- visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Procedure has been deemed unnecessary."); // >:)
- surgery_todo_list -= S
- continue
- sleep(SCALPEL_MAX_DURATION + HEMOSTAT_MAX_DURATION + REMOVE_OBJECT_MAX_DURATION)
- var/obj/item/alien_embryo/A = locate() in occupant
- var/mob/living/carbon/xenomorph/larva/L = locate() in occupant
- if(L)
- L.forceMove(occupant.loc) //funny stealth larva bursts incoming
- qdel(A)
- else
- A.forceMove(occupant.loc)
- occupant.status_flags &= ~XENO_HOST
+
if(prob(30)) visible_message("[icon2html(src, viewers(src))] \The [src] speaks: Procedure complete.");
surgery_todo_list -= S
@@ -657,6 +658,7 @@
return
to_chat(user, SPAN_NOTICE("You insert the data into the console, and the drive whirrs to life, reading the data"))
upgrades += upgrd.value
+ to_chat(user, upgrades)
/obj/structure/machinery/autodoc_console/attack_hand(mob/living/user)
if(..())
@@ -776,10 +778,12 @@
if(isnull(surgeryqueue["toxin"]))
dat += "Bloodstream Toxin Removal
"
dat += "
"
+ to_chat(user, "here")
if(upgrades.len > 0)
dat += "Orthopedic Surgeries"
- dat += "
"
for(var/iter in upgrades)
+ to_chat(user, iter)
+ to_chat(upgrades.len)
switch(iter)
if(AUTODOC_UPGRADE_BONEBREAK)
if(isnull(surgeryqueue["broken"]))
@@ -792,7 +796,7 @@
dat += "Organ Damage Treatment
"
if(AUTODOC_UPGRADE_LARVA)
if(isnull(surgeryqueue["larva"]))
- dat += "Experimental Parasite Exctraction
"
+ dat += "Experimental Parasite Exctraction
"
else
dat += "The autodoc is empty."
dat += text("Close", user)
@@ -848,9 +852,7 @@
N.fields["autodoc_manual"] += create_autodoc_surgery(null,ORGAN_SURGERY,"damage",1)
updateUsrDialog()
if(href_list["larva"])
- if(locate(/obj/item/alien_embryo) in connected.occupant)
- N.fields["autodoc_manual"] += create_autodoc_surgery("chest",ORGAN_SURGERY,"damage",0)
-
+ N.fields["autodoc_manual"] += create_autodoc_surgery("chest",ORGAN_SURGERY,"larva",0)
if(href_list["internal"])
for(var/obj/limb/L in connected.occupant.limbs)
if(L)
From 8ac8d49721abf357f2caedb84f103e000a1c820e Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Mon, 29 Jan 2024 13:57:33 -0500
Subject: [PATCH 013/113] sleeper, this one was quite easy
---
code/game/machinery/medical_pod/autodoc.dm | 3 ---
code/game/machinery/medical_pod/sleeper.dm | 18 ++++++++++++++++++
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/code/game/machinery/medical_pod/autodoc.dm b/code/game/machinery/medical_pod/autodoc.dm
index 1472dd574ec3..42de357c8ccb 100644
--- a/code/game/machinery/medical_pod/autodoc.dm
+++ b/code/game/machinery/medical_pod/autodoc.dm
@@ -658,7 +658,6 @@
return
to_chat(user, SPAN_NOTICE("You insert the data into the console, and the drive whirrs to life, reading the data"))
upgrades += upgrd.value
- to_chat(user, upgrades)
/obj/structure/machinery/autodoc_console/attack_hand(mob/living/user)
if(..())
@@ -782,8 +781,6 @@
if(upgrades.len > 0)
dat += "Orthopedic Surgeries"
for(var/iter in upgrades)
- to_chat(user, iter)
- to_chat(upgrades.len)
switch(iter)
if(AUTODOC_UPGRADE_BONEBREAK)
if(isnull(surgeryqueue["broken"]))
diff --git a/code/game/machinery/medical_pod/sleeper.dm b/code/game/machinery/medical_pod/sleeper.dm
index 84ef2f579ba1..d991c22c39ed 100644
--- a/code/game/machinery/medical_pod/sleeper.dm
+++ b/code/game/machinery/medical_pod/sleeper.dm
@@ -59,6 +59,20 @@
// tgui \\
+/obj/structure/machinery/sleep_console/attackby(obj/item/with, mob/user)
+ if(!istype(with, /obj/item/research_upgrades/sleeper))
+ return
+ if(connected.upgraded)
+ return
+ if(!user.drop_inv_item_to_loc(with, src))
+ return
+ to_chat(user, SPAN_NOTICE("You insert the data into the console, and the drive whirrs to life, reading the data"))
+ connected.upgraded = TRUE
+ connected.available_chemicals = connected.upgraded_chemicals
+ connected.emergency_chems = connected.upgraded_emergency_chems
+ connected.reagent_removed_per_second = connected.reagent_removed_per_second_upgraded
+
+
/obj/structure/machinery/sleep_console/attack_hand(mob/living/user)
if(..())
return
@@ -236,7 +250,9 @@
entry_timer = 2 SECONDS
var/available_chemicals = list("inaprovaline", "paracetamol", "anti_toxin", "dexalin", "tricordrazine")
+ var/upgraded_chemicals = list("inaprovaline", "tramadol", "anti_toxin", "dexalinp", "tricordrazine", "alkysine", "imidazoline")
var/emergency_chems = list("inaprovaline", "paracetamol", "anti_toxin", "dexalin", "tricordrazine", "oxycodone", "bicaridine", "kelotane")
+ var/upgraded_emergency_chems = list("inaprovaline", "tramadol", "anti_toxin", "dexalinp", "tricordrazine", "oxycodone", "bicaridine", "kelotane", "meralyne", "dermaline", "alkysine", "imidazoline")
var/amounts = list(5, 10)
var/filtering = FALSE
var/obj/structure/machinery/sleep_console/connected
@@ -244,7 +260,9 @@
var/max_chem = 40
var/auto_eject_dead = FALSE
var/reagent_removed_per_second = AMOUNT_PER_TIME(3, 1 SECONDS)
+ var/reagent_removed_per_second_upgraded = AMOUNT_PER_TIME(8, 1 SECONDS)
var/dialysis_started_reagent_vol = null // how many reagents the occupant had in them when we STARTED dialysis
+ var/upgraded = FALSE //research disk upgrade
use_power = USE_POWER_IDLE
idle_power_usage = 15
From b134076fcfcab55bac6ec0416ad05073a3f965cc Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Mon, 29 Jan 2024 14:04:51 -0500
Subject: [PATCH 014/113] usuless cherrypicking that I like
---
code/game/objects/items/research_upgrades.dm | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index d3abcee72977..52bbc7453a6a 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -41,7 +41,7 @@
return "ERROR"
/obj/item/research_upgrades/autodoc
- name = "Research Upgrade "
+ name = "Research Upgrade (AutoDoc)"
desc = "Research upgrade for AutoDoc, Technology on this disk is used "
value = AUTODOC_UPGRADE_LARVA
price = list(3000, 5000, 8000, 10000)
@@ -97,11 +97,11 @@
name = "Research Market (Credits)"
desc = "Research points disk for chemical synthesis, insert this into research computer to acquire two points" //need to balance this out somehow. either nerf passive income or remove grants from groundside
value = 1
- price = list(3000)
+ price = list(1000)
/obj/item/research_upgrades/packet
name = "Research Packet"
- desc = "A sealed opaque packet containing whatever research marvel the nerds upstairs were brewing, you shouldnt be able to see this!"
+ desc = " A plastic sealed opaque packet containing whatever research marvel the nerds upstairs were brewing, you shouldnt be able to see this!"
value = 0
//icon = ***
//icon_state = ***
@@ -131,6 +131,7 @@
price = list(2000)
value = 1
contains = list()//need to add actual attachments(sprites ;-;) too, so many shit todo holy shit.
+ //also, no idea what kinda of attachments were looking at in future
/obj/item/research_upgrades/packet/attachment/attack_self(mob/user)
. = ..()
From f5285bfe2575312003de2dfbf18a1aba80d87ef0 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Mon, 29 Jan 2024 14:22:46 -0500
Subject: [PATCH 015/113] more packets and sme other things
---
code/game/objects/items/research_upgrades.dm | 28 ++++++++++++++++----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index 52bbc7453a6a..f9ce07cb4691 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -95,7 +95,7 @@
/obj/item/research_upgrades/credits
name = "Research Market (Credits)"
- desc = "Research points disk for chemical synthesis, insert this into research computer to acquire two points" //need to balance this out somehow. either nerf passive income or remove grants from groundside
+ desc = "Research points disk for chemical synthesis, insert this into research computer in order to sell the data and acquire two points" //need to balance this out somehow. either nerf passive income or remove grants from groundside
value = 1
price = list(1000)
@@ -106,18 +106,20 @@
//icon = ***
//icon_state = ***
price = list(1000)
- var/list/contains = null //the item(s) the packet inside has.
+ var/list/could_contain = null //the item(s) the packet inside has.
var/is_opened = FALSE //ripped open or not
+ var/amount = 1 // how much items in packet(how many times to spawn the could_contain).
+ var/random = TRUE //should the items in packets be randomly given or exactly to what could_contain says
/obj/item/research_upgrades/packet/attack_self(mob/user)
. = ..()
playsound(src, "rip", 15, TRUE, 6)
- if(isnull(contains) && !is_opened)
+ if(isnull(could_contain) && !is_opened)
to_chat(user, SPAN_WARNING("The packet was empty, so you throw it out."))
qdel(src)
return
if(!is_opened)
- var/thing_to_spawn = pick(contains)
+ var/thing_to_spawn = pick(could_contain)
var/obj/item/spawn_item = new thing_to_spawn
spawn_item.forceMove(get_turf(user))
is_opened = TRUE
@@ -130,7 +132,7 @@
desc = "An opaque sealed packet containing one random experimental gun attachment"
price = list(2000)
value = 1
- contains = list()//need to add actual attachments(sprites ;-;) too, so many shit todo holy shit.
+ could_contain = list()//need to add actual attachments(sprites ;-;) too, so many shit todo holy shit.
//also, no idea what kinda of attachments were looking at in future
/obj/item/research_upgrades/packet/attachment/attack_self(mob/user)
@@ -138,9 +140,25 @@
//icon_state = insert torn packet here
return
+/obj/item/research_upgrades/packet/ammo_x//replace with actually initialls of ammo once sure which ammo to add
+ name = "Research Packet (Ammo)"
+ desc = "Contains a handfull of X ammo. Handle with care"
+ price = list(250, 200)
+ value = 2 // one for m41 cal and second for m39 cal
+ could_contain = list()//replace with a path to actuall ammo when done
+ amount = 3
+/obj/item/research_upgrades/packet/magazine
+ name = "Research Packet (Mag)"
+ desc = "Contains a single magazine for . Handle with care"
+ price = list(250, 200, 250)
+ value = 3 // m39, m41, m4ra defines to come.
+ could_contain = list()//replace with a path to actuall ammo when done
+ amount = 3
+
+
From 0ea30a86861ca8ffee94bfc7bd13f3b688426573 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Mon, 29 Jan 2024 16:02:26 -0500
Subject: [PATCH 016/113] defines defines defines
---
code/__DEFINES/misc.dm | 10 +++++++++-
code/game/objects/items/research_upgrades.dm | 4 ++--
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 2ab70bf39654..ea931ad20e8b 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -155,17 +155,25 @@
#define ASSEMBLY_UNLOCKED 1
#define ASSEMBLY_LOCKED 2
+// RESEARCH UPGRADES DEFINES //
+
// Matrix CAS Upgrades
#define MATRIX_DEFAULT 0
#define MATRIX_NVG 1
#define MATRIX_WIDE 2
-//autodoc upgrade via research
+//autodoc upgrade
#define AUTODOC_UPGRADE_IB 1
#define AUTODOC_UPGRADE_BONEBREAK 2
#define AUTODOC_UPGRADE_ORGAN 3
#define AUTODOC_UPGRADE_LARVA 4
+//Value define, read research_upgrades.dm for more info'
+#define ITEM_EXCLUDE_BUY 0
+
+
+// RESEARCH UPGRADES DEFINES END
+
// Statistics defines
#define STATISTIC_XENO "xeno"
#define STATISTIC_HUMAN "human"
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index f9ce07cb4691..82e2eb407bb9 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -34,7 +34,7 @@
desc = "Somehow you got this, you shouldnt be able to, consider yourself special."
icon = 'icons/obj/items/disk.dmi'
icon_state = "datadisk1"
- var/value = 0 //technology stored on this disk, goes through one to whatever levels of upgrades there are. 0 Excludes it from buying menu.
+ var/value = ITEM_EXCLUDE_BUY //technology stored on this disk, goes through one to whatever levels of upgrades there are. 0 Excludes it from buying menu.
var/list/price = list(1000) // initial price, multiplied by * price_increase at final checkout if there are better version
/obj/item/research_upgrades/proc/get_upgrade_desc(val, short = TRUE) //needed for those special cases like one below. only needed in cases where single disk can be many upgrades, otherwise use desc and name.
@@ -102,7 +102,7 @@
/obj/item/research_upgrades/packet
name = "Research Packet"
desc = " A plastic sealed opaque packet containing whatever research marvel the nerds upstairs were brewing, you shouldnt be able to see this!"
- value = 0
+ value = ITEM_EXCLUDE_BUY
//icon = ***
//icon_state = ***
price = list(1000)
From ef4f95fd1f78687fc47ad992226cf787088e0563 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 1 Feb 2024 14:37:33 -0500
Subject: [PATCH 017/113] yipppee work
---
code/__DEFINES/misc.dm | 16 ++-
code/game/machinery/computer/research.dm | 6 +
code/game/machinery/medical_pod/autodoc.dm | 28 ++---
.../objects/items/circuitboards/machine.dm | 10 ++
code/game/objects/items/research_upgrades.dm | 113 ++++++++++--------
.../mob/living/carbon/xenomorph/Xenomorph.dm | 12 +-
.../chemical_research/xenomorph_analyzer.dm | 3 +-
code/modules/surgery/xeno.dm | 23 ++--
8 files changed, 128 insertions(+), 83 deletions(-)
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index ea931ad20e8b..391bc6b84b8e 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -162,12 +162,16 @@
#define MATRIX_NVG 1
#define MATRIX_WIDE 2
-//autodoc upgrade
-#define AUTODOC_UPGRADE_IB 1
-#define AUTODOC_UPGRADE_BONEBREAK 2
-#define AUTODOC_UPGRADE_ORGAN 3
-#define AUTODOC_UPGRADE_LARVA 4
-
+//packet behavior defines
+#define PACKET_BEHAVIOR_RANDOM 0
+#define PACKET_BEHAVIOR_EXACT 1
+#define PACKET_BEHAVIOR_VALUE 2
+
+#define UPGRADE_TIER_1 1
+#define UPGRADE_TIER_2 2
+#define UPGRADE_TIER_3 3
+#define UPGRADE_TIER_4 4
+#define UPGRADE_TIER_5 5
//Value define, read research_upgrades.dm for more info'
#define ITEM_EXCLUDE_BUY 0
diff --git a/code/game/machinery/computer/research.dm b/code/game/machinery/computer/research.dm
index d5158cb76451..e996e7c7ae2d 100644
--- a/code/game/machinery/computer/research.dm
+++ b/code/game/machinery/computer/research.dm
@@ -53,6 +53,12 @@
var/obj/item/paper/research_report/CR = P.convert_to_chem_report()
GLOB.chemical_data.save_document(CR, response, CR.name)
return
+ //biomass credits rewards
+ if(istype(B, /obj/item/research_upgrades/credits))
+ var/obj/item/research_upgrades/credits/cred = B
+ GLOB.chemical_data.update_credits(2)
+ visible_message(SPAN_NOTICE("[user] inserts [cred.name] in [src], collecting 2 points from sales."))
+ qdel(cred)
//Clearance Updating
if(!istype(B, /obj/item/card/id))
return
diff --git a/code/game/machinery/medical_pod/autodoc.dm b/code/game/machinery/medical_pod/autodoc.dm
index 42de357c8ccb..18a94ddb944e 100644
--- a/code/game/machinery/medical_pod/autodoc.dm
+++ b/code/game/machinery/medical_pod/autodoc.dm
@@ -780,20 +780,20 @@
to_chat(user, "here")
if(upgrades.len > 0)
dat += "Orthopedic Surgeries"
- for(var/iter in upgrades)
- switch(iter)
- if(AUTODOC_UPGRADE_BONEBREAK)
- if(isnull(surgeryqueue["broken"]))
- dat += "Broken Bone Surgery
"
- if(AUTODOC_UPGRADE_IB)
- if(isnull(surgeryqueue["internal"]))
- dat += "Internal Bleeding Surgery
"
- if(AUTODOC_UPGRADE_ORGAN)
- if(isnull(surgeryqueue["organdamage"]))
- dat += "Organ Damage Treatment
"
- if(AUTODOC_UPGRADE_LARVA)
- if(isnull(surgeryqueue["larva"]))
- dat += "Experimental Parasite Exctraction
"
+ for(var/iter in upgrades)
+ switch(iter)
+ if(UPGRADE_TIER_2)
+ if(isnull(surgeryqueue["broken"]))
+ dat += "Broken Bone Surgery
"
+ if(UPGRADE_TIER_1)
+ if(isnull(surgeryqueue["internal"]))
+ dat += "Internal Bleeding Surgery
"
+ if(UPGRADE_TIER_3)
+ if(isnull(surgeryqueue["organdamage"]))
+ dat += "Organ Damage Treatment
"
+ if(UPGRADE_TIER_4)
+ if(isnull(surgeryqueue["larva"]))
+ dat += "Experimental Parasite Exctraction
"
else
dat += "The autodoc is empty."
dat += text("Close", user)
diff --git a/code/game/objects/items/circuitboards/machine.dm b/code/game/objects/items/circuitboards/machine.dm
index 248d0d5c8885..29f42d012fa3 100644
--- a/code/game/objects/items/circuitboards/machine.dm
+++ b/code/game/objects/items/circuitboards/machine.dm
@@ -65,6 +65,16 @@ to destroy them and players will be able to make replacements.
/obj/item/reagent_container/glass/beaker = 2,
)
+/obj/item/circuitboard/machine/xeno_analyzer
+ name = "Circuit board (Xenomorph Analyzer)"
+ build_path = /obj/structure/machinery/xenoanalyzer
+ frame_desc = "Requires 2 Beakers, 2 Extracted Xenomorphic samples, and 5 Wire."
+ req_components = list(
+ /obj/item/organ/heart/xeno/ = 2,
+ /obj/item/stack/cable_coil = 5,
+ /obj/item/reagent_container/glass/beaker = 2,
+
+ )
/obj/item/circuitboard/machine/pacman
name = "Circuit Board (PACMAN-type Generator)"
build_path = /obj/structure/machinery/power/port_gen/pacman
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index 82e2eb407bb9..4f1214dcfff4 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -34,16 +34,17 @@
desc = "Somehow you got this, you shouldnt be able to, consider yourself special."
icon = 'icons/obj/items/disk.dmi'
icon_state = "datadisk1"
- var/value = ITEM_EXCLUDE_BUY //technology stored on this disk, goes through one to whatever levels of upgrades there are. 0 Excludes it from buying menu.
- var/list/price = list(1000) // initial price, multiplied by * price_increase at final checkout if there are better version
+ ///technology stored on this disk, goes through one to whatever levels of upgrades there are. 0 Excludes it from buying menu.
+ var/value = ITEM_EXCLUDE_BUY
+ ///price of the upgrade, if a signle disk could mean many upgrades, use list in sync with upgrades to set its prices
+ var/list/price = list(1000)
/obj/item/research_upgrades/proc/get_upgrade_desc(val, short = TRUE) //needed for those special cases like one below. only needed in cases where single disk can be many upgrades, otherwise use desc and name.
- return "ERROR"
-
+ return
/obj/item/research_upgrades/autodoc
name = "Research Upgrade (AutoDoc)"
desc = "Research upgrade for AutoDoc, Technology on this disk is used "
- value = AUTODOC_UPGRADE_LARVA
+ value = UPGRADE_TIER_4
price = list(3000, 5000, 8000, 10000)
//starting at internal bleeding repair, 2 for bone repair, 3 for organ repair/etc, and 4 for larva removal. They are not exclusive, that means if you get level 4, you still dont have level 2 and 3 & 1.
//set to final upgrade to show the amount of upgrades
@@ -52,42 +53,42 @@
. = ..()
switch(value)
- if(AUTODOC_UPGRADE_IB)
+ if(UPGRADE_TIER_1)
. += "for stopping internal bleedings."
- if(AUTODOC_UPGRADE_BONEBREAK)
+ if(UPGRADE_TIER_2)
. += "for fixating and mending broken bones."
- if(AUTODOC_UPGRADE_ORGAN)
+ if(UPGRADE_TIER_3)
. += "for treating damaged organs."
- if(AUTODOC_UPGRADE_LARVA)
+ if(UPGRADE_TIER_4)
. += "for extracting unknown parasites."
/obj/item/research_upgrades/autodoc/get_upgrade_desc(val, short = TRUE)
if(short)
switch(val)
- if(AUTODOC_UPGRADE_IB)
+ if(UPGRADE_TIER_1)
. += "(Internal Bleedings)"
- if(AUTODOC_UPGRADE_BONEBREAK)
+ if(UPGRADE_TIER_2)
. += "(Broken Bones)"
- if(AUTODOC_UPGRADE_ORGAN)
+ if(UPGRADE_TIER_3)
. += "(Organ Treating)"
- if(AUTODOC_UPGRADE_LARVA)
+ if(UPGRADE_TIER_4)
. += "(Unknown Parasites)"
else
switch(val)
- if(AUTODOC_UPGRADE_IB)
+ if(UPGRADE_TIER_1)
. += "for stopping internal bleedings."
- if(AUTODOC_UPGRADE_BONEBREAK)
+ if(UPGRADE_TIER_2)
. += "for fixating and mending broken bones."
- if (AUTODOC_UPGRADE_ORGAN)
+ if (UPGRADE_TIER_3)
. += "for treating damaged organs"
- if (AUTODOC_UPGRADE_LARVA)
+ if (UPGRADE_TIER_4)
. += "for extracting unknown parasites"
return
/obj/item/research_upgrades/sleeper
name = "Research Upgrade (Sleeper)"
desc = "Research upgrade for Sleeper system, Technology on this disk is used on a sleeper to allow wider spectrum of chemicals to be administered"
- value = 1
+ value = UPGRADE_TIER_1
price = list(4000)
/obj/item/research_upgrades/sleeper/get_upgrade_desc(val, short = TRUE)
@@ -96,9 +97,24 @@
/obj/item/research_upgrades/credits
name = "Research Market (Credits)"
desc = "Research points disk for chemical synthesis, insert this into research computer in order to sell the data and acquire two points" //need to balance this out somehow. either nerf passive income or remove grants from groundside
- value = 1
+ value = UPGRADE_TIER_1
price = list(1000)
+/obj/item/research_upgrades/property
+ name = "Research Market (Propety)"
+ desc = "Research points disk for chemical synthesis, insert this into research computer in order to sell the data and acquire one random chemical property of your choice."
+ value = UPGRADE_TIER_3
+ price = list(2000, 4000, 8000)
+
+/obj/item/research_upgrades/property/get_upgrade_desc(val, short = TRUE)
+ switch(val)
+ if(UPGRADE_TIER_1)
+ . += "(Uncommon)"
+ if(UPGRADE_TIER_2)
+ . += "(Rare)"
+ if(UPGRADE_TIER_3)
+ . += "(Legendary)"
+ return
/obj/item/research_upgrades/packet
name = "Research Packet"
desc = " A plastic sealed opaque packet containing whatever research marvel the nerds upstairs were brewing, you shouldnt be able to see this!"
@@ -106,10 +122,14 @@
//icon = ***
//icon_state = ***
price = list(1000)
- var/list/could_contain = null //the item(s) the packet inside has.
- var/is_opened = FALSE //ripped open or not
- var/amount = 1 // how much items in packet(how many times to spawn the could_contain).
- var/random = TRUE //should the items in packets be randomly given or exactly to what could_contain says
+ ///What packet contains
+ var/list/could_contain = null
+ ///is the packet open
+ var/is_opened = FALSE
+ ///How many times to spawn the could_contain item(s
+ var/amount = 1
+ ///How does a packet use could_contain list, 3 types of behavior - _EXACT gives user exactly what is in could_contain, _RANDOM gives user a thing from could contain on random basis, and _VALUE makes it follow value var(spawns second thing in the list if value is two)
+ var/behavior = PACKET_BEHAVIOR_EXACT
/obj/item/research_upgrades/packet/attack_self(mob/user)
. = ..()
@@ -119,10 +139,22 @@
qdel(src)
return
if(!is_opened)
- var/thing_to_spawn = pick(could_contain)
- var/obj/item/spawn_item = new thing_to_spawn
- spawn_item.forceMove(get_turf(user))
+ for(var/iteration in 1 to amount)
+ switch(behavior)
+ if(PACKET_BEHAVIOR_RANDOM)
+ var/thing_to_spawn = pick(could_contain)
+ var/obj/item/spawn_item = new thing_to_spawn
+ spawn_item.forceMove(get_turf(user))
+ if(PACKET_BEHAVIOR_EXACT)
+ for(var/newthing in could_contain)
+ var/obj/item/spawn_item = new newthing
+ spawn_item.forceMove(get_turf(user))
+ if(PACKET_BEHAVIOR_VALUE)
+ var/thing_to_spawn = could_contain[value]
+ var/obj/item/spawn_item = new thing_to_spawn
+ spawn_item.forceMove(get_turf(user))
is_opened = TRUE
+ //icon_state = x
desc += "This one seems to be already opened"
return
@@ -131,32 +163,19 @@
name = "Research Packet (Attachment)"
desc = "An opaque sealed packet containing one random experimental gun attachment"
price = list(2000)
- value = 1
+ value = UPGRADE_TIER_1
could_contain = list()//need to add actual attachments(sprites ;-;) too, so many shit todo holy shit.
//also, no idea what kinda of attachments were looking at in future
-/obj/item/research_upgrades/packet/attachment/attack_self(mob/user)
- . = ..()
- //icon_state = insert torn packet here
- return
-
-/obj/item/research_upgrades/packet/ammo_x//replace with actually initialls of ammo once sure which ammo to add
- name = "Research Packet (Ammo)"
- desc = "Contains a handfull of X ammo. Handle with care"
- price = list(250, 200)
- value = 2 // one for m41 cal and second for m39 cal
- could_contain = list()//replace with a path to actuall ammo when done
- amount = 3
-
+/obj/item/research_upgrades/packet/armor_buff
+ name = "Research Packet (Armor)"
+ desc = "An opaque sealed packet containing one armor reinforcment compatible with M3 Marine armor."
+ price = list(2000, 4000, 8000)
+ value = UPGRADE_TIER_3
+ behavior = PACKET_BEHAVIOR_VALUE
+ could_contain = list() //omygod
-/obj/item/research_upgrades/packet/magazine
- name = "Research Packet (Mag)"
- desc = "Contains a single magazine for . Handle with care"
- price = list(250, 200, 250)
- value = 3 // m39, m41, m4ra defines to come.
- could_contain = list()//replace with a path to actuall ammo when done
- amount = 3
diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
index 46fac05c3f63..44ac8991d156 100644
--- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
+++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
@@ -348,11 +348,13 @@
src.hivenumber = old_xeno.hivenumber
else if(hivenumber)
src.hivenumber = hivenumber
-
- var/obj/item/organ/heart/xeno/organ = new() //give
- organ.forceMove(src)
- organ.research_value = tier
- organ.caste_origin = src.caste_type
+ if(!islarva(src))
+ var/obj/item/organ/heart/xeno/organ = new() //give
+ organ.forceMove(src)
+ organ.research_value = tier
+ if(isqueen(src)) //queens have tier 0
+ organ.research_value = 7 //queen is EXPENSIVE
+ organ.caste_origin = src.caste_type
var/datum/hive_status/hive = GLOB.hive_datum[src.hivenumber]
diff --git a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
index a1bb61b0d32b..2e80cc087408 100644
--- a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
+++ b/code/modules/reagents/chemical_research/xenomorph_analyzer.dm
@@ -107,8 +107,7 @@
return
playsound(src.loc, 'sound/machines/blender.ogg', 25, 1)
biomass_points += organ.research_value * 1000 //inflatizng values less goo
- qdel(organ)
- organ = null
+ QDEL_NULL(organ)
/obj/structure/machinery/xenoanalyzer/proc/start_print_upgrade(produce_path, cost, mob/user, variation)
if (stat & NOPOWER)
diff --git a/code/modules/surgery/xeno.dm b/code/modules/surgery/xeno.dm
index 3d8e28217dee..5612e8a825ee 100644
--- a/code/modules/surgery/xeno.dm
+++ b/code/modules/surgery/xeno.dm
@@ -1,10 +1,10 @@
-//Research stuff to extract stuff from xenomorphs for goodies. In other words, to extract usefull material that could be used to upgrade marines and etc. doesnt add anything of kind
+//Research stuff to extract stuff from xenomorphs for goodies. In other words, to extract usefull material that could be used to upgrade marines and etc.
/datum/surgery/xenomorph
name = "Experimental Harvesting Surgery"
invasiveness = list(SURGERY_DEPTH_SURFACE)
- required_surgery_skill = SKILL_SURGERY_NOVICE
+ required_surgery_skill = SKILL_SURGERY_TRAINED
possible_locs = list("head")
target_mobtypes = list(/mob/living/carbon/xenomorph)
steps = list(
@@ -44,10 +44,11 @@
SPAN_NOTICE("[user] starts to [pick("smash", "crack", "break")] [target.caste_type] carapace with \the [tool], Recklessly, with acid splashing them!"))
if(user.head && !(user.head.flags_inventory & COVEREYES))
var/datum/internal_organ/eyes/user_eye = user.internal_organs_by_name["eyes"]
- user_eye.take_damage(rand(3,5), FALSE)
+ user_eye.take_damage(rand(3,5), TRUE)
to_chat(user, SPAN_DANGER("Lots of acid gets into your eyes and on your skin!"))
user.emote("pain")
user.apply_damage(rand(10,25),BURN)
+ //we dont really need log interact since we're working with dead body... I hope
/datum/surgery_step/xenomorph/cut_exoskeleton/success(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
if(tool_type == /obj/item/tool/surgery/circular_saw)
@@ -72,6 +73,7 @@
SPAN_WARNING("Your hand slips, failing to destroy [target.caste_type] carapace into bits and pieces apart using \the [tool]."),
SPAN_WARNING("[user] hand slips, failing to destroy Your carapace into bits and pieces using \the [tool]."),
SPAN_WARNING("[user] hand slips, failing to destroy [target.caste_type] carapace into bits and pieces using \the [tool]."))
+ return FALSE
/datum/surgery_step/xenomorph/open_exoskeleton
name = "Pry exoskeleton open"
@@ -101,11 +103,12 @@
SPAN_NOTICE("[user] starts to open [target.caste_type] carapace with \the [tool] very carefully"))
/datum/surgery_step/xenomorph/open_exoskeleton/failure(mob/living/carbon/human/user, mob/living/carbon/xenomorph/target, target_zone, obj/item/tool, tool_type, datum/surgery/surgery)
- user.affected_message(target,
- SPAN_WARNING("Your hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
- SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
- SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"))
- user.apply_damage(rand(5, 15), BURN)
+ user.affected_message(target,
+ SPAN_WARNING("Your hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
+ SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"),
+ SPAN_WARNING("[user] hand slips, letting go of [target.caste_type] carapace and exoskeleton, slaming it back into place and splashing acid everywhere!"))
+ user.apply_damage(rand(15, 45), BURN)
+ return FALSE
/datum/surgery_step/xenomorph/severe_connections
name = "Severe organ connections"
@@ -145,7 +148,8 @@
SPAN_WARNING("Your hand slips, damaging one of [target.caste_type] [pick("arteries", "viens")], gushing acid blood everywhere!"),
SPAN_WARNING("[user] hand slips, damaging one of Your [pick("arteries", "viens")], gushing acid blood everywhere!"),
SPAN_WARNING("[user] hand slips, damaging one of [target.caste_type] [pick("arteries", "viens")], gushing acid blood everywhere!"))
- user.apply_damage(rand(5, 15), BURN)
+ user.apply_damage(rand(15, 45), BURN)
+ return FALSE
/datum/surgery_step/xenomorph/remove_organ
name = "Take out the organ"
@@ -199,4 +203,5 @@
SPAN_NOTICE("You fail to pull the [target.caste_type] organ out using \the [tool]"),
SPAN_NOTICE("[user] fails to pull Your organ out using \the [tool]"),
SPAN_NOTICE("[user] fails to pull the [target.caste_type] organ out using \the [tool]"))
+ return FALSE
From 5ac257df9bd42a0e2fa9c69b7f748e41cd789475 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 1 Feb 2024 14:45:57 -0500
Subject: [PATCH 018/113] ;-;
---
code/game/objects/items/research_upgrades.dm | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index 4f1214dcfff4..35110100dcee 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -34,15 +34,15 @@
desc = "Somehow you got this, you shouldnt be able to, consider yourself special."
icon = 'icons/obj/items/disk.dmi'
icon_state = "datadisk1"
- ///technology stored on this disk, goes through one to whatever levels of upgrades there are. 0 Excludes it from buying menu.
+ ///technology stored on this disk, goes through one to whatever levels of upgrades there are, set it to . 0 Excludes it from buying menu.
var/value = ITEM_EXCLUDE_BUY
- ///price of the upgrade, if a signle disk could mean many upgrades, use list in sync with upgrades to set its prices
+ ///price of the upgrade, if a single disk could mean many upgrades, use list in sync with upgrades to set its prices
var/list/price = list(1000)
/obj/item/research_upgrades/proc/get_upgrade_desc(val, short = TRUE) //needed for those special cases like one below. only needed in cases where single disk can be many upgrades, otherwise use desc and name.
return
/obj/item/research_upgrades/autodoc
- name = "Research Upgrade (AutoDoc)"
+ name = "Research Upgrade(AutoDoc)"
desc = "Research upgrade for AutoDoc, Technology on this disk is used "
value = UPGRADE_TIER_4
price = list(3000, 5000, 8000, 10000)
@@ -154,7 +154,8 @@
var/obj/item/spawn_item = new thing_to_spawn
spawn_item.forceMove(get_turf(user))
is_opened = TRUE
- //icon_state = x
+ //icon_state = x //sprites will come sprites will come sprites will come sprites will come
+ //man above is coping ^^^
desc += "This one seems to be already opened"
return
From 787c8c7fbc6f2868f57a2560254175f5349633f3 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 1 Feb 2024 14:47:19 -0500
Subject: [PATCH 019/113] oops
---
code/game/objects/items/research_upgrades.dm | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index 35110100dcee..755ccf8219dd 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -133,12 +133,13 @@
/obj/item/research_upgrades/packet/attack_self(mob/user)
. = ..()
- playsound(src, "rip", 15, TRUE, 6)
if(isnull(could_contain) && !is_opened)
+ playsound(src, "rip", 15, TRUE, 6)
to_chat(user, SPAN_WARNING("The packet was empty, so you throw it out."))
qdel(src)
return
if(!is_opened)
+ playsound(src, "rip", 15, TRUE, 6)
for(var/iteration in 1 to amount)
switch(behavior)
if(PACKET_BEHAVIOR_RANDOM)
From e6429e2eb123f16fe9f45cf83caf635259cdc4aa Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 1 Feb 2024 14:49:57 -0500
Subject: [PATCH 020/113] lol why
---
code/game/objects/items/research_upgrades.dm | 3 ---
1 file changed, 3 deletions(-)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index 755ccf8219dd..c18052958de4 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -91,9 +91,6 @@
value = UPGRADE_TIER_1
price = list(4000)
-/obj/item/research_upgrades/sleeper/get_upgrade_desc(val, short = TRUE)
- return
-
/obj/item/research_upgrades/credits
name = "Research Market (Credits)"
desc = "Research points disk for chemical synthesis, insert this into research computer in order to sell the data and acquire two points" //need to balance this out somehow. either nerf passive income or remove grants from groundside
From 8982d53d9b71b57f4cbfb9e554a9b690fff83cb5 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 1 Feb 2024 15:24:55 -0500
Subject: [PATCH 021/113] oof
---
code/game/objects/items/research_upgrades.dm | 2 +-
.../xenomorph_analyzer.dm | 0
colonialmarines.dme | 2 +-
3 files changed, 2 insertions(+), 2 deletions(-)
rename code/modules/reagents/{chemical_research => chemistry_machinery}/xenomorph_analyzer.dm (100%)
diff --git a/code/game/objects/items/research_upgrades.dm b/code/game/objects/items/research_upgrades.dm
index c18052958de4..ec095c642f3e 100644
--- a/code/game/objects/items/research_upgrades.dm
+++ b/code/game/objects/items/research_upgrades.dm
@@ -34,7 +34,7 @@
desc = "Somehow you got this, you shouldnt be able to, consider yourself special."
icon = 'icons/obj/items/disk.dmi'
icon_state = "datadisk1"
- ///technology stored on this disk, goes through one to whatever levels of upgrades there are, set it to . 0 Excludes it from buying menu.
+ ///technology stored on this disk, goes through one to whatever levels of upgrades there are, set it to last upgrade in your line. 0 Excludes it from buying menu.
var/value = ITEM_EXCLUDE_BUY
///price of the upgrade, if a single disk could mean many upgrades, use list in sync with upgrades to set its prices
var/list/price = list(1000)
diff --git a/code/modules/reagents/chemical_research/xenomorph_analyzer.dm b/code/modules/reagents/chemistry_machinery/xenomorph_analyzer.dm
similarity index 100%
rename from code/modules/reagents/chemical_research/xenomorph_analyzer.dm
rename to code/modules/reagents/chemistry_machinery/xenomorph_analyzer.dm
diff --git a/colonialmarines.dme b/colonialmarines.dme
index 02f9b32dd89d..1a27125a7eac 100644
--- a/colonialmarines.dme
+++ b/colonialmarines.dme
@@ -2214,7 +2214,6 @@
#include "code\modules\reagents\Chemistry-Vessel.dm"
#include "code\modules\reagents\chemical_research\Chemical-Research.dm"
#include "code\modules\reagents\chemical_research\generated_reagents.dm"
-#include "code\modules\reagents\chemical_research\xenomorph_analyzer.dm"
#include "code\modules\reagents\chemistry_machinery\acid_harness.dm"
#include "code\modules\reagents\chemistry_machinery\autodispenser.dm"
#include "code\modules\reagents\chemistry_machinery\centrifuge.dm"
@@ -2225,6 +2224,7 @@
#include "code\modules\reagents\chemistry_machinery\pandemic.dm"
#include "code\modules\reagents\chemistry_machinery\reagent_analyzer.dm"
#include "code\modules\reagents\chemistry_machinery\reagent_grinder.dm"
+#include "code\modules\reagents\chemistry_machinery\xenomorph_analyzer.dm"
#include "code\modules\reagents\chemistry_properties\chem_property.dm"
#include "code\modules\reagents\chemistry_properties\prop_negative.dm"
#include "code\modules\reagents\chemistry_properties\prop_neutral.dm"
From bce65458234dd349ff283407c22a2e5f1620b021 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Thu, 1 Feb 2024 15:53:32 -0500
Subject: [PATCH 022/113] forgorto remove
---
tools/build/build.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/build/build.js b/tools/build/build.js
index 104adaffc57c..c145ed391eb2 100644
--- a/tools/build/build.js
+++ b/tools/build/build.js
@@ -176,7 +176,7 @@ export const TguiTarget = new Juke.Target({
"tgui/.yarn/install-target",
"tgui/webpack.config.js",
"tgui/**/package.json",
- "tgui/packages/**/*.+(js|cjs|ts|tsx|jsx|scss)",
+ "tgui/packages/**/*.+(js|cjs|ts|tsx|scss)",
],
outputs: [
"tgui/public/tgui.bundle.css",
From e67736b9591fbe20c6f5680170c1d45067508637 Mon Sep 17 00:00:00 2001
From: kiVts <48099872+kiVts@users.noreply.github.com>
Date: Wed, 14 Feb 2024 23:46:11 -0500
Subject: [PATCH 023/113] wounds
---
icons/mob/xenos/wounds.dmi | Bin 68814 -> 36470 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/icons/mob/xenos/wounds.dmi b/icons/mob/xenos/wounds.dmi
index 730e367f43aecdbf019705b7a6ae312db3aa49d1..f06cefb7e2a0b9fb23538fcfeebbdaa604523d06 100644
GIT binary patch
literal 36470
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%0D#&&
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≧o?2zr!~fwS%3${
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