mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2025-12-25 01:22:24 +00:00
Adds Alien Reality pods, aka AR pods, for use in events or PoIs. (#5798)
* Fix some VR issues, add new VR issues I don't forsee. * Tweak re: Github Comments * Why * Mechoid stop being a me. * Add VR_LINK to all organs list.
This commit is contained in:
@@ -209,7 +209,10 @@
|
||||
#define O_ACID "acid gland"
|
||||
#define O_EGG "egg sac"
|
||||
#define O_RESIN "resin spinner"
|
||||
#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_ACID, O_EGG, O_RESIN)
|
||||
#define O_AREJECT "immune hub"
|
||||
#define O_VENTC "morphoplastic node"
|
||||
#define O_VRLINK "virtual node"
|
||||
#define O_ALL list(O_STANDARD, O_MOUTH, O_CELL, O_PLASMA, O_HIVE, O_NUTRIENT, O_STRATA, O_RESPONSE, O_GBLADDER, O_POLYP, O_ANCHOR, O_ACID, O_EGG, O_RESIN, O_AREJECT, O_VENTC, O_VRLINK)
|
||||
|
||||
// External organs, aka limbs
|
||||
#define BP_L_FOOT "l_foot"
|
||||
@@ -276,6 +279,9 @@
|
||||
#define SPECIES_VR_SKRELL "Virtual Reality Skrell"
|
||||
#define SPECIES_VR_TESHARI "Virtual Reality Teshari"
|
||||
#define SPECIES_VR_DIONA "Virtual Reality Diona"
|
||||
#define SPECIES_VR_MONKEY "Virtual Reality Monkey"
|
||||
#define SPECIES_VR_SKELETON "Virtual Reality Skeleton"
|
||||
#define SPECIES_VR_VOX "Virtual Reality Vox"
|
||||
|
||||
// Ayyy IDs.
|
||||
#define SPECIES_XENO "Xenomorph"
|
||||
@@ -290,6 +296,11 @@
|
||||
#define SPECIES_GOLEM "Golem"
|
||||
#define SPECIES_EVENT1 "X Occursus"
|
||||
|
||||
// Replicant types. Currently only used for alien pods and events.
|
||||
#define SPECIES_REPLICANT "Replicant"
|
||||
#define SPECIES_REPLICANT_ALPHA "Alpha Replicant"
|
||||
#define SPECIES_REPLICANT_BETA "Beta Replicant"
|
||||
|
||||
// Used to seperate simple animals by ""intelligence"".
|
||||
#define SA_PLANT 1
|
||||
#define SA_ANIMAL 2
|
||||
|
||||
134
code/game/machinery/virtual_reality/ar_console.dm
Normal file
134
code/game/machinery/virtual_reality/ar_console.dm
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This file contains the alien mind-transfer pod, or 'Alien Reality' pod.
|
||||
*/
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/alien
|
||||
name = "strange pod"
|
||||
desc = "A strange machine with what appears to be a comfortable, if quite vertical, bed. Numerous mechanical cylinders dot the ceiling, their purpose uncertain."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "alienpod_0"
|
||||
base_state = "alienpod_"
|
||||
|
||||
eject_dead = FALSE
|
||||
|
||||
var/produce_species = SPECIES_REPLICANT // The default species produced. Will be overridden if randomize_species is true.
|
||||
var/randomize_species = FALSE
|
||||
var/list/possible_species // Do we make the newly produced body a random species?
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/Initialize()
|
||||
. = ..()
|
||||
if(possible_species && possible_species.len)
|
||||
produce_species = pick(possible_species)
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/process()
|
||||
if(stat & (BROKEN))
|
||||
if(occupant)
|
||||
go_out()
|
||||
visible_message("<span class='notice'>\The [src] emits a low droning sound, before the pod door clicks open.</span>")
|
||||
return
|
||||
else if(eject_dead && occupant && occupant.stat == DEAD)
|
||||
visible_message("<span class='warning'>\The [src] sounds an alarm, swinging its hatch open.</span>")
|
||||
go_out()
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/attackby(var/obj/item/I, var/mob/user)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(occupant && (istype(I, /obj/item/device/healthanalyzer) || istype(I, /obj/item/device/robotanalyzer)))
|
||||
I.attack(occupant, user)
|
||||
return
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/eject()
|
||||
set src in view(1)
|
||||
set category = "Object"
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
var/forced = FALSE
|
||||
|
||||
if(stat & (BROKEN) || (eject_dead && occupant && occupant.stat == DEAD))
|
||||
forced = TRUE
|
||||
|
||||
go_out(forced)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/go_out(var/forced = TRUE)
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
if(!forced && avatar && avatar.stat != DEAD && alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", "Yes", "No") == "No")
|
||||
return
|
||||
|
||||
avatar.exit_vr()
|
||||
|
||||
if(occupant && occupant.client)
|
||||
occupant.client.eye = occupant.client.mob
|
||||
occupant.client.perspective = MOB_PERSPECTIVE
|
||||
occupant.loc = src.loc
|
||||
occupant = null
|
||||
for(var/atom/movable/A in src) // In case an object was dropped inside or something
|
||||
if(A == circuit)
|
||||
continue
|
||||
if(A in component_parts)
|
||||
continue
|
||||
A.loc = src.loc
|
||||
update_use_power(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/enter_vr()
|
||||
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
if(!occupant.mind)
|
||||
return
|
||||
|
||||
if(occupant.stat == DEAD && !occupant.client)
|
||||
return
|
||||
|
||||
if(avatar && !occupant.stat)
|
||||
to_chat(occupant,"<span class='alien'>\The [src] begins to [pick("whir","hum","pulse")] as a screen appears in front of you.</span>")
|
||||
if(alert(occupant, "This pod is already linked. Are you certain you wish to engage?", "Commmit?", "Yes", "No") == "No")
|
||||
visible_message("<span class='alien'>\The [src] pulses!</span>")
|
||||
|
||||
to_chat(occupant,"<span class='alien'>Your mind blurs as information bombards you.</span>")
|
||||
|
||||
if(!avatar)
|
||||
var/turf/T = get_turf(src)
|
||||
avatar = new(src, produce_species)
|
||||
if(occupant.species.name != "Promethean" && occupant.species.name != "Human" && mirror_first_occupant)
|
||||
avatar.shapeshifter_change_shape(occupant.species.name)
|
||||
avatar.Sleeping(6)
|
||||
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
var/newname = sanitize(input(avatar, "Your mind feels foggy. You're certain your name is [occupant.real_name], but it could also be [avatar.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
avatar.real_name = newname
|
||||
|
||||
avatar.forceMove(T)
|
||||
visible_message("<span class='alium'>\The [src] [pick("gurgles", "churns", "sloshes")] before spitting out \the [avatar]!</span>")
|
||||
|
||||
else
|
||||
|
||||
// There's only one body per one of these pods, so let's be kind.
|
||||
var/newname = sanitize(input(avatar, "Your mind feels foggy. You're certain your name is [occupant.real_name], but it feels like it is [avatar.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if(newname)
|
||||
avatar.real_name = newname
|
||||
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
|
||||
/*
|
||||
* Subtypes
|
||||
*/
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/random_replicant
|
||||
possible_species = list(SPECIES_REPLICANT, SPECIES_REPLICANT_ALPHA, SPECIES_REPLICANT_BETA)
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/alpha_replicant
|
||||
produce_species = SPECIES_REPLICANT_ALPHA
|
||||
|
||||
/obj/machinery/vr_sleeper/alien/beta_replicant
|
||||
produce_species = SPECIES_REPLICANT_BETA
|
||||
@@ -1,227 +1,262 @@
|
||||
/obj/machinery/vr_sleeper
|
||||
name = "virtual reality sleeper"
|
||||
desc = "A fancy bed with built-in sensory I/O ports and connectors to interface users' minds with their bodies in virtual reality."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "syndipod_0"
|
||||
density = 1
|
||||
anchored = 1
|
||||
circuit = /obj/item/weapon/circuitboard/vr_sleeper
|
||||
var/mob/living/carbon/human/occupant = null
|
||||
var/mob/living/carbon/human/avatar = null
|
||||
var/datum/mind/vr_mind = null
|
||||
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 200
|
||||
light_color = "#FF0000"
|
||||
|
||||
/obj/machinery/vr_sleeper/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/stack/material/glass/reinforced(src, 2)
|
||||
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/vr_sleeper/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/vr_sleeper/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
/obj/machinery/vr_sleeper/update_icon()
|
||||
icon_state = "syndipod_[occupant ? "1" : "0"]"
|
||||
|
||||
/obj/machinery/vr_sleeper/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(usr == occupant)
|
||||
to_chat(usr, "<span class='warning'>You can't reach the controls from the inside.</span>")
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["eject"])
|
||||
go_out()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/vr_sleeper/attackby(var/obj/item/I, var/mob/user)
|
||||
add_fingerprint(user)
|
||||
if(default_deconstruction_screwdriver(user, I))
|
||||
return
|
||||
else if(default_deconstruction_crowbar(user, I))
|
||||
if(occupant && avatar)
|
||||
avatar.exit_vr()
|
||||
avatar = null
|
||||
go_out()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/MouseDrop_T(var/mob/target, var/mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !isliving(target))
|
||||
return
|
||||
go_in(target, user)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/sleeper/relaymove(var/mob/user)
|
||||
..()
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
go_out()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/emp_act(var/severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
|
||||
if(occupant)
|
||||
// This will eject the user from VR
|
||||
// ### Fry the brain?
|
||||
go_out()
|
||||
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/vr_sleeper/verb/eject()
|
||||
set src in oview(1)
|
||||
set category = "Object"
|
||||
set name = "Eject VR Capsule"
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
if(usr != occupant && avatar && alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", "Yes", "No") == "No")
|
||||
return
|
||||
|
||||
// The player in VR is fine with leaving, kick them out and reset avatar
|
||||
avatar.exit_vr()
|
||||
avatar = null
|
||||
go_out()
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/vr_sleeper/verb/climb_in()
|
||||
set src in oview(1)
|
||||
set category = "Object"
|
||||
set name = "Enter VR Capsule"
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
go_in(usr, usr)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/vr_sleeper/relaymove(mob/user as mob)
|
||||
if(user.incapacitated())
|
||||
return 0 //maybe they should be able to get out with cuffs, but whatever
|
||||
go_out()
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/go_in(var/mob/M, var/mob/user)
|
||||
if(!M)
|
||||
return
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(!ishuman(M))
|
||||
user << "<span class='warning'>\The [src] rejects [M] with a sharp beep.</span>"
|
||||
if(occupant)
|
||||
user << "<span class='warning'>\The [src] is already occupied.</span>"
|
||||
return
|
||||
|
||||
if(M == user)
|
||||
visible_message("\The [user] starts climbing into \the [src].")
|
||||
else
|
||||
visible_message("\The [user] starts putting [M] into \the [src].")
|
||||
|
||||
if(do_after(user, 20))
|
||||
if(occupant)
|
||||
to_chat(user, "<span class='warning'>\The [src] is already occupied.</span>")
|
||||
return
|
||||
M.stop_pulling()
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
M.loc = src
|
||||
update_use_power(2)
|
||||
occupant = M
|
||||
|
||||
update_icon()
|
||||
|
||||
enter_vr()
|
||||
return
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/go_out()
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
if(occupant.client)
|
||||
occupant.client.eye = occupant.client.mob
|
||||
occupant.client.perspective = MOB_PERSPECTIVE
|
||||
occupant.loc = src.loc
|
||||
occupant = null
|
||||
for(var/atom/movable/A in src) // In case an object was dropped inside or something
|
||||
if(A == circuit)
|
||||
continue
|
||||
if(A in component_parts)
|
||||
continue
|
||||
A.loc = src.loc
|
||||
update_use_power(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/enter_vr()
|
||||
|
||||
// No mob to transfer a mind from
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
// No mind to transfer
|
||||
if(!occupant.mind)
|
||||
return
|
||||
|
||||
// Mob doesn't have an active consciousness to send/receive from
|
||||
if(occupant.stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
avatar = occupant.vr_link
|
||||
// If they've already enterred VR, and are reconnecting, prompt if they want a new body
|
||||
if(avatar && alert(occupant, "You already have a Virtual Reality avatar. Would you like to use it?", "New avatar", "Yes", "No") == "No")
|
||||
// Delink the mob
|
||||
occupant.vr_link = null
|
||||
avatar = null
|
||||
|
||||
if(!avatar)
|
||||
// Get the desired spawn location to put the body
|
||||
var/S = null
|
||||
var/list/vr_landmarks = list()
|
||||
for(var/obj/effect/landmark/virtual_reality/sloc in landmarks_list)
|
||||
vr_landmarks += sloc.name
|
||||
|
||||
S = input(occupant, "Please select a location to spawn your avatar at:", "Spawn location") as null|anything in vr_landmarks
|
||||
if(!S)
|
||||
return 0
|
||||
|
||||
for(var/obj/effect/landmark/virtual_reality/i in landmarks_list)
|
||||
if(i.name == S)
|
||||
S = i
|
||||
break
|
||||
|
||||
avatar = new(S, "Virtual Reality Avatar")
|
||||
// If the user has a non-default (Human) bodyshape, make it match theirs.
|
||||
if(occupant.species.name != "Promethean" && occupant.species.name != "Human")
|
||||
avatar.shapeshifter_change_shape(occupant.species.name)
|
||||
avatar.forceMove(get_turf(S)) // Put the mob on the landmark, instead of inside it
|
||||
avatar.Sleeping(1)
|
||||
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
// Prompt for username after they've enterred the body.
|
||||
var/newname = sanitize(input(avatar, "You are entering virtual reality. Your username is currently [src.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
avatar.real_name = newname
|
||||
|
||||
else
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
/obj/machinery/vr_sleeper
|
||||
name = "virtual reality sleeper"
|
||||
desc = "A fancy bed with built-in sensory I/O ports and connectors to interface users' minds with their bodies in virtual reality."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "syndipod_0"
|
||||
|
||||
var/base_state = "syndipod_"
|
||||
|
||||
density = 1
|
||||
anchored = 1
|
||||
circuit = /obj/item/weapon/circuitboard/vr_sleeper
|
||||
var/mob/living/carbon/human/occupant = null
|
||||
var/mob/living/carbon/human/avatar = null
|
||||
var/datum/mind/vr_mind = null
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke
|
||||
|
||||
var/eject_dead = TRUE
|
||||
|
||||
var/mirror_first_occupant = TRUE // Do we force the newly produced body to look like the occupant?
|
||||
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 200
|
||||
light_color = "#FF0000"
|
||||
|
||||
/obj/machinery/vr_sleeper/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/stack/material/glass/reinforced(src, 2)
|
||||
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/vr_sleeper/Initialize()
|
||||
. = ..()
|
||||
smoke = new
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/vr_sleeper/Destroy()
|
||||
. = ..()
|
||||
go_out()
|
||||
|
||||
/obj/machinery/vr_sleeper/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
if(occupant)
|
||||
go_out()
|
||||
visible_message("<span class='notice'>\The [src] emits a low droning sound, before the pod door clicks open.</span>")
|
||||
return
|
||||
else if(eject_dead && occupant && occupant.stat == DEAD) // If someone dies somehow while inside, spit them out.
|
||||
visible_message("<span class='warning'>\The [src] sounds an alarm, swinging its hatch open.</span>")
|
||||
go_out()
|
||||
|
||||
/obj/machinery/vr_sleeper/update_icon()
|
||||
icon_state = "[base_state][occupant ? "1" : "0"]"
|
||||
|
||||
/obj/machinery/vr_sleeper/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(usr == occupant)
|
||||
to_chat(usr, "<span class='warning'>You can't reach the controls from the inside.</span>")
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["eject"])
|
||||
go_out()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/vr_sleeper/attackby(var/obj/item/I, var/mob/user)
|
||||
add_fingerprint(user)
|
||||
|
||||
if(occupant && (istype(I, /obj/item/device/healthanalyzer) || istype(I, /obj/item/device/robotanalyzer)))
|
||||
I.attack(occupant, user)
|
||||
return
|
||||
|
||||
if(default_deconstruction_screwdriver(user, I))
|
||||
return
|
||||
else if(default_deconstruction_crowbar(user, I))
|
||||
if(occupant && avatar)
|
||||
avatar.exit_vr()
|
||||
avatar = null
|
||||
go_out()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/MouseDrop_T(var/mob/target, var/mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !isliving(target))
|
||||
return
|
||||
go_in(target, user)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/sleeper/relaymove(var/mob/user)
|
||||
..()
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
go_out()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/emp_act(var/severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
|
||||
if(occupant)
|
||||
// This will eject the user from VR
|
||||
// ### Fry the brain? Yes. Maybe.
|
||||
if(prob(15 / ( severity / 4 )) && occupant.species.has_organ[O_BRAIN] && occupant.internal_organs_by_name[O_BRAIN])
|
||||
var/obj/item/organ/O = occupant.internal_organs_by_name[O_BRAIN]
|
||||
O.take_damage(severity * 2)
|
||||
visible_message("<span class='danger'>\The [src]'s internal lighting flashes rapidly, before the hatch swings open with a cloud of smoke.</span>")
|
||||
smoke.set_up(n = severity, 0, src)
|
||||
smoke.start("#202020")
|
||||
go_out()
|
||||
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/vr_sleeper/verb/eject()
|
||||
set src in view(1)
|
||||
set category = "Object"
|
||||
set name = "Eject VR Capsule"
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
var/forced = FALSE
|
||||
|
||||
if(stat & (BROKEN|NOPOWER) || occupant && occupant.stat == DEAD)
|
||||
forced = TRUE
|
||||
|
||||
go_out(forced)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/vr_sleeper/verb/climb_in()
|
||||
set src in oview(1)
|
||||
set category = "Object"
|
||||
set name = "Enter VR Capsule"
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
go_in(usr, usr)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/vr_sleeper/relaymove(mob/user as mob)
|
||||
if(user.incapacitated())
|
||||
return 0 //maybe they should be able to get out with cuffs, but whatever
|
||||
go_out()
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/go_in(var/mob/M, var/mob/user)
|
||||
if(!M)
|
||||
return
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(!ishuman(M))
|
||||
to_chat(user, "<span class='warning'>\The [src] rejects [M] with a sharp beep.</span>")
|
||||
if(occupant)
|
||||
to_chat(user, "<span class='warning'>\The [src] is already occupied.</span>")
|
||||
return
|
||||
|
||||
if(M == user)
|
||||
visible_message("\The [user] starts climbing into \the [src].")
|
||||
else
|
||||
visible_message("\The [user] starts putting [M] into \the [src].")
|
||||
|
||||
if(do_after(user, 20))
|
||||
if(occupant)
|
||||
to_chat(user, "<span class='warning'>\The [src] is already occupied.</span>")
|
||||
return
|
||||
M.stop_pulling()
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
M.loc = src
|
||||
update_use_power(2)
|
||||
occupant = M
|
||||
|
||||
update_icon()
|
||||
|
||||
enter_vr()
|
||||
return
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/go_out(var/forced = TRUE)
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
if(!forced && avatar && alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", "Yes", "No") == "No")
|
||||
return
|
||||
|
||||
avatar.exit_vr()
|
||||
avatar = null
|
||||
|
||||
if(occupant.client)
|
||||
occupant.client.eye = occupant.client.mob
|
||||
occupant.client.perspective = MOB_PERSPECTIVE
|
||||
occupant.loc = src.loc
|
||||
occupant = null
|
||||
for(var/atom/movable/A in src) // In case an object was dropped inside or something
|
||||
if(A == circuit)
|
||||
continue
|
||||
if(A in component_parts)
|
||||
continue
|
||||
A.loc = src.loc
|
||||
update_use_power(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/enter_vr()
|
||||
|
||||
// No mob to transfer a mind from
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
// No mind to transfer
|
||||
if(!occupant.mind)
|
||||
return
|
||||
|
||||
// Mob doesn't have an active consciousness to send/receive from
|
||||
if(occupant.stat == DEAD)
|
||||
return
|
||||
|
||||
avatar = occupant.vr_link
|
||||
// If they've already enterred VR, and are reconnecting, prompt if they want a new body
|
||||
if(avatar && alert(occupant, "You already have a [avatar.stat == DEAD ? "" : "deceased "]Virtual Reality avatar. Would you like to use it?", "New avatar", "Yes", "No") == "No")
|
||||
// Delink the mob
|
||||
occupant.vr_link = null
|
||||
avatar = null
|
||||
|
||||
if(!avatar)
|
||||
// Get the desired spawn location to put the body
|
||||
var/S = null
|
||||
var/list/vr_landmarks = list()
|
||||
for(var/obj/effect/landmark/virtual_reality/sloc in landmarks_list)
|
||||
vr_landmarks += sloc.name
|
||||
|
||||
S = input(occupant, "Please select a location to spawn your avatar at:", "Spawn location") as null|anything in vr_landmarks
|
||||
if(!S)
|
||||
return 0
|
||||
|
||||
for(var/obj/effect/landmark/virtual_reality/i in landmarks_list)
|
||||
if(i.name == S)
|
||||
S = i
|
||||
break
|
||||
|
||||
avatar = new(S, "Virtual Reality Avatar")
|
||||
// If the user has a non-default (Human) bodyshape, make it match theirs.
|
||||
if(occupant.species.name != "Promethean" && occupant.species.name != "Human" && mirror_first_occupant)
|
||||
avatar.shapeshifter_change_shape(occupant.species.name)
|
||||
avatar.forceMove(get_turf(S)) // Put the mob on the landmark, instead of inside it
|
||||
avatar.Sleeping(1)
|
||||
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
// Prompt for username after they've enterred the body.
|
||||
var/newname = sanitize(input(avatar, "You are entering virtual reality. Your username is currently [src.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
avatar.real_name = newname
|
||||
|
||||
else
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* This species exists for the use of the Alien Reality pod, though can be used for events or other things.
|
||||
*/
|
||||
|
||||
/datum/species/shapeshifter/replicant
|
||||
name = SPECIES_REPLICANT
|
||||
name_plural = "Replicants"
|
||||
primitive_form = SPECIES_MONKEY
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
|
||||
blurb = "The remnants of some lost or dead race's research. These seem relatively normal."
|
||||
num_alternate_languages = 3
|
||||
species_language = LANGUAGE_GALCOM
|
||||
secondary_langs = list(LANGUAGE_TERMINUS)
|
||||
assisted_langs = list(LANGUAGE_ROOTGLOBAL)
|
||||
name_language = LANGUAGE_TERMINUS
|
||||
|
||||
blood_color = "#aaaadd"
|
||||
|
||||
show_ssd = "eerily still."
|
||||
|
||||
min_age = 0
|
||||
max_age = 999
|
||||
|
||||
health_hud_intensity = 1.5
|
||||
|
||||
flags = NO_MINOR_CUT | NO_HALLUCINATION | NO_INFECT
|
||||
|
||||
vision_flags = SEE_SELF
|
||||
darksight = 5
|
||||
|
||||
brute_mod = 0.9
|
||||
burn_mod = 0.9
|
||||
oxy_mod = 0.7
|
||||
toxins_mod = 0.85
|
||||
radiation_mod = 0.9
|
||||
flash_mod = 0.9
|
||||
sound_mod = 0.9
|
||||
siemens_coefficient = 0.9
|
||||
|
||||
spawn_flags = SPECIES_IS_RESTRICTED
|
||||
appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | HAS_UNDERWEAR
|
||||
|
||||
valid_transform_species = list(SPECIES_HUMAN, SPECIES_HUMAN_VATBORN, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_SKRELL, SPECIES_DIONA, SPECIES_TESHARI, SPECIES_MONKEY, SPECIES_VOX)
|
||||
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_shape,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_hair,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_gender,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_colour,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_hair_colors,
|
||||
/mob/living/carbon/human/proc/exit_vr
|
||||
)
|
||||
|
||||
has_organ = list(
|
||||
O_HEART = /obj/item/organ/internal/heart/replicant/rage,
|
||||
O_LUNGS = /obj/item/organ/internal/lungs/replicant/mending,
|
||||
O_VOICE = /obj/item/organ/internal/voicebox/replicant,
|
||||
O_LIVER = /obj/item/organ/internal/liver/replicant,
|
||||
O_KIDNEYS = /obj/item/organ/internal/kidneys/replicant,
|
||||
O_BRAIN = /obj/item/organ/internal/brain/replicant,
|
||||
O_EYES = /obj/item/organ/internal/eyes/replicant,
|
||||
O_AREJECT = /obj/item/organ/internal/immunehub/replicant,
|
||||
O_VRLINK = /obj/item/organ/internal/brainmirror
|
||||
)
|
||||
|
||||
/datum/species/shapeshifter/replicant/alpha
|
||||
name = SPECIES_REPLICANT_ALPHA
|
||||
blurb = "The remnants of some lost or dead race's research. These seem caustic."
|
||||
|
||||
blood_color = "#55ff55"
|
||||
|
||||
species_language = LANGUAGE_SIGN
|
||||
assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_SOL_COMMON, LANGUAGE_SKRELLIANFAR)
|
||||
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_shape,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_hair,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_gender,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_colour,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_hair_colors,
|
||||
/mob/living/carbon/human/proc/exit_vr,
|
||||
/mob/living/carbon/human/proc/corrosive_acid,
|
||||
/mob/living/carbon/human/proc/neurotoxin,
|
||||
/mob/living/carbon/human/proc/acidspit
|
||||
)
|
||||
|
||||
has_organ = list(
|
||||
O_HEART = /obj/item/organ/internal/heart/replicant,
|
||||
O_LUNGS = /obj/item/organ/internal/lungs/replicant,
|
||||
O_VOICE = /obj/item/organ/internal/voicebox/replicant,
|
||||
O_LIVER = /obj/item/organ/internal/liver/replicant,
|
||||
O_KIDNEYS = /obj/item/organ/internal/kidneys/replicant,
|
||||
O_BRAIN = /obj/item/organ/internal/brain/replicant,
|
||||
O_EYES = /obj/item/organ/internal/eyes/replicant,
|
||||
O_AREJECT = /obj/item/organ/internal/immunehub/replicant,
|
||||
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/replicant,
|
||||
O_ACID = /obj/item/organ/internal/xenos/acidgland/replicant,
|
||||
O_VRLINK = /obj/item/organ/internal/brainmirror
|
||||
)
|
||||
|
||||
/datum/species/shapeshifter/replicant/beta
|
||||
name = SPECIES_REPLICANT_BETA
|
||||
blurb = "The remnants of some lost or dead race's research. These seem elastic."
|
||||
|
||||
blood_color = "#C0C0C0"
|
||||
|
||||
species_language = LANGUAGE_SIGN
|
||||
secondary_langs = list(LANGUAGE_TERMINUS, LANGUAGE_ROOTGLOBAL) // Radio-waves.
|
||||
|
||||
has_organ = list(
|
||||
O_HEART = /obj/item/organ/internal/heart/replicant/rage,
|
||||
O_LUNGS = /obj/item/organ/internal/lungs/replicant/mending,
|
||||
O_VOICE = /obj/item/organ/internal/voicebox/replicant,
|
||||
O_LIVER = /obj/item/organ/internal/liver/replicant,
|
||||
O_KIDNEYS = /obj/item/organ/internal/kidneys/replicant,
|
||||
O_BRAIN = /obj/item/organ/internal/brain/replicant/torso,
|
||||
O_EYES = /obj/item/organ/internal/eyes/replicant,
|
||||
O_AREJECT = /obj/item/organ/internal/immunehub/replicant,
|
||||
O_VENTC = /obj/item/organ/internal/metamorphgland/replicant,
|
||||
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/replicant,
|
||||
O_RESIN = /obj/item/organ/internal/xenos/resinspinner/replicant,
|
||||
O_VRLINK = /obj/item/organ/internal/brainmirror
|
||||
)
|
||||
@@ -23,6 +23,8 @@
|
||||
male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg'
|
||||
female_sneeze_sound = 'sound/effects/mob_effects/f_sneeze.ogg'
|
||||
|
||||
valid_transform_species = list(SPECIES_HUMAN, SPECIES_HUMAN_VATBORN, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_SKRELL, SPECIES_DIONA, SPECIES_TESHARI, SPECIES_VOX, SPECIES_MONKEY, SPECIES_SKELETON)
|
||||
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
|
||||
has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime, O_EYES = /obj/item/organ/internal/eyes) // Slime core.
|
||||
heal_rate = 0 // Avatars don't naturally heal like prometheans, at least not for now
|
||||
|
||||
@@ -119,3 +119,63 @@
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/diona/foot/right)
|
||||
)
|
||||
|
||||
/datum/species/shapeshifter/promethean/avatar/monkey
|
||||
name = "Virtual Reality Monkey"
|
||||
icobase = 'icons/mob/human_races/monkeys/r_monkey.dmi'
|
||||
deform = 'icons/mob/human_races/monkeys/r_monkey.dmi'
|
||||
damage_overlays = 'icons/mob/human_races/masks/dam_monkey.dmi'
|
||||
damage_mask = 'icons/mob/human_races/masks/dam_mask_monkey.dmi'
|
||||
blood_mask = 'icons/mob/human_races/masks/blood_monkey.dmi'
|
||||
fire_icon_state = "monkey"
|
||||
appearance_flags = 0
|
||||
has_limbs = list(
|
||||
BP_TORSO = list("path" = /obj/item/organ/external/chest),
|
||||
BP_GROIN = list("path" = /obj/item/organ/external/groin),
|
||||
BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes),
|
||||
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
|
||||
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
|
||||
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
|
||||
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
|
||||
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
|
||||
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
|
||||
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
|
||||
)
|
||||
|
||||
/datum/species/shapeshifter/promethean/avatar/vox
|
||||
name = "Virtual Reality Vox"
|
||||
icobase = 'icons/mob/human_races/r_vox.dmi'
|
||||
deform = 'icons/mob/human_races/r_def_vox.dmi'
|
||||
appearance_flags = HAS_EYE_COLOR | HAS_HAIR_COLOR
|
||||
has_limbs = list(
|
||||
BP_TORSO = list("path" = /obj/item/organ/external/chest),
|
||||
BP_GROIN = list("path" = /obj/item/organ/external/groin),
|
||||
BP_HEAD = list("path" = /obj/item/organ/external/head/vox),
|
||||
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
|
||||
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
|
||||
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
|
||||
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
|
||||
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
|
||||
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
|
||||
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
|
||||
)
|
||||
|
||||
/datum/species/shapeshifter/promethean/avatar/skeleton
|
||||
name = "Virtual Reality Skeleton"
|
||||
icobase = 'icons/mob/human_races/r_skeleton.dmi'
|
||||
deform = 'icons/mob/human_races/r_skeleton.dmi'
|
||||
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
|
||||
has_limbs = list(
|
||||
BP_TORSO = list("path" = /obj/item/organ/external/chest),
|
||||
BP_GROIN = list("path" = /obj/item/organ/external/groin),
|
||||
BP_HEAD = list("path" = /obj/item/organ/external/head),
|
||||
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
|
||||
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
|
||||
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
|
||||
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
|
||||
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
|
||||
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
|
||||
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
|
||||
)
|
||||
|
||||
@@ -35,8 +35,11 @@ var/list/organ_cache = list()
|
||||
var/list/will_assist_languages = list()
|
||||
var/list/datum/language/assists_languages = list()
|
||||
|
||||
var/list/organ_verbs // Verbs added by the organ when present in the body.
|
||||
|
||||
/obj/item/organ/Destroy()
|
||||
|
||||
handle_organ_mod_special(TRUE)
|
||||
if(owner) owner = null
|
||||
if(transplant_data) transplant_data.Cut()
|
||||
if(autopsy_data) autopsy_data.Cut()
|
||||
@@ -80,6 +83,8 @@ var/list/organ_cache = list()
|
||||
else
|
||||
species = all_species["Human"]
|
||||
|
||||
handle_organ_mod_special()
|
||||
|
||||
/obj/item/organ/proc/set_dna(var/datum/dna/new_dna)
|
||||
if(new_dna)
|
||||
dna = new_dna.Clone()
|
||||
@@ -92,6 +97,7 @@ var/list/organ_cache = list()
|
||||
status |= ORGAN_DEAD
|
||||
damage = max_damage
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
handle_organ_mod_special(TRUE)
|
||||
if(owner && vital)
|
||||
owner.death()
|
||||
owner.can_defib = 0
|
||||
@@ -117,6 +123,8 @@ var/list/organ_cache = list()
|
||||
if(damage >= max_damage)
|
||||
die()
|
||||
|
||||
handle_organ_proc_special()
|
||||
|
||||
//Process infections
|
||||
if(robotic >= ORGAN_ROBOT || (owner && owner.species && (owner.species.flags & IS_PLANT || (owner.species.flags & NO_INFECT))))
|
||||
germ_level = 0
|
||||
@@ -221,6 +229,8 @@ var/list/organ_cache = list()
|
||||
damage = 0
|
||||
status = 0
|
||||
germ_level = 0
|
||||
if(owner)
|
||||
handle_organ_mod_special()
|
||||
if(!ignore_prosthetic_prefs && owner && owner.client && owner.client.prefs && owner.client.prefs.real_name == owner.real_name)
|
||||
var/status = owner.client.prefs.organ_data[organ_tag]
|
||||
if(status == "assisted")
|
||||
@@ -336,8 +346,11 @@ var/list/organ_cache = list()
|
||||
owner.death()
|
||||
owner.can_defib = 0
|
||||
|
||||
handle_organ_mod_special(TRUE)
|
||||
|
||||
owner = null
|
||||
|
||||
|
||||
/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
|
||||
|
||||
if(!istype(target)) return
|
||||
@@ -360,6 +373,8 @@ var/list/organ_cache = list()
|
||||
affected.internal_organs |= src
|
||||
target.internal_organs_by_name[organ_tag] = src
|
||||
|
||||
handle_organ_mod_special()
|
||||
|
||||
/obj/item/organ/proc/bitten(mob/user)
|
||||
|
||||
if(robotic >= ORGAN_ROBOT)
|
||||
@@ -399,4 +414,32 @@ var/list/organ_cache = list()
|
||||
return 0
|
||||
if(robotic && robotic < ORGAN_LIFELIKE) //Super fancy humanlike robotics probably have sensors, or something?
|
||||
return 0
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/obj/item/organ/proc/handle_organ_mod_special(var/removed = FALSE) // Called when created, transplanted, and removed.
|
||||
if(!istype(owner))
|
||||
return
|
||||
|
||||
var/list/save_verbs = list()
|
||||
|
||||
if(removed && organ_verbs) // Do we share verbs with any other organs? Are they functioning?
|
||||
var/list/all_organs = list()
|
||||
all_organs |= owner.organs
|
||||
all_organs |= owner.internal_organs
|
||||
|
||||
for(var/obj/item/organ/O in all_organs)
|
||||
if(O.status & ORGAN_DEAD && O.organ_verbs)
|
||||
for(var/verb_type in O.organ_verbs)
|
||||
if(verb_type in organ_verbs)
|
||||
save_verbs |= verb_type
|
||||
|
||||
if(!removed && organ_verbs)
|
||||
for(var/verb_path in organ_verbs)
|
||||
owner.verbs |= verb_path
|
||||
else if(organ_verbs)
|
||||
for(var/verb_path in organ_verbs)
|
||||
owner.verbs -= verb_path
|
||||
return
|
||||
|
||||
/obj/item/organ/proc/handle_organ_proc_special() // Called when processed.
|
||||
return
|
||||
|
||||
171
code/modules/organs/subtypes/replicant.dm
Normal file
171
code/modules/organs/subtypes/replicant.dm
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This file contains 'synthetic' fleshy organs, intended to not reject.
|
||||
*/
|
||||
|
||||
/obj/item/organ/internal/eyes/replicant
|
||||
name = "replicant eyes"
|
||||
desc = "A pair of rubber balls used for receiving optical information."
|
||||
can_reject = FALSE
|
||||
icon_state = "eyes_grey"
|
||||
|
||||
/obj/item/organ/internal/brain/replicant
|
||||
name = "replicant brain"
|
||||
desc = "A juicy piece of.. rubber, found in someone's head?"
|
||||
can_reject = FALSE
|
||||
icon_state = "brain_grey"
|
||||
|
||||
/obj/item/organ/internal/brain/replicant/torso
|
||||
parent_organ = BP_TORSO
|
||||
|
||||
/obj/item/organ/internal/voicebox/replicant
|
||||
name = "replicant voicebox"
|
||||
desc = "A rubbery piece of meat used for vocalizations."
|
||||
can_reject = FALSE
|
||||
|
||||
/obj/item/organ/internal/heart/replicant
|
||||
name = "replicant heart"
|
||||
desc = "A mass of rubber and muscle used for pumping fluid."
|
||||
can_reject = FALSE
|
||||
icon_state = "heart_grey-on"
|
||||
dead_icon = "heart_grey-off"
|
||||
|
||||
/obj/item/organ/internal/lungs/replicant
|
||||
name = "replicant lungs"
|
||||
desc = "A pair of rubbery sacs used for respiration."
|
||||
can_reject = FALSE
|
||||
icon_state = "lungs_grey"
|
||||
|
||||
/obj/item/organ/internal/liver/replicant
|
||||
name = "replicant liver"
|
||||
desc = "A mass of rubber used for filtering and breaking down chemicals."
|
||||
can_reject = FALSE
|
||||
icon_state = "liver_grey"
|
||||
|
||||
/obj/item/organ/internal/kidneys/replicant
|
||||
name = "replicant kidneys"
|
||||
desc = "A pair of small sacs used for filtering chemicals."
|
||||
can_reject = FALSE
|
||||
icon_state = "kidneys_grey"
|
||||
|
||||
/obj/item/organ/internal/xenos/plasmavessel/replicant
|
||||
name = "replicant phorogenic sac"
|
||||
desc = "A bulbous rubbery mass that converts nutrients from the host into a biological compound eerily similar to phoron."
|
||||
can_reject = FALSE
|
||||
icon_state = "plasma_grey"
|
||||
|
||||
/obj/item/organ/internal/xenos/acidgland/replicant
|
||||
name = "replicant aerosol tubule"
|
||||
desc = "A long, rubbery tube that ends in a hard plastic-like bulb."
|
||||
can_reject = FALSE
|
||||
icon_state = "acidgland_grey"
|
||||
|
||||
/obj/item/organ/internal/xenos/resinspinner/replicant
|
||||
name = "replicant biomesh spinner"
|
||||
desc = "A rubbery mass with protrusions for molding organic material."
|
||||
can_reject = FALSE
|
||||
icon_state = "xenode_grey"
|
||||
|
||||
/*
|
||||
* These are unique organs to Replicants and other Ancient Aliens, though they can be used elsewhere. They follow the same rules.
|
||||
*/
|
||||
|
||||
/obj/item/organ/internal/immunehub
|
||||
name = "lymphomatic control web"
|
||||
desc = "A mesh of twitching strings."
|
||||
organ_tag = O_AREJECT
|
||||
parent_organ = BP_TORSO
|
||||
icon_state = "immunehub"
|
||||
|
||||
var/rejection_adjust = 10
|
||||
|
||||
/obj/item/organ/internal/immunehub/replicant
|
||||
name = "replicant assimilation web"
|
||||
desc = "A mesh of jiggling rubber strings that dig at nearby flesh."
|
||||
can_reject = FALSE
|
||||
|
||||
/obj/item/organ/internal/immunehub/handle_organ_proc_special()
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
var/list/all_organs = list()
|
||||
all_organs |= owner.internal_organs
|
||||
all_organs |= owner.organs
|
||||
|
||||
var/modifier = round(rejection_adjust * (1 - 0.5 * is_bruised()))
|
||||
|
||||
for(var/obj/item/organ/I in all_organs)
|
||||
I.rejecting = max(0, rejecting - modifier)
|
||||
|
||||
/obj/item/organ/internal/metamorphgland
|
||||
name = "morphoplastic node"
|
||||
desc = "A strange clump of meat that doesn't quite stay in place."
|
||||
organ_tag = O_VENTC
|
||||
parent_organ = BP_GROIN
|
||||
icon_state = "innards"
|
||||
organ_verbs = list(
|
||||
/mob/living/proc/ventcrawl
|
||||
)
|
||||
|
||||
/obj/item/organ/internal/metamorphgland/replicant
|
||||
name = "replicant malleoshift node"
|
||||
desc = "A strange clump of rubbery meat that likes to move around."
|
||||
can_reject = FALSE
|
||||
icon_state = "vox_lung"
|
||||
|
||||
/obj/item/organ/internal/brainmirror // The device that lets Replicants and other Alien Pod minds return willingly to the pods.
|
||||
name = "quantum cortical entangler"
|
||||
desc = "An ominous device."
|
||||
can_reject = FALSE
|
||||
organ_tag = O_VRLINK
|
||||
parent_organ = BP_HEAD
|
||||
icon_state = "cortical-stack"
|
||||
robotic = ORGAN_LIFELIKE
|
||||
|
||||
organ_verbs = list(
|
||||
/mob/living/carbon/human/proc/exit_vr
|
||||
)
|
||||
|
||||
/*
|
||||
* These subtypes are used by the Replicant species, and provide bonuses to their owners. Even when transplanted!
|
||||
*/
|
||||
|
||||
/obj/item/organ/internal/heart/replicant/rage
|
||||
name = "replicant adrenal heart"
|
||||
desc = "A mass of rubber, muscle, and complex chemical networks used for pumping fluid."
|
||||
description_info = "This organ, when connected properly to the body, will attempt to induce an adrenaline surge in the implantee."
|
||||
var/prev_damage_tally = 0
|
||||
var/last_activation_time = 0
|
||||
|
||||
/obj/item/organ/internal/heart/replicant/rage/handle_organ_proc_special()
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
var/damage_tally = 0
|
||||
var/pain_tally = 0
|
||||
damage_tally += owner.getBruteLoss()
|
||||
damage_tally += owner.getFireLoss()
|
||||
pain_tally += owner.getHalLoss()
|
||||
|
||||
if(((damage_tally >= 50 || prev_damage_tally >= 50) && prev_damage_tally - damage_tally < 0) || pain_tally >= 60)
|
||||
if(world.time > last_activation_time + 60 SECONDS)
|
||||
last_activation_time = world.time
|
||||
owner.add_modifier(/datum/modifier/berserk, 20 SECONDS)
|
||||
take_damage(5)
|
||||
|
||||
/obj/item/organ/internal/lungs/replicant/mending
|
||||
name = "replicant hive lungs"
|
||||
desc = "A pair of rubbery sacs with large portions dedicated to honeycombed nanite filters."
|
||||
description_info = "This organ, when connected properly to the body, will attempt to keep some other organs repaired."
|
||||
var/list/repair_list = list(O_HEART, O_KIDNEYS, O_VOICE, O_GBLADDER, O_PLASMA)
|
||||
|
||||
/obj/item/organ/internal/lungs/replicant/mending/handle_organ_proc_special()
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
var/modifier = 1 - (0.5 * is_bruised())
|
||||
|
||||
if(istype(owner))
|
||||
for(var/o_tag in repair_list)
|
||||
var/obj/item/organ/O = owner.internal_organs_by_name[o_tag]
|
||||
if(O)
|
||||
O.take_damage(-1 * modifier)
|
||||
@@ -29,6 +29,27 @@
|
||||
var/stored_plasma = 0
|
||||
var/max_plasma = 500
|
||||
|
||||
organ_verbs = list(
|
||||
/mob/living/carbon/human/proc/transfer_plasma
|
||||
)
|
||||
|
||||
/obj/item/organ/internal/xenos/plasmavessel/handle_organ_proc_special()
|
||||
if(!istype(owner))
|
||||
return
|
||||
|
||||
var/modifier = 1 - 0.5 * is_bruised()
|
||||
|
||||
if(owner.bloodstr.has_reagent("phoron"))
|
||||
adjust_plasma(round(4 * modifier))
|
||||
|
||||
if(owner.ingested.has_reagent("phoron"))
|
||||
adjust_plasma(round(2 * modifier))
|
||||
|
||||
adjust_plasma(1)
|
||||
|
||||
/obj/item/organ/internal/xenos/plasmavessel/proc/adjust_plasma(var/amount = 0)
|
||||
stored_plasma = CLAMP(stored_plasma + amount, 0, max_plasma)
|
||||
|
||||
/obj/item/organ/internal/xenos/plasmavessel/grey
|
||||
icon_state = "plasma_grey"
|
||||
stored_plasma = 200
|
||||
@@ -61,6 +82,12 @@
|
||||
icon_state = "acidgland"
|
||||
organ_tag = O_ACID
|
||||
|
||||
organ_verbs = list(
|
||||
/mob/living/carbon/human/proc/corrosive_acid,
|
||||
/mob/living/carbon/human/proc/neurotoxin,
|
||||
/mob/living/carbon/human/proc/acidspit
|
||||
)
|
||||
|
||||
/obj/item/organ/internal/xenos/acidgland/grey
|
||||
icon_state = "acidgland_grey"
|
||||
|
||||
@@ -95,6 +122,10 @@
|
||||
icon_state = "xenode"
|
||||
organ_tag = O_RESIN
|
||||
|
||||
organ_verbs = list(
|
||||
/mob/living/carbon/human/proc/resin,
|
||||
/mob/living/carbon/human/proc/plant
|
||||
)
|
||||
|
||||
/obj/item/organ/internal/xenos/resinspinner/grey
|
||||
icon_state = "xenode_grey"
|
||||
|
||||
Reference in New Issue
Block a user