mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-13 11:43:31 +00:00
move associated code to modular folder
This commit is contained in:
@@ -0,0 +1 @@
|
||||
#define PROTEAN_EDIBLE_MATERIALS list(MAT_STEEL) //CHOMPedit: only steel
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
proteans
|
||||
*/
|
||||
/obj/item/weapon/rig/protean
|
||||
name = "nanosuit control cluster"
|
||||
suit_type = "nanomachine"
|
||||
icon = 'icons/obj/rig_modules_ch.dmi'
|
||||
default_mob_icon = 'icons/mob/rig_back_ch.dmi'
|
||||
icon_state = "nanomachine_rig"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 90)
|
||||
siemens_coefficient= 0.5
|
||||
slowdown = 0
|
||||
offline_slowdown = 0
|
||||
seal_delay = 1
|
||||
var/mob/living/carbon/human/myprotean
|
||||
initial_modules = list(/obj/item/rig_module/power_sink)
|
||||
|
||||
helm_type = /obj/item/clothing/head/helmet/space/rig/protean //These are important for sprite pointers
|
||||
boot_type = /obj/item/clothing/shoes/magboots/rig/protean
|
||||
chest_type = /obj/item/clothing/suit/space/rig/protean
|
||||
glove_type = /obj/item/clothing/gloves/gauntlets/rig/protean
|
||||
|
||||
//I doooon't think I can get rig_back.dmi as a _ch file. That is part of /obj/item/weapon/rig/update_icon(var/update_mob_icon).
|
||||
|
||||
/obj/item/weapon/rig/protean/relaymove(mob/user, var/direction)
|
||||
if(user.stat || user.stunned)
|
||||
return
|
||||
forced_move(direction, user, FALSE)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/protean
|
||||
name = "mass"
|
||||
desc = "A helmet-shaped clump of nanomachines."
|
||||
siemens_coefficient= 0
|
||||
light_overlay = "should not use a light overlay"
|
||||
species_restricted = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJ, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_XENOHYBRID, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN) //CHOMPEDIT: adding more races to the proto rig
|
||||
|
||||
/obj/item/clothing/gloves/gauntlets/rig/protean
|
||||
name = "mass"
|
||||
desc = "Glove-shaped clusters of nanomachines."
|
||||
siemens_coefficient= 0
|
||||
species_restricted = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJ, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_XENOHYBRID, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN) //CHOMPEDIT: adding more races to the proto rig
|
||||
|
||||
/obj/item/clothing/shoes/magboots/rig/protean
|
||||
name = "mass"
|
||||
desc = "Boot-shaped clusters of nanomachines."
|
||||
siemens_coefficient= 0
|
||||
species_restricted = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJ, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_XENOHYBRID, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN) //CHOMPEDIT: adding more races to the proto rig
|
||||
|
||||
/obj/item/clothing/suit/space/rig/protean
|
||||
name = "mass"
|
||||
desc = "A body-hugging mass of nanomachines."
|
||||
siemens_coefficient= 0
|
||||
can_breach = 0
|
||||
species_restricted = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJ, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_XENOHYBRID, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN)
|
||||
allowed = list(
|
||||
/obj/item/weapon/gun,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/tank,
|
||||
/obj/item/device/suit_cooling_unit,
|
||||
/obj/item/weapon/melee/baton,
|
||||
/obj/item/weapon/storage/backpack,
|
||||
) //Subspace radio is in for the citadel version. IDK if we have that and I don't think we need it so I removed it from this list.
|
||||
|
||||
|
||||
|
||||
|
||||
//Backend stuff to make the sprites work. Copied and pasted from rig_pieces_vr.dm, but added ch to everything. Only reason for this to be touched is to add or remove species. This might just need to go in a new file named rig_pieces_ch.dm.
|
||||
/obj/item/clothing/head/helmet/space/rig/protean
|
||||
sprite_sheets = list(
|
||||
SPECIES_HUMAN = 'icons/mob/head_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/mob/species/tajaran/helmet_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/mob/species/skrell/helmet_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/mob/species/unathi/helmet_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/mob/species/unathi/helmet_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/mob/species/akula/helmet_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/mob/species/sergal/helmet_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/mob/species/sergal/helmet_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/mob/species/vulpkanin/helmet_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/mob/species/fox/helmet_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/mob/species/vulpkanin/helmet_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/mob/species/skrell/helmet_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/inventory/head/mob_ch_teshari.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/mob/species/skrell/helmet_ch.dmi',
|
||||
SPECIES_VOX = 'icons/mob/species/vox/head_ch.dmi'
|
||||
)
|
||||
|
||||
sprite_sheets_obj = list(
|
||||
SPECIES_HUMAN = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/obj/clothing/hats_ch.dmi',
|
||||
SPECIES_VOX = 'icons/obj/clothing/hats_ch.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/space/rig/protean
|
||||
sprite_sheets = list(
|
||||
SPECIES_HUMAN = 'icons/mob/spacesuit_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/mob/species/tajaran/suit_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/mob/species/skrell/suit_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/mob/species/unathi/suit_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/mob/species/unathi/suit_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/mob/species/akula/suit_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/mob/species/sergal/suit_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/mob/species/sergal/suit_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/mob/species/vulpkanin/suit_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/mob/species/fox/suit_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/mob/species/vulpkanin/suit_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/mob/species/skrell/suit_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/inventory/suit/mob_ch_teshari.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/mob/species/skrell/suit_ch.dmi',
|
||||
SPECIES_VOX = 'icons/mob/species/vox/suit_ch.dmi'
|
||||
)
|
||||
|
||||
sprite_sheets_obj = list(
|
||||
SPECIES_HUMAN = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/obj/clothing/spacesuits_ch.dmi',
|
||||
SPECIES_VOX = 'icons/obj/clothing/spacesuits_ch.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/gloves/gauntlets/rig/protean
|
||||
sprite_sheets = list(
|
||||
SPECIES_HUMAN = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/mob/hands_ch.dmi',
|
||||
SPECIES_VOX = 'icons/mob/species/vox/gloves_ch.dmi'
|
||||
)
|
||||
|
||||
sprite_sheets_obj = list(
|
||||
SPECIES_HUMAN = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/obj/clothing/gloves_ch.dmi',
|
||||
SPECIES_VOX = 'icons/obj/clothing/gloves_ch.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/shoes/magboots/rig/protean
|
||||
sprite_sheets = list(
|
||||
SPECIES_HUMAN = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/mob/feet_ch.dmi',
|
||||
SPECIES_VOX = 'icons/mob/species/vox/shoes_ch.dmi'
|
||||
)
|
||||
|
||||
sprite_sheets_obj = list(
|
||||
SPECIES_HUMAN = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_TAJ = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_SKRELL = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_UNATHI = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_XENOHYBRID = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_AKULA = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_SERGAL = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_NEVREAN = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_VULPKANIN = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_ZORREN_HIGH = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_FENNEC = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_PROMETHEAN = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_TESHARI = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_VASILISSAN = 'icons/obj/clothing/shoes_ch.dmi',
|
||||
SPECIES_VOX = 'icons/obj/clothing/shoes_ch.dmi'
|
||||
)
|
||||
@@ -0,0 +1,195 @@
|
||||
// // // External Organs
|
||||
/obj/item/organ/external/chest/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 50 // <-- This is different from the rest
|
||||
min_broken_damage = 1000
|
||||
vital = TRUE // <-- This is different from the rest
|
||||
model = "protean"
|
||||
/obj/item/organ/external/groin/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 30 // <-- This is different from the rest
|
||||
min_broken_damage = 1000 //Multiple
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/head/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 30
|
||||
min_broken_damage = 1000 //Inheritance
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/arm/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000 //Please
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/arm/right/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/leg/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/leg/right/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/hand/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/hand/right/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/foot/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
/obj/item/organ/external/foot/right/unbreakable/nano
|
||||
robotic = ORGAN_NANOFORM
|
||||
encased = FALSE
|
||||
max_damage = 20
|
||||
min_broken_damage = 1000
|
||||
vital = FALSE
|
||||
model = "protean"
|
||||
|
||||
// // // Internal Organs
|
||||
/obj/item/organ/internal/nano
|
||||
robotic = ORGAN_ROBOT
|
||||
|
||||
/obj/item/organ/internal/nano/orchestrator
|
||||
name = "orchestrator module"
|
||||
desc = "A small computer, designed for highly parallel workloads."
|
||||
icon = 'icons/mob/species/protean/protean.dmi'
|
||||
icon_state = "orchestrator"
|
||||
organ_tag = O_ORCH
|
||||
parent_organ = BP_TORSO
|
||||
vital = TRUE
|
||||
organ_verbs = list(
|
||||
/mob/living/carbon/human/proc/self_diagnostics
|
||||
)
|
||||
|
||||
/obj/item/organ/internal/nano/refactory
|
||||
name = "refactory module"
|
||||
desc = "A miniature metal processing unit and nanite factory."
|
||||
icon = 'icons/mob/species/protean/protean.dmi'
|
||||
icon_state = "refactory"
|
||||
organ_tag = O_FACT
|
||||
parent_organ = BP_TORSO
|
||||
|
||||
var/list/materials = list(MAT_STEEL = 0)
|
||||
var/max_storage = 10000
|
||||
organ_verbs = list(
|
||||
/mob/living/carbon/human/proc/reagent_purge
|
||||
)
|
||||
|
||||
/obj/item/organ/internal/nano/refactory/proc/get_stored_material(var/material)
|
||||
if(status & ORGAN_DEAD)
|
||||
return 0
|
||||
return materials[material] || 0
|
||||
|
||||
/obj/item/organ/internal/nano/refactory/proc/add_stored_material(var/material,var/amt)
|
||||
if(status & ORGAN_DEAD)
|
||||
return 0
|
||||
var/increase = min(amt,max(max_storage-materials[material],0))
|
||||
if(isnum(materials[material]))
|
||||
materials[material] += increase
|
||||
else
|
||||
materials[material] = increase
|
||||
|
||||
return increase
|
||||
|
||||
/obj/item/organ/internal/nano/refactory/proc/use_stored_material(var/material,var/amt)
|
||||
if(status & ORGAN_DEAD)
|
||||
return 0
|
||||
|
||||
var/available = materials[material]
|
||||
|
||||
//Success
|
||||
if(available >= amt)
|
||||
var/new_amt = available-amt
|
||||
if(new_amt == 0)
|
||||
materials -= material
|
||||
else
|
||||
materials[material] = new_amt
|
||||
return amt
|
||||
|
||||
//Failure
|
||||
return 0
|
||||
|
||||
/obj/item/organ/internal/mmi_holder/posibrain/nano
|
||||
name = "protean posibrain"
|
||||
desc = "A more advanced version of the standard posibrain, typically found in protean bodies."
|
||||
icon = 'icons/mob/species/protean/protean.dmi'
|
||||
icon_state = "posi"
|
||||
parent_organ = BP_TORSO
|
||||
|
||||
brain_type = /obj/item/device/mmi/digital/posibrain/nano
|
||||
|
||||
/obj/item/organ/internal/mmi_holder/posibrain/nano/robotize()
|
||||
. = ..()
|
||||
icon_state = "posi1"
|
||||
|
||||
/obj/item/organ/internal/mmi_holder/posibrain/nano/mechassist()
|
||||
. = ..()
|
||||
icon_state = "posi1"
|
||||
|
||||
|
||||
/obj/item/organ/internal/mmi_holder/posibrain/nano/update_from_mmi()
|
||||
. = ..()
|
||||
icon = initial(icon)
|
||||
icon_state = "posi1"
|
||||
stored_mmi.icon_state = "posi1"
|
||||
|
||||
stored_mmi.brainmob.languages = owner.languages
|
||||
|
||||
// The 'out on the ground' object, not the organ holder
|
||||
/obj/item/device/mmi/digital/posibrain/nano
|
||||
name = "protean posibrain"
|
||||
desc = "A more advanced version of the standard posibrain, typically found in protean bodies."
|
||||
icon = 'icons/mob/species/protean/protean.dmi'
|
||||
icon_state = "posi"
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/nano/Initialize()
|
||||
. = ..()
|
||||
icon_state = "posi"
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/nano/request_player()
|
||||
icon_state = initial(icon_state)
|
||||
return //We don't do this stuff
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/nano/reset_search()
|
||||
icon_state = initial(icon_state)
|
||||
return //Don't do this either because of the above
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/nano/transfer_personality()
|
||||
. = ..()
|
||||
icon_state = "posi1"
|
||||
|
||||
/obj/item/device/mmi/digital/posibrain/nano/transfer_identity()
|
||||
. = ..()
|
||||
icon_state = "posi1"
|
||||
@@ -0,0 +1,553 @@
|
||||
// Simple animal nanogoopeyness
|
||||
/mob/living/simple_mob/protean_blob
|
||||
name = "protean blob"
|
||||
desc = "Some sort of big viscous pool of jelly."
|
||||
tt_desc = "Animated nanogoop"
|
||||
icon = 'icons/mob/species/protean/protean.dmi'
|
||||
icon_state = "to_puddle"
|
||||
icon_living = "puddle2"
|
||||
icon_rest = "rest"
|
||||
icon_dead = "puddle"
|
||||
|
||||
faction = "neutral"
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
say_list_type = /datum/say_list/protean_blob
|
||||
|
||||
show_stat_health = FALSE //We will do it ourselves
|
||||
|
||||
response_help = "pets the" //CHOMP Edit
|
||||
response_disarm = "gently pushes aside the " //CHOMP Edit
|
||||
response_harm = "hits the" //CHOMP Edit
|
||||
|
||||
harm_intent_damage = 3
|
||||
melee_damage_lower = 5 //CHOMP Edit
|
||||
melee_damage_upper = 5 //CHOMP Edit
|
||||
attacktext = list("slashed")
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 900
|
||||
movement_cooldown = 2
|
||||
|
||||
var/mob/living/carbon/human/humanform
|
||||
var/obj/item/organ/internal/nano/refactory/refactory
|
||||
var/datum/modifier/healing
|
||||
|
||||
var/obj/prev_left_hand
|
||||
var/obj/prev_right_hand
|
||||
|
||||
var/human_brute = 0
|
||||
var/human_burn = 0
|
||||
|
||||
player_msg = "In this form, your health will regenerate as long as you have metal in you." //CHOMP Edit removed ventcrawl
|
||||
|
||||
can_buckle = TRUE //Blobsurfing
|
||||
|
||||
/datum/say_list/protean_blob
|
||||
speak = list("Blrb?","Sqrsh.","Glrsh!")
|
||||
emote_hear = list("squishes softly","spluts quietly","makes wet noises")
|
||||
emote_see = list("shifts wetly","undulates placidly")
|
||||
|
||||
//Constructor allows passing the human to sync damages
|
||||
/mob/living/simple_mob/protean_blob/New(var/newloc, var/mob/living/carbon/human/H)
|
||||
..()
|
||||
if(H)
|
||||
humanform = H
|
||||
updatehealth()
|
||||
refactory = locate() in humanform.internal_organs
|
||||
// verbs |= /mob/living/proc/ventcrawl //CHOMP Removal
|
||||
verbs |= /mob/living/proc/hide
|
||||
verbs |= /mob/living/simple_mob/protean_blob/proc/rig_transform //CHOMP Addition
|
||||
verbs |= /mob/living/proc/usehardsuit //CHOMP Addition
|
||||
else
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/Login()
|
||||
. = ..()
|
||||
copy_from_prefs_vr(bellies = FALSE) //Load vore prefs
|
||||
|
||||
/mob/living/simple_mob/protean_blob/Destroy()
|
||||
humanform = null
|
||||
refactory = null
|
||||
vore_organs = null
|
||||
vore_selected = null
|
||||
if(healing)
|
||||
healing.expire()
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/say_understands(var/mob/other, var/datum/language/speaking = null)
|
||||
// The parent of this proc and its parent are SHAMS and should be rewritten, but I'm not up to it right now.
|
||||
if(!speaking)
|
||||
return TRUE // can understand common, they're like, a normal person thing
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/speech_bubble_appearance()
|
||||
return "synthetic"
|
||||
|
||||
/mob/living/simple_mob/protean_blob/get_available_emotes()
|
||||
return global._robot_default_emotes
|
||||
|
||||
/mob/living/simple_mob/protean_blob/init_vore()
|
||||
return //Don't make a random belly, don't waste your time
|
||||
|
||||
/mob/living/simple_mob/protean_blob/isSynthetic()
|
||||
return TRUE // yup
|
||||
|
||||
/mob/living/simple_mob/protean_blob/Stat()
|
||||
..()
|
||||
if(humanform)
|
||||
humanform.species.Stat(humanform)
|
||||
|
||||
/mob/living/simple_mob/protean_blob/update_icon()
|
||||
if(humanform)
|
||||
//Still have a refactory
|
||||
if(istype(refactory))
|
||||
icon_living = "puddle2"
|
||||
|
||||
//Else missing one
|
||||
else
|
||||
icon_living = "puddle1"
|
||||
|
||||
//Not human-based
|
||||
else
|
||||
icon_living = "puddle0"
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/updatehealth()
|
||||
if(!humanform)
|
||||
return ..()
|
||||
|
||||
//Set the max
|
||||
maxHealth = humanform.getMaxHealth()*2 //HUMANS, and their 'double health', bleh.
|
||||
//Set us to their health, but, human health ignores robolimbs so we do it 'the hard way'
|
||||
human_brute = humanform.getActualBruteLoss()
|
||||
human_burn = humanform.getActualFireLoss()
|
||||
health = maxHealth - humanform.getOxyLoss() - humanform.getToxLoss() - humanform.getCloneLoss() - human_brute - human_burn
|
||||
|
||||
//Alive, becoming dead
|
||||
if((stat < DEAD) && (health <= 0))
|
||||
death()
|
||||
|
||||
//Overhealth
|
||||
if(health > getMaxHealth())
|
||||
health = getMaxHealth()
|
||||
|
||||
//Grab any other interesting values
|
||||
confused = humanform.confused
|
||||
radiation = humanform.radiation
|
||||
paralysis = humanform.paralysis
|
||||
|
||||
//Update our hud if we have one
|
||||
if(healths)
|
||||
if(stat != DEAD)
|
||||
var/heal_per = (health / getMaxHealth()) * 100
|
||||
switch(heal_per)
|
||||
if(100 to INFINITY)
|
||||
healths.icon_state = "health0"
|
||||
if(80 to 100)
|
||||
healths.icon_state = "health1"
|
||||
if(60 to 80)
|
||||
healths.icon_state = "health2"
|
||||
if(40 to 60)
|
||||
healths.icon_state = "health3"
|
||||
if(20 to 40)
|
||||
healths.icon_state = "health4"
|
||||
if(0 to 20)
|
||||
healths.icon_state = "health5"
|
||||
else
|
||||
healths.icon_state = "health6"
|
||||
else
|
||||
healths.icon_state = "health7"
|
||||
|
||||
// All the damage and such to the blob translates to the human
|
||||
/mob/living/simple_mob/protean_blob/apply_effect(var/effect = 0, var/effecttype = STUN, var/blocked = 0, var/check_protection = 1)
|
||||
if(humanform)
|
||||
return humanform.apply_effect(effect, effecttype, blocked, check_protection)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/adjustBruteLoss(var/amount,var/include_robo)
|
||||
amount *= 1.5
|
||||
if(humanform)
|
||||
return humanform.adjustBruteLoss(amount)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/adjustFireLoss(var/amount,var/include_robo)
|
||||
amount *= 1.5
|
||||
if(humanform)
|
||||
return humanform.adjustFireLoss(amount)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/adjustToxLoss(amount)
|
||||
if(humanform)
|
||||
return humanform.adjustToxLoss(amount)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/adjustOxyLoss(amount)
|
||||
if(humanform)
|
||||
return humanform.adjustOxyLoss(amount)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/adjustHalLoss(amount)
|
||||
if(humanform)
|
||||
return humanform.adjustHalLoss(amount)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/adjustCloneLoss(amount)
|
||||
if(humanform)
|
||||
return humanform.adjustCloneLoss(amount)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/emp_act(severity)
|
||||
if(humanform)
|
||||
return humanform.emp_act(severity)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/ex_act(severity)
|
||||
if(humanform)
|
||||
return humanform.ex_act(severity)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/rad_act(severity)
|
||||
if(humanform)
|
||||
return humanform.ex_act(severity)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/bullet_act(obj/item/projectile/P)
|
||||
if(humanform)
|
||||
return humanform.bullet_act(P)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/death(gibbed, deathmessage = "dissolves away, leaving only a few spare parts!")
|
||||
if(humanform)
|
||||
humanform.death(gibbed, deathmessage)
|
||||
else
|
||||
animate(src, alpha = 0, time = 2 SECONDS)
|
||||
sleep(2 SECONDS)
|
||||
|
||||
if(!QDELETED(src)) // Human's handle death should have taken us, but maybe we were adminspawned or something without a human counterpart
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_mob/protean_blob/Life()
|
||||
. = ..()
|
||||
if(. && istype(refactory) && humanform)
|
||||
if(!healing && (human_brute || human_burn) && refactory.get_stored_material(MAT_STEEL) >= 100)
|
||||
healing = humanform.add_modifier(/datum/modifier/protean/steel, origin = refactory)
|
||||
else if(healing && !(human_brute || human_burn))
|
||||
healing.expire()
|
||||
healing = null
|
||||
|
||||
/mob/living/simple_mob/protean_blob/lay_down()
|
||||
..()
|
||||
if(resting)
|
||||
animate(src,alpha = 40,time = 1 SECOND)
|
||||
mouse_opacity = 0
|
||||
plane = ABOVE_OBJ_PLANE
|
||||
else
|
||||
mouse_opacity = 1
|
||||
icon_state = "wake"
|
||||
animate(src,alpha = 255,time = 1 SECOND)
|
||||
plane = MOB_PLANE
|
||||
sleep(7)
|
||||
update_icon()
|
||||
//Potential glob noms
|
||||
if(can_be_drop_pred) //Toggleable in vore panel
|
||||
var/list/potentials = living_mobs(0)
|
||||
if(potentials.len)
|
||||
var/mob/living/target = pick(potentials)
|
||||
if(istype(target) && target.devourable && target.can_be_drop_prey && vore_selected)
|
||||
if(target.buckled)
|
||||
target.buckled.unbuckle_mob(target, force = TRUE)
|
||||
target.forceMove(vore_selected)
|
||||
to_chat(target,"<span class='warning'>\The [src] quickly engulfs you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!</span>")
|
||||
|
||||
/mob/living/simple_mob/protean_blob/attack_target(var/atom/A)
|
||||
if(refactory && istype(A,/obj/item/stack/material))
|
||||
var/obj/item/stack/material/S = A
|
||||
var/substance = S.material.name
|
||||
var allowed = FALSE
|
||||
for(var/material in PROTEAN_EDIBLE_MATERIALS)
|
||||
if(material == substance) allowed = TRUE
|
||||
if(!allowed)
|
||||
return
|
||||
if(refactory.add_stored_material(S.material.name,1*S.perunit) && S.use(1))
|
||||
visible_message("<b>[name]</b> gloms over some of \the [S], absorbing it.")
|
||||
else if(isitem(A) && a_intent == "grab") //CHOMP Add all this block, down to I.forceMove.
|
||||
var/obj/item/I = A
|
||||
if(!vore_selected)
|
||||
to_chat(src,"<span class='warning'>You either don't have a belly selected, or don't have a belly!</span>")
|
||||
return FALSE
|
||||
if(is_type_in_list(I,item_vore_blacklist) || I.anchored)
|
||||
to_chat(src, "<span class='warning'>You can't eat this.</span>")
|
||||
return
|
||||
|
||||
if(is_type_in_list(I,edible_trash) | adminbus_trash)
|
||||
if(I.hidden_uplink)
|
||||
to_chat(src, "<span class='warning'>You really should not be eating this.</span>")
|
||||
message_admins("[key_name(src)] has attempted to ingest an uplink item. ([src ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>" : "null"])")
|
||||
return
|
||||
visible_message("<b>[name]</b> stretches itself over the [I], engulfing it whole!")
|
||||
I.forceMove(vore_selected)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/attackby(var/obj/item/O, var/mob/user)
|
||||
if(refactory && istype(O,/obj/item/stack/material))
|
||||
var/obj/item/stack/material/S = O
|
||||
var/substance = S.material.name
|
||||
var allowed = FALSE
|
||||
for(var/material in PROTEAN_EDIBLE_MATERIALS)
|
||||
if(material == substance) allowed = TRUE
|
||||
if(!allowed)
|
||||
return
|
||||
if(refactory.add_stored_material(S.material.name,1*S.perunit) && S.use(1))
|
||||
visible_message("<b>[name]</b> gloms over some of \the [S], absorbing it.")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/attack_hand(mob/living/L) //CHOMP Add this whole block.
|
||||
if(L.get_effective_size() >= (src.get_effective_size() + 0.5) )
|
||||
src.get_scooped(L)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/MouseDrop(var/atom/over_object) //CHOMP Add this whole block.
|
||||
if(ishuman(over_object) && usr == src && src.Adjacent(over_object))
|
||||
var/mob/living/carbon/human/H = over_object
|
||||
get_scooped(H, TRUE)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/MouseEntered(location,control,params)
|
||||
if(resting)
|
||||
return
|
||||
..()
|
||||
|
||||
var/global/list/disallowed_protean_accessories = list(
|
||||
/obj/item/clothing/accessory/holster,
|
||||
/obj/item/clothing/accessory/storage,
|
||||
/obj/item/clothing/accessory/armor
|
||||
)
|
||||
|
||||
// Helpers - Unsafe, WILL perform change.
|
||||
/mob/living/carbon/human/proc/nano_intoblob(force)
|
||||
if(loc == /obj/item/weapon/rig/protean) //CHOMP Add
|
||||
return //CHOMP Add
|
||||
if(!force && !isturf(loc))
|
||||
to_chat(src,"<span class='warning'>You can't change forms while inside something.</span>")
|
||||
return
|
||||
|
||||
var/panel_was_up = FALSE
|
||||
if(client?.statpanel == "Protean")
|
||||
panel_was_up = TRUE
|
||||
|
||||
handle_grasp() //It's possible to blob out before some key parts of the life loop. This results in things getting dropped at null. TODO: Fix the code so this can be done better.
|
||||
remove_micros(src, src) //Living things don't fare well in roblobs.
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob()
|
||||
if(LAZYLEN(buckled_mobs))
|
||||
for(var/buckledmob in buckled_mobs)
|
||||
riding_datum.force_dismount(buckledmob)
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
stop_pulling()
|
||||
|
||||
//Record where they should go
|
||||
var/atom/creation_spot = drop_location()
|
||||
|
||||
//Create our new blob
|
||||
var/mob/living/simple_mob/protean_blob/blob = new(creation_spot,src)
|
||||
|
||||
//Drop all our things
|
||||
var/list/things_to_drop = contents.Copy()
|
||||
var/list/things_to_not_drop = list(w_uniform,nif,l_store,r_store,wear_id,l_ear,r_ear) //And whatever else we decide for balancing.
|
||||
|
||||
/* No for now, because insta-pepperspray or flash on unblob
|
||||
if(l_hand && l_hand.w_class <= ITEMSIZE_SMALL) //Hands but only if small or smaller
|
||||
things_to_not_drop += l_hand
|
||||
if(r_hand && r_hand.w_class <= ITEMSIZE_SMALL)
|
||||
things_to_not_drop += r_hand
|
||||
*/
|
||||
|
||||
things_to_drop -= things_to_not_drop //Crunch the lists
|
||||
things_to_drop -= organs //Mah armbs
|
||||
things_to_drop -= internal_organs //Mah sqeedily spooch
|
||||
for(var/obj/item/weapon/rig/protean/O in things_to_drop) //CHOMP Add
|
||||
things_to_drop -= O //CHOMP Add
|
||||
|
||||
for(var/obj/item/I in things_to_drop) //rip hoarders
|
||||
drop_from_inventory(I)
|
||||
|
||||
if(w_uniform && istype(w_uniform,/obj/item/clothing)) //No webbings tho. We do this after in case a suit was in the way
|
||||
var/obj/item/clothing/uniform = w_uniform
|
||||
if(LAZYLEN(uniform.accessories))
|
||||
for(var/obj/item/clothing/accessory/A in uniform.accessories)
|
||||
if(is_type_in_list(A, disallowed_protean_accessories))
|
||||
uniform.remove_accessory(null,A) //First param is user, but adds fingerprints and messages
|
||||
|
||||
//Size update
|
||||
blob.transform = matrix()*size_multiplier
|
||||
blob.size_multiplier = size_multiplier
|
||||
|
||||
if(l_hand) blob.prev_left_hand = l_hand //Won't save them if dropped above, but necessary if handdrop is disabled.
|
||||
if(r_hand) blob.prev_right_hand = r_hand
|
||||
|
||||
//Put our owner in it (don't transfer var/mind)
|
||||
blob.ckey = ckey
|
||||
blob.ooc_notes = ooc_notes
|
||||
temporary_form = blob
|
||||
|
||||
//Mail them to nullspace
|
||||
moveToNullspace()
|
||||
|
||||
//Message
|
||||
blob.visible_message("<b>[src.name]</b> collapses into a gooey blob!")
|
||||
|
||||
//Duration of the to_puddle iconstate that the blob starts with
|
||||
sleep(13)
|
||||
blob.update_icon() //Will remove the collapse anim
|
||||
|
||||
//Transfer vore organs
|
||||
blob.vore_organs = vore_organs
|
||||
blob.vore_selected = vore_selected
|
||||
for(var/obj/belly/B as anything in vore_organs)
|
||||
B.forceMove(blob)
|
||||
B.owner = blob
|
||||
|
||||
//We can still speak our languages!
|
||||
blob.languages = languages.Copy()
|
||||
|
||||
//Flip them to the protean panel
|
||||
if(panel_was_up)
|
||||
client?.statpanel = "Protean"
|
||||
|
||||
//Return our blob in case someone wants it
|
||||
return blob
|
||||
|
||||
//For some reason, there's no way to force drop all the mobs grabbed. This ought to fix that. And be moved elsewhere. Call with caution, doesn't handle cycles.
|
||||
/proc/remove_micros(var/src, var/mob/root)
|
||||
for(var/obj/item/I in src)
|
||||
remove_micros(I, root) //Recursion. I'm honestly depending on there being no containment loop, but at the cost of performance that can be fixed too.
|
||||
if(istype(I, /obj/item/weapon/holder))
|
||||
root.remove_from_mob(I)
|
||||
|
||||
//CHOMP Add start
|
||||
/mob/living/simple_mob/protean_blob/proc/rig_transform() //CHOMP Add this whole block.
|
||||
set name = "Modify Form - Hardsuit"
|
||||
set desc = "Allows a protean blob to solidify its form into one extremely similar to a hardsuit."
|
||||
set category = "Abilities"
|
||||
|
||||
if(istype(loc, /obj/item/weapon/rig/protean))
|
||||
var/obj/item/weapon/rig/protean/prig = loc
|
||||
src.forceMove(get_turf(prig))
|
||||
qdel(prig)
|
||||
return
|
||||
|
||||
if(isturf(loc))
|
||||
var/obj/item/weapon/rig/protean/prig = new(loc)
|
||||
if(prig)
|
||||
prig.forceMove(get_turf(src))
|
||||
src.forceMove(prig)
|
||||
return
|
||||
|
||||
/mob/living/proc/usehardsuit()
|
||||
set name = "Utilize Hardsuit Interface"
|
||||
set desc = "Allows a protean blob to open hardsuit interface."
|
||||
set category = "Abilities"
|
||||
|
||||
if(istype(loc, /obj/item/weapon/rig/protean))
|
||||
var/obj/item/weapon/rig/protean/prig = loc
|
||||
to_chat(src, "You attempt to interface with the [prig].")
|
||||
prig.ui_interact(src, interactive_state)
|
||||
else
|
||||
to_chat(src, "You are not in RIG form.")
|
||||
//CHOMP Add end
|
||||
|
||||
/mob/living/carbon/human/proc/nano_outofblob(var/mob/living/simple_mob/protean_blob/blob, force)
|
||||
if(!istype(blob))
|
||||
return
|
||||
if(blob.loc == /obj/item/weapon/rig/protean) //CHOMP Add
|
||||
return //CHOMP Add
|
||||
if(!force && !isturf(blob.loc))
|
||||
to_chat(blob,"<span class='warning'>You can't change forms while inside something.</span>")
|
||||
return
|
||||
|
||||
var/panel_was_up = FALSE
|
||||
if(client?.statpanel == "Protean")
|
||||
panel_was_up = TRUE
|
||||
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob()
|
||||
if(LAZYLEN(buckled_mobs))
|
||||
for(var/buckledmob in buckled_mobs)
|
||||
riding_datum.force_dismount(buckledmob)
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
stop_pulling()
|
||||
|
||||
//Stop healing if we are
|
||||
if(blob.healing)
|
||||
blob.healing.expire()
|
||||
|
||||
//Play the animation
|
||||
blob.icon_state = "from_puddle"
|
||||
|
||||
//Message
|
||||
blob.visible_message("<b>[src.name]</b> reshapes into a humanoid appearance!")
|
||||
|
||||
//Duration of above animation
|
||||
sleep(8)
|
||||
|
||||
//Record where they should go
|
||||
var/atom/reform_spot = blob.drop_location()
|
||||
|
||||
//Size update
|
||||
resize(blob.size_multiplier, FALSE, ignore_prefs = TRUE)
|
||||
|
||||
//Move them back where the blob was
|
||||
forceMove(reform_spot)
|
||||
|
||||
//Put our owner in it (don't transfer var/mind)
|
||||
ckey = blob.ckey
|
||||
ooc_notes = blob.ooc_notes // Lets give the protean any updated notes from blob form.
|
||||
temporary_form = null
|
||||
|
||||
//Transfer vore organs
|
||||
vore_selected = blob.vore_selected
|
||||
for(var/obj/belly/B as anything in blob.vore_organs)
|
||||
B.forceMove(src)
|
||||
B.owner = src
|
||||
|
||||
if(blob.prev_left_hand) put_in_l_hand(blob.prev_left_hand) //The restore for when reforming.
|
||||
if(blob.prev_right_hand) put_in_r_hand(blob.prev_right_hand)
|
||||
|
||||
Life(1) //Fix my blindness right meow //Has to be moved up here, there exists a circumstance where blob could be deleted without vore organs moving right.
|
||||
|
||||
//Get rid of friend blob
|
||||
qdel(blob)
|
||||
|
||||
//Flip them to the protean panel
|
||||
if(panel_was_up)
|
||||
client?.statpanel = "Protean"
|
||||
|
||||
//Return ourselves in case someone wants it
|
||||
return src
|
||||
@@ -0,0 +1,507 @@
|
||||
//TODO: Replace ventcrawl with morphing. /mob/living/simple_mob/vore/hostile/morph
|
||||
#define PER_LIMB_STEEL_COST SHEET_MATERIAL_AMOUNT
|
||||
////
|
||||
// One-part Refactor
|
||||
////
|
||||
/mob/living/carbon/human/proc/nano_partswap()
|
||||
set name = "Ref - Single Limb"
|
||||
set desc = "Allows you to replace and reshape your limbs as you see fit."
|
||||
set category = "Abilities"
|
||||
set hidden = TRUE
|
||||
|
||||
if(stat)
|
||||
to_chat(src,"<span class='warning'>You must be awake and standing to perform this action!</span>")
|
||||
return
|
||||
|
||||
if(!isturf(loc))
|
||||
to_chat(src,"<span class='warning'>You need more space to perform this action!</span>")
|
||||
return
|
||||
|
||||
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
|
||||
//Missing the organ that does this
|
||||
if(!istype(refactory))
|
||||
to_chat(src,"<span class='warning'>You don't have a working refactory module!</span>")
|
||||
return
|
||||
var/choice = tgui_input_list(src,"Pick the bodypart to change:", "Refactor - One Bodypart", species.has_limbs)
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
//Organ is missing, needs restoring
|
||||
if(!organs_by_name[choice] || istype(organs_by_name[choice], /obj/item/organ/external/stump)) //allows limb stumps to regenerate like removed limbs.
|
||||
if(refactory.get_stored_material(MAT_STEEL) < PER_LIMB_STEEL_COST)
|
||||
to_chat(src,"<span class='warning'>You're missing that limb, and need to store at least [PER_LIMB_STEEL_COST] steel to regenerate it.</span>")
|
||||
return
|
||||
var/regen = tgui_alert(src,"That limb is missing, do you want to regenerate it in exchange for [PER_LIMB_STEEL_COST] steel?","Regenerate limb?",list("Yes","No"))
|
||||
if(regen != "Yes")
|
||||
return
|
||||
if(!refactory.use_stored_material(MAT_STEEL,PER_LIMB_STEEL_COST))
|
||||
return
|
||||
if(organs_by_name[choice])
|
||||
var/obj/item/organ/external/oldlimb = organs_by_name[choice]
|
||||
oldlimb.removed()
|
||||
qdel(oldlimb)
|
||||
|
||||
var/mob/living/simple_mob/protean_blob/blob = nano_intoblob()
|
||||
active_regen = TRUE
|
||||
if(do_after(blob,5 SECONDS))
|
||||
var/list/limblist = species.has_limbs[choice]
|
||||
var/limbpath = limblist["path"]
|
||||
var/obj/item/organ/external/new_eo = new limbpath(src)
|
||||
organs_by_name[choice] = new_eo
|
||||
new_eo.robotize(synthetic ? synthetic.company : null) //Use the base we started with
|
||||
new_eo.sync_colour_to_human(src)
|
||||
regenerate_icons()
|
||||
active_regen = FALSE
|
||||
nano_outofblob(blob)
|
||||
return
|
||||
|
||||
//Organ exists, let's reshape it
|
||||
var/list/usable_manufacturers = list()
|
||||
for(var/company in chargen_robolimbs)
|
||||
var/datum/robolimb/M = chargen_robolimbs[company]
|
||||
if(!(choice in M.parts))
|
||||
continue
|
||||
if(impersonate_bodytype in M.species_cannot_use)
|
||||
continue
|
||||
if(M.whitelisted_to && !(ckey in M.whitelisted_to))
|
||||
continue
|
||||
usable_manufacturers[company] = M
|
||||
if(!usable_manufacturers.len)
|
||||
return
|
||||
var/manu_choice = tgui_input_list(src, "Which manufacturer do you wish to mimic for this limb?", "Manufacturer for [choice]", usable_manufacturers)
|
||||
|
||||
if(!manu_choice)
|
||||
return //Changed mind
|
||||
|
||||
var/obj/item/organ/external/eo = organs_by_name[choice]
|
||||
if(!eo)
|
||||
return //Lost it meanwhile
|
||||
|
||||
eo.robotize(manu_choice)
|
||||
visible_message("<B>[src]</B>'s [choice] loses its shape, then reforms.")
|
||||
update_icons_body()
|
||||
|
||||
////
|
||||
// Full Refactor
|
||||
////
|
||||
/*
|
||||
/mob/living/carbon/human/proc/nano_regenerate()
|
||||
set name = "Regenerate"
|
||||
set desc = "Allows you to regrow limbs and replace organs."
|
||||
set category = "Abilities"
|
||||
set hidden = TRUE
|
||||
|
||||
if(nutrition < 250)
|
||||
to_chat(src, "<span class='warning'>You lack the energy to begin regeneration!</span>")
|
||||
return
|
||||
|
||||
if(active_regen)
|
||||
to_chat(src, "<span class='warning'>You are already regenerating!</span>")
|
||||
return
|
||||
else
|
||||
active_regen = TRUE
|
||||
src.visible_message("<B>[src]</B>'s nanites begin to regenerate...")
|
||||
|
||||
|
||||
var/mob/living/simple_mob/protean_blob/blob = nano_intoblob()
|
||||
var/delay_length = round(active_regen_delay * species.active_regen_mult)
|
||||
if(do_after(blob, delay_length, null, 0))
|
||||
if(stat != DEAD)
|
||||
adjust_nutrition(-200)
|
||||
species.create_organs(src)
|
||||
var/obj/item/organ/external/torso = organs_by_name[BP_TORSO]
|
||||
torso.robotize() //synthetic wasn't defined here.
|
||||
LAZYCLEARLIST(blood_DNA)
|
||||
LAZYCLEARLIST(feet_blood_DNA)
|
||||
blood_color = null
|
||||
feet_blood_color = null
|
||||
regenerate_icons() //Probably worth it, yeah.
|
||||
to_chat(src, "<span class='notice'>Your regeneration is complete.</span>") //Guarantees the message shows no matter how bad the timing.
|
||||
to_chat(blob, "<span class='notice'>Your regeneration is complete!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='critical'>Your regeneration has failed.</span>")
|
||||
to_chat(blob, "<span class='critical'>Your regeneration has failed!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='critical'>Your regeneration is interrupted.</span>")
|
||||
to_chat(blob, "<span class='critical'>Your regeneration is interrupted!</span>")
|
||||
active_regen = FALSE
|
||||
nano_outofblob(blob)
|
||||
|
||||
|
||||
|
||||
var/delay_length = round(active_regen_delay * species.active_regen_mult)
|
||||
if(do_after(src,delay_length))
|
||||
adjust_nutrition(-200)
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
if(I.robotic >= ORGAN_ROBOT) // No free robofix.
|
||||
continue
|
||||
if(I.damage > 0)
|
||||
I.damage = max(I.damage - 30, 0) //Repair functionally half of a dead internal organ.
|
||||
I.status = 0 // Wipe status, as it's being regenerated from possibly dead.
|
||||
to_chat(src, "<span class='notice'>You feel a soothing sensation within your [I.name]...</span>")
|
||||
|
||||
// Replace completely missing limbs.
|
||||
for(var/limb_type in src.species.has_limbs)
|
||||
var/obj/item/organ/external/E = src.organs_by_name[limb_type]
|
||||
|
||||
if(E && E.disfigured)
|
||||
E.disfigured = 0
|
||||
if(E && (E.is_stump() || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED))))
|
||||
E.removed()
|
||||
qdel(E)
|
||||
E = null
|
||||
if(!E)
|
||||
var/list/organ_data = src.species.has_limbs[limb_type]
|
||||
var/limb_path = organ_data["path"]
|
||||
var/obj/item/organ/O = new limb_path(src)
|
||||
organ_data["descriptor"] = O.name
|
||||
to_chat(src, "<span class='notice'>You feel a slithering sensation as your [O.name] reform.</span>")
|
||||
|
||||
var/agony_to_apply = round(0.66 * O.max_damage) // 66% of the limb's health is converted into pain.
|
||||
src.apply_damage(agony_to_apply, HALLOSS)
|
||||
|
||||
for(var/organtype in species.has_organ) // Replace completely missing internal organs. -After- external ones, so they all should exist.
|
||||
if(!src.internal_organs_by_name[organtype])
|
||||
var/organpath = species.has_organ[organtype]
|
||||
var/obj/item/organ/Int = new organpath(src, TRUE)
|
||||
|
||||
Int.rejuvenate(TRUE)
|
||||
|
||||
handle_organs() // Update everything
|
||||
|
||||
update_icons_body()
|
||||
active_regen = FALSE
|
||||
else
|
||||
to_chat(src, "<span class='critical'>Your regeneration is interrupted!</span>")
|
||||
adjust_nutrition(-75)
|
||||
active_regen = FALSE
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/proc/nano_regenerate() //fixed the proc, it used to leave active_regen true.
|
||||
set name = "Ref - Whole Body"
|
||||
set desc = "Allows you to regrow limbs and replace organs, given you have enough materials."
|
||||
set category = "Abilities"
|
||||
set hidden = TRUE
|
||||
|
||||
|
||||
|
||||
if(stat)
|
||||
to_chat(src,"<span class='warning'>You must be awake and standing to perform this action!</span>")
|
||||
return
|
||||
|
||||
if(!isturf(loc))
|
||||
to_chat(src,"<span class='warning'>You need more space to perform this action!</span>")
|
||||
return
|
||||
|
||||
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
|
||||
//Missing the organ that does this
|
||||
if(!istype(refactory))
|
||||
to_chat(src,"<span class='warning'>You don't have a working refactory module!</span>")
|
||||
return
|
||||
|
||||
//Already regenerating
|
||||
if(active_regen)
|
||||
to_chat(src, "<span class='warning'>You are already refactoring!</span>")
|
||||
return
|
||||
|
||||
var/swap_not_rebuild = tgui_alert(src,"Do you want to rebuild, or reshape?","Rebuild or Reshape",list("Reshape","Cancel","Rebuild"))
|
||||
if(swap_not_rebuild == "Cancel")
|
||||
return
|
||||
if(swap_not_rebuild == "Reshape")
|
||||
var/list/usable_manufacturers = list()
|
||||
for(var/company in chargen_robolimbs)
|
||||
var/datum/robolimb/M = chargen_robolimbs[company]
|
||||
if(!(BP_TORSO in M.parts))
|
||||
continue
|
||||
if(impersonate_bodytype in M.species_cannot_use)
|
||||
continue
|
||||
if(M.whitelisted_to && !(ckey in M.whitelisted_to))
|
||||
continue
|
||||
usable_manufacturers[company] = M
|
||||
if(!usable_manufacturers.len)
|
||||
return
|
||||
var/manu_choice = tgui_input_list(src, "Which manufacturer do you wish to mimic?", "Manufacturer", usable_manufacturers)
|
||||
|
||||
if(!manu_choice)
|
||||
return //Changed mind
|
||||
if(!organs_by_name[BP_TORSO])
|
||||
return //Ain't got a torso!
|
||||
|
||||
var/obj/item/organ/external/torso = organs_by_name[BP_TORSO]
|
||||
to_chat(src, "<span class='danger'>Remain still while the process takes place! It will take 5 seconds.</span>")
|
||||
visible_message("<B>[src]</B>'s form collapses into an amorphous blob of black ichor...")
|
||||
|
||||
var/mob/living/simple_mob/protean_blob/blob = nano_intoblob()
|
||||
active_regen = TRUE
|
||||
if(do_after(blob,5 SECONDS))
|
||||
synthetic = usable_manufacturers[manu_choice]
|
||||
torso.robotize(manu_choice) //Will cascade to all other organs.
|
||||
regenerate_icons()
|
||||
visible_message("<B>[src]</B>'s form reshapes into a new one...")
|
||||
active_regen = FALSE
|
||||
nano_outofblob(blob)
|
||||
return
|
||||
|
||||
//Not enough resources (AND spends the resources, should be the last check)
|
||||
if(!refactory.use_stored_material(MAT_STEEL,refactory.max_storage))
|
||||
to_chat(src, "<span class='warning'>You need to be maxed out on normal metal to do this!</span>")
|
||||
return
|
||||
|
||||
var/delay_length = round(active_regen_delay * species.active_regen_mult)
|
||||
to_chat(src, "<span class='danger'>Remain still while the process takes place! It will take [delay_length/10] seconds.</span>")
|
||||
visible_message("<B>[src]</B>'s form begins to shift and ripple as if made of oil...")
|
||||
active_regen = TRUE
|
||||
|
||||
var/mob/living/simple_mob/protean_blob/blob = nano_intoblob()
|
||||
if(do_after(blob, delay_length, null, 0))
|
||||
if(stat != DEAD && refactory)
|
||||
var/list/holder = refactory.materials
|
||||
species.create_organs(src)
|
||||
var/obj/item/organ/external/torso = organs_by_name[BP_TORSO]
|
||||
torso.robotize() //synthetic wasn't defined here.
|
||||
LAZYCLEARLIST(blood_DNA)
|
||||
LAZYCLEARLIST(feet_blood_DNA)
|
||||
blood_color = null
|
||||
feet_blood_color = null
|
||||
regenerate_icons() //Probably worth it, yeah.
|
||||
var/obj/item/organ/internal/nano/refactory/new_refactory = locate() in internal_organs
|
||||
if(!new_refactory)
|
||||
log_debug("[src] protean-regen'd but lacked a refactory when done.")
|
||||
else
|
||||
new_refactory.materials = holder
|
||||
to_chat(src, "<span class='notice'>Your refactoring is complete.</span>") //Guarantees the message shows no matter how bad the timing.
|
||||
to_chat(blob, "<span class='notice'>Your refactoring is complete!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='critical'>Your refactoring has failed.</span>")
|
||||
to_chat(blob, "<span class='critical'>Your refactoring has failed!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='critical'>Your refactoring is interrupted.</span>")
|
||||
to_chat(blob, "<span class='critical'>Your refactoring is interrupted!</span>")
|
||||
active_regen = FALSE
|
||||
nano_outofblob(blob)
|
||||
|
||||
////
|
||||
// Storing metal
|
||||
////
|
||||
/mob/living/carbon/human/proc/nano_metalnom()
|
||||
set name = "Ref - Store Metals"
|
||||
set desc = "If you're holding a stack of material, you can consume some and store it for later."
|
||||
set category = "Abilities"
|
||||
set hidden = TRUE
|
||||
|
||||
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
|
||||
//Missing the organ that does this
|
||||
if(!istype(refactory))
|
||||
to_chat(src,"<span class='warning'>You don't have a working refactory module!</span>")
|
||||
return
|
||||
|
||||
var/held = get_active_hand()
|
||||
if(!istype(held,/obj/item/stack/material))
|
||||
to_chat(src,"<span class='warning'>You aren't holding a stack of materials in your active hand...!</span>")
|
||||
return
|
||||
|
||||
var/obj/item/stack/material/matstack = held
|
||||
var/substance = matstack.material.name
|
||||
var allowed = FALSE
|
||||
for(var/material in PROTEAN_EDIBLE_MATERIALS)
|
||||
if(material == substance) allowed = TRUE
|
||||
if(!allowed)
|
||||
to_chat(src,"<span class='warning'>You can't process [substance]!</span>")
|
||||
return //Only a few things matter, the rest are best not cluttering the lists.
|
||||
|
||||
var/howmuch = input(src,"How much do you want to store? (0-[matstack.get_amount()])","Select amount") as null|num
|
||||
if(!howmuch || matstack != get_active_hand() || howmuch > matstack.get_amount())
|
||||
return //Quietly fail
|
||||
|
||||
var/actually_added = refactory.add_stored_material(substance,howmuch*matstack.perunit)
|
||||
matstack.use(CEILING((actually_added/matstack.perunit), 1))
|
||||
if(actually_added && actually_added < howmuch)
|
||||
to_chat(src,"<span class='warning'>Your refactory module is now full, so only [actually_added] units were stored.</span>")
|
||||
visible_message("<span class='notice'>[src] nibbles some of the [substance] right off the stack!</span>")
|
||||
else if(actually_added)
|
||||
to_chat(src,"<span class='notice'>You store [actually_added] units of [substance].</span>")
|
||||
visible_message("<span class='notice'>[src] devours some of the [substance] right off the stack!</span>")
|
||||
else
|
||||
to_chat(src,"<span class='notice'>You're completely capped out on [substance]!</span>")
|
||||
|
||||
////
|
||||
// Blob Form
|
||||
////
|
||||
/mob/living/carbon/human/proc/nano_blobform()
|
||||
set name = "Toggle Blobform"
|
||||
set desc = "Switch between amorphous and humanoid forms."
|
||||
set category = "Abilities"
|
||||
set hidden = TRUE
|
||||
|
||||
var/atom/movable/to_locate = temporary_form || src
|
||||
if(!isturf(to_locate.loc))
|
||||
to_chat(to_locate,"<span class='warning'>You need more space to perform this action!</span>")
|
||||
return
|
||||
|
||||
//Blob form
|
||||
if(temporary_form)
|
||||
if(health < maxHealth*0.5)
|
||||
to_chat(temporary_form,"<span class='warning'>You need to regenerate more nanites first!</span>")
|
||||
else if(temporary_form.stat)
|
||||
to_chat(temporary_form,"<span class='warning'>You can only do this while not stunned.</span>")
|
||||
else
|
||||
nano_outofblob(temporary_form)
|
||||
|
||||
//Human form
|
||||
else if(stat)
|
||||
to_chat(src,"<span class='warning'>You can only do this while not stunned.</span>")
|
||||
return
|
||||
else
|
||||
nano_intoblob()
|
||||
|
||||
////
|
||||
// Change fitting
|
||||
////
|
||||
/mob/living/carbon/human/proc/nano_change_fitting()
|
||||
set name = "Change Species Fit"
|
||||
set desc = "Tweak your shape to change what suits you fit into (and their sprites!)."
|
||||
set category = "Abilities"
|
||||
|
||||
if(stat)
|
||||
to_chat(src,"<span class='warning'>You must be awake and standing to perform this action!</span>")
|
||||
return
|
||||
|
||||
var/new_species = tgui_input_list(usr, "Please select a species to emulate.", "Shapeshifter Body", GLOB.playable_species)
|
||||
if(new_species)
|
||||
impersonate_bodytype = new_species
|
||||
species?.base_species = new_species // Really though you better have a species
|
||||
regenerate_icons() //Expensive, but we need to recrunch all the icons we're wearing
|
||||
|
||||
////
|
||||
// Change size
|
||||
////
|
||||
/*CHOMP Removal start - I am replacing this with the OG set size. No more metal requirement.
|
||||
/mob/living/carbon/human/proc/nano_set_size()
|
||||
set name = "Adjust Volume"
|
||||
set category = "Abilities"
|
||||
set hidden = TRUE
|
||||
|
||||
var/mob/living/user = temporary_form || src
|
||||
|
||||
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
|
||||
//Missing the organ that does this
|
||||
if(!istype(refactory))
|
||||
to_chat(user,"<span class='warning'>You don't have a working refactory module!</span>")
|
||||
return
|
||||
|
||||
var/nagmessage = "Adjust your mass to be a size between 25 to 200% (or between 1 to 600% in dorms area). Up-sizing consumes metal, downsizing returns metal."
|
||||
var/new_size = input(user, nagmessage, "Pick a Size", user.size_multiplier*100) as num|null
|
||||
if(!new_size || !size_range_check(new_size))
|
||||
return
|
||||
|
||||
var/size_factor = new_size/100
|
||||
|
||||
//Will be: -1.75 for 200->25, and 1.75 for 25->200
|
||||
var/sizediff = size_factor - user.size_multiplier
|
||||
|
||||
//Negative if shrinking, positive if growing
|
||||
//Will be (PLSC*2)*-1.75 to 1.75
|
||||
//For 2000 PLSC that's -7000 to 7000
|
||||
var/cost = (PER_LIMB_STEEL_COST*2)*sizediff
|
||||
|
||||
//Sizing up
|
||||
if(cost > 0)
|
||||
if(refactory.use_stored_material(MAT_STEEL,cost))
|
||||
user.resize(size_factor, ignore_prefs = TRUE)
|
||||
else
|
||||
to_chat(user,"<span class='warning'>That size change would cost [cost] steel, which you don't have.</span>")
|
||||
//Sizing down (or not at all)
|
||||
else if(cost <= 0)
|
||||
cost = abs(cost)
|
||||
var/actually_added = refactory.add_stored_material(MAT_STEEL,cost)
|
||||
user.resize(size_factor, ignore_prefs = TRUE)
|
||||
if(actually_added != cost)
|
||||
to_chat(user,"<span class='warning'>Unfortunately, [cost-actually_added] steel was lost due to lack of storage space.</span>")
|
||||
|
||||
user.visible_message("<span class='notice'>Black mist swirls around [user] as they change size.</span>")
|
||||
CHOMP Removal end*/
|
||||
|
||||
/// /// /// A helper to reuse
|
||||
/mob/living/proc/nano_get_refactory(obj/item/organ/internal/nano/refactory/R)
|
||||
if(istype(R))
|
||||
if(!(R.status & ORGAN_DEAD))
|
||||
return R
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/protean_blob/nano_get_refactory()
|
||||
if(refactory)
|
||||
return ..(refactory)
|
||||
if(humanform)
|
||||
return humanform.nano_get_refactory()
|
||||
|
||||
/mob/living/carbon/human/nano_get_refactory()
|
||||
return ..(locate(/obj/item/organ/internal/nano/refactory) in internal_organs)
|
||||
|
||||
|
||||
|
||||
/// /// /// Ability objects for stat panel
|
||||
/obj/effect/protean_ability
|
||||
name = "Activate"
|
||||
desc = ""
|
||||
icon = 'icons/mob/species/protean/protean_powers.dmi'
|
||||
var/ability_name
|
||||
var/to_call
|
||||
|
||||
/obj/effect/protean_ability/proc/atom_button_text()
|
||||
return src
|
||||
|
||||
/obj/effect/protean_ability/Click(var/location, var/control, var/params)
|
||||
var/list/clickprops = params2list(params)
|
||||
var/opts = clickprops["shift"]
|
||||
|
||||
if(opts)
|
||||
to_chat(usr,"<span class='notice'><b>[ability_name]</b> - [desc]</span>")
|
||||
else
|
||||
//Humanform using it
|
||||
if(ishuman(usr))
|
||||
do_ability(usr)
|
||||
//Blobform using it
|
||||
else
|
||||
var/mob/living/simple_mob/protean_blob/blob = usr
|
||||
do_ability(blob.humanform)
|
||||
|
||||
/obj/effect/protean_ability/proc/do_ability(var/mob/living/L)
|
||||
if(istype(L))
|
||||
call(L,to_call)()
|
||||
return FALSE
|
||||
|
||||
/// The actual abilities
|
||||
/obj/effect/protean_ability/into_blob
|
||||
ability_name = "Toggle Blobform"
|
||||
desc = "Discard your shape entirely, changing to a low-energy blob that can fit into small spaces. You'll consume steel to repair yourself in this form."
|
||||
icon_state = "blob"
|
||||
to_call = /mob/living/carbon/human/proc/nano_blobform
|
||||
|
||||
/*CHOMP removal start - This doesn't do anything at all now. Normal resize proc is being used instead.
|
||||
/obj/effect/protean_ability/change_volume //CHOMP Edit
|
||||
ability_name = "Change Volume"
|
||||
desc = "Alter your size between 25% and 200%." //CHOMP Edit - Removed talk about requiring metal
|
||||
icon_state = "volume"
|
||||
to_call = /mob/living/carbon/human/proc/nano_set_size
|
||||
CHOMP removal end*/
|
||||
|
||||
/obj/effect/protean_ability/reform_limb
|
||||
ability_name = "Ref - Single Limb"
|
||||
desc = "Rebuild or replace a single limb, assuming you have 2000 steel."
|
||||
icon_state = "limb"
|
||||
to_call = /mob/living/carbon/human/proc/nano_partswap
|
||||
|
||||
/obj/effect/protean_ability/reform_body
|
||||
ability_name = "Ref - Whole Body"
|
||||
desc = "Rebuild your entire body into whatever design you want, assuming you have 10,000 metal."
|
||||
icon_state = "body"
|
||||
to_call = /mob/living/carbon/human/proc/nano_regenerate
|
||||
|
||||
/obj/effect/protean_ability/metal_nom
|
||||
ability_name = "Ref - Store Metals"
|
||||
desc = "Store the metal you're holding. Your refactory can only store steel, and all other metals will be converted into nanites ASAP for various effects."
|
||||
icon_state = "metal"
|
||||
to_call = /mob/living/carbon/human/proc/nano_metalnom
|
||||
|
||||
#undef PER_LIMB_STEEL_COST
|
||||
@@ -0,0 +1,383 @@
|
||||
#define DAM_SCALE_FACTOR 0.01
|
||||
#define METAL_PER_TICK 100
|
||||
/datum/species/protean
|
||||
name = SPECIES_PROTEAN
|
||||
name_plural = "Proteans"
|
||||
blurb = "Sometimes very advanced civilizations will produce the ability to swap into manufactured, robotic bodies. And sometimes \
|
||||
<i>VERY</i> advanced civilizations have the option of 'nanoswarm' bodies. Effectively a single robot body comprised \
|
||||
of millions of tiny nanites working in concert to maintain cohesion."
|
||||
show_ssd = "totally quiescent"
|
||||
death_message = "rapidly loses cohesion, dissolving into a cloud of gray dust..."
|
||||
knockout_message = "collapses inwards, forming a disordered puddle of gray goo."
|
||||
remains_type = /obj/effect/decal/cleanable/ash
|
||||
|
||||
blood_color = "#505050" //This is the same as the 80,80,80 below, but in hex
|
||||
flesh_color = "#505050"
|
||||
base_color = "#FFFFFF" //Color mult, start out with this
|
||||
|
||||
flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT | NO_HALLUCINATION | NO_INFECT | NO_PAIN
|
||||
appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | HAS_UNDERWEAR | HAS_LIPS
|
||||
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE
|
||||
health_hud_intensity = 2
|
||||
num_alternate_languages = 3
|
||||
assisted_langs = list(LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
|
||||
color_mult = TRUE
|
||||
|
||||
breath_type = null
|
||||
poison_type = null
|
||||
|
||||
male_scream_sound = null //CHOMPedit
|
||||
female_scream_sound = null //CHOMPedit
|
||||
|
||||
virus_immune = 1
|
||||
blood_volume = 0
|
||||
min_age = 18
|
||||
max_age = 200
|
||||
brute_mod = 0.8
|
||||
burn_mod = 1.5
|
||||
oxy_mod = 0
|
||||
item_slowdown_mod = 1.33
|
||||
|
||||
cold_level_1 = 280 //Default 260 - Lower is better
|
||||
cold_level_2 = 220 //Default 200
|
||||
cold_level_3 = 130 //Default 120
|
||||
|
||||
heat_level_1 = 320 //Default 360
|
||||
heat_level_2 = 370 //Default 400
|
||||
heat_level_3 = 600 //Default 1000
|
||||
|
||||
hazard_low_pressure = -1 //Space doesn't bother them
|
||||
hazard_high_pressure = 200 //They can cope with slightly higher pressure
|
||||
|
||||
//Cold/heat does affect them, but it's done in special ways below
|
||||
cold_level_1 = -INFINITY
|
||||
cold_level_2 = -INFINITY
|
||||
cold_level_3 = -INFINITY
|
||||
heat_level_1 = INFINITY
|
||||
heat_level_2 = INFINITY
|
||||
heat_level_3 = INFINITY
|
||||
|
||||
body_temperature = 290
|
||||
|
||||
siemens_coefficient = 1.5 //Very bad zappy times
|
||||
rarity_value = 5
|
||||
|
||||
genders = list(MALE, FEMALE, PLURAL, NEUTER)
|
||||
|
||||
has_organ = list(
|
||||
O_BRAIN = /obj/item/organ/internal/mmi_holder/posibrain/nano,
|
||||
O_ORCH = /obj/item/organ/internal/nano/orchestrator,
|
||||
O_FACT = /obj/item/organ/internal/nano/refactory,
|
||||
)
|
||||
has_limbs = list(
|
||||
BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable/nano),
|
||||
BP_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable/nano),
|
||||
BP_HEAD = list("path" = /obj/item/organ/external/head/unbreakable/nano),
|
||||
BP_L_ARM = list("path" = /obj/item/organ/external/arm/unbreakable/nano),
|
||||
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/unbreakable/nano),
|
||||
BP_L_LEG = list("path" = /obj/item/organ/external/leg/unbreakable/nano),
|
||||
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/unbreakable/nano),
|
||||
BP_L_HAND = list("path" = /obj/item/organ/external/hand/unbreakable/nano),
|
||||
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/unbreakable/nano),
|
||||
BP_L_FOOT = list("path" = /obj/item/organ/external/foot/unbreakable/nano),
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable/nano)
|
||||
)
|
||||
|
||||
heat_discomfort_strings = list("You feel too warm.")
|
||||
cold_discomfort_strings = list("You feel too cool.")
|
||||
|
||||
//These verbs are hidden, for hotkey use only
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/nano_regenerate, //These verbs are hidden so you can macro them,
|
||||
/mob/living/carbon/human/proc/nano_partswap,
|
||||
/mob/living/carbon/human/proc/nano_metalnom,
|
||||
/mob/living/carbon/human/proc/nano_blobform,
|
||||
/mob/living/proc/set_size,
|
||||
/mob/living/carbon/human/proc/nano_change_fitting, //These verbs are displayed normally,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_hair,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_hair_colors,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_colour,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_eye_colour,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_gender,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_wings,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_tail,
|
||||
/mob/living/carbon/human/proc/shapeshifter_select_ears,
|
||||
/mob/living/carbon/human/proc/succubus_drain,
|
||||
/mob/living/carbon/human/proc/slime_feed,
|
||||
/mob/living/carbon/human/proc/succubus_drain_finalize,
|
||||
/mob/living/carbon/human/proc/succubus_drain_lethal,
|
||||
/mob/living/proc/eat_trash
|
||||
) //CHOMP Edit - Added succ stuff that promies have too. Also changed nano_set_size to standard set_size so there is no metal cost.
|
||||
|
||||
var/global/list/abilities = list()
|
||||
|
||||
var/monochromatic = FALSE //IGNORE ME
|
||||
|
||||
/datum/species/protean/New()
|
||||
..()
|
||||
if(!LAZYLEN(abilities))
|
||||
var/list/powertypes = subtypesof(/obj/effect/protean_ability)
|
||||
for(var/path in powertypes)
|
||||
abilities += new path()
|
||||
|
||||
/datum/species/protean/create_organs(var/mob/living/carbon/human/H)
|
||||
var/obj/item/device/nif/saved_nif = H.nif
|
||||
if(saved_nif)
|
||||
H.nif.unimplant(H) //Needs reference to owner to unimplant right.
|
||||
H.nif.moveToNullspace()
|
||||
..()
|
||||
if(saved_nif)
|
||||
saved_nif.quick_implant(H)
|
||||
|
||||
/datum/species/protean/get_bodytype(var/mob/living/carbon/human/H)
|
||||
if(H)
|
||||
return H.impersonate_bodytype || ..()
|
||||
return ..()
|
||||
|
||||
/datum/species/protean/handle_post_spawn(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
H.synth_color = TRUE
|
||||
|
||||
/datum/species/protean/equip_survival_gear(var/mob/living/carbon/human/H)
|
||||
..() //CHOMP Edit this calls the parent function which should spawn the survival box.
|
||||
var/obj/item/stack/material/steel/metal_stack = new()
|
||||
metal_stack.set_amount(5) //CHOMP Edit
|
||||
|
||||
var/obj/item/clothing/accessory/permit/nanotech/permit = new()
|
||||
permit.set_name(H.real_name)
|
||||
|
||||
if(H.backbag == 1) //Somewhat misleading, 1 == no bag (not boolean)
|
||||
H.equip_to_slot_or_del(permit, slot_l_hand)
|
||||
H.equip_to_slot_or_del(metal_stack, slot_r_hand)
|
||||
else
|
||||
H.equip_to_slot_or_del(permit, slot_in_backpack)
|
||||
H.equip_to_slot_or_del(metal_stack, slot_in_backpack)
|
||||
|
||||
spawn(0) //Let their real nif load if they have one
|
||||
if(!H) //Human could have been deleted in this amount of time. Observing does this, mannequins, etc.
|
||||
return
|
||||
if(!H.nif)
|
||||
var/obj/item/device/nif/protean/new_nif = new()
|
||||
new_nif.quick_implant(H)
|
||||
else
|
||||
H.nif.durability = 25
|
||||
|
||||
var/obj/item/weapon/rig/protean/prig = new /obj/item/weapon/rig/protean(H)
|
||||
prig.myprotean = H
|
||||
|
||||
/datum/species/protean/hug(var/mob/living/carbon/human/H, var/mob/living/target)
|
||||
return ..() //Wut
|
||||
|
||||
/datum/species/protean/get_blood_colour(var/mob/living/carbon/human/H)
|
||||
return rgb(80,80,80,230)
|
||||
|
||||
/datum/species/protean/get_flesh_colour(var/mob/living/carbon/human/H)
|
||||
return rgb(80,80,80,230)
|
||||
|
||||
/datum/species/protean/handle_death(var/mob/living/carbon/human/H)
|
||||
if(!H)
|
||||
return // Iono!
|
||||
|
||||
if(H.temporary_form)
|
||||
H.forceMove(H.temporary_form.drop_location())
|
||||
H.ckey = H.temporary_form.ckey
|
||||
QDEL_NULL(H.temporary_form)
|
||||
|
||||
to_chat(H, "<span class='warning'>You died as a Protean. Please sit out of the round for at least 5 or 10 minutes before respawning, to represent the time it would take to ship a new-you to the station, depending on how you died.</span>")
|
||||
|
||||
spawn(1)
|
||||
if(H)
|
||||
H.gib()
|
||||
|
||||
/datum/species/protean/handle_environment_special(var/mob/living/carbon/human/H)
|
||||
if((H.getActualBruteLoss() + H.getActualFireLoss()) > H.maxHealth*0.5 && isturf(H.loc)) //So, only if we're not a blob (we're in nullspace) or in someone (or a locker, really, but whatever)
|
||||
return ..() //Any instakill shot runtimes since there are no organs after this. No point to not skip these checks, going to nullspace anyway.
|
||||
|
||||
/*CHOMP Station removal start
|
||||
var/obj/item/organ/internal/nano/refactory/refactory = locate() in H.internal_organs
|
||||
if(refactory && !(refactory.status & ORGAN_DEAD))
|
||||
|
||||
//MHydrogen adds speeeeeed
|
||||
if(refactory.get_stored_material(MAT_METALHYDROGEN) >= METAL_PER_TICK)
|
||||
H.add_modifier(/datum/modifier/protean/mhydrogen, origin = refactory)
|
||||
|
||||
//Uranium adds brute armor
|
||||
if(refactory.get_stored_material(MAT_URANIUM) >= METAL_PER_TICK)
|
||||
H.add_modifier(/datum/modifier/protean/uranium, origin = refactory)
|
||||
|
||||
//Gold adds burn armor
|
||||
if(refactory.get_stored_material(MAT_GOLD) >= METAL_PER_TICK)
|
||||
H.add_modifier(/datum/modifier/protean/gold, origin = refactory)
|
||||
|
||||
//Silver adds accuracy and evasion
|
||||
if(refactory.get_stored_material(MAT_SILVER) >= METAL_PER_TICK)
|
||||
H.add_modifier(/datum/modifier/protean/silver, origin = refactory)
|
||||
|
||||
return ..()
|
||||
CHOMP Station removal end*/
|
||||
|
||||
/datum/species/protean/get_additional_examine_text(var/mob/living/carbon/human/H)
|
||||
return ..() //Hmm, what could be done here?
|
||||
|
||||
/datum/species/protean/Stat(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
if(statpanel("Protean"))
|
||||
var/obj/item/organ/internal/nano/refactory/refactory = H.nano_get_refactory()
|
||||
if(refactory && !(refactory.status & ORGAN_DEAD))
|
||||
stat(null, "- -- --- Refactory Metal Storage --- -- -")
|
||||
var/max = refactory.max_storage
|
||||
for(var/material in refactory.materials)
|
||||
var/amount = refactory.get_stored_material(material)
|
||||
stat("[capitalize(material)]", "[amount]/[max]")
|
||||
else
|
||||
stat(null, "- -- --- REFACTORY ERROR! --- -- -")
|
||||
|
||||
stat(null, "- -- --- Abilities (Shift+LMB Examines) --- -- -")
|
||||
for(var/obj/effect/protean_ability/A as anything in abilities)
|
||||
stat("[A.ability_name]",A.atom_button_text())
|
||||
|
||||
// Various modifiers
|
||||
/datum/modifier/protean
|
||||
stacks = MODIFIER_STACK_FORBID
|
||||
var/material_use = METAL_PER_TICK
|
||||
var/material_name = MAT_STEEL
|
||||
|
||||
/datum/modifier/protean/on_applied()
|
||||
. = ..()
|
||||
if(holder.temporary_form)
|
||||
to_chat(holder.temporary_form,on_created_text)
|
||||
|
||||
/datum/modifier/protean/on_expire()
|
||||
. = ..()
|
||||
if(holder.temporary_form)
|
||||
to_chat(holder.temporary_form,on_expired_text)
|
||||
|
||||
/datum/modifier/protean/check_if_valid()
|
||||
//No origin set
|
||||
if(!istype(origin))
|
||||
expire()
|
||||
|
||||
//No refactory
|
||||
var/obj/item/organ/internal/nano/refactory/refactory = origin.resolve()
|
||||
if(!istype(refactory) || refactory.status & ORGAN_DEAD)
|
||||
expire()
|
||||
|
||||
//Out of materials
|
||||
if(!refactory.use_stored_material(material_name,material_use))
|
||||
expire()
|
||||
|
||||
/*CHOMP Removal start
|
||||
/datum/modifier/protean/mhydrogen
|
||||
name = "Protean Effect - M.Hydrogen"
|
||||
desc = "You're affected by the presence of metallic hydrogen."
|
||||
|
||||
on_created_text = "<span class='notice'>You feel yourself accelerate, the metallic hydrogen increasing your speed temporarily.</span>"
|
||||
on_expired_text = "<span class='notice'>Your refactory finishes consuming the metallic hydrogen, and you return to normal speed.</span>"
|
||||
|
||||
material_name = MAT_METALHYDROGEN
|
||||
|
||||
slowdown = -1
|
||||
|
||||
/datum/modifier/protean/uranium
|
||||
name = "Protean Effect - Uranium"
|
||||
desc = "You're affected by the presence of uranium."
|
||||
|
||||
on_created_text = "<span class='notice'>You feel yourself become nearly impervious to physical attacks as uranium is incorporated in your nanites.</span>"
|
||||
on_expired_text = "<span class='notice'>Your refactory finishes consuming the uranium, and you return to your normal nanites.</span>"
|
||||
|
||||
material_name = MAT_URANIUM
|
||||
|
||||
incoming_brute_damage_percent = 0.8
|
||||
|
||||
/datum/modifier/protean/gold
|
||||
name = "Protean Effect - Gold"
|
||||
desc = "You're affected by the presence of gold."
|
||||
|
||||
on_created_text = "<span class='notice'>You feel yourself become more reflective, able to resist heat and fire better for a time.</span>"
|
||||
on_expired_text = "<span class='notice'>Your refactory finishes consuming the gold, and you return to your normal nanites.</span>"
|
||||
|
||||
material_name = MAT_GOLD
|
||||
|
||||
incoming_fire_damage_percent = 0.8
|
||||
|
||||
/datum/modifier/protean/silver
|
||||
name = "Protean Effect - Silver"
|
||||
desc = "You're affected by the presence of silver."
|
||||
|
||||
on_created_text = "<span class='notice'>Your physical control is improved for a time, making it easier to hit targets, and avoid being hit.</span>"
|
||||
on_expired_text = "<span class='notice'>Your refactory finishes consuming the silver, and your motor control returns to normal.</span>"
|
||||
|
||||
material_name = MAT_SILVER
|
||||
|
||||
accuracy = 30
|
||||
evasion = 30
|
||||
CHOMP Removal end*/
|
||||
|
||||
/datum/modifier/protean/steel
|
||||
name = "Protean Effect - Steel"
|
||||
desc = "You're affected by the presence of steel."
|
||||
|
||||
on_created_text = "<span class='notice'>You feel new nanites being produced from your stockpile of steel, healing you slowly.</span>"
|
||||
on_expired_text = "<span class='notice'>Your steel supply has either run out, or is no longer needed, and your healing stops.</span>"
|
||||
|
||||
material_name = MAT_STEEL
|
||||
|
||||
/datum/modifier/protean/steel/tick()
|
||||
holder.adjustBruteLoss(-1,include_robo = TRUE) //Modified by species resistances
|
||||
holder.adjustFireLoss(-0.5,include_robo = TRUE) //Modified by species resistances
|
||||
var/mob/living/carbon/human/H = holder
|
||||
for(var/obj/item/organ/O as anything in H.internal_organs)
|
||||
// Fix internal damage
|
||||
if(O.damage > 0)
|
||||
O.damage = max(0,O.damage-0.1)
|
||||
// If not damaged, but dead, fix it
|
||||
else if(O.status & ORGAN_DEAD)
|
||||
O.status &= ~ORGAN_DEAD //Unset dead if we repaired it entirely
|
||||
|
||||
|
||||
// PAN Card
|
||||
/obj/item/clothing/accessory/permit/nanotech
|
||||
name = "\improper P.A.N. card"
|
||||
desc = "This is a 'Permit for Advanced Nanotechnology' card. It allows the owner to possess and operate advanced nanotechnology on NanoTrasen property. It must be renewed on a monthly basis."
|
||||
icon = 'icons/mob/species/protean/protean.dmi'
|
||||
icon_state = "permit_pan"
|
||||
|
||||
var/validstring = "VALID THROUGH END OF: "
|
||||
var/registring = "REGISTRANT: "
|
||||
|
||||
/obj/item/clothing/accessory/permit/nanotech/set_name(var/new_name)
|
||||
owner = 1
|
||||
if(new_name)
|
||||
name += " ([new_name])"
|
||||
validstring += "[time2text(world.timeofday, "Month") +" "+ num2text(text2num(time2text(world.timeofday, "YYYY"))+544)]" //YW EDIT
|
||||
registring += "[new_name]"
|
||||
|
||||
/obj/item/clothing/accessory/permit/nanotech/examine(mob/user)
|
||||
. = ..()
|
||||
. += validstring
|
||||
. += registring
|
||||
|
||||
//CHOMP Add start
|
||||
/mob/living/carbon/human/proc/rig_transform()
|
||||
set name = "Modify Form - Hardsuit"
|
||||
set desc = "Allows a protean to solidify its form into one extremely similar to a hardsuit."
|
||||
set category = "Abilities"
|
||||
|
||||
if(istype(loc, /obj/item/weapon/rig/protean))
|
||||
var/obj/item/weapon/rig/protean/prig = loc
|
||||
src.forceMove(get_turf(prig))
|
||||
prig.forceMove(src)
|
||||
return
|
||||
|
||||
if(isturf(loc))
|
||||
var/obj/item/weapon/rig/protean/prig
|
||||
for(var/obj/item/weapon/rig/protean/O in contents)
|
||||
prig = O
|
||||
break
|
||||
if(prig)
|
||||
prig.forceMove(get_turf(src))
|
||||
src.forceMove(prig)
|
||||
return
|
||||
//CHOMP Add end
|
||||
#undef DAM_SCALE_FACTOR
|
||||
#undef METAL_PER_TICK
|
||||
Reference in New Issue
Block a user