move associated code to modular folder

This commit is contained in:
BlackMajor
2022-04-17 19:31:21 +12:00
parent 414b01d8bc
commit c8b8ff2e0f
7 changed files with 15 additions and 1 deletions

View File

@@ -0,0 +1 @@
#define PROTEAN_EDIBLE_MATERIALS list(MAT_STEEL) //CHOMPedit: only steel

View File

@@ -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'
)

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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