Skip to content

Commit

Permalink
Merge pull request #3468 from MistakeNot4892/fbp
Browse files Browse the repository at this point in the history
Readding FBP.
  • Loading branch information
out-of-phaze authored Nov 3, 2023
2 parents b85f827 + 1d40113 commit 3cf7707
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 22 deletions.
15 changes: 15 additions & 0 deletions code/__defines/aspects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,19 @@
model = MODEL_PATH; \
parent = /decl/aspect/prosthetic_limb/right_leg; \
aspect_cost = COST; \
} \
/decl/aspect/prosthetic_limb/head/##MODEL_ID { \
model = MODEL_PATH; \
parent = /decl/aspect/prosthetic_limb/head; \
aspect_cost = COST * 0.5; \
} \
/decl/aspect/prosthetic_limb/chest/##MODEL_ID { \
model = MODEL_PATH; \
parent = /decl/aspect/prosthetic_limb/chest; \
aspect_cost = COST * 0.5; \
} \
/decl/aspect/prosthetic_limb/groin/##MODEL_ID { \
model = MODEL_PATH; \
parent = /decl/aspect/prosthetic_limb/groin; \
aspect_cost = COST * 0.5; \
}
38 changes: 36 additions & 2 deletions code/modules/aspects/aspects_prosthetic_limbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
sort_value = 2
aspect_flags = ASPECTS_PHYSICAL
abstract_type = /decl/aspect/prosthetic_limb
var/fullbody_synthetic_only = FALSE
var/replace_children = TRUE
var/check_bodytype
var/bodypart_name
var/apply_to_limb = BP_L_HAND
Expand Down Expand Up @@ -63,6 +65,10 @@
/decl/aspect/prosthetic_limb/is_available_to(datum/preferences/pref)
. = ..()
if(.)
if(fullbody_synthetic_only)
var/decl/bodytype/bodytype = pref.get_bodytype_decl()
if(!bodytype?.is_robotic)
return FALSE
if(model)
var/decl/bodytype/prosthetic/R = GET_DECL(model)
if(!istype(R))
Expand All @@ -89,15 +95,19 @@

// Robotize the selected limb.
if(. && apply_to_limb)
var/use_model = model || get_base_model(holder.get_species_name())
var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(holder, apply_to_limb)
if(!istype(E))
var/list/organ_data = holder.should_have_limb(apply_to_limb)
var/limb_path = organ_data["path"]
if("path" in organ_data)
E = new limb_path(holder, null, model || get_base_model(holder.get_species_name()))
E = new limb_path(holder, null, use_model)
if(istype(E) && E.bodytype != model) // sometimes in the last line we save ourselves some work here
// this should be pre-validated by is_available_to()
E.set_bodytype_with_children(model || get_base_model(holder.get_species_name()))
if(replace_children)
E.set_bodytype_with_children(use_model)
else
E.set_bodytype(use_model)

/decl/aspect/prosthetic_limb/left_hand
bodypart_name = "Left Hand"
Expand Down Expand Up @@ -142,3 +152,27 @@
aspect_cost = 2
apply_to_limb = BP_R_LEG
incompatible_with_limbs = list(BP_R_FOOT, BP_R_LEG)

/decl/aspect/prosthetic_limb/head
bodypart_name = "Head"
aspect_cost = 1
apply_to_limb = BP_HEAD
incompatible_with_limbs = list(BP_HEAD)
fullbody_synthetic_only = TRUE
replace_children = FALSE

/decl/aspect/prosthetic_limb/chest
bodypart_name = "Upper Body"
aspect_cost = 1
apply_to_limb = BP_CHEST
incompatible_with_limbs = list(BP_CHEST)
fullbody_synthetic_only = TRUE
replace_children = FALSE

/decl/aspect/prosthetic_limb/groin
bodypart_name = "Lower Body"
aspect_cost = 1
apply_to_limb = BP_GROIN
incompatible_with_limbs = list(BP_GROIN)
fullbody_synthetic_only = TRUE
replace_children = FALSE
11 changes: 8 additions & 3 deletions code/modules/fabrication/designs/robotics/designs_prosthetics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@
} \
/datum/fabricator_recipe/robotics/prosthetic/model_##MODEL_ID/groin { \
path = /obj/item/organ/external/groin; \
}
/* Readd if FBP construction is desirable
} \
/datum/fabricator_recipe/robotics/prosthetic/model_##MODEL_ID/chest { \
path = /obj/item/organ/external/chest; \
} \
*/
/datum/fabricator_recipe/robotics/prosthetic/model_##MODEL_ID/head { \
path = /obj/item/organ/external/head; \
} \
/datum/fabricator_recipe/robotics/prosthetic/model_##MODEL_ID/groin { \
path = /obj/item/organ/external/groin; \
}

/datum/fabricator_recipe/robotics/prosthetic
var/model

Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/human/human_movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,6 @@
var/mob/M = buckled
M.unbuckle_mob()
var/decl/bodytype/B = get_bodytype()
playsound(loc, isSynthetic() ? pick(B.synthetic_bodyfall_sounds) : pick(B.bodyfall_sounds), 50, TRUE, -1)
playsound(loc, B.bodyfall_sounds, 50, TRUE, -1)
else if(!lying && !old_buckled_lying)
handle_stance() // Force an immediate stance update.
14 changes: 11 additions & 3 deletions code/modules/organs/external/_external.dm
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,14 @@
LAZYADD(unarmed_attacks, attack_type)
get_icon()

/obj/item/organ/external/set_bodytype(decl/bodytype/new_bodytype, override_material = null)
. = ..()
/obj/item/organ/external/set_bodytype(decl/bodytype/new_bodytype, override_material = null, apply_to_internal_organs = TRUE)
var/decl/bodytype/old_bodytype = bodytype
. = ..(new_bodytype, override_material)
if(bodytype != old_bodytype && apply_to_internal_organs)
bodytype.rebuild_internal_organs(src, override_material)
slowdown = bodytype.movement_slowdown
update_icon(TRUE)
if(.)
update_icon(TRUE)

/obj/item/organ/external/proc/set_bodytype_with_children(decl/bodytype/new_bodytype, override_material = null)
set_bodytype(new_bodytype, override_material)
Expand Down Expand Up @@ -428,6 +432,8 @@
//If attached to an owner mob
if(istype(owner))

owner.full_prosthetic = null

// Initialize fingerprints if we don't already have some (TODO: we're assuming this is our first owner, maybe check for this elsewhere?).
if((limb_flags & ORGAN_FLAG_FINGERPRINT) && !fingerprint && !BP_IS_PROSTHETIC(src))
fingerprint = owner.get_full_print(ignore_blockers = TRUE)
Expand Down Expand Up @@ -1388,6 +1394,8 @@ Note that amputating the affected organ does in fact remove the infection from t
continue
organ.do_install(null, src, FALSE, update_icon, FALSE) //Forcemove the organ and properly set it up in our internal data

victim.full_prosthetic = null

//Note that we don't need to change our own hierarchy when not removing from a mob

// Remove parent references
Expand Down
4 changes: 2 additions & 2 deletions code/modules/organs/external/head.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@
/obj/item/organ/external/head/get_agony_multiplier()
return (owner && owner.headcheck(organ_tag)) ? 1.50 : 1

/obj/item/organ/external/head/set_bodytype(decl/bodytype/new_bodytype, override_material = null)
/obj/item/organ/external/head/set_bodytype(decl/bodytype/new_bodytype, override_material = null, apply_to_internal_organs = TRUE)
. = ..()
has_lips = bodytype.appearance_flags & HAS_LIPS
has_lips = (bodytype.appearance_flags & HAS_LIPS)
can_intake_reagents = !(bodytype.body_flags & BODY_FLAG_NO_EAT)
draw_eyes = bodytype.has_eyes

Expand Down
12 changes: 8 additions & 4 deletions code/modules/organs/organ.dm
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,16 @@
blood_DNA = list(dna.unique_enzymes = dna.b_type)
set_species(dna.species)

/obj/item/organ/proc/set_bodytype(decl/bodytype/new_bodytype, override_material = null)
/obj/item/organ/proc/set_bodytype(decl/bodytype/new_bodytype, override_material = null, apply_to_internal_organs = TRUE)
SHOULD_CALL_PARENT(TRUE)
if(isnull(new_bodytype))
CRASH("Null bodytype passed to set_bodytype!")
PRINT_STACK_TRACE("Null bodytype passed to set_bodytype!")
return FALSE
if(ispath(new_bodytype, /decl/bodytype))
new_bodytype = GET_DECL(new_bodytype)
if(!istype(new_bodytype))
CRASH("Invalid bodytype [new_bodytype]")
PRINT_STACK_TRACE("Invalid bodytype [new_bodytype]")
return FALSE
bodytype = new_bodytype
if(bodytype.modifier_string)
name = "[bodytype.modifier_string] [initial(name)]"
Expand All @@ -141,7 +144,7 @@
min_broken_damage *= bodytype.hardiness
bodytype.resize_organ(src)
set_material(override_material || bodytype.material)
matter = bodytype.matter
matter = bodytype.matter?.Copy()
create_matter()
// maybe this should be a generalized repopulate_reagents helper??
if(reagents)
Expand All @@ -150,6 +153,7 @@
if(bodytype.body_flags & BODY_FLAG_NO_DNA)
QDEL_NULL(dna)
reset_status()
return TRUE

/obj/item/organ/proc/set_species(specie_name)
vital_to_owner = null // This generally indicates the owner mob is having species set, and this value may be invalidated.
Expand Down
9 changes: 9 additions & 0 deletions code/modules/organs/prosthetics/prosthetics_manufacturer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
material = /decl/material/solid/metal/steel
eye_flash_mod = 1
eye_darksight_range = 2
associated_gender = PLURAL
bodyfall_sounds = list(
'sound/foley/metal1.ogg'
)
has_organ = list(
BP_BRAIN = /obj/item/organ/internal/mmi_holder,
BP_EYES = /obj/item/organ/internal/eyes,
BP_CELL = /obj/item/organ/internal/cell
)
/// Determines which bodyparts can use this limb.
var/list/applies_to_part

Expand Down
41 changes: 36 additions & 5 deletions code/modules/species/species_bodytype.dm
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ var/global/list/bodytypes_by_category = list()
'sound/foley/meat2.ogg'
)

var/list/synthetic_bodyfall_sounds = list(
'sound/foley/metal1.ogg'
)

// Used for initializing prefs/preview
var/base_color = COLOR_BLACK
var/base_eye_color = COLOR_BLACK
Expand All @@ -91,7 +87,7 @@ var/global/list/bodytypes_by_category = list()
/// Used to initialize organ material
var/material = /decl/material/solid/organic/meat
/// Used to initialize organ matter
var/matter = null
var/list/matter = null
/// The reagent organs are filled with, which currently affects what mobs that eat the organ will receive.
/// TODO: Remove this in a later matter edibility refactor.
var/edible_reagent = /decl/material/liquid/nutriment/protein
Expand Down Expand Up @@ -391,3 +387,38 @@ var/global/list/bodytypes_by_category = list()
outfit.equip_outfit(mannequin, equip_adjustments = (OUTFIT_ADJUSTMENT_SKIP_SURVIVAL_GEAR|OUTFIT_ADJUSTMENT_SKIP_BACKPACK))
mannequin.update_icon()
mannequin.update_transform()

/decl/bodytype/proc/rebuild_internal_organs(var/obj/item/organ/external/limb, var/override_material)

if(!limb.owner)
return

// Work out what we want to have in this organ.
var/list/replacing_organs = list()
for(var/organ_tag in has_organ)
var/obj/item/organ/internal/organ_prototype = has_organ[organ_tag]
if(initial(organ_prototype.parent_organ) == limb.organ_tag)
replacing_organs[organ_tag] = organ_prototype

// No organs, just delete everything.
if(!length(replacing_organs))
for(var/obj/item/organ/internal/innard in limb.internal_organs)
limb.owner.remove_organ(innard, FALSE, FALSE, TRUE, TRUE, FALSE)
qdel(innard)
return

// Check what we already have that matches.
for(var/obj/item/organ/internal/innard in limb.internal_organs)
var/obj/item/organ/internal/organ_prototype = replacing_organs[innard.organ_tag]
if(organ_prototype && istype(innard, organ_prototype))
innard.set_bodytype(type, override_material || material)
replacing_organs -= innard.organ_tag
else
limb.owner.remove_organ(innard, FALSE, FALSE, TRUE, TRUE, FALSE)
qdel(innard)

// Install any necessary new organs.
for(var/organ_tag in replacing_organs)
var/organ_type = replacing_organs[organ_tag]
var/obj/item/organ/internal/new_innard = new organ_type(limb.owner, null, limb.owner.dna, src)
limb.owner.add_organ(new_innard, GET_EXTERNAL_ORGAN(limb.owner, new_innard.parent_organ), FALSE, FALSE)
2 changes: 1 addition & 1 deletion code/modules/species/species_bodytype_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@
pref.body_markings = base_markings?.Copy()

/decl/bodytype/proc/apply_appearance(var/mob/living/carbon/human/H)
H.skin_colour = base_color
H.skin_colour = base_color
4 changes: 3 additions & 1 deletion code/modules/species/station/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
spawn_flags = SPECIES_CAN_JOIN
inherent_verbs = list(/mob/living/carbon/human/proc/tie_hair)

// Add /decl/bodytype/prosthetic/basic_human to this list to allow full-body prosthetics.
available_bodytypes = list(
/decl/bodytype/human,
/decl/bodytype/human/masculine
/decl/bodytype/human/masculine,
/decl/bodytype/prosthetic/basic_human
)

exertion_effect_chance = 10
Expand Down

0 comments on commit 3cf7707

Please sign in to comment.