mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-16 02:17:06 +01:00
Greimorian Egg Cluster Implantation Refactor (#21554)
Fixes https://github.com/Aurorastation/Aurora.3/issues/21509 **Summary:** Cleans up a lot of old Greimorian egg implantation code- rewrote the actual worker injection behavior to use the organ/internal/parasite code we have, instead of creating effects with their loc set to the organ itself. This largely means that not only is Greimorian implantation able to be treated pharmaceutically (as you'd expect, with them being parasitic and medicine including antiparasitics), but it also means that 'greimorian eggs' also get the same treatment as nerve flukes, etc. That is to say, antags can now purchase Greimorian Clade Kits from the uplink and inject people or monkeys with them to cause Unhappy Tidings. This code is also fairly easy to modify, if one wanted to create more implantable parasites that burst out of people, unrelated to Greimorians. **Changes:** - refactor: "Refactors the egg injection of Greimorian Workers to use parasite code; it can now be treated with anti-parasitic medicines in addition to amputation of the affected limb. Works on all playable species, and monkeys." - rscadd: "New reagent 'Greimorian Eggs' creates an egg cluster parasite in a random organ when metabolized in the bloodstream. It also has very mild soporific effects." - balance: "Greimorian Workers and playable Greimorian Servants/Queen now inject Greimorian Eggs instead of Soporific." - rscadd: "Greimorian Clade Kit now available in Uplink under Bioweapons section (Greimorians now able to be introduced to ship by egg cluster or injectable reagent)." - balance: "All parasite kit bioweapons have had their vial reagent count increased from 2 -> 5." - balance: "Helmizole no longer treats K'ois Mycosis, Black K'ois Mycosis, Zombification, or Tumors (Benign or Malignant)." - code_imp: "Updates a lot of code documentation to dmdocs."
This commit is contained in:
@@ -3129,6 +3129,7 @@
|
||||
#include "code\modules\organs\subtypes\augment\augments\zengu_plate.dm"
|
||||
#include "code\modules\organs\subtypes\parasite\_parasite.dm"
|
||||
#include "code\modules\organs\subtypes\parasite\black_kois.dm"
|
||||
#include "code\modules\organs\subtypes\parasite\greim_eggs.dm"
|
||||
#include "code\modules\organs\subtypes\parasite\heart_fluke.dm"
|
||||
#include "code\modules\organs\subtypes\parasite\kois.dm"
|
||||
#include "code\modules\organs\subtypes\parasite\tumours.dm"
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
#define BP_WORM_NERVE "nerve fluke"
|
||||
#define BP_TUMOUR_NONSPREADING "benign tumour"
|
||||
#define BP_TUMOUR_SPREADING "malignant tumour"
|
||||
#define BP_GREIMORIAN_EGGCLUSTER "greimorian egg cluster"
|
||||
|
||||
//Augment organs
|
||||
#define BP_AUG_ACC_CORDS "modified synthetic vocal cords"
|
||||
|
||||
+54
-42
@@ -5,8 +5,8 @@
|
||||
//Checks if all high bits in req_mask are set in bitfield
|
||||
#define BIT_TEST_ALL(bitfield, req_mask) ((~(bitfield) & (req_mask)) == 0)
|
||||
|
||||
//Inverts the colour of an HTML string
|
||||
/proc/invertHTML(HTMLstring)
|
||||
/// Inverts the colour of an HTML string
|
||||
/proc/htmlInvertColor(HTMLstring)
|
||||
|
||||
if (!( istext(HTMLstring) ))
|
||||
CRASH("Given non-text argument!")
|
||||
@@ -30,7 +30,7 @@
|
||||
textr = "0[textb]"
|
||||
return "#[textr][textg][textb]"
|
||||
|
||||
//Returns the middle-most value
|
||||
/// Returns the middle-most value
|
||||
/proc/dd_range(var/low, var/high, var/num)
|
||||
return max(low,min(high,num))
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
ty += AM.step_y
|
||||
return SIMPLIFY_DEGREES(arctan(ty - sy, tx - sx))
|
||||
|
||||
//Returns location. Returns null if no location was found.
|
||||
/// Returns location. Returns null if no location was found.
|
||||
/proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = 0, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0)
|
||||
/*
|
||||
Location where the teleport begins, target that will teleport, distance to go, density checking 0/1(yes/no).
|
||||
@@ -227,19 +227,27 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/getline(atom/M,atom/N)//Ultra-Fast Bresenham Line-Drawing Algorithm
|
||||
var/px=M.x //starting x
|
||||
/// Ultra-Fast Bresenham Line-Drawing Algorithm
|
||||
/proc/getline(atom/M,atom/N)
|
||||
/// starting x
|
||||
var/px=M.x
|
||||
var/py=M.y
|
||||
var/line[] = list(locate(px,py,M.z))
|
||||
var/dx=N.x-px //x distance
|
||||
/// x distance
|
||||
var/dx=N.x-px
|
||||
var/dy=N.y-py
|
||||
var/dxabs=abs(dx)//Absolute value of x distance
|
||||
/// Absolute value of x distance
|
||||
var/dxabs=abs(dx)
|
||||
var/dyabs=abs(dy)
|
||||
var/sdx=SIGN(dx) //Sign of x distance (+ or -)
|
||||
/// Sign of x distance (+ or -)
|
||||
var/sdx=SIGN(dx)
|
||||
var/sdy=SIGN(dy)
|
||||
var/x=dxabs>>1 //Counters for steps taken, setting to distance/2
|
||||
var/y=dyabs>>1 //Bit-shifting makes me l33t. It also makes getline() unnessecarrily fast.
|
||||
var/j //Generic integer for counting
|
||||
/// Counters for steps taken, setting to distance/2
|
||||
var/x=dxabs>>1
|
||||
var/y=dyabs>>1
|
||||
/// Generic integer for counting
|
||||
var/j
|
||||
|
||||
if(dxabs>=dyabs) //x distance is greater than y
|
||||
for(j=0;j<dxabs;j++)//It'll take dxabs steps to get there
|
||||
y+=dyabs
|
||||
@@ -259,7 +267,9 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return line
|
||||
|
||||
#define LOCATE_COORDS(X, Y, Z) locate(between(1, X, world.maxx), between(1, Y, world.maxy), Z)
|
||||
/proc/getcircle(turf/center, var/radius) //Uses a fast Bresenham rasterization algorithm to return the turfs in a thin circle.
|
||||
|
||||
/// Uses a fast Bresenham rasterization algorithm to return the turfs in a thin circle.
|
||||
/proc/getcircle(turf/center, var/radius)
|
||||
if(!radius) return list(center)
|
||||
|
||||
var/x = 0
|
||||
@@ -285,7 +295,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
|
||||
#undef LOCATE_COORDS
|
||||
|
||||
///Returns whether or not a player is a guest using their ckey as an input
|
||||
/// Returns whether or not a player is a guest using their ckey as an input
|
||||
/proc/IsGuestKey(key)
|
||||
if (findtext(key, "Guest-", 1, 7) != 1) //was findtextEx
|
||||
return 0
|
||||
@@ -301,7 +311,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return 0
|
||||
return 1
|
||||
|
||||
///Ensure the frequency is within bounds of what it should be sending/recieving at
|
||||
/// Ensure the frequency is within bounds of what it should be sending/recieving at
|
||||
/proc/sanitize_frequency(var/f, var/low = PUBLIC_LOW_FREQ, var/high = PUBLIC_HIGH_FREQ)
|
||||
f = round(f)
|
||||
f = max(low, f)
|
||||
@@ -310,15 +320,15 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
f += 1
|
||||
return f
|
||||
|
||||
///Turns 1479 into 147.9
|
||||
/// Turns 1479 into 147.9
|
||||
/proc/format_frequency(var/f)
|
||||
return "[round(f / 10)].[f % 10]"
|
||||
|
||||
///Picks a string of symbols to display as the law number for hacked or ion laws
|
||||
/// Picks a string of symbols to display as the law number for hacked or ion laws
|
||||
/proc/ionnum()
|
||||
return "[pick("1","2","3","4","5","6","7","8","9","0")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")][pick("!","@","#","$","%","^","&","*")]"
|
||||
|
||||
///When an AI is activated, it can choose from a list of non-slaved borgs to have as a slave.
|
||||
/// When an AI is activated, it can choose from a list of non-slaved borgs to have as a slave.
|
||||
/proc/freeborg()
|
||||
var/select = null
|
||||
var/list/borgs = list()
|
||||
@@ -332,7 +342,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
select = input("Unshackled borg signals detected:", "Borg selection", null, null) as null|anything in borgs
|
||||
return borgs[select]
|
||||
|
||||
///When a borg is activated, it can choose which AI it wants to be slaved to
|
||||
/// When a borg is activated, it can choose which AI it wants to be slaved to
|
||||
/proc/active_ais()
|
||||
. = list()
|
||||
for(var/mob/living/silicon/ai/A in GLOB.living_mob_list)
|
||||
@@ -343,7 +353,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
. += A
|
||||
return .
|
||||
|
||||
///Find an active ai with the least borgs. VERBOSE PROCNAME HUH!
|
||||
/// Find an active ai with the least borgs. VERBOSE PROCNAME HUH!
|
||||
/proc/select_active_ai_with_fewest_borgs()
|
||||
var/mob/living/silicon/ai/selected
|
||||
var/list/active = active_ais()
|
||||
@@ -388,7 +398,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
new_list += Dead_list
|
||||
return new_list
|
||||
|
||||
///Returns a list of all mobs with their name
|
||||
/// Returns a list of all mobs with their name
|
||||
/proc/getmobs()
|
||||
|
||||
var/list/mobs = sortmobs()
|
||||
@@ -414,7 +424,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
|
||||
return creatures
|
||||
|
||||
///Orders mobs by type then by name
|
||||
/// Orders mobs by type then by name
|
||||
/proc/sortmobs()
|
||||
var/list/moblist = list()
|
||||
var/list/sortmob = sortAtom(GLOB.mob_list)
|
||||
@@ -494,18 +504,17 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return locate(x,y,A.z)
|
||||
|
||||
|
||||
// returns turf relative to A offset in dx and dy tiles
|
||||
// bound to map limits
|
||||
/// Returns turf relative to A offset in dx and dy tiles. Bound to map limits.
|
||||
/proc/get_offset_target_turf(var/atom/A, var/dx, var/dy)
|
||||
var/x = min(world.maxx, max(1, A.x + dx))
|
||||
var/y = min(world.maxy, max(1, A.y + dy))
|
||||
return locate(x,y,A.z)
|
||||
|
||||
///Makes sure MIDDLE is between LOW and HIGH. If not, it adjusts it. Returns the adjusted value.
|
||||
/// Makes sure MIDDLE is between LOW and HIGH. If not, it adjusts it. Returns the adjusted value.
|
||||
/proc/between(var/low, var/middle, var/high)
|
||||
return max(min(middle, high), low)
|
||||
|
||||
///Returns random gauss number
|
||||
/// Returns random gauss number
|
||||
/proc/GaussRand(var/sigma)
|
||||
var/x,y,rsq
|
||||
do
|
||||
@@ -515,7 +524,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
while(rsq>1 || !rsq)
|
||||
return sigma*y*sqrt(-2*log(rsq)/rsq)
|
||||
|
||||
///Step-towards method of determining whether one atom can see another. Similar to viewers()
|
||||
/// Step-towards method of determining whether one atom can see another. Similar to viewers()
|
||||
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldn't be arsed to do actual raycasting :I This is horribly inaccurate.
|
||||
var/turf/current = get_turf(source)
|
||||
var/turf/target_turf = get_turf(target)
|
||||
@@ -769,8 +778,10 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//Takes: Anything that could possibly have variables and a varname to check.
|
||||
//Returns: 1 if found, 0 if not.
|
||||
/**
|
||||
* Takes: Anything that could possibly have variables and a varname to check.
|
||||
* Returns: 1 if found, 0 if not.
|
||||
*/
|
||||
/proc/hasvar(var/datum/A, var/varname)
|
||||
if(A.vars.Find(lowertext(varname))) return 1
|
||||
else return 0
|
||||
@@ -798,7 +809,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
var/dy = abs(B.y - A.y)
|
||||
return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)
|
||||
|
||||
/proc/get_compass_dir(atom/start, atom/end) //get_dir() only considers an object to be north/south/east/west if there is zero deviation. This uses rounding instead. // Ported from CM-SS13
|
||||
/// get_dir() only considers an object to be north/south/east/west if there is zero deviation. This uses rounding instead.
|
||||
/proc/get_compass_dir(atom/start, atom/end)
|
||||
if(!start || !end)
|
||||
return 0
|
||||
if(!start.z || !end.z)
|
||||
@@ -892,7 +904,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return get_turf(location)
|
||||
|
||||
|
||||
//Quick type checks for some tools ~ BRAH wtf is this shit that's not how one should do this
|
||||
/// Quick type checks for some tools ~ BRAH wtf is this shit that's not how one should do this
|
||||
GLOBAL_LIST_INIT(common_tools, list(
|
||||
/obj/item/stack/cable_coil,
|
||||
/obj/item/wrench,
|
||||
@@ -942,7 +954,7 @@ GLOBAL_LIST_INIT(common_tools, list(
|
||||
if(istype(W, /obj/item/melee/energy))
|
||||
return 3500
|
||||
|
||||
//Whether or not the given item counts as sharp in terms of dealing damage
|
||||
/// Whether or not the given item counts as sharp in terms of dealing damage
|
||||
/proc/is_sharp(obj/O)
|
||||
if (!O)
|
||||
return 0
|
||||
@@ -952,7 +964,7 @@ GLOBAL_LIST_INIT(common_tools, list(
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//Whether or not the given item counts as cutting with an edge in terms of removing limbs
|
||||
/// Whether or not the given item counts as cutting with an edge in terms of removing limbs
|
||||
/proc/has_edge(obj/O)
|
||||
if (!O)
|
||||
return 0
|
||||
@@ -966,7 +978,7 @@ GLOBAL_LIST_INIT(common_tools, list(
|
||||
/proc/is_borg_item(obj/item/W)
|
||||
return W && W.loc && isrobot(W.loc)
|
||||
|
||||
//check if mob is lying down on something we can operate him on.
|
||||
/// Check if mob is lying down on something we can operate him on.
|
||||
/proc/can_operate(mob/living/carbon/M) //If it's 2, commence surgery, if it's 1, fail surgery, if it's 0, attack
|
||||
var/surgery_attempt = SURGERY_IGNORE
|
||||
var/located = FALSE
|
||||
@@ -989,9 +1001,7 @@ GLOBAL_LIST_INIT(common_tools, list(
|
||||
surgery_attempt = SURGERY_IGNORE //hit yourself if you're not lying
|
||||
return surgery_attempt
|
||||
|
||||
/*
|
||||
Checks if that loc and dir has a item on the wall
|
||||
*/
|
||||
/// Checks if that loc and dir has a item on the wall
|
||||
GLOBAL_LIST_INIT(wall_items, typecacheof(list(
|
||||
/obj/machinery/power/apc,
|
||||
/obj/machinery/alarm,
|
||||
@@ -1044,9 +1054,11 @@ GLOBAL_LIST_INIT(wall_items, typecacheof(list(
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Returns a variable type as string, optionally with some details:
|
||||
// Objects (datums) get their type, paths get the type name, scalars show length (text) and value (numbers), lists show length.
|
||||
// Also attempts some detection of otherwise undetectable types using ref IDs
|
||||
/**
|
||||
* Returns a variable type as string, optionally with some details:
|
||||
* Objects (datums) get their type, paths get the type name, scalars show length (text) and value (numbers), lists show length.
|
||||
* Also attempts some detection of otherwise undetectable types using ref IDs
|
||||
*/
|
||||
/proc/get_debug_type(var/V, var/details = TRUE, var/print_numbers = TRUE, var/path_names = TRUE, var/text_lengths = TRUE, var/list_lengths = TRUE, var/show_useless_subtypes = TRUE)
|
||||
// scalars / basic types
|
||||
if(isnull(V))
|
||||
@@ -1150,11 +1162,11 @@ GLOBAL_LIST_INIT(wall_items, typecacheof(list(
|
||||
colour += temp_col
|
||||
return "#[colour]"
|
||||
|
||||
// call to generate a stack trace and print to runtime logs
|
||||
/// Call to generate a stack trace and print to runtime logs
|
||||
/proc/crash_with(msg)
|
||||
CRASH(msg)
|
||||
|
||||
//similar function to RANGE_TURFS(), but will search spiralling outwards from the center (like the above, but only turfs)
|
||||
/// Similar function to RANGE_TURFS(), but will search spiraling outwards from the center (like the above, but only turfs)
|
||||
/proc/spiral_range_turfs(dist=0, center=usr, orange=0)
|
||||
if(!dist)
|
||||
if(!orange)
|
||||
|
||||
@@ -20,8 +20,14 @@
|
||||
telecrystal_cost = 5
|
||||
path = /obj/item/storage/box/syndie_kit/heartworms
|
||||
|
||||
/datum/uplink_item/item/bioweapons/greimorian_eggs
|
||||
name = "Greimorian Eggs"
|
||||
/datum/uplink_item/item/bioweapons/greimorians_kit
|
||||
name = "Parasitic Eggs Kit - Greimorian Clade"
|
||||
desc = "Contains the eggs of a Greimorian clade. Semi-lethal and incapacitating. Compatible with most sapient bipedal species (including Earth monkeys)."
|
||||
telecrystal_cost = 4
|
||||
path = /obj/item/storage/box/syndie_kit/greimorians
|
||||
|
||||
/datum/uplink_item/item/bioweapons/greimorian_eggcluster
|
||||
name = "Greimorian Egg Cluster"
|
||||
desc = "A cluster of greimorian eggs. (They will be planted at your feet on-purchase and CANNOT be moved, so make sure you're where you want them to be)"
|
||||
telecrystal_cost = 4
|
||||
path = /obj/effect/spider/eggcluster
|
||||
|
||||
@@ -84,13 +84,13 @@
|
||||
return prob(30)
|
||||
return TRUE
|
||||
|
||||
/// The effect/spider/eggcluster is only for egg clusters spawned in-world, not implanted by a worker.
|
||||
/obj/effect/spider/eggcluster
|
||||
name = "egg cluster"
|
||||
desc = "They seem to pulse slightly with an inner life."
|
||||
icon_state = "eggs"
|
||||
health = 10
|
||||
var/amount_grown = 0
|
||||
var/last_itch = 0
|
||||
|
||||
/obj/effect/spider/eggcluster/Initialize(var/mapload, var/atom/parent)
|
||||
. = ..(mapload)
|
||||
@@ -112,29 +112,16 @@
|
||||
/obj/effect/spider/eggcluster/process()
|
||||
amount_grown += rand(0, 2)
|
||||
|
||||
var/obj/item/organ/external/O = null
|
||||
if(isorgan(loc))
|
||||
O = loc
|
||||
|
||||
if(amount_grown >= 100)
|
||||
var/num = rand(6,24)
|
||||
|
||||
for(var/i = 0, i < num, i++)
|
||||
var/spiderling = new /obj/effect/spider/spiderling(src.loc, src, 0.75)
|
||||
if(O)
|
||||
O.implants += spiderling
|
||||
new /obj/effect/spider/spiderling(src.loc, src, 0.75)
|
||||
qdel(src)
|
||||
else if (O && O.owner && prob(1))
|
||||
if(world.time > last_itch + 30 SECONDS)
|
||||
last_itch = world.time
|
||||
to_chat(O.owner, SPAN_NOTICE("Your [O.name] itches."))
|
||||
|
||||
/obj/effect/spider/eggcluster/proc/take_damage(var/damage)
|
||||
health -= damage
|
||||
if(health <= 0)
|
||||
var/obj/item/organ/external/O = loc
|
||||
if(istype(O) && O.owner)
|
||||
to_chat(O.owner, SPAN_WARNING("You feel something dissolve in your [O.name]..."))
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/spider/spiderling
|
||||
@@ -144,29 +131,41 @@
|
||||
They originate from the Badlands planet Greima, once covered in crystalized phoron. A decaying orbit led to its combustion from proximity to its sun, and its dominant inhabitants \
|
||||
managed to survive in orbit. Countless years later, they prove to be a menace across the galaxy, having carried themselves within the hulls of Human vessels to spread wildly."
|
||||
icon_state = "spiderling"
|
||||
anchored = 0
|
||||
layer = 2.7
|
||||
anchored = FALSE
|
||||
layer = OPEN_DOOR_LAYER // 2.7
|
||||
health = 3
|
||||
var/last_itch = 0
|
||||
var/amount_grown = -1
|
||||
/// % chance that the spiderling will eventually turn into a fully-grown greimorian.
|
||||
var/can_mature_chance = 50
|
||||
var/can_mature = FALSE
|
||||
/// Multiplier to growth gained per tick.
|
||||
var/growth_rate = 1
|
||||
/// Their current growth, from 0-100.
|
||||
var/growth_level = 0
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
|
||||
var/travelling_in_vent = 0
|
||||
var/list/possible_offspring
|
||||
/// Possible creatures the larva can mature into.
|
||||
var/list/possible_offspring = list(
|
||||
/mob/living/simple_animal/hostile/giant_spider,
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse,
|
||||
/mob/living/simple_animal/hostile/giant_spider/emp,
|
||||
/mob/living/simple_animal/hostile/giant_spider/hunter,
|
||||
/mob/living/simple_animal/hostile/giant_spider/bombardier
|
||||
)
|
||||
|
||||
/obj/effect/spider/spiderling/Initialize(var/mapload, var/atom/parent, var/new_rate = 1, var/list/spawns = list(/mob/living/simple_animal/hostile/giant_spider, /mob/living/simple_animal/hostile/giant_spider/nurse, /mob/living/simple_animal/hostile/giant_spider/emp, /mob/living/simple_animal/hostile/giant_spider/hunter, /mob/living/simple_animal/hostile/giant_spider/bombardier))
|
||||
/obj/effect/spider/spiderling/Initialize(var/mapload, var/atom/parent, var/new_growth_rate = 1, var/list/new_possible_offspring = possible_offspring)
|
||||
. = ..(mapload)
|
||||
|
||||
pixel_x = rand(6,-6)
|
||||
pixel_y = rand(6,-6)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
//50% chance to grow up
|
||||
if(prob(50))
|
||||
amount_grown = 1
|
||||
if(prob(can_mature_chance))
|
||||
can_mature = TRUE
|
||||
|
||||
growth_rate = new_rate
|
||||
growth_rate = new_growth_rate
|
||||
|
||||
possible_offspring = spawns
|
||||
possible_offspring = new_possible_offspring
|
||||
|
||||
get_light_and_color(parent)
|
||||
|
||||
@@ -247,32 +246,16 @@
|
||||
GLOB.move_manager.move_to(src, entry_vent, 0, 5)
|
||||
break
|
||||
|
||||
if(isturf(loc) && amount_grown >= 100)
|
||||
if(isturf(loc) && growth_level >= 100)
|
||||
var/spawn_type = pick(possible_offspring)
|
||||
new spawn_type(src.loc, src)
|
||||
qdel(src)
|
||||
else if(isorgan(loc))
|
||||
var/obj/item/organ/external/O = loc
|
||||
if(amount_grown > 70)
|
||||
burst_out(O)
|
||||
if (O.owner)
|
||||
if(amount_grown > 40 && prob(1))
|
||||
O.owner.apply_damage(1, DAMAGE_TOXIN, O.limb_name)
|
||||
if(world.time > last_itch + 30 SECONDS)
|
||||
last_itch = world.time
|
||||
O.owner.visible_message(
|
||||
SPAN_WARNING("You think you see something moving around in \the [O.owner]'s [O.name]."),
|
||||
SPAN_WARNING("You [prob(25) ? "see" : "feel"] something large move around in your [O.name]!"))
|
||||
else if (prob(1))
|
||||
if(world.time > last_itch + 30 SECONDS)
|
||||
last_itch = world.time
|
||||
to_chat(O.owner, SPAN_WARNING("You feel something large move around in your [O.name]!"))
|
||||
|
||||
else if(prob(1))
|
||||
src.visible_message(SPAN_NOTICE("\The [src] skitters."))
|
||||
|
||||
if (amount_grown > -1)
|
||||
amount_grown += (rand(0, 1) * growth_rate)
|
||||
if(can_mature)
|
||||
growth_level += (rand(0, 1) * growth_rate)
|
||||
|
||||
/obj/effect/spider/spiderling/attack_hand(mob/living/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
@@ -294,43 +277,6 @@
|
||||
die()
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Makes the organ spew out all of the spiderlings it has. It's triggered at the point
|
||||
* of the first spiderling reaching 80% of more amount grown. This stops them from growing
|
||||
* to full size inside a human.
|
||||
*
|
||||
* The proc also drops the limb if it's on a human, or gibs it if it's on the floor. For
|
||||
* maximum drama, of course!
|
||||
*
|
||||
* @param O The organ/external limb the src is located inside of.
|
||||
*/
|
||||
/obj/effect/spider/spiderling/proc/burst_out(obj/item/organ/external/O = src.loc)
|
||||
if (!istype(O))
|
||||
return
|
||||
|
||||
if (O.owner)
|
||||
O.owner.visible_message(
|
||||
SPAN_DANGER("A group of [src] burst out of [O.owner]'s [O]!"),
|
||||
SPAN_DANGER("A group of [src] burst out of your [O]!"))
|
||||
O.owner.emote("scream")
|
||||
else
|
||||
O.visible_message(SPAN_DANGER("A group of [src] burst out of \the [O]!"))
|
||||
|
||||
var/target_loc = O.owner ? O.owner.loc : O.loc
|
||||
|
||||
// Swarm all of the spiders out so we can gib the limb.
|
||||
for (var/obj/effect/spider/spiderling/S in O.implants)
|
||||
O.implants -= S
|
||||
S.forceMove(target_loc)
|
||||
|
||||
// if owner, dismember the shit out of it.
|
||||
if (O.owner)
|
||||
O.droplimb(0, DROPLIMB_BLUNT)
|
||||
else
|
||||
O.visible_message(SPAN_DANGER("\The [O] explodes into a pile of gore!"))
|
||||
gibs(target_loc)
|
||||
qdel(O)
|
||||
|
||||
/obj/effect/decal/cleanable/spiderling_remains
|
||||
name = "greimorian larva remains"
|
||||
desc = "Green squishy mess."
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
. = ..()
|
||||
if(is_open_container())
|
||||
atom_flags ^= ATOM_FLAG_OPEN_CONTAINER
|
||||
reagents.add_reagent(/singleton/reagent/toxin/nerveworm_eggs, 2)
|
||||
reagents.add_reagent(/singleton/reagent/toxin/nerveworm_eggs, 5)
|
||||
desc = "<b>BIOHAZARDOUS! - Nerve Fluke eggs.</b> Purchased from <i>SciSupply Eridani</i>, recently incorporated into <i>Zeng-Hu Pharmaceuticals' Keiretsu</i>!"
|
||||
update_icon()
|
||||
|
||||
@@ -109,10 +109,21 @@
|
||||
. = ..()
|
||||
if(is_open_container())
|
||||
atom_flags ^= ATOM_FLAG_OPEN_CONTAINER
|
||||
reagents.add_reagent(/singleton/reagent/toxin/heartworm_eggs, 2)
|
||||
reagents.add_reagent(/singleton/reagent/toxin/heartworm_eggs, 5)
|
||||
desc = "<b>BIOHAZARDOUS! - Heart Fluke eggs.</b> Purchased from <i>SciSupply Eridani</i>, recently incorporated into <i>Zeng-Hu Pharmaceuticals' Keiretsu</i>!"
|
||||
update_icon()
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/vial/greimorian_eggs
|
||||
atom_flags = 0
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/vial/greimorian_eggs/Initialize()
|
||||
. = ..()
|
||||
if(is_open_container())
|
||||
atom_flags ^= ATOM_FLAG_OPEN_CONTAINER
|
||||
reagents.add_reagent(/singleton/reagent/toxin/greimorian_eggs, 5)
|
||||
desc = "<b>BIOHAZARDOUS! - Greimorian eggs.</b> Purchased from <i>SciSupply Eridani</i>, recently incorporated into <i>Zeng-Hu Pharmaceuticals' Keiretsu</i>!"
|
||||
update_icon()
|
||||
|
||||
/obj/item/reagent_containers/powder
|
||||
name = "chemical powder"
|
||||
desc = "A powdered form of... something."
|
||||
|
||||
@@ -220,6 +220,11 @@
|
||||
desc = "Contains the eggs of a Heart Fluke (lethal)."
|
||||
starts_with = list(/obj/item/reagent_containers/glass/beaker/vial/heartworm_eggs = 1, /obj/item/reagent_containers/syringe = 1, /obj/item/reagent_containers/pill/antiparasitic = 1, /obj/item/reagent_containers/pill/asinodryl = 1)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/greimorians
|
||||
name = "greimorian clade kit"
|
||||
desc = "Contains the eggs of greimorian clade (semi-lethal, incapacitating)."
|
||||
starts_with = list(/obj/item/reagent_containers/glass/beaker/vial/greimorian_eggs = 1, /obj/item/reagent_containers/syringe = 1, /obj/item/reagent_containers/pill/antiparasitic = 1, /obj/item/reagent_containers/pill/asinodryl = 1)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/radsuit
|
||||
name = "radiation suit kit"
|
||||
desc = "Contains a radiation suit and geiger counter to protect you from radiation."
|
||||
|
||||
@@ -2,46 +2,55 @@
|
||||
gender = MALE
|
||||
accent = ACCENT_CETI
|
||||
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
||||
var/datum/species/species //Contains icon generation and language information, set during New().
|
||||
//stomach contents redefined at mob/living level, removed from here
|
||||
|
||||
var/analgesic = 0 // when this is set, the mob isn't affected by shock or pain
|
||||
// life should decrease this by 1 every tick
|
||||
// total amount of wounds on mob, used to spread out healing and the like over all wounds
|
||||
/// Contains icon generation and language information, set during New().
|
||||
var/datum/species/species
|
||||
/// When this is set, the mob isn't affected by shock or pain.
|
||||
var/analgesic = 0
|
||||
/// life should decrease this by 1 every tick (??? -batra)
|
||||
/// total amount of wounds on mob, used to spread out healing and the like over all wounds (??? -batra)
|
||||
var/number_wounds = 0
|
||||
var/obj/item/handcuffed = null //Whether or not the mob is handcuffed
|
||||
var/obj/item/legcuffed = null //Same as handcuffs but for legs. Bear traps use this.
|
||||
//Surgery info
|
||||
/// Whether or not the mob is handcuffed.
|
||||
var/obj/item/handcuffed = null
|
||||
/// Same as handcuffs but for legs. Bear traps use this.
|
||||
var/obj/item/legcuffed = null
|
||||
/// Surgery info
|
||||
var/datum/surgery_status/op_stage = new/datum/surgery_status
|
||||
//Active emote/pose
|
||||
/// Active emote/pose
|
||||
var/pose = null
|
||||
var/list/chem_effects = list()
|
||||
var/list/chem_doses = list()
|
||||
/// For keeping count of misc values (amount of damage, number of ticks, etc)
|
||||
/// For keeping count of misc values (amount of damage, number of ticks, etc).
|
||||
var/list/chem_tracking = list()
|
||||
var/intoxication = 0//Units of alcohol in their system
|
||||
var/datum/reagents/metabolism/bloodstr = null
|
||||
var/datum/reagents/metabolism/touching = null
|
||||
var/datum/reagents/metabolism/breathing = null
|
||||
|
||||
//these two help govern taste. The first is the last time a taste message was shown to the plaer.
|
||||
//the second is the message in question.
|
||||
/// These two help govern taste. The first is the last time a taste message was shown to the player.
|
||||
/// The second is the message in question.
|
||||
var/last_taste_time = 0
|
||||
var/last_taste_text = ""
|
||||
|
||||
var/last_smell_time = 0
|
||||
var/last_smell_text = ""
|
||||
|
||||
var/coughedtime = null // should only be useful for carbons as the only thing using it has a carbon arg.
|
||||
/// Should only be useful for carbons as the only thing using it has a carbon arg.
|
||||
var/coughedtime = null
|
||||
|
||||
var/willfully_sleeping = FALSE
|
||||
var/consume_nutrition_from_air = FALSE // used by Diona
|
||||
/// Used by Diona.
|
||||
var/consume_nutrition_from_air = FALSE
|
||||
|
||||
var/help_up_offer = 0 //if they have their hand out to offer someone up from the ground.
|
||||
/// If they have their hand out to offer someone up from the ground.
|
||||
var/help_up_offer = 0
|
||||
|
||||
var/list/organs_by_name = list() // map organ names to organs
|
||||
var/list/internal_organs_by_name = list() // so internal organs have less ickiness too
|
||||
/// Map organ names to organs.
|
||||
var/list/organs_by_name = list()
|
||||
/// So internal organs have less ickiness too.
|
||||
var/list/internal_organs_by_name = list()
|
||||
|
||||
var/list/stasis_sources = list()
|
||||
var/stasis_value
|
||||
var/pain_immune = FALSE //for special cases where something permanently removes a mob's ability to feel pain
|
||||
/// For special cases where something permanently removes a mob's ability to feel pain.
|
||||
var/pain_immune = FALSE
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@
|
||||
|
||||
spark(src, 5)
|
||||
|
||||
//Handles chem traces
|
||||
/// Handles chem traces
|
||||
/mob/living/carbon/human/proc/handle_trace_chems()
|
||||
//New are added for reagents to random organs.
|
||||
for(var/_A in reagents.reagent_volumes)
|
||||
|
||||
@@ -64,9 +64,9 @@
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 10
|
||||
armor_penetration = 20
|
||||
venom_per_bite = 10
|
||||
venom_per_bite = 4
|
||||
var/atom/cocoon_target
|
||||
venom_type = /singleton/reagent/soporific
|
||||
venom_type = /singleton/reagent/toxin/greimorian_eggs
|
||||
var/fed = 0
|
||||
sample_data = list("Genetic markers identified as being linked with stem cell differentiaton", "Cellular structures indicative of high offspring production")
|
||||
|
||||
@@ -82,9 +82,9 @@
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 20
|
||||
armor_penetration = 30
|
||||
venom_per_bite = 10
|
||||
venom_per_bite = 1
|
||||
speed = -2
|
||||
venom_type = /singleton/reagent/soporific
|
||||
venom_type = /singleton/reagent/toxin/greimorian_eggs
|
||||
fed = 1
|
||||
var/playable = TRUE
|
||||
sample_data = list("Genetic markers identified as being linked with stem cell differentiaton", "Cellular structures indicative of high offspring production", "Tissue sample contains high neural cell content")
|
||||
@@ -190,16 +190,17 @@
|
||||
for(var/armor in armors)
|
||||
var/datum/component/armor/armor_datum = armor
|
||||
inject_probability -= armor_datum.armor_values[MELEE] * 1.8
|
||||
if(prob(inject_probability))
|
||||
if(prob(inject_probability) && !BP_IS_ROBOTIC(limb))
|
||||
to_chat(target, SPAN_WARNING("You feel a tiny prick."))
|
||||
target.reagents.add_reagent(venom_type, venom_per_bite)
|
||||
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse/on_attack_mob(var/mob/hit_mob, var/obj/item/organ/external/limb)
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse/on_attack_mob(var/mob/living/carbon/human/hit_mob, var/obj/item/organ/external/limb)
|
||||
. = ..()
|
||||
if(ishuman(hit_mob) && istype(limb) && !BP_IS_ROBOTIC(limb) && prob(venom_per_bite))
|
||||
var/eggs = new /obj/effect/spider/eggcluster(limb, src)
|
||||
limb.implants += eggs
|
||||
to_chat(hit_mob, SPAN_WARNING("\The [src] injects something into your [limb.name]!"))
|
||||
if(istype(limb))
|
||||
if(BP_IS_ROBOTIC(limb))
|
||||
to_chat(hit_mob, SPAN_WARNING("\The [src] tries to inject something into your [limb.name], but fortunately it finds no living flesh!"))
|
||||
else
|
||||
to_chat(hit_mob, SPAN_WARNING("\The [src] injects something into your [limb.name]!"))
|
||||
|
||||
/mob/living/simple_animal/hostile/giant_spider/emp/on_attack_mob(var/mob/hit_mob, var/obj/item/organ/external/limb)
|
||||
. = ..()
|
||||
|
||||
@@ -854,11 +854,11 @@
|
||||
if(transforming) return 0
|
||||
return 1
|
||||
|
||||
// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet.
|
||||
/// Not sure what to call this. Used to check if humans are wearing an AI-controlled exosuit and hence don't need to fall over yet.
|
||||
/mob/proc/can_stand_overridden()
|
||||
return 0
|
||||
|
||||
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
|
||||
/// Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
|
||||
/mob/proc/update_canmove()
|
||||
if(in_neck_grab())
|
||||
lying = FALSE
|
||||
@@ -976,7 +976,7 @@
|
||||
return facedir(client.client_dir(SOUTH))
|
||||
|
||||
|
||||
//This might need a rename but it should replace the can this mob use things check
|
||||
/// This might need a rename but it should replace the can this mob use things check
|
||||
/mob/proc/IsAdvancedToolUser()
|
||||
return 0
|
||||
|
||||
|
||||
@@ -2,23 +2,29 @@
|
||||
INTERNAL ORGANS DEFINES
|
||||
****************************************************/
|
||||
/obj/item/organ/internal
|
||||
var/dead_icon // Icon to use when the organ has died.
|
||||
var/damage_reduction = 0.5 //modifier for internal organ injury
|
||||
var/unknown_pain_location = TRUE // if TRUE, pain messages will point to the parent organ, otherwise it will print the organ name
|
||||
/// Icon to use when the organ has died.
|
||||
var/dead_icon
|
||||
/// Modifier for internal organ injury.
|
||||
var/damage_reduction = 0.5
|
||||
/// If TRUE, pain messages will point to the parent organ, otherwise it will print the organ name.
|
||||
var/unknown_pain_location = TRUE
|
||||
var/toxin_type = "undefined"
|
||||
var/relative_size = 25 //Used for size calcs
|
||||
/// The icon state to overlay on the mob
|
||||
/// Used for size calcs.
|
||||
var/relative_size = 25
|
||||
/// The icon state to overlay on the mob.
|
||||
var/on_mob_icon
|
||||
/// If the icon state has an active overlay
|
||||
/// If the icon state has an active overlay.
|
||||
var/active_overlay = FALSE
|
||||
/// If the icon state has an active emissive overlay
|
||||
/// If the icon state has an active emissive overlay.
|
||||
var/active_emissive = FALSE
|
||||
var/list/possible_modifications = list("Normal","Assisted","Mechanical") //this is used in the character setup
|
||||
/// Used in character setup.
|
||||
var/list/possible_modifications = list("Normal","Assisted","Mechanical")
|
||||
|
||||
/// The amount all organs heal themselves by per second when not being affected by chems.
|
||||
var/organ_self_heal_per_second = 0.2
|
||||
|
||||
min_broken_damage = 10 //Internal organs are frail, man.
|
||||
/// Internal organs are frail, man.
|
||||
min_broken_damage = 10
|
||||
|
||||
/obj/item/organ/internal/Destroy()
|
||||
if(owner)
|
||||
@@ -31,6 +37,7 @@
|
||||
if(istype(E)) E.internal_organs -= src
|
||||
return ..()
|
||||
|
||||
/// Sets the internal organ as belonging to the targeted external organ, and matches the target's species/robotness. Also updates all organ lists belonging to the owner.
|
||||
/obj/item/organ/internal/replaced(var/mob/living/carbon/human/target, var/obj/item/organ/external/affected)
|
||||
if(!istype(target))
|
||||
return 0
|
||||
|
||||
@@ -459,6 +459,7 @@ INITIALIZE_IMMEDIATE(/obj/item/organ)
|
||||
owner.update_action_buttons()
|
||||
owner = null
|
||||
|
||||
/// Sets the organ's owner to the proc's target, and ensures its forceMoved into that target.
|
||||
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target, var/obj/item/organ/external/affected)
|
||||
owner = target
|
||||
action_button_name = initial(action_button_name)
|
||||
|
||||
@@ -1135,10 +1135,15 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
if(victim.get_blood_color())
|
||||
gore.basecolor = victim.get_blood_color()
|
||||
gore.update_icon()
|
||||
// Tiny amount of blood and not impacted by anything like coagulants, etc- we just want it for effect.
|
||||
victim.blood_squirt(2, loc, rand(2,5))
|
||||
add_blood(victim)
|
||||
|
||||
INVOKE_ASYNC(gore, TYPE_PROC_REF(/atom/movable, throw_at), get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1,3), 4)
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.removed()
|
||||
victim.blood_squirt(2, loc, rand(2,5))
|
||||
if(istype(loc,/turf))
|
||||
INVOKE_ASYNC(I, TYPE_PROC_REF(/atom/movable, throw_at), get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1,3), 4)
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
/obj/item/organ/internal/parasite/process()
|
||||
..()
|
||||
if(!owner)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(owner.chem_effects[CE_ANTIPARASITE] && !drug_resistance)
|
||||
@@ -74,6 +75,13 @@
|
||||
/obj/item/organ/internal/parasite/proc/stage_effect()
|
||||
return
|
||||
|
||||
/// Removes the parasite on next process().
|
||||
/obj/item/organ/internal/parasite/proc/remove_parasite()
|
||||
recession = 1000
|
||||
stage = 1
|
||||
stage_ticker = 0
|
||||
drug_resistance = FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/infest_with_parasite(var/mob/living/carbon/victim, var/parasite_type, var/obj/item/organ/external/organ_to_infest, var/chance_to_infest = 100, var/parasite_limit = 3)
|
||||
if(ishuman(victim))
|
||||
var/mob/living/carbon/human/H = victim
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/obj/item/organ/internal/parasite/greimorian_eggcluster
|
||||
name = "cluster of greimorian eggs"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "eggs"
|
||||
dead_icon = "eggs"
|
||||
|
||||
organ_tag = BP_GREIMORIAN_EGGCLUSTER
|
||||
parent_organ = BP_CHEST
|
||||
subtle = 1
|
||||
|
||||
/// ~2 minutes/stage (at two seconds/tick)
|
||||
stage_interval = 60
|
||||
|
||||
max_stage = 5
|
||||
|
||||
origin_tech = list(TECH_BIO = 4)
|
||||
|
||||
egg = /singleton/reagent/toxin/greimorian_eggs
|
||||
|
||||
/// Everyone's favorite-named variable
|
||||
var/gestating_spiderlings = 0
|
||||
|
||||
var/last_crawling_msg = 0
|
||||
|
||||
/// True when it has ruptured; end additional behavior.
|
||||
var/ruptured = FALSE
|
||||
|
||||
/obj/item/organ/internal/parasite/greimorian_eggcluster/process()
|
||||
..()
|
||||
|
||||
if(!owner && gestating_spiderlings)
|
||||
return
|
||||
|
||||
if(ruptured)
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/affecting_organ = owner.organs_by_name[parent_organ]
|
||||
|
||||
if(prob(8))
|
||||
gestating_spiderlings += 1
|
||||
|
||||
if(prob(5))
|
||||
to_chat(affecting_organ.owner, SPAN_NOTICE("Your [affecting_organ.name] itches."))
|
||||
|
||||
if(prob(33))
|
||||
owner.adjustNutritionLoss(3)
|
||||
|
||||
if(stage >= 2) //after ~2.5 minutes
|
||||
if(prob(8))
|
||||
gestating_spiderlings += rand(1,2)
|
||||
|
||||
if(prob(33))
|
||||
owner.adjustNutritionLoss(4)
|
||||
if(prob(5))
|
||||
owner.emote("whimper")
|
||||
if(prob(3))
|
||||
to_chat(owner, SPAN_WARNING(pick("You feel nauseous and hungry at the same time.", "You feel a burning pain in your [parent_organ].", "Your sense of balance seems broken.")))
|
||||
|
||||
if(stage >= 3) //after ~5 minutes
|
||||
if(prob(8))
|
||||
gestating_spiderlings += rand(1,3)
|
||||
|
||||
if(prob(33))
|
||||
owner.adjustNutritionLoss(5)
|
||||
if(prob(10))
|
||||
affecting_organ.take_damage(rand(1,3))
|
||||
owner.adjustHalLoss(8)
|
||||
if(world.time > last_crawling_msg + 15 SECONDS)
|
||||
last_crawling_msg = world.time
|
||||
owner.visible_message(
|
||||
SPAN_WARNING("You think you see something moving around in \the [owner.name]'s [affecting_organ.name]."),
|
||||
SPAN_WARNING("You [prob(25) ? "see" : "feel"] something large move around in your [affecting_organ.name]!"))
|
||||
if(prob(1))
|
||||
owner.seizure(0.4)
|
||||
|
||||
if(stage >= 4) //after ~7.5 minutes
|
||||
if(prob(8))
|
||||
gestating_spiderlings += rand(1,4)
|
||||
|
||||
if(prob(5))
|
||||
owner.reagents.add_reagent(/singleton/reagent/toxin/greimorian_eggs, (gestating_spiderlings / 3))
|
||||
owner.adjustHalLoss(12)
|
||||
to_chat(owner, SPAN_WARNING(pick("A sharp, caustic pain boils out from your [affecting_organ.name]!", "You can feel the flesh of your [affecting_organ.name] beginning to bulge!", "It's going to burst! Your [affecting_organ.name] is going to burst!")))
|
||||
if(prob(5))
|
||||
owner.seizure(0.5)
|
||||
|
||||
if(stage >= 5) //after ~9 minutes
|
||||
if(prob(8))
|
||||
gestating_spiderlings += rand(1,5)
|
||||
|
||||
if(prob(10))
|
||||
owner.seizure(0.6)
|
||||
if(prob(5))
|
||||
ruptured = TRUE
|
||||
owner.adjustHalLoss(75)
|
||||
owner.seizure()
|
||||
src.owner.emote("scream")
|
||||
owner.visible_message(
|
||||
SPAN_DANGER("You can see the flesh of [owner.name]'s [affecting_organ.name] begin rippling violently!"),
|
||||
SPAN_DANGER("An <b>extreme</b>, nauseating pain erupts from your [affecting_organ.name]; you feel something burst inside it. The flesh begins to ripple violently!"))
|
||||
addtimer(CALLBACK(src, PROC_REF(rupture)), rand(30, 50))
|
||||
|
||||
/obj/item/organ/internal/parasite/greimorian_eggcluster/Destroy()
|
||||
var/obj/item/organ/external/affecting_organ = owner.organs_by_name[parent_organ]
|
||||
to_chat(src.owner, SPAN_WARNING("Mercifully, you feel something finally dissolve in your [affecting_organ.name]..."))
|
||||
..()
|
||||
|
||||
/**
|
||||
* Makes the victim spew out all of the spiderlings it has. It's triggered at the point
|
||||
* of the parasite hitting stage 5 of its growth.
|
||||
*
|
||||
* The proc also drops the limb if it's on a human, or gibs it if it's on the floor. For
|
||||
* maximum drama, of course!
|
||||
*/
|
||||
/obj/item/organ/internal/parasite/greimorian_eggcluster/proc/rupture()
|
||||
var/obj/item/organ/external/victim_external_organ = owner.organs_by_name[parent_organ]
|
||||
if(src.owner)
|
||||
src.owner.visible_message(
|
||||
SPAN_DANGER("A group of [src] burst out of [owner]'s [victim_external_organ.name]!"),
|
||||
SPAN_DANGER("A group of [src] burst out of your [victim_external_organ.name]!"))
|
||||
src.owner.emote("scream")
|
||||
|
||||
var/target_loc = src.owner ? src.owner.loc : src.loc
|
||||
for(var/i = 0 to gestating_spiderlings)
|
||||
// For details on the spiderlings, check out 'code\game\objects\effects\spiders.dm'
|
||||
new /obj/effect/spider/spiderling(target_loc, src, 3)
|
||||
|
||||
if(victim_external_organ.owner)
|
||||
victim_external_organ.droplimb(0, DROPLIMB_BLUNT)
|
||||
|
||||
remove_parasite()
|
||||
@@ -2015,13 +2015,12 @@
|
||||
M.add_chemical_effect(CE_EMETIC, M.chem_doses[type]/2)
|
||||
|
||||
/singleton/reagent/antiparasitic/overdose(mob/living/carbon/M, alien, removed, scale, datum/reagents/holder)
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
for(var/obj/item/organ/internal/parasite/P in H.internal_organs)
|
||||
if(P)
|
||||
if(P.drug_resistance == 0)
|
||||
P.drug_resistance = 1
|
||||
M.dizziness = max(50, M.dizziness)
|
||||
M.make_dizzy(5)
|
||||
M.adjustHydrationLoss(2*removed)
|
||||
M.adjustNutritionLoss(8*removed)
|
||||
M.adjustHalLoss(5)
|
||||
to_chat(M, SPAN_WARNING(pick("You feel flushed and woozy.", "Your guts feel like they're crawling.")))
|
||||
|
||||
/singleton/reagent/antibodies
|
||||
name = "Hylemnomil-Zeta Antibodies"
|
||||
|
||||
@@ -1029,6 +1029,44 @@
|
||||
var/obj/item/organ/internal/parasite/heartworm/infest = new()
|
||||
infest.replaced(H, affected)
|
||||
|
||||
/// Functions as a weaker version of soporific and also infests the victim with eggs.
|
||||
/singleton/reagent/toxin/greimorian_eggs
|
||||
name = "Greimorian Eggs"
|
||||
description = "The eggs of a greimorian clade. They are highly opportunistic, capable of infesting almost any organism, and are feared for the relatively swift speed with which they gestate. Immediate surgical removal or pharmaceutical intervention is a vital necessity."
|
||||
reagent_state = SOLID
|
||||
color = "#5f683f"
|
||||
metabolism = REM*2
|
||||
ingest_met = REM*2
|
||||
touch_met = REM*5
|
||||
taste_description = "something noxious"
|
||||
taste_mult = 0.25
|
||||
strength = 0
|
||||
|
||||
/singleton/reagent/toxin/greimorian_eggs/affect_blood(mob/living/carbon/mob, alien, removed, datum/reagents/holder)
|
||||
..()
|
||||
if(istype(mob,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/victim = mob
|
||||
|
||||
victim.add_chemical_effect(CE_PULSE, -2)
|
||||
var/dose = victim.chem_doses[type]
|
||||
if(dose > 2)
|
||||
if(ishuman(victim) && (dose == metabolism * 2 || prob(3)))
|
||||
victim.emote("yawn")
|
||||
if(dose > 20)
|
||||
victim.eye_blurry = max(victim.eye_blurry, 10)
|
||||
if(dose > 40)
|
||||
victim.Weaken(1)
|
||||
victim.drowsiness = max(victim.drowsiness, 20)
|
||||
|
||||
if(victim.chem_effects[CE_ANTIPARASITE])
|
||||
return
|
||||
|
||||
if(!victim.internal_organs_by_name[BP_GREIMORIAN_EGGCLUSTER])
|
||||
var/obj/item/organ/external/affected = pick(victim.organs)
|
||||
var/obj/item/organ/internal/parasite/greimorian_eggcluster/infest = new()
|
||||
infest.parent_organ = affected.limb_name
|
||||
infest.replaced(victim, affected)
|
||||
|
||||
/singleton/reagent/toxin/malignant_tumour_cells
|
||||
name = "Malignant Tumour Cells"
|
||||
description = "Cells of a malignant tumour which have broken off and entered the circulatory and/or lymphatic system to spread to other regions of the body."
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Your name.
|
||||
author: Batrachophrenoboocosmomachia
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
|
||||
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- refactor: "Refactors the egg injection of Greimorian Workers to use parasite code; it can now be treated with anti-parasitic medicines in addition to amputation of the affected limb. Works on all playable species, and monkeys."
|
||||
- rscadd: "New reagent 'Greimorian Eggs' creates an egg cluster parasite in a random organ when metabolized in the bloodstream. It also has very mild soporific effects."
|
||||
- balance: "Greimorian Workers and playable Greimorian Servants/Queen now inject Greimorian Eggs instead of Soporific."
|
||||
- rscadd: "Greimorian Clade Kit now available in Uplink under Bioweapons section (Greimorians now able to be introduced to ship by egg cluster or injectable reagent)."
|
||||
- balance: "All parasite kit bioweapons have had their vial reagent count increased from 2 -> 5."
|
||||
- balance: "Helmizole no longer treats K'ois Mycosis, Black K'ois Mycosis, Zombification, or Tumors (Benign or Malignant)."
|
||||
- code_imp: "Updates a lot of code documentation to dmdocs."
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user