Adds nymph-limbs: The Return (#12374)

This commit is contained in:
Alberyk
2021-11-01 00:13:15 -03:00
committed by GitHub
parent c3d918917a
commit 3940c6a044
17 changed files with 410 additions and 8 deletions
+1 -1
View File
@@ -121,7 +121,7 @@
//Blood regeneration if there is some space
if(blood_volume < species.blood_volume && blood_volume)
if(REAGENT_DATA(owner.vessel, /decl/reagent/blood)) // Make sure there's blood at all
owner.vessel.add_reagent(/decl/reagent/blood, 0.1 + LAZYACCESS(owner.chem_effects, CE_BLOODRESTORE), temperature = species?.body_temperature)
owner.vessel.add_reagent(/decl/reagent/blood, BLOOD_REGEN_RATE + LAZYACCESS(owner.chem_effects, CE_BLOODRESTORE), temperature = species?.body_temperature)
if(blood_volume <= BLOOD_VOLUME_SAFE) //We lose nutrition and hydration very slowly if our blood is too low
owner.adjustNutritionLoss(2)
owner.adjustHydrationLoss(1)
+8 -2
View File
@@ -102,6 +102,8 @@
var/obj/item/organ/infect_target_internal //make internal organs become infected one at a time instead of all at once
var/obj/item/organ/infect_target_external //make child and parent organs become infected one at a time instead of all at once
var/mob/living/carbon/alien/diona/nymph //used by dionae limbs
/obj/item/organ/external/proc/invalidate_marking_cache()
cached_markings = null
@@ -597,6 +599,10 @@ This function completely restores a damaged organ to perfect condition.
if(!(status & ORGAN_BROKEN))
perma_injury = 0
if(status & ORGAN_NYMPH)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
if(surge_damage && (status & ORGAN_ASSISTED))
tick_surge_damage() //Yes, this being here is intentional since this proc does not call ..() unless the owner is null.
@@ -655,7 +661,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return
if(germ_level <= 0) //Catch any weirdness that might happen with negative values
germ_level = 0
germ_level = 0
if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//** Syncing germ levels with external wounds
@@ -703,7 +709,7 @@ Note that amputating the affected organ does in fact remove the infection from t
antibiotics = owner.chem_effects[CE_ANTIBIOTIC]
if(germ_level < INFECTION_LEVEL_TWO)
//null out the infect targets since at this point we're not in danger of spreading our infection.
//null out the infect targets since at this point we're not in danger of spreading our infection.
infect_target_internal = null
infect_target_external = null
return ..()
+346
View File
@@ -0,0 +1,346 @@
// Left Leg
/obj/item/organ/external/leg/nymph
var/nymph_child = /obj/item/organ/external/foot/nymph
/obj/item/organ/external/leg/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/leg/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
// Right Leg
/obj/item/organ/external/leg/right/nymph
var/nymph_child = /obj/item/organ/external/foot/right/nymph
/obj/item/organ/external/leg/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/leg/right/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
// Left Arm
/obj/item/organ/external/arm/nymph
var/nymph_child = /obj/item/organ/external/hand/nymph
/obj/item/organ/external/arm/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/arm/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
// Right Arm
/obj/item/organ/external/arm/right/nymph
var/nymph_child = /obj/item/organ/external/hand/right/nymph
/obj/item/organ/external/arm/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/obj/item/organ/external/arm/right/nymph/process()
..()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.handle_nymph(src)
// Left Hand
/obj/item/organ/external/hand/nymph
/obj/item/organ/external/hand/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
// Right Hand
/obj/item/organ/external/hand/right/nymph
/obj/item/organ/external/hand/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
// Left Foot
/obj/item/organ/external/foot/nymph
/obj/item/organ/external/foot/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
// Right Foot
/obj/item/organ/external/foot/right/nymph
/obj/item/organ/external/foot/right/nymph/Initialize()
. = ..()
AddComponent(/datum/component/nymph_limb)
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
N.setup_limb(src)
/datum/component/nymph_limb
var/list/valid_species = list(SPECIES_UNATHI, SPECIES_SKRELL)
var/list/valid_organs_to_replace = list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG)
// Main limb where the Nymph mob lives
var/list/nymph_limb_types = list(
/obj/item/organ/external/arm/nymph,
/obj/item/organ/external/arm/right/nymph,
/obj/item/organ/external/leg/nymph,
/obj/item/organ/external/leg/right/nymph
)
// Child limbs
var/list/nymph_extremity_types = list(
/obj/item/organ/external/hand/nymph,
/obj/item/organ/external/hand/right/nymph,
/obj/item/organ/external/foot/nymph,
/obj/item/organ/external/foot/right/nymph
)
var/list/nymph_limb_types_by_name = list(
BP_L_ARM = /obj/item/organ/external/arm/nymph,
BP_R_ARM = /obj/item/organ/external/arm/right/nymph,
BP_L_LEG = /obj/item/organ/external/leg/nymph,
BP_R_LEG = /obj/item/organ/external/leg/right/nymph,
BP_L_HAND = /obj/item/organ/external/hand/nymph,
BP_R_HAND = /obj/item/organ/external/hand/right/nymph,
BP_L_FOOT = /obj/item/organ/external/foot/nymph,
BP_R_FOOT = /obj/item/organ/external/foot/right/nymph
)
/datum/component/nymph_limb/proc/setup_limb(var/obj/item/organ/external/E)
if(is_type_in_list(E, nymph_limb_types))
E.nymph = new /mob/living/carbon/alien/diona
else if(!is_type_in_list(E, nymph_extremity_types))
return
E.status |= (ORGAN_PLANT | ORGAN_NYMPH)
E.species = all_species["Nymph Limb"]
E.fingerprints = null
if(!E.dna)
E.blood_DNA = list()
E.set_dna(new /datum/dna)
E.limb_flags &= ~(ORGAN_CAN_BREAK | ORGAN_CAN_MAIM | ORGAN_HAS_TENDON)
// Called by process()
/datum/component/nymph_limb/proc/handle_nymph(var/obj/item/organ/external/E)
var/mob/living/carbon/alien/diona/limb_nymph = E.nymph
if(!istype(limb_nymph))
return FALSE
if(!E || !is_type_in_list(E, nymph_limb_types))
return FALSE
if((!E.owner || limb_nymph.stat == DEAD))
nymph_out(E, limb_nymph)
return FALSE
if(!E.is_usable())
nymph_out(E, limb_nymph, forced = TRUE)
return FALSE
var/blood_volume = round(REAGENT_VOLUME(E.owner.vessel, /decl/reagent/blood))
if(blood_volume)
if(REAGENT_DATA(E.owner.vessel, /decl/reagent/blood))
E.owner.vessel.remove_reagent(/decl/reagent/blood, BLOOD_REGEN_RATE / (2 * nymph_limb_types_by_name.len))
if(blood_volume <= 0)
nymph_out(E, limb_nymph, forced = TRUE)
// Host detach
/mob/living/carbon/human/proc/detach_nymph_limb()
set category = "Abilities"
set name = "Detach Nymph"
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
// Find our existing nymphlimbs
var/list/my_nymph_limbs = list()
for(var/obj/item/organ/external/O in organs)
if(is_type_in_list(O, N.nymph_limb_types))
my_nymph_limbs += O
if(!my_nymph_limbs.len)
return FALSE
// Player picks a nymphlimb and removes it
var/obj/item/organ/external/E = input(src, "Select a limb to detach:", "Nymph Limb Detach") as null|anything in my_nymph_limbs
if(!istype(E))
return
if(!do_after(src, delay = 3 SECONDS, needhand = FALSE))
return
if(E.detach_nymph_limb() && my_nymph_limbs.len == 1)
verbs -= /mob/living/carbon/human/proc/detach_nymph_limb
regenerate_icons()
// Nymph detach
/mob/living/carbon/alien/diona/proc/detach_nymph_limb()
set category = "Abilities"
set name = "Detach from Host"
var/obj/item/organ/external/E = loc
if(istype(E))
to_chat(src, "You start to detach from your host.")
to_chat(E.owner, "The nymph acting as your [E.name] starts to unattach itself.")
if(do_after(src, delay = 3 SECONDS, needhand = FALSE))
E.detach_nymph_limb()
// Organ detach
/obj/item/organ/external/proc/detach_nymph_limb()
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
var/mob/living/carbon/alien/diona/nymph = src:nymph
var/nymph_owner = owner
if(nymph)
N.nymph_out(src, nymph)
to_chat(nymph_owner, span("warning", "The nymph attached to you as \a [name] unlatches its tendrils from your body and drops to \the [get_turf(src)]."))
to_chat(nymph, span("notice", "You tear your tendrils free of your host and drop to \the [get_turf(src)]."))
return TRUE
// Nymph attach
/mob/living/carbon/alien/diona/proc/attach_nymph_limb()
set category = "Abilities"
set name = "Attach to Nearby Host"
if(incapacitated())
return
if(!isturf(loc))
return
if(!can_attach)
to_chat(src, span("warning", "You do not have the strength to attach to another host so soon."))
var/datum/component/nymph_limb/N = GetComponent(/datum/component/nymph_limb)
var/list/mob/living/carbon/human/mob_list = list()
// Find a new host
for(var/mob/living/carbon/human/H in view(1))
if(ishuman(H) && (H.species?.name in N.valid_species) && \
H.client && H.stat == CONSCIOUS)
mob_list += H
if(!LAZYLEN(mob_list))
to_chat(src, span("warning", "There are no valid hosts to bond to."))
return FALSE
var/choice = input(src, "Choose a host to bond to:", "Attach to Host") in mob_list
var/mob/living/carbon/human/target = choice
if(!Adjacent(target) || target.stat || !target.client)
return
// Find a location to bond to, on the host
var/list/valid_locations = list()
for(var/O in target.organs_by_name)
if(!target.organs_by_name[O] && (O in N.valid_organs_to_replace))
valid_locations += O
var/limb_choice
if(!valid_locations.len)
to_chat(src, span("warning", "\The [target.name] has no suitable spots for you to attach to their body!"))
return
else
limb_choice = input(src,"Choose a location to attach onto \the [target.name]","Nymph Attachment Point") as null|anything in valid_locations
if(!limb_choice)
return
if(!do_after(src, delay = 3 SECONDS, needhand = FALSE))
return
// Make new limb and put it on the host
limb_choice = N.nymph_limb_types_by_name[limb_choice]
var/obj/item/organ/external/new_nymph_limb = new limb_choice
if(!istype(new_nymph_limb))
return
new_nymph_limb.replaced(target)
if(new_nymph_limb:nymph_child)
var/obj/item/organ/external/new_nymph_child = new new_nymph_limb:nymph_child
new_nymph_child.replaced(target)
target.regenerate_icons()
N.nymph_in(new_nymph_limb, src)
/datum/component/nymph_limb/proc/nymph_in(var/obj/item/organ/external/E, var/mob/living/carbon/alien/diona/nymph)
var/mob/living/carbon/alien/diona/limb_nymph = E.nymph
if(limb_nymph)
if(!limb_nymph.client)
QDEL_NULL(limb_nymph)
else
return
if(nymph.client)
nymph.client.eye = E.owner
limb_nymph = nymph
limb_nymph.forceMove(E)
/datum/component/nymph_limb/proc/nymph_out(var/obj/item/organ/external/E, var/mob/living/carbon/alien/diona/nymph, var/forced = FALSE)
if(nymph.client)
nymph.client.eye = nymph
nymph.forceMove(get_turf(E))
E.nymph = null
if(forced)
nymph.can_attach = FALSE
addtimer(CALLBACK(nymph, /datum/component/nymph_limb/.proc/can_attach, nymph), 5 MINUTES, TIMER_UNIQUE)
E.removed(E.owner)
qdel(E)
/datum/component/nymph_limb/proc/can_attach(var/mob/living/carbon/alien/diona/nymph)
if(nymph)
nymph.can_attach = TRUE
to_chat(nymph, span("notice", "Your body has regained enough strength to attach to a new host, if you can find one."))
// For limbs created by character setup
/datum/component/nymph_limb/proc/nymphize(var/mob/living/carbon/human/H, var/organ_name, var/forced = FALSE)
if(!H.should_have_limb(organ_name))
return
if(H.organs_by_name[organ_name])
if(forced) // Do we wish to remove any limbs currently occupying that spot?
var/obj/item/organ/external/O = H.get_organ(organ_name)
qdel(O)
H.organs_by_name[organ_name] = null
else
return
// Create and attach our new nymph limb
var/nymph_limb_type = nymph_limb_types_by_name[organ_name]
var/obj/item/organ/external/E = new nymph_limb_type
E.replaced(H)
for(var/obj/item/organ/external/child in E.children)
nymphize(H, child.organ_tag, TRUE)
H.verbs |= /mob/living/carbon/human/proc/detach_nymph_limb
/datum/species/diona/nymph_limb // For use on nymph-limb organs only
name = "Nymph Limb"
short_name = "nym"
name_plural = "Nymph Limbs"
bodytype = "Nymph"
icobase = 'icons/mob/human_races/limbs_nymph.dmi'
deform = 'icons/mob/human_races/limbs_nymph.dmi'
has_organ = list()
has_limbs = list(
BP_L_ARM = list( "path" = /obj/item/organ/external/arm/nymph),
BP_R_ARM = list( "path" = /obj/item/organ/external/arm/right/nymph),
BP_L_LEG = list( "path" = /obj/item/organ/external/leg/nymph),
BP_R_LEG = list( "path" = /obj/item/organ/external/leg/right/nymph),
BP_L_HAND = list( "path" = /obj/item/organ/external/hand/nymph),
BP_R_HAND = list( "path" = /obj/item/organ/external/hand/right/nymph),
BP_L_FOOT = list( "path" = /obj/item/organ/external/foot/nymph),
BP_R_FOOT = list( "path" = /obj/item/organ/external/foot/right/nymph)
)