mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-25 04:57:12 +01:00
Renames all typepaths + names of implants to biochips (#23172)
* The fix * Contraaaaaa * Fixes CI * Fixes the pads + cases * Uplink datums * Update code/datums/mind.dm Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> * Update code/__HELPERS/unsorted.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/research/designs/medical_designs.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/research/designs/medical_designs.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/research/designs/medical_designs.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/research/designs/medical_designs.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Update code/modules/surgery/implant_removal.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Outfits now use a proper variable name * Fixes surgery (oops) * More .dme changes * Renames the folder * Fixes bad merge * Contra review * Update code/game/objects/items/weapons/dice.dm Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> * Fixes CI fail --------- Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: Contrabang <91113370+Contrabang@users.noreply.github.com> Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com>
This commit is contained in:
co-authored by
Burzah
Contrabang
S34N
parent
fad6509b5e
commit
382a71df0d
@@ -0,0 +1,244 @@
|
||||
/// If used, an implant will trigger when an emote is intentionally used.
|
||||
#define BIOCHIP_EMOTE_TRIGGER_INTENTIONAL (1<<0)
|
||||
/// If used, an implant will trigger when an emote is forced/unintentionally used.
|
||||
#define BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL (1<<1)
|
||||
/// If used, an implant will always trigger when the user makes an emote.
|
||||
#define BIOCHIP_EMOTE_TRIGGER_ALWAYS (BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL | BIOCHIP_EMOTE_TRIGGER_INTENTIONAL)
|
||||
/// If used, an implant will trigger on the user's first death.
|
||||
#define BIOCHIP_TRIGGER_DEATH_ONCE (1<<2)
|
||||
/// If used, an implant will trigger any time a user dies.
|
||||
#define BIOCHIP_TRIGGER_DEATH_ANY (1<<3)
|
||||
/// If used, an implant will NOT trigger on death when a user is gibbed.
|
||||
#define BIOCHIP_TRIGGER_NOT_WHEN_GIBBED (1<<4)
|
||||
|
||||
// Defines related to the way that the implant is activated. This is the value for implant.activated
|
||||
/// The implant is passively active (like a mindshield)
|
||||
#define BIOCHIP_ACTIVATED_PASSIVE 0
|
||||
/// The implant is activated manually by a trigger
|
||||
#define BIOCHIP_ACTIVATED_ACTIVE 1
|
||||
|
||||
/**
|
||||
* # Implants
|
||||
*
|
||||
* Code for implants that can be inserted into a person and have some sort of passive or triggered action.
|
||||
*
|
||||
*/
|
||||
/obj/item/bio_chip
|
||||
name = "bio-chip"
|
||||
icon = 'icons/obj/bio_chips.dmi'
|
||||
icon_state = "generic" //Shows up as a auto surgeon, used as a placeholder when a implant doesn't have a sprite
|
||||
origin_tech = "materials=2;biotech=3;programming=2"
|
||||
actions_types = list(/datum/action/item_action/hands_free/activate)
|
||||
item_color = "black"
|
||||
flags = DROPDEL // By default, don't let implants be harvestable.
|
||||
|
||||
///which implant overlay should be used for implant cases. This should point to a state in bio_chips.dmi
|
||||
var/implant_state = "implant-default"
|
||||
/// How the implant is activated.
|
||||
var/activated = BIOCHIP_ACTIVATED_ACTIVE
|
||||
/// Whether the implant is implanted. Null if it's never been inserted, TRUE if it's currently inside someone, or FALSE if it's been removed.
|
||||
var/implanted
|
||||
/// Who the implant is inside of.
|
||||
var/mob/living/imp_in
|
||||
|
||||
/// Whether multiple implants of this same type can be inserted into someone.
|
||||
var/allow_multiple = FALSE
|
||||
/// Amount of times that the implant can be triggered by the user. If the implant can't be used, it can't be inserted.
|
||||
var/uses = -1
|
||||
|
||||
/// List of emote keys that activate this implant when used.
|
||||
var/list/trigger_emotes
|
||||
/// What type of action will trigger this emote. Bitfield of IMPLANT_EMOTE_* defines.
|
||||
var/trigger_causes
|
||||
/// Whether this implant has already triggered on death or not, to prevent it firing multiple times.
|
||||
var/has_triggered_on_death = FALSE
|
||||
|
||||
///the implant_fluff datum attached to this implant, purely cosmetic "lore" information
|
||||
var/datum/implant_fluff/implant_data = /datum/implant_fluff
|
||||
|
||||
/obj/item/bio_chip/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ispath(implant_data))
|
||||
implant_data = new implant_data
|
||||
|
||||
/obj/item/bio_chip/Destroy()
|
||||
if(imp_in)
|
||||
removed(imp_in)
|
||||
QDEL_NULL(implant_data)
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/proc/unregister_emotes()
|
||||
if(imp_in && LAZYLEN(trigger_emotes))
|
||||
for(var/emote in trigger_emotes)
|
||||
UnregisterSignal(imp_in, COMSIG_MOB_EMOTED(emote))
|
||||
|
||||
/**
|
||||
* Set the emote that will trigger the implant.
|
||||
* * user - User who is trying to associate the implant to themselves.
|
||||
* * emote_key - Key of the emote that should trigger the implant.
|
||||
* * on_implant - Whether this proc is being called during the implantation of the implant.
|
||||
* * silent - If true, the user won't get any to_chat messages if an implantation fails.
|
||||
*/
|
||||
/obj/item/bio_chip/proc/set_trigger(mob/user, emote_key, on_implant = FALSE, silent = TRUE)
|
||||
if(imp_in != user)
|
||||
return FALSE
|
||||
|
||||
if(!emote_key)
|
||||
return FALSE
|
||||
|
||||
if(LAZYIN(trigger_emotes, emote_key) && !on_implant)
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'> You've already registered [emote_key]!")
|
||||
return FALSE
|
||||
|
||||
if(emote_key == "me" || emote_key == "custom")
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'> You can't trigger [src] with a custom emote.")
|
||||
return FALSE
|
||||
|
||||
if(!(emote_key in user.usable_emote_keys(trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL)))
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'> You can't trigger [src] with that emote! Try *help to see emotes you can use.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!(emote_key in user.usable_emote_keys(trigger_causes & BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL)))
|
||||
CRASH("User was given an bio-chip for an unintentional emote that they can't use.")
|
||||
|
||||
LAZYADD(trigger_emotes, emote_key)
|
||||
RegisterSignal(user, COMSIG_MOB_EMOTED(emote_key), PROC_REF(on_emote))
|
||||
|
||||
/obj/item/bio_chip/proc/on_emote(mob/living/user, datum/emote/fired_emote, key, emote_type, message, intentional)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!implanted || !imp_in)
|
||||
return
|
||||
|
||||
if(!(intentional && (trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL)) && !(!intentional && (trigger_causes & BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL)))
|
||||
return
|
||||
|
||||
add_attack_logs(user, user, "[intentional ? "intentionally" : "unintentionally"] [src] was [intentional ? "intentionally" : "unintentionally"] triggered with the emote [fired_emote].")
|
||||
emote_trigger(key, user, intentional)
|
||||
|
||||
/obj/item/bio_chip/proc/on_death(mob/source, gibbed)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!implanted || !imp_in)
|
||||
return
|
||||
|
||||
if(gibbed && (trigger_causes & BIOCHIP_TRIGGER_NOT_WHEN_GIBBED))
|
||||
return
|
||||
|
||||
// This should help avoid infinite recursion for things like dust that call death()
|
||||
if(has_triggered_on_death && (trigger_causes & BIOCHIP_TRIGGER_DEATH_ONCE))
|
||||
return
|
||||
|
||||
has_triggered_on_death = TRUE
|
||||
|
||||
add_attack_logs(source, source, "had their [src] bio-chip triggered on [gibbed ? "gib" : "death"].")
|
||||
death_trigger(source, gibbed)
|
||||
|
||||
/obj/item/bio_chip/proc/emote_trigger(emote, mob/source, force)
|
||||
return
|
||||
|
||||
/obj/item/bio_chip/proc/death_trigger(mob/source, gibbed)
|
||||
return
|
||||
|
||||
/obj/item/bio_chip/proc/activate(cause)
|
||||
return
|
||||
|
||||
/obj/item/bio_chip/ui_action_click()
|
||||
activate("action_button")
|
||||
|
||||
/**
|
||||
* Try to implant ourselves into a mob.
|
||||
*
|
||||
* * source - The person the implant is being administered to.
|
||||
* * user - The person who is doing the implanting.
|
||||
*
|
||||
* Returns
|
||||
* 1 if the implant injects successfully
|
||||
* -1 if the implant fails to inject
|
||||
* 0 if there's no room for the implant.
|
||||
*/
|
||||
/obj/item/bio_chip/proc/implant(mob/source, mob/user, force)
|
||||
if(!force && !can_implant(source, user))
|
||||
return
|
||||
var/obj/item/bio_chip/imp_e = locate(type) in source
|
||||
if(!allow_multiple && imp_e && imp_e != src)
|
||||
if(imp_e.uses < initial(imp_e.uses)*2)
|
||||
if(uses == -1)
|
||||
imp_e.uses = -1
|
||||
else
|
||||
imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
loc = source
|
||||
imp_in = source
|
||||
implanted = TRUE
|
||||
if(trigger_emotes)
|
||||
if(!(trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL | BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL))
|
||||
CRASH("Bio-chip [src] has trigger emotes defined but no trigger cause with which to use them!")
|
||||
if(!activated && (trigger_causes & BIOCHIP_EMOTE_TRIGGER_INTENTIONAL))
|
||||
CRASH("Bio-chip [src] has intentional emote triggers on a passive bio-chip")
|
||||
// If you can't activate the implant manually, you shouldn't be able to deliberately activate it with an emote
|
||||
for(var/emote in trigger_emotes)
|
||||
set_trigger(source, emote, TRUE, TRUE)
|
||||
if(activated)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Grant(source)
|
||||
if(trigger_causes & (BIOCHIP_TRIGGER_DEATH_ONCE | BIOCHIP_TRIGGER_DEATH_ANY))
|
||||
RegisterSignal(source, COMSIG_MOB_DEATH, PROC_REF(on_death))
|
||||
if(ishuman(source))
|
||||
var/mob/living/carbon/human/H = source
|
||||
H.sec_hud_set_implants()
|
||||
|
||||
if(user)
|
||||
add_attack_logs(user, source, "Chipped with [src]")
|
||||
|
||||
return 1
|
||||
|
||||
/**
|
||||
* Check that we can actually implant this before implanting it
|
||||
* * source - The person being implanted
|
||||
* * user - The person doing the implanting
|
||||
*
|
||||
* Returns
|
||||
* TRUE - I could care less, implant it, maybe don't. I don't care.
|
||||
* FALSE - Don't implant!
|
||||
*/
|
||||
/obj/item/bio_chip/proc/can_implant(mob/source, mob/user)
|
||||
return TRUE
|
||||
|
||||
|
||||
/**
|
||||
* Clean up when an implant is removed.
|
||||
* * source - the user who the implant was removed from.
|
||||
*/
|
||||
/obj/item/bio_chip/proc/removed(mob/source)
|
||||
loc = null
|
||||
imp_in = null
|
||||
implanted = FALSE
|
||||
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Remove(source)
|
||||
|
||||
if(ishuman(source))
|
||||
var/mob/living/carbon/human/H = source
|
||||
H.sec_hud_set_implants()
|
||||
|
||||
if(trigger_causes & (BIOCHIP_TRIGGER_DEATH_ONCE | BIOCHIP_TRIGGER_DEATH_ANY))
|
||||
UnregisterSignal(source, COMSIG_MOB_DEATH)
|
||||
|
||||
unregister_emotes()
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/item/bio_chip/dropped(mob/user)
|
||||
. = TRUE
|
||||
..()
|
||||
@@ -0,0 +1,59 @@
|
||||
/obj/item/bio_chip/abductor
|
||||
name = "recall bio-chip"
|
||||
desc = "Returns you to the mothership."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "implant"
|
||||
activated = BIOCHIP_ACTIVATED_ACTIVE
|
||||
origin_tech = "materials=2;biotech=7;magnets=4;bluespace=4;abductor=5"
|
||||
implant_data = /datum/implant_fluff/abductor
|
||||
implant_state = "implant-alien"
|
||||
|
||||
var/obj/machinery/abductor/pad/home
|
||||
var/cooldown = 30
|
||||
var/total_cooldown = 30
|
||||
|
||||
/obj/item/bio_chip/abductor/activate()
|
||||
if(cooldown == total_cooldown)
|
||||
home.Retrieve(imp_in, 1)
|
||||
cooldown = 0
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
to_chat(imp_in, "<span class='warning'>You must wait [(total_cooldown - cooldown) * 2] seconds to use [src] again!</span>")
|
||||
|
||||
/obj/item/bio_chip/abductor/process()
|
||||
if(cooldown < total_cooldown)
|
||||
cooldown++
|
||||
if(cooldown == total_cooldown)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/bio_chip/abductor/implant(mob/source, mob/user)
|
||||
if(..())
|
||||
var/obj/machinery/abductor/console/console
|
||||
if(ishuman(source))
|
||||
var/mob/living/carbon/human/H = source
|
||||
if(isabductor(H))
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
console = get_team_console(S.team)
|
||||
home = console.pad
|
||||
|
||||
if(!home)
|
||||
console = get_team_console(pick(1, 2, 3, 4))
|
||||
home = console.pad
|
||||
return TRUE
|
||||
|
||||
/obj/item/bio_chip/abductor/proc/get_team_console(team)
|
||||
var/obj/machinery/abductor/console/console
|
||||
for(var/obj/machinery/abductor/console/c in GLOB.abductor_equipment)
|
||||
if(c.team == team)
|
||||
console = c
|
||||
break
|
||||
return console
|
||||
|
||||
/obj/item/bio_chip_implanter/abductor
|
||||
name = "bio-chip implanter (abductor)"
|
||||
implant_type = /obj/item/bio_chip/abductor
|
||||
|
||||
/obj/item/bio_chip_case/abductor
|
||||
name = "bio-chip case - 'abductor'"
|
||||
desc = "A glass case containing an abductor bio-chip."
|
||||
implant_type = /obj/item/bio_chip/abductor
|
||||
@@ -0,0 +1,34 @@
|
||||
/obj/item/bio_chip/adrenalin
|
||||
name = "adrenal bio-chip"
|
||||
desc = "Removes all stuns and knockdowns."
|
||||
icon_state = "adrenal"
|
||||
origin_tech = "materials=2;biotech=4;combat=3;syndicate=4"
|
||||
uses = 3
|
||||
implant_data = /datum/implant_fluff/adrenaline
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
/obj/item/bio_chip/adrenalin/activate()
|
||||
uses--
|
||||
to_chat(imp_in, "<span class='notice'>You feel a sudden surge of energy!</span>")
|
||||
imp_in.SetStunned(0)
|
||||
imp_in.SetWeakened(0)
|
||||
imp_in.SetKnockDown(0)
|
||||
imp_in.SetParalysis(0)
|
||||
imp_in.adjustStaminaLoss(-75)
|
||||
imp_in.stand_up(TRUE)
|
||||
SEND_SIGNAL(imp_in, COMSIG_LIVING_CLEAR_STUNS)
|
||||
|
||||
imp_in.reagents.add_reagent("synaptizine", 10)
|
||||
imp_in.reagents.add_reagent("omnizine", 10)
|
||||
imp_in.reagents.add_reagent("stimulative_agent", 10)
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bio_chip_implanter/adrenalin
|
||||
name = "bio-chip implanter (adrenalin)"
|
||||
implant_type = /obj/item/bio_chip/adrenalin
|
||||
|
||||
/obj/item/bio_chip_case/adrenaline
|
||||
name = "bio-chip case - 'Adrenaline'"
|
||||
desc = "A glass case containing an adrenaline bio-chip."
|
||||
implant_type = /obj/item/bio_chip/adrenalin
|
||||
@@ -0,0 +1,69 @@
|
||||
/obj/item/bio_chip_case
|
||||
name = "bio-chip case"
|
||||
desc = "A glass case containing a bio-chip."
|
||||
icon = 'icons/obj/bio_chips.dmi'
|
||||
icon_state = "implantcase"
|
||||
item_state = "implantcase"
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
origin_tech = "materials=1;biotech=2"
|
||||
container_type = OPENCONTAINER | INJECTABLE | DRAWABLE
|
||||
materials = list(MAT_GLASS = 500)
|
||||
|
||||
var/obj/item/bio_chip/imp
|
||||
var/obj/item/bio_chip/implant_type
|
||||
|
||||
/obj/item/bio_chip_case/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!implant_type)
|
||||
return
|
||||
imp = new implant_type(src)
|
||||
update_state()
|
||||
|
||||
/obj/item/bio_chip_case/Destroy()
|
||||
if(imp)
|
||||
QDEL_NULL(imp)
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip_case/proc/update_state()
|
||||
if(imp)
|
||||
origin_tech = imp.origin_tech
|
||||
flags = imp.flags & ~DROPDEL
|
||||
reagents = imp.reagents
|
||||
else
|
||||
origin_tech = initial(origin_tech)
|
||||
flags = initial(flags)
|
||||
reagents = null
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/item/bio_chip_case/update_overlays()
|
||||
. = ..()
|
||||
if(imp)
|
||||
var/image/implant_overlay = image('icons/obj/bio_chips.dmi', imp.implant_state)
|
||||
. += implant_overlay
|
||||
|
||||
/obj/item/bio_chip_case/attackby(obj/item/W, mob/user)
|
||||
..()
|
||||
|
||||
if(is_pen(W))
|
||||
rename_interactive(user, W)
|
||||
else if(istype(W, /obj/item/bio_chip_implanter))
|
||||
var/obj/item/bio_chip_implanter/I = W
|
||||
if(I.imp)
|
||||
if(imp || I.imp.implanted)
|
||||
return
|
||||
I.imp.forceMove(src)
|
||||
imp = I.imp
|
||||
I.imp = null
|
||||
update_state()
|
||||
I.update_icon(UPDATE_ICON_STATE)
|
||||
else
|
||||
if(imp)
|
||||
if(I.imp)
|
||||
return
|
||||
imp.loc = I
|
||||
I.imp = imp
|
||||
imp = null
|
||||
update_state()
|
||||
I.update_icon(UPDATE_ICON_STATE)
|
||||
@@ -0,0 +1,52 @@
|
||||
/obj/item/bio_chip/chem
|
||||
name = "chem bio-chip"
|
||||
desc = "Injects things."
|
||||
icon_state = "reagents"
|
||||
origin_tech = "materials=3;biotech=4"
|
||||
container_type = OPENCONTAINER
|
||||
trigger_causes = BIOCHIP_TRIGGER_DEATH_ANY
|
||||
implant_data = /datum/implant_fluff/chem
|
||||
implant_state = "implant-nanotrasen"
|
||||
|
||||
/obj/item/bio_chip/chem/Initialize(mapload)
|
||||
. = ..()
|
||||
create_reagents(50)
|
||||
GLOB.tracked_implants += src
|
||||
|
||||
/obj/item/bio_chip/chem/Destroy()
|
||||
GLOB.tracked_implants -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/chem/death_trigger(mob/victim, gibbed)
|
||||
activate(reagents.total_volume)
|
||||
|
||||
/obj/item/bio_chip/chem/activate(cause)
|
||||
if(!cause || !imp_in)
|
||||
return FALSE
|
||||
var/mob/living/carbon/R = imp_in
|
||||
var/injectamount
|
||||
|
||||
var/list/implant_chems = list()
|
||||
for(var/datum/reagent/chems in reagents.reagent_list)
|
||||
implant_chems += chems.name
|
||||
var/contained_chemicals = english_list(implant_chems)
|
||||
|
||||
if(cause == "action_button")
|
||||
injectamount = reagents.total_volume
|
||||
else
|
||||
injectamount = cause
|
||||
reagents.trans_to(R, injectamount)
|
||||
add_attack_logs(usr, R, "Chem bio-chip activated injecting [injectamount]u of [contained_chemicals]")
|
||||
to_chat(R, "<span class='italics'>You hear a faint beep.</span>")
|
||||
if(!reagents.total_volume)
|
||||
to_chat(R, "<span class='italics'>You hear a faint click from your chest.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bio_chip_implanter/chem
|
||||
name = "bio-chip implanter (chem)"
|
||||
implant_type = /obj/item/bio_chip/chem
|
||||
|
||||
/obj/item/bio_chip_case/chem
|
||||
name = "bio-chip case - 'Remote Chemical'"
|
||||
desc = "A glass case containing a remote chemical bio-chip."
|
||||
implant_type = /obj/item/bio_chip/chem
|
||||
@@ -0,0 +1,63 @@
|
||||
/obj/item/bio_chip/death_alarm
|
||||
name = "death alarm bio-chip"
|
||||
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
|
||||
activated = BIOCHIP_ACTIVATED_PASSIVE
|
||||
trigger_causes = BIOCHIP_TRIGGER_DEATH_ANY
|
||||
implant_data = /datum/implant_fluff/death_alarm
|
||||
implant_state = "implant-nanotrasen"
|
||||
|
||||
var/mobname = "Unknown"
|
||||
var/static/list/stealth_areas = typecacheof(list(/area/syndicate_mothership, /area/shuttle/syndicate_elite))
|
||||
|
||||
/obj/item/bio_chip/death_alarm/implant(mob/target)
|
||||
. = ..()
|
||||
if(.)
|
||||
mobname = target.real_name
|
||||
|
||||
/obj/item/bio_chip/death_alarm/activate(cause) // Death signal sends name followed by the gibbed / not gibbed check
|
||||
var/mob/M = imp_in
|
||||
var/area/t = get_area(M)
|
||||
|
||||
var/obj/item/radio/headset/a = new /obj/item/radio/headset(src)
|
||||
a.follow_target = M
|
||||
|
||||
switch(cause)
|
||||
if("gib")
|
||||
a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm")
|
||||
qdel(src)
|
||||
if("emp")
|
||||
var/name = prob(50) ? t.name : pick(SSmapping.teleportlocs)
|
||||
a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm")
|
||||
else
|
||||
if(is_type_in_typecache(t, stealth_areas))
|
||||
//give the syndies a bit of stealth
|
||||
a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm")
|
||||
else
|
||||
a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm")
|
||||
qdel(src)
|
||||
|
||||
qdel(a)
|
||||
|
||||
/obj/item/bio_chip/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
|
||||
activate("emp") //let's shout that this dude is dead
|
||||
|
||||
/obj/item/bio_chip/death_alarm/death_trigger(mob/source, gibbed)
|
||||
if(gibbed)
|
||||
activate("gib")
|
||||
else
|
||||
activate("death")
|
||||
|
||||
/obj/item/bio_chip/death_alarm/removed(mob/target)
|
||||
if(..())
|
||||
UnregisterSignal(target, COMSIG_MOB_DEATH)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/bio_chip_implanter/death_alarm
|
||||
name = "bio-chip implanter (Death Alarm)"
|
||||
implant_type = /obj/item/bio_chip/death_alarm
|
||||
|
||||
/obj/item/bio_chip_case/death_alarm
|
||||
name = "bio-chip Case - 'Death Alarm'"
|
||||
desc = "A case containing a death alarm bio-chip."
|
||||
implant_type = /obj/item/bio_chip/death_alarm
|
||||
@@ -0,0 +1,35 @@
|
||||
// Dust implant, for CC officers. Prevents gear theft if they die.
|
||||
|
||||
/obj/item/bio_chip/dust
|
||||
name = "duster bio-chip"
|
||||
desc = "A remote controlled bio-chip that will dust the user upon activation (or death of user)."
|
||||
icon = 'icons/obj/bio_chips.dmi'
|
||||
icon_state = "dust"
|
||||
actions_types = list(/datum/action/item_action/hands_free/activate/always)
|
||||
trigger_causes = BIOCHIP_TRIGGER_DEATH_ONCE | BIOCHIP_TRIGGER_NOT_WHEN_GIBBED
|
||||
implant_data = /datum/implant_fluff/dust
|
||||
implant_state = "implant-nanotrasen"
|
||||
|
||||
/obj/item/bio_chip/dust/death_trigger(mob/source, force)
|
||||
activate("death")
|
||||
|
||||
/obj/item/bio_chip/dust/activate(cause)
|
||||
if(!cause || !imp_in || cause == "emp")
|
||||
return FALSE
|
||||
if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your dusting bio-chip? This will turn you to ash!", "Dusting Confirmation", "Yes", "No") != "Yes")
|
||||
return FALSE
|
||||
to_chat(imp_in, "<span class='notice'>Your dusting bio-chip activates!</span>")
|
||||
imp_in.visible_message("<span class = 'warning'>[imp_in] burns up in a flash!</span>")
|
||||
imp_in.dust()
|
||||
|
||||
/obj/item/bio_chip/dust/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/bio_chip_implanter/dust
|
||||
name = "bio-chip implanter (Dust-on-death)"
|
||||
implant_type = /obj/item/bio_chip/dust
|
||||
|
||||
/obj/item/bio_chip_case/dust
|
||||
name = "bio-chip case - 'Dust'"
|
||||
desc = "A glass case containing a dust bio-chip."
|
||||
implant_type = /obj/item/bio_chip/dust
|
||||
@@ -0,0 +1,23 @@
|
||||
/obj/item/bio_chip/emp
|
||||
name = "emp bio-chip"
|
||||
desc = "Triggers an EMP."
|
||||
icon_state = "emp"
|
||||
origin_tech = "biotech=3;magnets=4;syndicate=1"
|
||||
uses = 2
|
||||
implant_data = /datum/implant_fluff/emp
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
/obj/item/bio_chip/emp/activate()
|
||||
uses--
|
||||
INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(empulse), get_turf(imp_in), 3, 5, 1)
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bio_chip_implanter/emp
|
||||
name = "bio-chip implanter (EMP)"
|
||||
implant_type = /obj/item/bio_chip/emp
|
||||
|
||||
/obj/item/bio_chip_case/emp
|
||||
name = "bio-chip case - 'EMP'"
|
||||
desc = "A glass case containing an EMP bio-chip."
|
||||
implant_type = /obj/item/bio_chip/emp
|
||||
@@ -0,0 +1,148 @@
|
||||
/obj/item/bio_chip/explosive
|
||||
name = "microbomb bio-chip"
|
||||
desc = "And boom goes the weasel."
|
||||
icon_state = "explosive"
|
||||
origin_tech = "materials=2;combat=3;biotech=4;syndicate=4"
|
||||
actions_types = list(/datum/action/item_action/hands_free/activate/always)
|
||||
trigger_causes = BIOCHIP_TRIGGER_DEATH_ONCE // Not surviving that
|
||||
implant_data = /datum/implant_fluff/explosive
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
var/detonating = FALSE
|
||||
var/weak = 2
|
||||
var/medium = 0.8
|
||||
var/heavy = 0.4
|
||||
var/delay = 7
|
||||
|
||||
/obj/item/bio_chip/explosive/death_trigger(mob/source, gibbed)
|
||||
activate("death")
|
||||
|
||||
/obj/item/bio_chip/explosive/activate(cause)
|
||||
if(!cause || !imp_in)
|
||||
return FALSE
|
||||
if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your microbomb bio-chip? This will cause you to explode!", "Microbomb Bio-chip Confirmation", "Yes", "No") != "Yes")
|
||||
return FALSE
|
||||
if(detonating)
|
||||
return FALSE
|
||||
heavy = round(heavy)
|
||||
medium = round(medium)
|
||||
weak = round(weak)
|
||||
detonating = TRUE
|
||||
to_chat(imp_in, "<span class='danger'>You activate your microbomb bio-chip.</span>")
|
||||
//If the delay is short, just blow up already jeez
|
||||
if(delay <= 7)
|
||||
self_destruct()
|
||||
return
|
||||
timed_explosion()
|
||||
|
||||
/// Gib the implantee and delete their destructible contents.
|
||||
/obj/item/bio_chip/explosive/proc/self_destruct()
|
||||
if(!imp_in)
|
||||
return
|
||||
|
||||
explosion(src, heavy, medium, weak, weak, flame_range = weak)
|
||||
|
||||
// In case something happens to the implantee between now and the
|
||||
// self-destruct
|
||||
var/current_location = get_turf(imp_in)
|
||||
|
||||
var/list/destructed_items = list()
|
||||
|
||||
// Iterate over the implantee's contents and take out indestructible
|
||||
// things to avoid having to worry about containers and recursion
|
||||
for(var/obj/item/I in imp_in.get_contents())
|
||||
if(I == src) // Don't delete ourselves prematurely
|
||||
continue
|
||||
// Drop indestructible items on the ground first, to avoid them
|
||||
// getting deleted when destroying the rest of the items, which we
|
||||
// track in a list to qdel afterwards
|
||||
if(I.resistance_flags & INDESTRUCTIBLE)
|
||||
I.forceMove(current_location)
|
||||
else
|
||||
destructed_items += I
|
||||
|
||||
QDEL_LIST_CONTENTS(destructed_items)
|
||||
|
||||
imp_in.gib()
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bio_chip/explosive/implant(mob/source)
|
||||
var/obj/item/bio_chip/explosive/imp_e = locate(type) in source
|
||||
if(imp_e && imp_e != src)
|
||||
imp_e.heavy += heavy
|
||||
imp_e.medium += medium
|
||||
imp_e.weak += weak
|
||||
imp_e.delay += delay
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/explosive/proc/timed_explosion()
|
||||
imp_in.visible_message("<span class = 'warning'>[imp_in] starts beeping ominously!</span>")
|
||||
playsound(loc, 'sound/items/timer.ogg', 30, 0)
|
||||
var/wait_delay = delay / 4
|
||||
sleep(wait_delay)
|
||||
if(imp_in && imp_in.stat)
|
||||
imp_in.visible_message("<span class = 'warning'>[imp_in] doubles over in pain!</span>")
|
||||
imp_in.Weaken(14 SECONDS)
|
||||
playsound(loc, 'sound/items/timer.ogg', 30, 0)
|
||||
sleep(wait_delay)
|
||||
playsound(loc, 'sound/items/timer.ogg', 30, 0)
|
||||
sleep(wait_delay)
|
||||
playsound(loc, 'sound/items/timer.ogg', 30, 0)
|
||||
sleep(wait_delay)
|
||||
self_destruct()
|
||||
|
||||
/obj/item/bio_chip/explosive/macro
|
||||
name = "macrobomb bio-chip"
|
||||
desc = "And boom goes the weasel. And everything else nearby."
|
||||
icon_state = "explosive"
|
||||
origin_tech = "materials=3;combat=5;biotech=4;syndicate=5"
|
||||
weak = 16
|
||||
medium = 8
|
||||
heavy = 4
|
||||
delay = 3 SECONDS
|
||||
implant_data = new /datum/implant_fluff/explosive_macro
|
||||
|
||||
/obj/item/bio_chip/explosive/macro/activate(cause)
|
||||
if(!cause || !imp_in)
|
||||
return FALSE
|
||||
if(cause == "action_button" && alert(imp_in, "Are you sure you want to activate your macrobomb bio-chip? This will cause you to explode and gib!", "Macrobomb Bio-chip Confirmation", "Yes", "No") != "Yes")
|
||||
return FALSE
|
||||
to_chat(imp_in, "<span class='notice'>You activate your macrobomb bio-chip.</span>")
|
||||
timed_explosion()
|
||||
|
||||
/obj/item/bio_chip/explosive/macro/implant(mob/source)
|
||||
var/obj/item/bio_chip/explosive/imp_e = locate(type) in source
|
||||
if(imp_e && imp_e != src)
|
||||
return FALSE
|
||||
imp_e = locate(/obj/item/bio_chip/explosive) in source
|
||||
if(imp_e && imp_e != src)
|
||||
heavy += imp_e.heavy
|
||||
medium += imp_e.medium
|
||||
weak += imp_e.weak
|
||||
delay += imp_e.delay
|
||||
qdel(imp_e)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/bio_chip_implanter/explosive
|
||||
name = "bio-chip implanter (explosive)"
|
||||
implant_type = /obj/item/bio_chip/explosive
|
||||
|
||||
/obj/item/bio_chip_case/explosive
|
||||
name = "bio-chip case - 'Micro Explosive'"
|
||||
desc = "A glass case containing a micro explosive bio-chip."
|
||||
implant_type = /obj/item/bio_chip/explosive
|
||||
|
||||
/obj/item/bio_chip_implanter/explosive_macro
|
||||
name = "bio-chip implanter (macro-explosive)"
|
||||
implant_type = /obj/item/bio_chip/explosive/macro
|
||||
|
||||
/obj/item/bio_chip_case/explosive_macro
|
||||
name = "bio-chip case - 'Macro Explosive'"
|
||||
desc = "A glass case containing a macro explosive bio-chip."
|
||||
implant_type = /obj/item/bio_chip/explosive/macro
|
||||
@@ -0,0 +1,136 @@
|
||||
|
||||
/**
|
||||
* # Bio-chip Fluff Datum
|
||||
*
|
||||
* Bio-chip fluff is just lore about the bio-chip that is accessed through the implantpad, you must attach
|
||||
* one of these datums to the implant_data var on a bio-chip for it to show it up.
|
||||
*/
|
||||
/datum/implant_fluff
|
||||
var/name = "Unknown bio-chip"
|
||||
var/life = "Not Specified."
|
||||
var/notes = "No Notes."
|
||||
var/function = "An electronic insert that supplements biological functions."
|
||||
|
||||
/datum/implant_fluff/abductor
|
||||
name = "GC$X9%D#G"
|
||||
life = "Unknown."
|
||||
notes = "Appears to contain highly advanced bluespace technology."
|
||||
|
||||
/datum/implant_fluff/adrenaline
|
||||
name = "Cybersun Industries RX-2 Adrenaline Bio-chip"
|
||||
life = "Five days."
|
||||
notes = "One of Cybersun Industries oldest and simplest implants, even in its simplicity it is rumoured to be one of Cybersun Industries best-selling products."
|
||||
function = "Subjects injected with this bio-chip can activate an injection of medical cocktails that removes stuns, increases speed, and has mild healing effects."
|
||||
|
||||
/datum/implant_fluff/supercharge
|
||||
name = "Cybersun Industries RX-4 Synthetic Supercharge Bio-chip"
|
||||
life = "Known to last for up to a year."
|
||||
notes = "One of Cybersun Industries simplest implants, it's rumored that synthetic rights groups maintain stockpiles of these."
|
||||
function = "Synthetic subjects injected with this bio-chip can activate an injection of lubricants, coolants, and positronic patching fluid."
|
||||
|
||||
/datum/implant_fluff/chem
|
||||
name = "BioTech Solutions MJ-420 Prisoner Management Bio-chip" //ah yes, MJ-420, old coders are FUNNY
|
||||
life = "Deactivates upon death but remains within the body."
|
||||
notes = "Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units. Can only be loaded while still in its original case."
|
||||
function = "Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal the bio-chip releases the chemicals directly into the blood stream."
|
||||
|
||||
/datum/implant_fluff/death_alarm
|
||||
name = "BioTech Solutions MJ-102 Death Alarm Bio-chip"
|
||||
notes = "Alerts crew to crewmember death."
|
||||
function = "Contains a compact radio signaler that triggers when the host's lifesigns cease."
|
||||
|
||||
/datum/implant_fluff/dust
|
||||
name = "Nanotrasen Employee Dust Bio-chip"
|
||||
life = "Unknown, attempts to retrieve a sample of the bio-chip have often led to the destruction of the bio-chip... and user."
|
||||
notes = "Activates upon death or from manual activation by the user."
|
||||
function = "Contains a compact, electrically activated heat source that turns its host to ash upon activation, or their death."
|
||||
|
||||
/datum/implant_fluff/emp
|
||||
name = "Cybersun Industries RX-22 Electromagnetic Pulse Emitter Bio-chip"
|
||||
life = "Destroyed upon final activation."
|
||||
notes = "An minituarized nuclear squib fit snuggly into a bio-chip."
|
||||
function = "Upon detonization the bio-chip will release an EMP affecting the immediate area around the user."
|
||||
|
||||
/datum/implant_fluff/explosive
|
||||
name = "Cybersun Industries RX-78 Employee Management Bio-chip"
|
||||
life = "Destroyed upon activation."
|
||||
notes = "Appears to contain a small, dense explosive device wired to a signaller chip, the serial number on the side is scratched out."
|
||||
function = "Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death."
|
||||
|
||||
/datum/implant_fluff/explosive_macro
|
||||
name = "Cybersun Industries RX-79 Employee Management Bio-chip"
|
||||
life = "Destroyed upon activation."
|
||||
notes = "Compared to its predecessor, the RX-79 contains a much larger explosive; sometimes you just need a bigger boom. Due to its bulkiness, it has been known to press into the user's frontal lobe, impairing judgement."
|
||||
function = "Contains a bulky, electrically triggered explosive that detonates upon receiving a specially encoded signal or upon host death."
|
||||
|
||||
/datum/implant_fluff/freedom
|
||||
name = "Cybersun Industries RX-92 Quick Escape Bio-chip"
|
||||
life = "Destroyed after 4 uses."
|
||||
notes = "A bio-chip that is illegal in many systems. It is notoriously known for allowing users to grotesquely fracture bones and over-exert joints in order to slip out of the tightest of restraints."
|
||||
function = "Uses a mixture of cybernetic nanobots, bone regrowth chemicals, and radio signals to quickly break the user out of restraints."
|
||||
|
||||
/datum/implant_fluff/protofreedom
|
||||
name = "Cybersun Industries X-92 Quick Escape Bio-chip"
|
||||
life = "Destroyed after 1 use."
|
||||
notes = "A bio-chip that is illegal in many systems. This is the early prototype version of the RX-92. It's significantly cheaper than it's newer version."
|
||||
function = "Uses a mixture of cheap cybernetic nanobots, bone regrowth chemicals, and radio signals to quickly break the user out of restraints."
|
||||
|
||||
/datum/implant_fluff/health
|
||||
name = "Nanotrasen Health Bio-chip"
|
||||
|
||||
/datum/implant_fluff/krav_maga
|
||||
name = "Prospero Foreign Industries Krav Maga Neurotrainer"
|
||||
life = "Will cease functioning 4 hours after death of host."
|
||||
notes = "As a consequence of using a neurotrainer, using this bio-chip will overwrite other martial arts knowledge in the users brain."
|
||||
function = "Teaches even the clumsiest host the arts of Krav Maga."
|
||||
|
||||
/datum/implant_fluff/mindshield
|
||||
name = "Nanotrasen Type 3 Mindshield Bio-chip"
|
||||
life = "Studies have shown the bio-chip to last up to 10 years."
|
||||
notes = "This is the third iteration of a bio-chip that has garnered attention from many galactic humanoid rights groups over concerns of self autonomy. Allegedly, it used to force the user to be completely loyal to Nanotrasen."
|
||||
function = "Personnel injected with this device can better resist mental compulsions such as brainwashing and mindslaving."
|
||||
|
||||
/datum/implant_fluff/storage
|
||||
name = "Cybersun Industries RX-16 Collapsible Body Cavity Bio-chip"
|
||||
notes = "Prolonged usage of this bio-chip often results in the users bones being fractured and occassionaly complete organ failure."
|
||||
function = "Allows the user to store two small objects within a cybernetic body cavity."
|
||||
|
||||
/datum/implant_fluff/tracking
|
||||
name = "Nanotrasen RFID Tracking Bio-chip"
|
||||
life = "Unknown, known to last up to a few years."
|
||||
notes = "Tracking bio-chips are Neuro-safe! Makes use of a specialized shell that will melt and disintegrate into bio-safe elements in the event of a malfunction. "
|
||||
function = "Continuously transmits a low power signal. Can be used for tracking and teleporting to the user."
|
||||
|
||||
/datum/implant_fluff/traitor
|
||||
name = "Syndicate Type E Mindslave Bio-chip"
|
||||
life = "Unknown, no collected sample has been active long enough to determine lifespan."
|
||||
notes = "Any humanoid injected with this bio-chip will become loyal to the injector, unless of course the host is already loyal to someone else. It's Diplomacy made easy. The Syndicate is known to use this for political and diplomatic leverage."
|
||||
function = " Contains a small pod of nanobots that manipulate the host's mental functions and slave the host to the implanter."
|
||||
|
||||
/datum/implant_fluff/uplink
|
||||
name = "Syndicate Agent Uplink Bio-chip"
|
||||
life = "Unknown, no collected sample has been active long enough to determine lifespan."
|
||||
notes = "An intricate piece of machinery that interfaces directly with the users brain and which inner workings are a closely guarded syndicate secret."
|
||||
function = "Allows the user to access a syndicate uplink connected contained within their body, invisible from the outside but provides the same functionality as a regular uplink."
|
||||
|
||||
/datum/implant_fluff/sad_trombone
|
||||
name = "BioTech Solutions Comedy Bio-chip"
|
||||
function = "Plays a sad trombone noise upon death of the implantee, allows clowns to entertain the crew even post-mortem."
|
||||
|
||||
/datum/implant_fluff/pathfinder
|
||||
name = "Paizo Productions 5-E Pathfinder Implant"
|
||||
life = "Lasts 2-12 months. Known to fail at the worst possible time, space radation may be a factor."
|
||||
notes = "By use of an internal private GPS signal, allows the pathfinder module to have the MODsuit find the user. Also wirelessly transfers ID information to the suit, to allow doors to open."
|
||||
function = "Allows for the recall of a Modular Outerwear Device by the implant owner at any time."
|
||||
|
||||
/datum/implant_fluff/gorilla_rampage
|
||||
name = "Magillitis Serum Bio-chip"
|
||||
life = "Unknown, no collected sample has been active long enough to determine lifespan."
|
||||
notes = "An experimental serum which causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas."
|
||||
function = "Allows the user to transform into an angry fast and robust gorilla. Very deadly in close quarters."
|
||||
|
||||
/datum/implant_fluff/stealth
|
||||
name = "Syndicate S3 \"Stealth\" Bio-chip"
|
||||
life = "Unknown. No collected sample has been active long enough to determine lifespan."
|
||||
notes = "Manually activated by the user."
|
||||
function = "Allows the user to summon a box from a bluespace pocket located inside the implant. The exterior of this box is lined with experimental cloaking panels which render the box invisible to the naked eye."
|
||||
@@ -0,0 +1,56 @@
|
||||
/obj/item/bio_chip/freedom
|
||||
name = "freedom bio-chip"
|
||||
desc = "Use this to escape from those evil Red Shirts."
|
||||
icon_state = "freedom"
|
||||
item_color = "r"
|
||||
origin_tech = "combat=5;magnets=3;biotech=4;syndicate=2"
|
||||
uses = 4
|
||||
implant_data = /datum/implant_fluff/freedom
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
|
||||
/obj/item/bio_chip/freedom/activate()
|
||||
uses--
|
||||
to_chat(imp_in, "You feel a faint click.")
|
||||
if(iscarbon(imp_in))
|
||||
var/mob/living/carbon/C_imp_in = imp_in
|
||||
C_imp_in.uncuff()
|
||||
for(var/obj/item/grab/G in C_imp_in.grabbed_by)
|
||||
var/mob/living/carbon/M = G.assailant
|
||||
C_imp_in.visible_message("<span class='warning'>[C_imp_in] suddenly shocks [M] from their wrists and slips out of their grab!</span>")
|
||||
M.Stun(2 SECONDS) //Drops the grab
|
||||
M.apply_damage(2, BURN, "r_hand", M.run_armor_check("r_hand", "energy"))
|
||||
M.apply_damage(2, BURN, "l_hand", M.run_armor_check("l_hand", "energy"))
|
||||
C_imp_in.SetStunned(0) //This only triggers if they are grabbed, to have them break out of the grab, without the large stun time.
|
||||
C_imp_in.SetWeakened(0)
|
||||
playsound(C_imp_in.loc, "sound/weapons/egloves.ogg", 75, 1)
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bio_chip_implanter/freedom
|
||||
name = "bio-chip implanter (freedom)"
|
||||
implant_type = /obj/item/bio_chip/freedom
|
||||
|
||||
/obj/item/bio_chip_case/freedom
|
||||
name = "bio-chip case - 'Freedom'"
|
||||
desc = "A glass case containing a freedom bio-chip."
|
||||
implant_type = /obj/item/bio_chip/freedom
|
||||
|
||||
/obj/item/bio_chip/freedom/prototype
|
||||
name = "prototype freedom bio-chip"
|
||||
desc = "Use this to escape from those evil Red Shirts. Works only once!"
|
||||
icon_state = "freedom"
|
||||
item_color = "r"
|
||||
origin_tech = "combat=5;magnets=3;biotech=3;syndicate=1"
|
||||
uses = 1
|
||||
implant_data = /datum/implant_fluff/protofreedom
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
/obj/item/bio_chip_implanter/freedom/prototype
|
||||
name = "bio-chip implanter (proto-freedom)"
|
||||
implant_type = /obj/item/bio_chip/freedom/prototype
|
||||
|
||||
/obj/item/bio_chip_case/freedom/prototype
|
||||
name = "bio-chip case - 'Proto-Freedom'"
|
||||
desc = "A glass case containing a prototype freedom bio-chip."
|
||||
implant_type = /obj/item/bio_chip/freedom/prototype
|
||||
@@ -0,0 +1,25 @@
|
||||
/obj/item/bio_chip/gorilla_rampage //Dumb path but easier to search for admins
|
||||
name = "magillitis serum bio-chip"
|
||||
desc = "An experimental biochip which causes irreversable rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas."
|
||||
icon_state = "gorilla_rampage"
|
||||
origin_tech = "combat=5;biotech=5;syndicate=2"
|
||||
uses = 1
|
||||
implant_data = /datum/implant_fluff/gorilla_rampage
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
/obj/item/bio_chip/gorilla_rampage/activate()
|
||||
if(!iscarbon(imp_in))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/target = imp_in
|
||||
target.visible_message("<span class='userdanger'>[target] swells and their hair grows rapidly. Uh oh!.</span>","<span class='userdanger'>You feel your muscles swell and your hair grow as you return to monke.</span>", "<span class='userdanger'>You hear angry gorilla noises.</span>")
|
||||
target.gorillize(TRUE)
|
||||
|
||||
/obj/item/bio_chip_implanter/gorilla_rampage
|
||||
name = "bio-chip implanter (magillitis serum)"
|
||||
implant_type = /obj/item/bio_chip/gorilla_rampage
|
||||
|
||||
/obj/item/bio_chip_case/gorilla_rampage
|
||||
name = "bio-chip case - 'magillitis serum'"
|
||||
desc = "A glass case containing a magillitis bio-chip."
|
||||
implant_type = /obj/item/bio_chip/gorilla_rampage
|
||||
@@ -0,0 +1,23 @@
|
||||
/obj/item/bio_chip/health
|
||||
name = "health bio-chip"
|
||||
activated = FALSE
|
||||
implant_data = /datum/implant_fluff/health
|
||||
implant_state = "implant-default"
|
||||
|
||||
var/healthstring = ""
|
||||
|
||||
/obj/item/bio_chip/health/proc/sensehealth()
|
||||
if(!imp_in)
|
||||
return "ERROR"
|
||||
else
|
||||
healthstring = "[round(imp_in.getOxyLoss())] - [round(imp_in.getFireLoss())] - [round(imp_in.getToxLoss())] - [round(imp_in.getBruteLoss())]"
|
||||
return healthstring
|
||||
|
||||
/obj/item/bio_chip_implanter/health
|
||||
name = "implanter (health)"
|
||||
implant_type = /obj/item/bio_chip/health
|
||||
|
||||
/obj/item/bio_chip_case/health
|
||||
name = "implant case - 'Health'"
|
||||
desc = "A glass case containing a health implant."
|
||||
implant_type = /obj/item/bio_chip/health
|
||||
@@ -0,0 +1,29 @@
|
||||
/obj/item/bio_chip/krav_maga
|
||||
name = "krav maga bio-chip"
|
||||
desc = "Teaches you the arts of Krav Maga in 5 short instructional videos beamed directly into your eyeballs."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state ="scroll2"
|
||||
activated = BIOCHIP_ACTIVATED_ACTIVE
|
||||
origin_tech = "materials=2;biotech=4;combat=5;syndicate=4"
|
||||
implant_data = /datum/implant_fluff/krav_maga
|
||||
implant_state = "implant-default"
|
||||
|
||||
var/datum/martial_art/krav_maga/style = new
|
||||
|
||||
/obj/item/bio_chip/krav_maga/activate()
|
||||
var/mob/living/carbon/human/H = imp_in
|
||||
if(!ishuman(H) || !H.mind)
|
||||
return
|
||||
if(istype(H.mind.martial_art, /datum/martial_art/krav_maga))
|
||||
style.remove(H)
|
||||
else
|
||||
style.teach(H, TRUE)
|
||||
|
||||
/obj/item/bio_chip_implanter/krav_maga
|
||||
name = "bio-chip implanter (krav maga)"
|
||||
implant_type = /obj/item/bio_chip/krav_maga
|
||||
|
||||
/obj/item/bio_chip_case/krav_maga
|
||||
name = "bio-chip case - 'Krav Maga'"
|
||||
desc = "A glass case containing a bio-chip that can teach the user the art of Krav Maga."
|
||||
implant_type = /obj/item/bio_chip/krav_maga
|
||||
@@ -0,0 +1,43 @@
|
||||
/obj/item/bio_chip/mindshield
|
||||
name = "mindshield bio-chip"
|
||||
desc = "Stops people messing with your mind."
|
||||
origin_tech = "materials=2;biotech=4;programming=4"
|
||||
activated = BIOCHIP_ACTIVATED_PASSIVE
|
||||
implant_data = /datum/implant_fluff/mindshield
|
||||
implant_state = "implant-nanotrasen"
|
||||
|
||||
/obj/item/bio_chip/mindshield/can_implant(mob/source, mob/user)
|
||||
if(source.mind?.has_antag_datum(/datum/antagonist/rev/head))
|
||||
source.visible_message("<span class='biggerdanger'>[source] seems to resist [src]!</span>",
|
||||
"<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/mindshield/implant(mob/target)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(target.mind)
|
||||
if(target.mind.has_antag_datum(/datum/antagonist/rev))
|
||||
SSticker.mode.remove_revolutionary(target.mind)
|
||||
if(target.mind in SSticker.mode.cult)
|
||||
to_chat(target, "<span class='warning'>You feel the corporate tendrils of Nanotrasen try to invade your mind!</span>")
|
||||
return TRUE
|
||||
|
||||
to_chat(target, "<span class='notice'>Your mind feels hardened - more resistant to brainwashing.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/bio_chip/mindshield/removed(mob/target, silent = 0)
|
||||
if(..())
|
||||
if(target.stat != DEAD && !silent)
|
||||
to_chat(target, "<span class='boldnotice'>Your mind softens. You feel susceptible to the effects of brainwashing once more.</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/bio_chip_implanter/mindshield
|
||||
name = "bio-chip implanter (mindshield)"
|
||||
implant_type = /obj/item/bio_chip/mindshield
|
||||
|
||||
/obj/item/bio_chip_case/mindshield
|
||||
name = "bio-chip case - 'mindshield'"
|
||||
desc = "A glass case containing a mindshield bio-chip."
|
||||
implant_type = /obj/item/bio_chip/mindshield
|
||||
@@ -0,0 +1,95 @@
|
||||
/obj/item/bio_chip_pad
|
||||
name = "bio-chip pad"
|
||||
desc = "Used to modify bio-chips."
|
||||
icon = 'icons/obj/bio_chips.dmi'
|
||||
icon_state = "implantpad-off"
|
||||
item_state = "electronic"
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
var/obj/item/bio_chip_case/case
|
||||
|
||||
/obj/item/bio_chip_pad/Destroy()
|
||||
if(case)
|
||||
eject_case()
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip_pad/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>You can <b>Alt-Click</b> [src] to remove it's stored implant.</span>"
|
||||
|
||||
/obj/item/bio_chip_pad/update_icon_state()
|
||||
if(case)
|
||||
icon_state = "implantpad-on"
|
||||
else
|
||||
icon_state = "implantpad-off"
|
||||
|
||||
/obj/item/bio_chip_pad/attack_self(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/bio_chip_pad/attackby(obj/item/bio_chip_case/C, mob/user)
|
||||
if(istype(C))
|
||||
addcase(user, C)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip_pad/proc/addcase(mob/user, obj/item/bio_chip_case/C)
|
||||
if(!user || !C)
|
||||
return
|
||||
if(case)
|
||||
to_chat(user, "<span class='warning'>There's already a bio-chip in the pad!</span>")
|
||||
return
|
||||
user.unEquip(C)
|
||||
C.forceMove(src)
|
||||
case = C
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/item/bio_chip_pad/proc/eject_case(mob/user)
|
||||
if(!case)
|
||||
return
|
||||
if(user)
|
||||
if(user.put_in_hands(case))
|
||||
add_fingerprint(user)
|
||||
case.add_fingerprint(user)
|
||||
case = null
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
return
|
||||
|
||||
case.forceMove(get_turf(src))
|
||||
case = null
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/item/bio_chip_pad/AltClick(mob/user)
|
||||
if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
|
||||
return
|
||||
|
||||
eject_case(user)
|
||||
|
||||
/obj/item/bio_chip_pad/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ImplantPad", name, 410, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/bio_chip_pad/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["contains_case"] = case ? TRUE : FALSE
|
||||
if(case && case.imp)
|
||||
var/datum/implant_fluff/implant_data = case.imp.implant_data
|
||||
data["implant"] = list(
|
||||
"name" = implant_data.name,
|
||||
"life" = implant_data.life,
|
||||
"notes" = implant_data.notes,
|
||||
"function" = implant_data.function,
|
||||
"image" = "[icon2base64(icon(initial(case.imp.icon), initial(case.imp.icon_state), SOUTH, 1))]",
|
||||
)
|
||||
return data
|
||||
|
||||
/obj/item/bio_chip_pad/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("eject_case")
|
||||
eject_case(ui.user)
|
||||
@@ -0,0 +1,48 @@
|
||||
/obj/item/bio_chip/grey_autocloner
|
||||
name = "technocracy cloning bio-chip"
|
||||
desc = "Allows for advanced instantanious cloning!"
|
||||
icon_state = "generic"
|
||||
origin_tech = "materials=3;combat=5;syndicate=2"
|
||||
activated = FALSE
|
||||
trigger_causes = BIOCHIP_TRIGGER_DEATH_ANY
|
||||
implant_state = "implant-alien"
|
||||
var/obj/machinery/grey_autocloner/linked
|
||||
var/datum/dna2/record/our_record
|
||||
|
||||
/obj/item/bio_chip/grey_autocloner/Destroy()
|
||||
linked = null
|
||||
our_record = null
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/grey_autocloner/death_trigger(mob/source, gibbed)
|
||||
imp_in.ghostize(TRUE)
|
||||
if(linked)
|
||||
linked.growclone(our_record)
|
||||
|
||||
/obj/item/bio_chip/grey_autocloner/implant(mob/source, mob/user, force)
|
||||
if(!linked)
|
||||
to_chat(user, "<span class='warning'>Please link the implanter with a Technocracy cloning pod!</span>")
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(!. || !ishuman(imp_in))
|
||||
return FALSE
|
||||
our_record = new /datum/dna2/record()
|
||||
our_record.ckey = imp_in.ckey
|
||||
var/obj/item/organ/B = imp_in.get_int_organ(/obj/item/organ/internal/brain)
|
||||
B.dna.check_integrity()
|
||||
our_record.dna = B.dna.Clone()
|
||||
our_record.id = copytext(md5(B.dna.real_name), 2, 6)
|
||||
our_record.name = B.dna.real_name
|
||||
our_record.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE
|
||||
our_record.languages = imp_in.languages
|
||||
if(imp_in.mind) //Save that mind so traitors can continue traitoring after cloning.
|
||||
our_record.mind = imp_in.mind.UID()
|
||||
|
||||
/obj/item/bio_chip_implanter/grey_autocloner
|
||||
name = "bio-chip implanter (Technocracy cloning)"
|
||||
implant_type = /obj/item/bio_chip/grey_autocloner
|
||||
|
||||
/obj/item/bio_chip_case/grey_autocloner
|
||||
name = "bio-chip case - 'Technocracy cloning'"
|
||||
desc = "A glass case containing an Technocracy bio-chip."
|
||||
implant_type = /obj/item/bio_chip/grey_autocloner
|
||||
@@ -0,0 +1,27 @@
|
||||
/obj/item/bio_chip/sad_trombone
|
||||
name = "sad trombone bio-chip"
|
||||
activated = FALSE
|
||||
trigger_emotes = list("deathgasp")
|
||||
// If something forces the clown to fake death, it's pretty funny to still see the sad trombone played
|
||||
trigger_causes = BIOCHIP_EMOTE_TRIGGER_UNINTENTIONAL | BIOCHIP_TRIGGER_DEATH_ANY
|
||||
implant_data = /datum/implant_fluff/sad_trombone
|
||||
implant_state = "implant-honk"
|
||||
|
||||
/obj/item/bio_chip/sad_trombone/emote_trigger(emote, mob/source, force)
|
||||
activate(emote)
|
||||
|
||||
/obj/item/bio_chip/sad_trombone/death_trigger(mob/user, gibbed)
|
||||
activate(gibbed)
|
||||
|
||||
|
||||
/obj/item/bio_chip/sad_trombone/activate()
|
||||
playsound(loc, 'sound/misc/sadtrombone.ogg', 50, FALSE)
|
||||
|
||||
/obj/item/bio_chip_implanter/sad_trombone
|
||||
name = "bio-chip implanter (sad trombone)"
|
||||
implant_type = /obj/item/bio_chip/sad_trombone
|
||||
|
||||
/obj/item/bio_chip_case/sad_trombone
|
||||
name = "bio-chip case - 'Sad Trombone'"
|
||||
desc = "A glass case containing a sad trombone bio-chip."
|
||||
implant_type = /obj/item/bio_chip/sad_trombone
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* # Stealth Implant
|
||||
*
|
||||
* Implant which allows you to summon an MGS-style cardboard box that turns you invisble after a short delay.
|
||||
*/
|
||||
/obj/item/bio_chip/stealth
|
||||
name = "S3 bio-chip"
|
||||
desc = "Allows you to be hidden in plain sight."
|
||||
implant_state = "implant-syndicate"
|
||||
implant_data = /datum/implant_fluff/stealth
|
||||
actions_types = list(/datum/action/item_action/agent_box)
|
||||
|
||||
/obj/item/bio_chip_implanter/stealth
|
||||
name = "bio-chip implanter (stealth)"
|
||||
implant_type = /obj/item/bio_chip/stealth
|
||||
|
||||
/datum/action/item_action/agent_box
|
||||
name = "Deploy Box"
|
||||
desc = "Find inner peace, here, in the box."
|
||||
check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS | AB_CHECK_STUNNED
|
||||
background_icon_state = "bg_agent"
|
||||
button_icon_state = "deploy_box"
|
||||
use_itemicon = FALSE
|
||||
/// If TRUE, the box can't be deployed
|
||||
var/on_cooldown = FALSE
|
||||
|
||||
/datum/action/item_action/agent_box/Trigger(trigger_flags, left_click)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(istype(owner.loc, /obj/structure/closet/cardboard/agent))
|
||||
var/obj/structure/closet/cardboard/agent/box = owner.loc
|
||||
if(box.open())
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
recall_box_animation()
|
||||
return
|
||||
// Box closing from here on out.
|
||||
if(!isturf(owner.loc)) //Don't let the player use this to escape mechs/welded closets.
|
||||
to_chat(owner, "<span class='warning'>You need more space to activate this implant!</span>")
|
||||
return
|
||||
owner.playsound_local(owner, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
spawn_box()
|
||||
|
||||
/datum/action/item_action/agent_box/proc/spawn_box()
|
||||
// Do the box's fade in spawn animation with an image so it follows the owner.
|
||||
var/image/fake_box = image('icons/obj/cardboard_boxes.dmi', owner, "agentbox", ABOVE_MOB_LAYER)
|
||||
flick_overlay_view(fake_box, owner, 0.4 SECONDS)
|
||||
fake_box.alpha = 0
|
||||
fake_box.pixel_z = 30
|
||||
animate(fake_box, pixel_z = fake_box.pixel_z - 30, alpha = fake_box.alpha + 255, time = 3, loop = 1)
|
||||
sleep(3)
|
||||
|
||||
// Spawn the actual box
|
||||
var/obj/structure/closet/cardboard/agent/box = new(get_turf(owner), owner)
|
||||
box.implant_user_UID = owner.UID()
|
||||
// Slightly shorter time since we needed 0.3s to to do the spawn animation.
|
||||
INVOKE_ASYNC(box, TYPE_PROC_REF(/obj/structure/closet/cardboard/agent, go_invisible), 1.7 SECONDS)
|
||||
box.create_fake_box()
|
||||
owner.forceMove(box)
|
||||
RegisterSignal(box, COMSIG_PARENT_QDELETING, PROC_REF(start_cooldown))
|
||||
|
||||
/datum/action/item_action/agent_box/proc/start_cooldown(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
on_cooldown = TRUE
|
||||
addtimer(CALLBACK(src, PROC_REF(end_cooldown)), 10 SECONDS)
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/item_action/agent_box/proc/end_cooldown()
|
||||
on_cooldown = FALSE
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/item_action/agent_box/IsAvailable()
|
||||
if(..() && !on_cooldown)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/action/item_action/agent_box/proc/recall_box_animation()
|
||||
var/image/fake_box = image('icons/obj/cardboard_boxes.dmi', owner, "agentbox", ABOVE_MOB_LAYER)
|
||||
flick_overlay_view(fake_box, owner, 0.4 SECONDS)
|
||||
animate(fake_box, pixel_z = fake_box.pixel_z + 30, alpha = fake_box.alpha - 255, time = 3, loop = 1)
|
||||
|
||||
/datum/action/item_action/agent_box/Grant(mob/grant_to)
|
||||
. = ..()
|
||||
if(owner)
|
||||
RegisterSignal(owner, COMSIG_HUMAN_SUICIDE_ACT, PROC_REF(suicide_act))
|
||||
|
||||
/datum/action/item_action/agent_box/Remove(mob/M)
|
||||
if(owner)
|
||||
UnregisterSignal(owner, COMSIG_HUMAN_SUICIDE_ACT)
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/agent_box/proc/suicide_act(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(owner.loc, /obj/structure/closet/cardboard/agent))
|
||||
return
|
||||
var/obj/structure/closet/cardboard/agent/box = owner.loc
|
||||
owner.visible_message("<span class='suicide'>[owner] falls out of [box]! It looks like [owner.p_they()] committed suicide!</span>")
|
||||
owner.playsound_local(box, 'sound/misc/box_deploy.ogg', 50, TRUE)
|
||||
INVOKE_ASYNC(box, TYPE_PROC_REF(/obj/structure/closet/cardboard/agent, open))
|
||||
INVOKE_ASYNC(owner, TYPE_PROC_REF(/atom/movable, throw_at), get_turf(owner))
|
||||
return OXYLOSS
|
||||
|
||||
// Stealth implant box
|
||||
/obj/structure/closet/cardboard/agent
|
||||
name = "inconspicious box"
|
||||
desc = "It's so normal that you didn't notice it before."
|
||||
icon_state = "agentbox"
|
||||
max_integrity = 1
|
||||
move_speed_multiplier = 0.5 // You can move at run speed while in this box.
|
||||
material_drop = null
|
||||
/// UID of the person who summoned this box with an implant.
|
||||
var/implant_user_UID
|
||||
// This has to be a separate object and not just an image because the image will inherit the box's 0 alpha while it is stealthed.
|
||||
/// A holder effect which follows the src box so we can display an image to the person inside the box.
|
||||
var/obj/effect/fake_box
|
||||
/// The box image attached to the `fake_box` object.
|
||||
var/image/box_img
|
||||
|
||||
/obj/structure/closet/cardboard/agent/Destroy()
|
||||
var/mob/living/implant_user = locateUID(implant_user_UID)
|
||||
implant_user?.client?.images -= box_img
|
||||
QDEL_NULL(fake_box)
|
||||
QDEL_NULL(box_img)
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/cardboard/agent/open()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
qdel(src)
|
||||
|
||||
// When the box is opened, it's deleted, so we never need to update this.
|
||||
/obj/structure/closet/cardboard/agent/update_icon_state()
|
||||
return
|
||||
|
||||
/obj/structure/closet/cardboard/agent/proc/create_fake_box()
|
||||
if(fake_box)
|
||||
return
|
||||
fake_box = new(get_turf(src))
|
||||
fake_box.mouse_opacity = MOUSE_OPACITY_TRANSPARENT // This object should be completely invisible.
|
||||
box_img = image(icon, fake_box, icon_state, ABOVE_MOB_LAYER)
|
||||
box_img.alpha = 128
|
||||
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(move_fake_box))
|
||||
var/mob/living/implant_user = locateUID(implant_user_UID)
|
||||
implant_user.client?.images += box_img
|
||||
|
||||
/obj/structure/closet/cardboard/agent/proc/move_fake_box(datum/source, oldloc, move_dir)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// For non-standard movement such as teleports.
|
||||
if(!move_dir)
|
||||
fake_box.loc = get_turf(src)
|
||||
return
|
||||
// For basic 8-directional movement.
|
||||
fake_box.loc = get_step(fake_box, move_dir)
|
||||
|
||||
/obj/structure/closet/cardboard/agent/proc/go_invisible(invis_time = 2 SECONDS)
|
||||
animate(src, alpha = 0, time = invis_time)
|
||||
sleep(invis_time)
|
||||
// This is so people can't locate the box by spamming right click everywhere.
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/structure/closet/cardboard/agent/proc/reveal()
|
||||
alpha = 255
|
||||
mouse_opacity = MOUSE_OPACITY_OPAQUE
|
||||
addtimer(CALLBACK(src, PROC_REF(go_invisible)), 1 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
|
||||
/obj/structure/closet/cardboard/agent/Bump(atom/A)
|
||||
. = ..()
|
||||
if(isliving(A))
|
||||
reveal()
|
||||
|
||||
/obj/structure/closet/cardboard/agent/Bumped(atom/movable/A)
|
||||
. = ..()
|
||||
if(isliving(A))
|
||||
reveal()
|
||||
@@ -0,0 +1,74 @@
|
||||
/obj/item/storage/hidden/implant
|
||||
name = "bluespace pocket"
|
||||
storage_slots = 2
|
||||
max_w_class = WEIGHT_CLASS_NORMAL
|
||||
max_combined_w_class = WEIGHT_CLASS_GIGANTIC
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
cant_hold = list(/obj/item/disk/nuclear)
|
||||
w_class_override = list(/obj/item/storage/belt)
|
||||
silent = TRUE
|
||||
|
||||
/obj/item/bio_chip/storage
|
||||
name = "storage bio-chip"
|
||||
desc = "Stores up to two big items in a bluespace pocket."
|
||||
icon_state = "storage"
|
||||
origin_tech = "materials=2;magnets=4;bluespace=5;syndicate=4"
|
||||
item_color = "r"
|
||||
implant_data = /datum/implant_fluff/storage
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
var/obj/item/storage/hidden/implant/storage
|
||||
|
||||
/obj/item/bio_chip/storage/Initialize(mapload)
|
||||
. = ..()
|
||||
storage = new /obj/item/storage/hidden/implant(src)
|
||||
|
||||
/obj/item/bio_chip/storage/emp_act(severity)
|
||||
..()
|
||||
storage.emp_act(severity)
|
||||
|
||||
/obj/item/bio_chip/storage/activate()
|
||||
if(!length(storage.mobs_viewing))
|
||||
storage.MouseDrop(imp_in)
|
||||
else
|
||||
for(var/mob/to_close in storage.mobs_viewing)
|
||||
storage.close(to_close)
|
||||
|
||||
/obj/item/bio_chip/storage/removed(source)
|
||||
if(..())
|
||||
for(var/mob/M in range(1))
|
||||
if(M.s_active == storage)
|
||||
storage.close(M)
|
||||
for(var/obj/item/I in storage)
|
||||
storage.remove_from_storage(I, get_turf(source))
|
||||
return TRUE
|
||||
|
||||
/obj/item/bio_chip/storage/implant(mob/source)
|
||||
var/obj/item/bio_chip/storage/imp_e = locate(type) in source
|
||||
if(imp_e)
|
||||
imp_e.storage.storage_slots += storage.storage_slots
|
||||
imp_e.storage.max_combined_w_class += storage.max_combined_w_class
|
||||
imp_e.storage.contents += storage.contents
|
||||
|
||||
for(var/mob/M in range(1))
|
||||
if(M.s_active == storage)
|
||||
storage.close(M)
|
||||
storage.show_to(source)
|
||||
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/storage/proc/get_contents() //Used for swiftly returning a list of the implant's contents i.e. for checking a theft objective's completion.
|
||||
if(storage && storage.contents)
|
||||
return storage.contents
|
||||
|
||||
/obj/item/bio_chip_implanter/storage
|
||||
name = "bio-chip implanter (storage)"
|
||||
implant_type = /obj/item/bio_chip/storage
|
||||
|
||||
/obj/item/bio_chip_case/storage
|
||||
name = "bio-chip case - 'Storage'"
|
||||
desc = "A glass case containing a storage bio-chip."
|
||||
implant_type = /obj/item/bio_chip/storage
|
||||
@@ -0,0 +1,34 @@
|
||||
/obj/item/bio_chip/supercharge
|
||||
name = "supercharge bio-chip"
|
||||
desc = "Removes all stuns and knockdowns."
|
||||
icon_state = "adrenal"
|
||||
origin_tech = "materials=3;combat=5;syndicate=4"
|
||||
uses = 3
|
||||
implant_data = /datum/implant_fluff/adrenaline
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
/obj/item/bio_chip/supercharge/activate()
|
||||
uses--
|
||||
to_chat(imp_in, "<span class='notice'>You feel an electric sensation as your components enter overdrive!</span>")
|
||||
imp_in.SetStunned(0)
|
||||
imp_in.SetWeakened(0)
|
||||
imp_in.SetKnockDown(0)
|
||||
imp_in.SetParalysis(0)
|
||||
imp_in.adjustStaminaLoss(-75)
|
||||
imp_in.stand_up(TRUE)
|
||||
SEND_SIGNAL(imp_in, COMSIG_LIVING_CLEAR_STUNS)
|
||||
|
||||
imp_in.reagents.add_reagent("surge_plus", 10)
|
||||
imp_in.reagents.add_reagent("liquid_solder", 10)
|
||||
imp_in.reagents.add_reagent("combatlube", 10)
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bio_chip_implanter/supercharge
|
||||
name = "bio-chip implanter (supercharge)"
|
||||
implant_type = /obj/item/bio_chip/supercharge
|
||||
|
||||
/obj/item/bio_chip_case/supercharge
|
||||
name = "bio-chip case - 'supercharge'"
|
||||
desc = "A glass case containing an supercharge bio-chip."
|
||||
implant_type = /obj/item/bio_chip/supercharge
|
||||
@@ -0,0 +1,43 @@
|
||||
/obj/item/bio_chip/tracking
|
||||
name = "tracking bio-chip"
|
||||
desc = "Track with this."
|
||||
activated = BIOCHIP_ACTIVATED_PASSIVE
|
||||
origin_tech = "materials=2;magnets=2;programming=2;biotech=2"
|
||||
implant_data = /datum/implant_fluff/tracking
|
||||
implant_state = "implant-nanotrasen"
|
||||
var/warn_cooldown = 0
|
||||
var/obj/item/gps/internal_gps
|
||||
var/internal_gps_path = /obj/item/gps/internal/tracking_implant
|
||||
|
||||
/obj/item/bio_chip/tracking/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.tracked_implants += src
|
||||
|
||||
/obj/item/bio_chip/tracking/Destroy()
|
||||
QDEL_NULL(internal_gps)
|
||||
GLOB.tracked_implants -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/tracking/implant(mob/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
internal_gps = new internal_gps_path(src)
|
||||
|
||||
/obj/item/bio_chip/tracking/removed(mob/target)
|
||||
. = ..()
|
||||
if(.)
|
||||
QDEL_NULL(internal_gps)
|
||||
|
||||
/obj/item/gps/internal/tracking_implant
|
||||
gpstag = "TRACK0"
|
||||
local = FALSE
|
||||
|
||||
/obj/item/bio_chip_implanter/tracking
|
||||
name = "bio-chip implanter (tracking)"
|
||||
implant_type = /obj/item/bio_chip/tracking
|
||||
|
||||
/obj/item/bio_chip_case/tracking
|
||||
name = "bio-chip case - 'Tracking'"
|
||||
desc = "A glass case containing a tracking bio-chip."
|
||||
implant_type = /obj/item/bio_chip/tracking
|
||||
@@ -0,0 +1,55 @@
|
||||
/obj/item/bio_chip/traitor
|
||||
name = "Mindslave Bio-chip"
|
||||
desc = "Divide and Conquer"
|
||||
origin_tech = "programming=5;biotech=5;syndicate=8"
|
||||
activated = FALSE
|
||||
implant_data = /datum/implant_fluff/traitor
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
/// The UID of the mindslave's `mind`. Stored to solve GC race conditions and ensure we can remove their mindslave status even when they're deleted or gibbed.
|
||||
var/mindslave_UID
|
||||
|
||||
/obj/item/bio_chip/traitor/implant(mob/living/carbon/human/mindslave_target, mob/living/carbon/human/user)
|
||||
// Check `activated` here so you can't just keep taking it out and putting it back into other people.
|
||||
if(activated || !istype(mindslave_target) || !istype(user)) // Both the target and the user need to be human.
|
||||
return FALSE
|
||||
|
||||
// If the target is catatonic or doesn't have a mind, return.
|
||||
if(!mindslave_target.mind)
|
||||
to_chat(user, "<span class='warning'><i>This person doesn't have a mind for you to slave!</i></span>")
|
||||
return FALSE
|
||||
|
||||
// Fails if they're already a mindslave of someone, or if they're mindshielded.
|
||||
if(ismindslave(mindslave_target) || ismindshielded(mindslave_target))
|
||||
mindslave_target.visible_message(
|
||||
"<span class='warning'>[mindslave_target] seems to resist the bio-chip!</span>", \
|
||||
"<span class='warning'>You feel a strange sensation in your head that quickly dissipates.</span>")
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
// Mindslaving yourself.
|
||||
if(mindslave_target == user)
|
||||
to_chat(user, "<span class='notice'>Making yourself loyal to yourself was a great idea! Perhaps even the best idea ever! Actually, you just feel like an idiot.</span>")
|
||||
user.adjustBrainLoss(20)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
// Create a new mindslave datum for the target with the user as their master.
|
||||
mindslave_target.mind.add_antag_datum(new /datum/antagonist/mindslave(user.mind))
|
||||
mindslave_UID = mindslave_target.mind.UID()
|
||||
log_admin("[key_name_admin(user)] has mind-slaved [key_name_admin(mindslave_target)].")
|
||||
return ..()
|
||||
|
||||
/obj/item/bio_chip/traitor/removed(mob/target)
|
||||
. = ..()
|
||||
var/datum/mind/M = locateUID(mindslave_UID)
|
||||
M.remove_antag_datum(/datum/antagonist/mindslave)
|
||||
|
||||
/obj/item/bio_chip_implanter/traitor
|
||||
name = "bio-chip implanter (Mindslave)"
|
||||
implant_type = /obj/item/bio_chip/traitor
|
||||
|
||||
/obj/item/bio_chip_case/traitor
|
||||
name = "bio-chip case - 'Mindslave'"
|
||||
desc = "A glass case containing a mindslave bio-chip."
|
||||
implant_type = /obj/item/bio_chip/traitor
|
||||
@@ -0,0 +1,62 @@
|
||||
/obj/item/bio_chip/uplink
|
||||
name = "uplink bio-chip"
|
||||
desc = "Summon things."
|
||||
icon = 'icons/obj/radio.dmi'
|
||||
icon_state = "radio"
|
||||
origin_tech = "materials=4;magnets=4;programming=4;biotech=4;syndicate=5;bluespace=5"
|
||||
implant_data = /datum/implant_fluff/uplink
|
||||
implant_state = "implant-syndicate"
|
||||
|
||||
/obj/item/bio_chip/uplink/Initialize(mapload)
|
||||
. = ..()
|
||||
hidden_uplink = new(src)
|
||||
hidden_uplink.uses = 50
|
||||
|
||||
/obj/item/bio_chip/uplink/nuclear/Initialize(mapload)
|
||||
. = ..()
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.update_uplink_type(UPLINK_TYPE_NUCLEAR)
|
||||
|
||||
/obj/item/bio_chip/uplink/sit/Initialize(mapload)
|
||||
. = ..()
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.update_uplink_type(UPLINK_TYPE_SIT)
|
||||
|
||||
/obj/item/bio_chip/uplink/admin/Initialize(mapload)
|
||||
. = ..()
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.update_uplink_type(UPLINK_TYPE_ADMIN)
|
||||
|
||||
|
||||
/obj/item/bio_chip/uplink/implant(mob/source)
|
||||
var/obj/item/bio_chip/imp_e = locate(type) in source
|
||||
if(imp_e && imp_e != src)
|
||||
imp_e.hidden_uplink.uses += hidden_uplink.uses
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
if(..())
|
||||
hidden_uplink.uplink_owner="[source.key]"
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/bio_chip/uplink/activate()
|
||||
if(hidden_uplink)
|
||||
hidden_uplink.check_trigger(imp_in)
|
||||
|
||||
/obj/item/bio_chip_implanter/uplink
|
||||
name = "bio-chip implanter (uplink)"
|
||||
implant_type = /obj/item/bio_chip/uplink
|
||||
|
||||
/obj/item/bio_chip_case/uplink
|
||||
name = "bio-chip case - 'Syndicate Uplink'"
|
||||
desc = "A glass case containing an uplink bio-chip."
|
||||
implant_type = /obj/item/bio_chip/uplink
|
||||
|
||||
/obj/item/bio_chip_implanter/nuclear
|
||||
name = "bio-chip implanter (Nuclear Agent Uplink)"
|
||||
implant_type = /obj/item/bio_chip/uplink/nuclear
|
||||
|
||||
/obj/item/bio_chip_case/nuclear
|
||||
name = "bio-chip case - 'Nuclear Agent Uplink'"
|
||||
implant_type = /obj/item/bio_chip/uplink/nuclear
|
||||
@@ -0,0 +1,56 @@
|
||||
/obj/item/bio_chip_implanter
|
||||
name = "bio-chip implanter"
|
||||
desc = "A sterile automatic bio-chip injector."
|
||||
icon = 'icons/obj/bio_chips.dmi'
|
||||
icon_state = "implanter0"
|
||||
item_state = "syringe_0"
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "materials=2;biotech=3"
|
||||
materials = list(MAT_METAL = 600, MAT_GLASS = 200)
|
||||
toolspeed = 1
|
||||
var/obj/item/bio_chip/imp
|
||||
var/obj/item/bio_chip/implant_type
|
||||
|
||||
/obj/item/bio_chip_implanter/update_icon_state()
|
||||
if(imp)
|
||||
icon_state = "implanter1"
|
||||
origin_tech = imp.origin_tech
|
||||
else
|
||||
icon_state = "implanter0"
|
||||
origin_tech = initial(origin_tech)
|
||||
|
||||
/obj/item/bio_chip_implanter/attack(mob/living/carbon/M, mob/user)
|
||||
if(!iscarbon(M))
|
||||
return
|
||||
if(user && imp)
|
||||
if(M != user)
|
||||
M.visible_message("<span class='warning'>[user] is attempting to bio-chip [M].</span>")
|
||||
|
||||
var/turf/T = get_turf(M)
|
||||
if(T && (M == user || do_after(user, 50 * toolspeed, target = M)))
|
||||
if(user && M && (get_turf(M) == T) && src && imp)
|
||||
if(imp.implant(M, user))
|
||||
if(M == user)
|
||||
to_chat(user, "<span class='notice'>You bio-chip yourself.</span>")
|
||||
else
|
||||
M.visible_message("[user] has implanted [M].", "<span class='notice'>[user] bio-chips you.</span>")
|
||||
imp = null
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/item/bio_chip_implanter/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(is_pen(W))
|
||||
rename_interactive(user, W)
|
||||
|
||||
/obj/item/bio_chip_implanter/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!implant_type)
|
||||
return
|
||||
imp = new implant_type()
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/item/bio_chip_implanter/Destroy()
|
||||
QDEL_NULL(imp)
|
||||
. = ..()
|
||||
Reference in New Issue
Block a user