Skip to content

Commit

Permalink
life crystals need to be equiped by their owner (#6036)
Browse files Browse the repository at this point in the history
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request

<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->

## Why It's Good For The Game
This is how life crystals are supposed to be used
<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->

## Changelog

<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->

:cl:
tweak: tweaked life crystals to work only when equiped by the owner, and
improved processing
/:cl:

<!-- Both :cl:'s are required for the changelog to work! You can put
your name to the right of the first :cl: if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
  • Loading branch information
TheLordME authored Oct 4, 2023
1 parent a291ec5 commit 0bcbed3
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 121 deletions.
1 change: 1 addition & 0 deletions citadel.dme
Original file line number Diff line number Diff line change
Expand Up @@ -4774,6 +4774,7 @@
#include "code\modules\vore\fluffstuff\custom_items_cit.dm"
#include "code\modules\vore\fluffstuff\custom_mecha.dm"
#include "code\modules\vore\fluffstuff\custom_permits.dm"
#include "code\modules\vore\fluffstuff\life_crystals.dm"
#include "code\modules\vore\fluffstuff\guns\bsharpoon.dm"
#include "code\modules\vore\fluffstuff\guns\crestrose.dm"
#include "code\modules\vore\fluffstuff\guns\dominator.dm"
Expand Down
121 changes: 0 additions & 121 deletions code/modules/vore/fluffstuff/custom_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -411,127 +411,6 @@
icon_state = "amp"
body_cover_flags = 0

//Lots of people are using this now.
/obj/item/clothing/accessory/collar/vmcrystal
name = "life crystal"
desc = "A small crystal with four little dots in it. It feels slightly warm to the touch. \
Read manual before use! Can be worn, held, or attached to uniform. NOTE: Device contains antimatter."
w_class = ITEMSIZE_SMALL

icon = 'icons/vore/custom_items_vr.dmi'
icon_override = 'icons/vore/custom_items_vr.dmi'

icon_state = "khlife"
item_state = "khlife_overlay"
overlay_state = "khlife_overlay"

slot_flags = SLOT_TIE

var/mob/owner = null
var/client/owner_c = null //They'll be dead when we message them probably.
var/state = 0 //0 - New, 1 - Paired, 2 - Breaking, 3 - Broken (same as iconstates)

/obj/item/clothing/accessory/collar/vmcrystal/Initialize(mapload)
. = ..()
update_state(0)

/obj/item/clothing/accessory/collar/vmcrystal/Destroy() //Waitwaitwait
if(state == 1)
process() //Nownownow
return ..() //Okfine

/obj/item/clothing/accessory/collar/vmcrystal/process(delta_time)
check_owner()
if((state > 1) || !owner)
STOP_PROCESSING(SSobj, src)

/obj/item/clothing/accessory/collar/vmcrystal/attack_self(mob/user)
. = ..()
if(.)
return
if(state > 0) //Can't re-pair, one time only, for security reasons.
to_chat(user, "<span class='notice'>The [name] doesn't do anything.</span>")
return 0

owner = user //We're paired to this guy
owner_c = user.client //This is his client
update_state(1)
to_chat(user, "<span class='notice'>The [name] glows pleasantly blue.</span>")
START_PROCESSING(SSobj, src)

/obj/item/clothing/accessory/collar/vmcrystal/proc/check_owner()
//He's dead, jim
if((state == 1) && owner && (owner.stat == DEAD))
update_state(2)
audible_message("<span class='warning'>The [name] begins flashing red.</span>")
sleep(30)
visible_message("<span class='warning'>The [name] shatters into dust!</span>")
if(owner_c)
to_chat(owner_c, "<span class='notice'>The HAVENS system is notified of your demise via \the [name].</span>")
update_state(3)
name = "broken [initial(name)]"
desc = "This seems like a necklace, but the actual pendant is missing."

/obj/item/clothing/accessory/collar/vmcrystal/proc/update_state(var/tostate)
state = tostate
icon_state = "[initial(icon_state)][tostate]"
update_icon()
/*
/obj/item/paper/vmcrystal_manual
name = "VM-LC91-1 manual"
info = {"<h4>VM-LC91-1 Life Crystal</h4>
<h5>Usage</h5>
<ol>
<li>Hold new crystal in hand.</li>
<li>Make fist with that hand.</li>
<li>Wait 1 second.</li>
</ol>
<br />
<h5>Purpose</h5>
<p>The VeyMed Life Crystal is a small device typically worn around the neck for the purpose of reporting your status to the HAVENS (VeyMed's High-AVailability ENgram Storage) system, so that appropriate measures can be taken in the case of your body's demise. The whole device is housed inside a pleasing-to-the-eye elongated diamond.</p>
<p>Upon your body's desmise, the crystal will send a transmission to HAVENS. Depending on your membership level, the appropriate actions can be taken to ensure that you are back up and enjoying existence as soon as possible.</p>
<p>Nanotrasen has negotiated a <i>FREE</i> Star membership for you in the HAVENS system, though an upgrade can be obtained depending on your citizenship and reputation level.</p>
As a reminder, the membership levels in HAVENS are:
<ul>
<li><b>HAVENS Star:</b> Upon reciving a signal from a transmitter indicating body demise, HAVENS will attempt to contact the owner for 48 hours, before starting the process of resleeving the owner into a new body they selected when registering their HAVENS membership.</li>
<li><b>HAVENS Nebula:</b> After the contact period from the Star service has expired, an agent will be alotted a HAVENS spacecraft, and will attempt to locate your remains, and any belongings you had, for up to one week. If possible, any more recent memory recordings or mindstates will be recovered before your resleeving. (Great for explorers! Don't miss out on anything you discovered!)</li>
<li><b>HAVENS Galaxy:</b> Upon reciving the signal from the Star service, a HAVENS High-Threat Response Team will be alotted a HAVENS FTL-capable Interdictor-class spacecraft and dispatched to your last known position to locate and recover your remains, plus any belongings. You will be resleeved on-site to continue where you left off.</li>
</ul>
<br />
<h5>Technical</h5>
<p>The Life Crystal is a small 5cm long diamond containing four main components which are visible inside the translucent gem.</p>
From tip to top, they are:
<ol>
<li><b>Qubit Bucket:</b> This small cube contains 200 bits worth of quantum-entangled bits for transmitting to HAVENS. QE transmission technologies cannot be jammed or interfered with, and are effectively instant over any distance.
<li><b>Antimatter Bottle:</b> This tiny antimatter vessel is required to power the transmitter for the time it takes to transmit the signal to HAVENS. The inside of the crystal is thick enough to block any alpha or beta particles emitted when this antimatter contacts matter, however the crystal will be destroyed when activated.
<li><b>Decay Reactor:</b> This long-term microreactor will last for around one month and provide sufficient power to power all but the transmitter. This power is required for containing the antimatter bottle.
<li><b>Sensor Suite:</b> The sensor that tracks the owner's life-state, such that it can be transmitted back to HAVENS when necessary.
</ol>
<p>The diamond itself is coated in a layer of graphene, to give it a pleasant rainbow finish. This also serves as a conductor that, if broken, will discharge the antimatter bottle immediately as it is unsafe to do so any point after the crystal is broken via physical means.</p>
<br />
<h5>Special Notes</h5>
<i>\[AM WARNING\]</i>
<p>This device contains antimatter. Please consult all local regulations when travelling to ensure compliance with local laws.</p>"}
*/
/obj/item/storage/box/vmcrystal
name = "life crystal case"
icon = 'icons/vore/custom_items_vr.dmi'
icon_state = "khlifebox"
desc = "This case can only hold the VM-LC91-1 and a manual."
item_state_slots = list(SLOT_ID_RIGHT_HAND = "syringe_kit", SLOT_ID_LEFT_HAND = "syringe_kit")
storage_slots = 2
can_hold = list(/obj/item/clothing/accessory/collar/vmcrystal)
max_storage_space = ITEMSIZE_COST_SMALL * 2
w_class = ITEMSIZE_SMALL

/obj/item/storage/box/vmcrystal/Initialize(mapload)
. = ..()
// new /obj/item/paper/vmcrystal_manual(src)
new /obj/item/clothing/accessory/collar/vmcrystal(src)

/obj/item/cane/fluff
name = "cane"
desc = "A cane used by a true gentlemen. Or a clown."
Expand Down
156 changes: 156 additions & 0 deletions code/modules/vore/fluffstuff/life_crystals.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
//Lots of people are using this now.
/obj/item/clothing/accessory/collar/vmcrystal
name = "life crystal"
desc = "A small crystal with four little dots in it. It feels slightly warm to the touch. \
Read manual before use! Can be worn, held, or attached to uniform. NOTE: Device contains antimatter."
w_class = ITEMSIZE_SMALL

icon = 'icons/vore/custom_items_vr.dmi'
icon_override = 'icons/vore/custom_items_vr.dmi'

icon_state = "khlife"
item_state = "khlife_overlay"
overlay_state = "khlife_overlay"

slot_flags = SLOT_TIE

var/mob/owner = null
var/client/owner_c = null //They'll be dead when we message them probably.
var/state = 0 //0 - New, 1 - Paired, 2 - Breaking, 3 - Broken (same as iconstates)
var/last_vitals //Write world.time in once owner dies or the crystal is removed

/obj/item/clothing/accessory/collar/vmcrystal/Initialize(mapload)
. = ..()
update_state(0)

/obj/item/clothing/accessory/collar/vmcrystal/Destroy() //Waitwaitwait
if(state == 1)
process() //Nownownow
return ..() //Okfine

/obj/item/clothing/accessory/collar/vmcrystal/process(delta_time)
check_owner()
if(!owner)
STOP_PROCESSING(SSobj, src)

/obj/item/clothing/accessory/collar/vmcrystal/attack_self(mob/user)
. = ..()
if(.)
return
if(state > 0) //Can't re-pair, one time only, for security reasons.
to_chat(user, "<span class='notice'>The [name] doesn't do anything.</span>")
return 0

owner = user //We're paired to this guy
owner_c = user.client //This is his client
update_state(1)
to_chat(user, "<span class='notice'>The [name] glows pleasantly blue.</span>")
START_PROCESSING(SSobj, src)

/obj/item/clothing/accessory/collar/vmcrystal/proc/check_owner()
//He's dead, jim
if(state < 1)
return
if(!owner)//How did we get here?
return
if((owner.stat == DEAD) || (get_turf(owner) != get_turf(src)))
if(state == 1)
become_alert()
if((state == 2) && (last_vitals < world.time - 1 MINUTE))
send_message()
else
if(state == 2)
become_calm()


/obj/item/clothing/accessory/collar/vmcrystal/proc/become_alert()
update_state(2)
audible_message(SPAN_WARNING("The [name] begins flashing red and vibrating in at a low frequency."),
SPAN_WARNING("The [name] begins vibrating in at a low frequency."))
last_vitals = world.time

/obj/item/clothing/accessory/collar/vmcrystal/proc/become_calm()
update_state(1)
audible_message(SPAN_NOTICE("[src] stops flashing red and vibrating as it resyncronises with its linked owner."),
SPAN_NOTICE("[src] stops vibrating in at a low frequency"))

/obj/item/clothing/accessory/collar/vmcrystal/proc/send_message()
visible_message(SPAN_WARNING("The [name] shatters into dust!"))
GLOB.global_announcer.autosay("[owner] has died!", "[owner]'s Life Crystal")
if(owner_c)
to_chat(owner_c, "<span class='notice'>The HAVENS system is notified of your demise via \the [name].</span>")
update_state(3)
name = "broken [initial(name)]"
desc = "This seems like a necklace, but the actual pendant is missing."

/obj/item/clothing/accessory/collar/vmcrystal/proc/update_state(var/tostate)
state = tostate
icon_state = "[initial(icon_state)][tostate]"
update_icon()

/obj/item/clothing/accessory/collar/vmcrystal/dropped(mob/user, flags, atom/newLoc)
. = ..()
check_owner()

/obj/item/clothing/accessory/collar/vmcrystal/pickup(mob/user, flags, atom/oldLoc)
. = ..()
check_owner()

/obj/item/clothing/accessory/collar/vmcrystal/unequipped(mob/user, slot, flags)
. = ..()
check_owner()
/*
/obj/item/paper/vmcrystal_manual
name = "VM-LC91-1 manual"
info = {"<h4>VM-LC91-1 Life Crystal</h4>
<h5>Usage</h5>
<ol>
<li>Hold new crystal in hand.</li>
<li>Make fist with that hand.</li>
<li>Wait 1 second.</li>
</ol>
<br />
<h5>Purpose</h5>
<p>The VeyMed Life Crystal is a small device typically worn around the neck for the purpose of reporting your status to the HAVENS (VeyMed's High-AVailability ENgram Storage) system, so that appropriate measures can be taken in the case of your body's demise. The whole device is housed inside a pleasing-to-the-eye elongated diamond.</p>
<p>Upon your body's desmise, the crystal will send a transmission to HAVENS. Depending on your membership level, the appropriate actions can be taken to ensure that you are back up and enjoying existence as soon as possible.</p>
<p>Nanotrasen has negotiated a <i>FREE</i> Star membership for you in the HAVENS system, though an upgrade can be obtained depending on your citizenship and reputation level.</p>
As a reminder, the membership levels in HAVENS are:
<ul>
<li><b>HAVENS Star:</b> Upon reciving a signal from a transmitter indicating body demise, HAVENS will attempt to contact the owner for 48 hours, before starting the process of resleeving the owner into a new body they selected when registering their HAVENS membership.</li>
<li><b>HAVENS Nebula:</b> After the contact period from the Star service has expired, an agent will be alotted a HAVENS spacecraft, and will attempt to locate your remains, and any belongings you had, for up to one week. If possible, any more recent memory recordings or mindstates will be recovered before your resleeving. (Great for explorers! Don't miss out on anything you discovered!)</li>
<li><b>HAVENS Galaxy:</b> Upon reciving the signal from the Star service, a HAVENS High-Threat Response Team will be alotted a HAVENS FTL-capable Interdictor-class spacecraft and dispatched to your last known position to locate and recover your remains, plus any belongings. You will be resleeved on-site to continue where you left off.</li>
</ul>
<br />
<h5>Technical</h5>
<p>The Life Crystal is a small 5cm long diamond containing four main components which are visible inside the translucent gem.</p>
From tip to top, they are:
<ol>
<li><b>Qubit Bucket:</b> This small cube contains 200 bits worth of quantum-entangled bits for transmitting to HAVENS. QE transmission technologies cannot be jammed or interfered with, and are effectively instant over any distance.
<li><b>Antimatter Bottle:</b> This tiny antimatter vessel is required to power the transmitter for the time it takes to transmit the signal to HAVENS. The inside of the crystal is thick enough to block any alpha or beta particles emitted when this antimatter contacts matter, however the crystal will be destroyed when activated.
<li><b>Decay Reactor:</b> This long-term microreactor will last for around one month and provide sufficient power to power all but the transmitter. This power is required for containing the antimatter bottle.
<li><b>Sensor Suite:</b> The sensor that tracks the owner's life-state, such that it can be transmitted back to HAVENS when necessary.
</ol>
<p>The diamond itself is coated in a layer of graphene, to give it a pleasant rainbow finish. This also serves as a conductor that, if broken, will discharge the antimatter bottle immediately as it is unsafe to do so any point after the crystal is broken via physical means.</p>
<br />
<h5>Special Notes</h5>
<i>\[AM WARNING\]</i>
<p>This device contains antimatter. Please consult all local regulations when travelling to ensure compliance with local laws.</p>"}
*/
/obj/item/storage/box/vmcrystal
name = "life crystal case"
icon = 'icons/vore/custom_items_vr.dmi'
icon_state = "khlifebox"
desc = "This case can only hold the VM-LC91-1 and a manual."
item_state_slots = list(SLOT_ID_RIGHT_HAND = "syringe_kit", SLOT_ID_LEFT_HAND = "syringe_kit")
storage_slots = 2
can_hold = list(/obj/item/clothing/accessory/collar/vmcrystal)
max_storage_space = ITEMSIZE_COST_SMALL * 2
w_class = ITEMSIZE_SMALL

/obj/item/storage/box/vmcrystal/Initialize(mapload)
. = ..()
// new /obj/item/paper/vmcrystal_manual(src)
new /obj/item/clothing/accessory/collar/vmcrystal(src)

0 comments on commit 0bcbed3

Please sign in to comment.