diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm
index 438a805b9c..692100d15f 100644
--- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm
+++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_blob.dm
@@ -54,7 +54,7 @@
humanform = H
updatehealth()
refactory = locate() in humanform.internal_organs
- verbs |= /mob/living/simple_animal/protean_blob/proc/revert_form
+ verbs |= /mob/living/proc/nano_set_size
verbs |= /mob/living/proc/ventcrawl
verbs |= /mob/living/proc/hide
else
@@ -74,29 +74,8 @@
/mob/living/simple_animal/protean_blob/Stat()
..()
- if(statpanel("Status"))
- stat(null, "- -- --- Protean Stats --- -- -")
- stat(null, "Condition: [health]/[maxHealth]")
- if(refactory)
- var/max = refactory.max_storage
- for(var/material in refactory.materials)
- var/amount = refactory.get_stored_material(material)
- stat(null, "[capitalize(material)]: [amount]/[max]")
-
-/mob/living/simple_animal/protean_blob/proc/revert_form()
- set name = "Ref - Humanoid"
- set desc = "Regain your humanoid form."
- set category = "Abilities"
-
- if(health < maxHealth*0.5)
- to_chat(src,"You're too injured for that! Regenerate using steel first.")
- return
-
if(humanform)
- humanform.nano_outofblob(src)
- else
- to_chat(src,"Something's gone terribly wrong and we can't find your human body. Admin-help this.")
- return
+ humanform.species.Stat(humanform)
/mob/living/simple_animal/protean_blob/update_icon()
if(humanform)
@@ -243,6 +222,10 @@
//Create our new blob
var/mob/living/simple_animal/protean_blob/blob = new(creation_spot,src)
+ //Size update
+ blob.transform = matrix()*size_multiplier
+ blob.size_multiplier = size_multiplier
+
//Put our owner in it (don't transfer var/mind)
blob.ckey = ckey
temporary_form = blob
@@ -293,6 +276,10 @@
//Record where they should go
var/atom/reform_spot = blob.drop_location()
+ //Size update
+ transform = matrix()*blob.size_multiplier
+ size_multiplier = blob.size_multiplier
+
//Move them back where the blob was
forceMove(reform_spot)
diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm
index bc93a8fbab..6240c4a44d 100644
--- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm
+++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_powers.dm
@@ -12,11 +12,13 @@
to_chat(src,"You must be awake and standing to perform this action!")
return
- var/obj/item/organ/internal/nano/refactory/refactory = locate() in internal_organs
- if(!refactory || refactory.status & ORGAN_DEAD)
- to_chat(src,"You don't have a refactory module!")
+ var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
+ //Missing the organ that does this
+ if(!istype(refactory))
+ to_chat(src,"You don't have a working refactory module!")
return
+
var/choice = input(src,"Pick the bodypart to change:", "Refactor - One Bodypart") as null|anything in species.has_limbs
if(!choice)
return
@@ -70,7 +72,6 @@
eo.robotize(manu_choice)
visible_message("[src]'s ")
update_icons_body()
-#undef PER_LIMB_STEEL_COST
////
// Full Refactor
@@ -85,10 +86,10 @@
to_chat(src,"You must be awake and standing to perform this action!")
return
- var/obj/item/organ/internal/nano/refactory/refactory = locate() in internal_organs
+ var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this
if(!istype(refactory))
- to_chat(src,"You don't have a refactory module!")
+ to_chat(src,"You don't have a working refactory module!")
return
//Already regenerating
@@ -176,10 +177,10 @@
set category = "Abilities"
set hidden = TRUE
- var/obj/item/organ/internal/nano/refactory/refactory = locate() in internal_organs
+ var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this
if(!istype(refactory))
- to_chat(src,"You don't have a refactory module!")
+ to_chat(src,"You don't have a working refactory module!")
return
var/held = get_active_hand()
@@ -204,16 +205,27 @@
// Blob Form
////
/mob/living/carbon/human/proc/nano_blobform()
- set name = "Become Amorphous"
- set desc = "Drop your shape and assume a more natural form."
+ set name = "Toggle Blobform"
+ set desc = "Switch between amorphous and humanoid forms."
set category = "Abilities"
set hidden = TRUE
- if(stat)
- to_chat(src,"You must be awake and standing to perform this action!")
+ //Blob form
+ if(temporary_form)
+ if(health < maxHealth*0.5)
+ to_chat(temporary_form,"You need to regenerate more nanites first!")
+ else if(temporary_form.stat)
+ to_chat(temporary_form,"You can only do this while not stunned.")
+ return
+ else
+ nano_outofblob(temporary_form)
+
+ //Human form
+ else if(stat)
+ to_chat(src,"You can only do this while not stunned.")
return
-
- nano_intoblob()
+ else
+ nano_intoblob()
////
// Change fitting
@@ -230,7 +242,67 @@
var/new_species = input("Please select a species to emulate.", "Shapeshifter Body") as null|anything in playable_species
if(new_species)
impersonate_bodytype = new_species
- regenerate_icons()
+ regenerate_icons() //Expensive, but we need to recrunch all the icons we're wearing
+
+////
+// Change size
+////
+/mob/living/proc/nano_set_size()
+ set name = "Adjust Volume"
+ 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,"You don't have a working refactory module!")
+ return
+
+ var/nagmessage = "Adjust your mass to be a size between 25 to 200%. Up-sizing consumes metal, downsizing returns metal."
+ var/new_size = input(src, nagmessage, "Pick a Size", size_multiplier*100) as num|null
+ if(!new_size || !IsInRange(new_size,25,200))
+ return
+
+ var/size_factor = new_size/100
+
+ //Will be: -1.75 for 200->25, and 1.75 for 25->200
+ var/sizediff = size_factor - 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("steel",cost))
+ resize(size_factor)
+ else
+ to_chat(src,"That size change would cost [cost] steel, which you don't have.")
+ return
+ //Sizing down (or not at all)
+ if(cost <= 0)
+ cost = abs(cost)
+ var/actually_added = refactory.add_stored_material("steel",cost)
+ resize(size_factor)
+ if(actually_added != cost)
+ to_chat(src,"Unfortunately, [cost-actually_added] steel was lost due to lack of storage space.")
+
+/// /// /// 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_animal/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)
@@ -252,20 +324,34 @@
if(opts)
to_chat(usr,"[ability_name] - [desc]")
else
- do_ability(usr)
+ //Humanform using it
+ if(ishuman(usr))
+ do_ability(usr)
+ //Blobform using it
+ else
+ var/mob/living/simple_animal/protean_blob/blob = usr
+ if(!blob.humanform)
+ return
+ do_ability(blob.humanform)
-/obj/effect/protean_ability/proc/do_ability(var/mob/living/carbon/human/H)
- if(istype(H) && !H.stat)
- call(H,to_call)()
+/obj/effect/protean_ability/proc/do_ability(var/mob/living/L)
+ if(istype(L) && !L.stat)
+ call(L,to_call)()
return FALSE
/// The actual abilities
/obj/effect/protean_ability/into_blob
- ability_name = "Become Amorphous"
+ 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
+/obj/effect/protean_ability/change_volume
+ ability_name = "Change Volume"
+ desc = "Alter your size by consuming steel to produce additional nanites, or regain steel by reducing your size and reclaiming them."
+ icon_state = "volume"
+ to_call = /mob/living/proc/nano_set_size
+
/obj/effect/protean_ability/reform_limb
ability_name = "Ref - Single Limb"
desc = "Rebuild or replace a single limb, assuming you have 2000 steel."
@@ -283,3 +369,5 @@
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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm
index 0d3da709c1..80d62c1946 100644
--- a/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm
+++ b/code/modules/mob/living/carbon/human/species/station/protean_vr/protean_species.dm
@@ -86,6 +86,7 @@
/mob/living/carbon/human/proc/nano_partswap,
/mob/living/carbon/human/proc/nano_metalnom,
/mob/living/carbon/human/proc/nano_blobform,
+ /mob/living/proc/nano_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,
@@ -185,7 +186,7 @@
/datum/species/protean/Stat(var/mob/living/carbon/human/H)
..()
if(statpanel("Protean"))
- var/obj/item/organ/internal/nano/refactory/refactory = locate() in H.internal_organs
+ 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
diff --git a/icons/mob/species/protean/protean_powers.dmi b/icons/mob/species/protean/protean_powers.dmi
index 48debef854..febd3522a0 100644
Binary files a/icons/mob/species/protean/protean_powers.dmi and b/icons/mob/species/protean/protean_powers.dmi differ