Merge pull request #3252 from VOREStation/aro-protean

Protean species
This commit is contained in:
Aronai Sieyes
2018-03-17 13:02:50 -04:00
committed by GitHub
17 changed files with 1085 additions and 11 deletions
+1
View File
@@ -49,6 +49,7 @@
#define ORGAN_ASSISTED 1 // Like pacemakers, not robotic
#define ORGAN_ROBOT 2 // Fully robotic, no organic parts
#define ORGAN_LIFELIKE 3 // Robotic, made to appear organic
#define ORGAN_NANOFORM 4 // VOREStation Add - Fully nanoswarm organ
//Germs and infections.
#define GERM_LEVEL_AMBIENT 110 // Maximum germ level you can reach by standing still.
+4
View File
@@ -8,3 +8,7 @@
#define VIS_AUGMENTED 25
#define VIS_COUNT 25
//Protean organs
#define O_ORCH "orchestrator"
#define O_FACT "refactory"
@@ -6,3 +6,4 @@
var/wagging = 0 //UGH.
var/flapping = 0
var/vantag_pref = VANTAG_NONE //What's my status?
var/impersonate_bodytype //For impersonating a bodytype
@@ -18,4 +18,10 @@
..(new_loc, "Xenomorph Hybrid")
/mob/living/carbon/human/spider/New(var/new_loc)
..(new_loc, "Vasilissan")
..(new_loc, "Vasilissan")
/mob/living/carbon/human/vulpkanin/New(var/new_loc)
..(new_loc, "Vulpkanin")
/mob/living/carbon/human/protean/New(var/new_loc)
..(new_loc, "Protean")
@@ -65,5 +65,5 @@
/mob/living/carbon/human/sparram/New(var/new_loc)
..(new_loc, "Sparra")
/mob/living/carbon/human/vulpkaninm/New(var/new_loc)
/mob/living/carbon/human/wolpin/New(var/new_loc)
..(new_loc, "Wolpin")
@@ -0,0 +1,309 @@
// Simple animal nanogoopeyness
/mob/living/simple_animal/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
ai_inactive = TRUE //Always off
show_stat_health = FALSE //We will do it ourselves
response_help = "pats the"
response_disarm = "gently pushes aside the"
response_harm = "hits the"
harm_intent_damage = 2
melee_damage_lower = 10
melee_damage_upper = 10
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
speak_chance = 1
speak = list("Blrb?","Sqrsh.","Glrsh!")
emote_hear = list("squishes softly","spluts quietly","makes wet noises")
emote_see = list("shifts wetly","undulates placidly")
var/mob/living/carbon/human/humanform
var/obj/item/organ/internal/nano/refactory/refactory
var/datum/modifier/healing
player_msg = "In this form, you can move a little faster, your health will regenerate as long as you have metal in you, and you can ventcrawl!"
//Constructor allows passing the human to sync damages
/mob/living/simple_animal/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/simple_animal/protean_blob/proc/revert_form
verbs |= /mob/living/proc/ventcrawl
verbs |= /mob/living/proc/hide
else
update_icon()
/mob/living/simple_animal/protean_blob/Destroy()
humanform = null
refactory = null
vore_organs = null
vore_selected = null
if(healing)
healing.expire()
return ..()
/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,"<span class='warning'>You're too injured for that! Regenerate using steel first.</span>")
return
if(humanform)
humanform.nano_outofblob(src)
else
to_chat(src,"<span class='warning'>Something's gone terribly wrong and we can't find your human body. Admin-help this.</span>")
return
/mob/living/simple_animal/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_animal/protean_blob/updatehealth()
if(humanform)
//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'
health = maxHealth - humanform.getOxyLoss() - humanform.getToxLoss() - humanform.getCloneLoss() - humanform.getActualFireLoss() - humanform.getActualBruteLoss()
//Alive, becoming dead
if((stat < DEAD) && (health <= 0))
death()
//Overhealth
if(health > getMaxHealth())
health = getMaxHealth()
//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"
else
..()
/mob/living/simple_animal/protean_blob/adjustBruteLoss(var/amount)
if(humanform)
humanform.adjustBruteLoss(amount)
else
..()
/mob/living/simple_animal/protean_blob/adjustFireLoss(var/amount)
if(humanform)
humanform.adjustFireLoss(amount)
else
..()
/mob/living/simple_animal/protean_blob/death(gibbed, deathmessage = "dissolves away, leaving only a few spare parts!")
if(humanform)
humanform.death(gibbed = gibbed)
for(var/organ in humanform.internal_organs)
var/obj/item/organ/internal/O = organ
O.removed()
O.forceMove(drop_location())
qdel_null(humanform) //Don't leave it just sitting in nullspace
animate(src,alpha = 0,time = 2 SECONDS)
sleep(2 SECONDS)
qdel(src)
..()
/mob/living/simple_animal/protean_blob/Life()
. = ..()
if(. && istype(refactory) && humanform)
if(!healing && health < maxHealth && refactory.get_stored_material(DEFAULT_WALL_MATERIAL) >= 100)
healing = humanform.add_modifier(/datum/modifier/protean/steel, origin = refactory)
else if(healing && health == maxHealth)
healing.expire()
healing = null
/mob/living/simple_animal/protean_blob/lay_down()
..()
if(resting)
animate(src,alpha = 40,time = 1 SECOND)
mouse_opacity = 0
else
mouse_opacity = 1
icon_state = "wake"
animate(src,alpha = 255,time = 1 SECOND)
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) && vore_selected)
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_animal/protean_blob/DoPunch(var/atom/A)
if(refactory && istype(A,/obj/item/stack/material))
var/obj/item/stack/material/S = A
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_animal/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
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_animal/protean_blob/MouseEntered(location,control,params)
if(resting)
return
..()
// Helpers - Unsafe, WILL perform change.
/mob/living/carbon/human/proc/nano_intoblob()
if(buckled)
buckled.unbuckle_mob()
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_animal/protean_blob/blob = new(creation_spot,src)
//Put our owner in it (don't transfer var/mind)
blob.ckey = ckey
temporary_form = blob
//Mail them to nullspace
forceMove(null)
//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/belly in vore_organs)
var/obj/belly/B = belly
B.forceMove(blob)
//Return our blob in case someone wants it
return blob
/mob/living/carbon/human/proc/nano_outofblob(var/mob/living/simple_animal/protean_blob/blob)
if(!istype(blob))
return
if(buckled)
buckled.unbuckle_mob()
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()
//Move them back where the blob was
forceMove(reform_spot)
//Put our owner in it (don't transfer var/mind)
ckey = blob.ckey
temporary_form = null
Life(1) //Fix my blindness right meow
//Transfer vore organs
for(var/belly in vore_organs)
var/obj/belly/B = belly
B.forceMove(src)
//Get rid of friend blob
qdel(blob)
//Return ourselves in case someone wants it
return src
@@ -0,0 +1,284 @@
#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
var/obj/item/organ/internal/nano/refactory/refactory = locate() in internal_organs
if(!refactory || refactory.status & ORGAN_DEAD)
to_chat(src,"<span class='warning'>You don't have a refactory module!</span>")
return
var/choice = input(src,"Pick the bodypart to change:", "Refactor - One Bodypart") as null|anything in species.has_limbs
if(!choice)
return
//Organ is missing, needs restoring
if(!organs_by_name[choice])
if(refactory.get_stored_material(DEFAULT_WALL_MATERIAL) < 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 = alert(src,"That limb is missing, do you want to regenerate it in exchange for [PER_LIMB_STEEL_COST] steel?","Regenerate limb?","Yes","No")
if(regen != "Yes")
return
if(!refactory.use_stored_material(DEFAULT_WALL_MATERIAL,PER_LIMB_STEEL_COST))
return
var/mob/living/simple_animal/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
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(species.name 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 = input(src, "Which manufacturer do you wish to mimmic for this limb?", "Manufacturer for [choice]") as null|anything in 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 ")
update_icons_body()
#undef PER_LIMB_STEEL_COST
////
// Full Refactor
////
/mob/living/carbon/human/proc/nano_regenerate()
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
var/obj/item/organ/internal/nano/refactory/refactory = locate() in internal_organs
//Missing the organ that does this
if(!istype(refactory))
to_chat(src,"<span class='warning'>You don't have a 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 = alert(src,"Do you want to rebuild, or reshape?","Rebuild or Reshape","Rebuild","Cancel","Reshape")
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(species.name 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 = input(src, "Which manufacturer do you wish to mimmic?", "Manufacturer") as null|anything in 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_animal/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(DEFAULT_WALL_MATERIAL,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
nano_intoblob()
if(do_after(src,delay_length))
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.company)
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>")
else
to_chat(src, "<span class='critical'>Your refactoring is interrupted!</span>")
nano_outofblob()
////
// 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 = locate() in internal_organs
//Missing the organ that does this
if(!istype(refactory))
to_chat(src,"<span class='warning'>You don't have a 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/howmuch = input(src,"How much do you want to store? (0-[matstack.amount])","Select amount") as null|num
if(!howmuch || matstack != get_active_hand() || howmuch > matstack.amount)
return //Quietly fail
var/substance = matstack.material.name
var/actually_added = refactory.add_stored_material(substance,howmuch*matstack.perunit)
matstack.use(Ceiling(actually_added/matstack.perunit))
if(actually_added < howmuch)
to_chat(src,"<span class='warning'>Your refactory module is now full, so only [actually_added] units were stored.</span>")
else
to_chat(src,"<span class='notice'>You store [actually_added] units of [substance].</span>")
////
// 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 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
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 = input("Please select a species to emulate.", "Shapeshifter Body") as null|anything in playable_species
if(new_species)
impersonate_bodytype = new_species
regenerate_icons()
/// /// /// 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
do_ability(usr)
/obj/effect/protean_ability/proc/do_ability(var/mob/living/carbon/human/H)
if(istype(H) && !H.stat)
call(H,to_call)()
return FALSE
/// The actual abilities
/obj/effect/protean_ability/into_blob
ability_name = "Become Amorphous"
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/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
@@ -0,0 +1,303 @@
#define DAM_SCALE_FACTOR 0.01
/datum/species/protean
name = "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 = "#000000"
flesh_color = "#000000"
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
health_hud_intensity = 2
num_alternate_languages = 3
species_language = LANGUAGE_SOL_COMMON
breath_type = null
poison_type = null
virus_immune = 1
blood_volume = 0
min_age = 18
max_age = 200
brute_mod = 0.2 //Brute isn't very effective, they're made of dust
burn_mod = 2.0 //Burn, however, is
oxy_mod = 0
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
//Space doesn't bother them
hazard_low_pressure = -1
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 = 3 //Very bad zappy times
rarity_value = 5
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/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
)
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.nif.forceMove(null)
..()
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)
var/obj/item/stack/material/steel/metal_stack = new()
metal_stack.amount = 3
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.nif)
var/obj/item/device/nif/bioadap/new_nif = new()
new_nif.quick_implant(H)
else
H.nif.durability = rand(21,25)
/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)
to_chat(H,"<span class='warning'>You died as a Protean. Please sit out of the round for at least 30 minutes before respawning, to represent the time it would take to ship a new-you to the station.</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)
H.nano_intoblob()
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("mhydrogen") >= 100)
H.add_modifier(/datum/modifier/protean/mhydrogen, origin = refactory)
//Plasteel adds brute armor
if(refactory.get_stored_material("plasteel") >= 100)
H.add_modifier(/datum/modifier/protean/plasteel, origin = refactory)
//Diamond adds burn armor
if(refactory.get_stored_material("diamond") >= 100)
H.add_modifier(/datum/modifier/protean/diamond, origin = refactory)
return ..()
/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 = locate() in H.internal_organs
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/ability in abilities)
var/obj/effect/protean_ability/A = ability
stat("[A.ability_name]",A.atom_button_text())
// Various modifiers
/datum/modifier/protean
stacks = MODIFIER_STACK_FORBID
var/material_use = 100
var/material_name = DEFAULT_WALL_MATERIAL
/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/tick()
//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()
/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_use = 100
material_name = "mhydrogen"
slowdown = -1
/datum/modifier/protean/plasteel
name = "Protean Effect - Plasteel"
desc = "You're affected by the presence of plasteel."
on_created_text = "<span class='notice'>You feel yourself become nearly impervious to physical attacks as plasteel nanites are made.</span>"
on_expired_text = "<span class='notice'>Your refactory finishes consuming the plasteel, and you return to your normal nanites.</span>"
material_use = 100
material_name = "plasteel"
incoming_brute_damage_percent = 0.5
/datum/modifier/protean/diamond
name = "Protean Effect - Diamond"
desc = "You're affected by the presence of diamond."
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 diamond, and you return to your normal nanites.</span>"
material_use = 100
material_name = "diamond"
incoming_fire_damage_percent = 0.2
/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_use = 100
material_name = "steel"
/datum/modifier/protean/steel/tick()
..()
holder.adjustBruteLoss(-10,include_robo = TRUE) //Looks high, but these ARE modified by species resistances, so this is really 20% of this
holder.adjustFireLoss(-1,include_robo = TRUE) //And this is really double this
var/mob/living/carbon/human/H = holder
for(var/organ in H.internal_organs)
var/obj/item/organ/O = organ
// 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"
/obj/item/clothing/accessory/permit/nanotech/set_name(var/new_name)
owner = 1
if(new_name)
src.name += " ([new_name])"
desc += "\nVALID THROUGH END OF: [time2text(world.timeofday, "Month") +" "+ num2text(text2num(time2text(world.timeofday, "YYYY"))+544)]\nREGISTRANT: [new_name]"
#undef DAM_SCALE_FACTOR
@@ -265,7 +265,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(part.robotic >= ORGAN_ROBOT)
icon_key += "2[part.model ? "-[part.model]": ""]"
robolimb_count++
if(part.organ_tag == BP_HEAD || part.organ_tag == BP_TORSO || part.organ_tag == BP_GROIN)
if((part.robotic == ORGAN_ROBOT || part.robotic == ORGAN_LIFELIKE) && (part.organ_tag == BP_HEAD || part.organ_tag == BP_TORSO || part.organ_tag == BP_GROIN)) //VOREStation Edit - Not for nanoform parts
robobody_count ++
else if(part.status & ORGAN_DEAD)
icon_key += "3"
+3 -4
View File
@@ -1,5 +1,4 @@
/mob
var/vantag_hud = 0 // Do I have the HUD enabled?
var/flying = 0 //Allows flight
var/can_be_drop_prey = 0
var/can_be_drop_pred = 1 //Mobs are pred by default.
var/vantag_hud = 0 // Do I have the HUD enabled?
var/flying = 0 // Allows flight
var/mob/temporary_form // For holding onto a temporary form
+9 -3
View File
@@ -816,7 +816,11 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!cannot_amputate)
if(nonsolid && damage >= max_damage)
droplimb(DROPLIMB_BLUNT)
droplimb(TRUE, DROPLIMB_BLUNT)
//VOREStation Add Start
if(robotic >= ORGAN_NANOFORM && damage >= max_damage)
droplimb(TRUE, DROPLIMB_BURN)
//VOREStation Add End
/****************************************************
DISMEMBERMENT
@@ -827,8 +831,10 @@ Note that amputating the affected organ does in fact remove the infection from t
if(cannot_amputate || !owner)
return
if(disintegrate == DROPLIMB_EDGE && nonsolid)
//VOREStation Add
if(robotic >= ORGAN_NANOFORM)
disintegrate = DROPLIMB_BURN //Ashes will be fine
else if(disintegrate == DROPLIMB_EDGE && nonsolid) //VOREStation Add End
disintegrate = DROPLIMB_BLUNT //splut
switch(disintegrate)
+155
View File
@@ -0,0 +1,155 @@
// // // 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
/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
/obj/item/organ/external/head/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000 //Inheritance
vital = FALSE
/obj/item/organ/external/arm/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000 //Please
vital = FALSE
/obj/item/organ/external/arm/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/leg/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/leg/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/hand/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/hand/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/foot/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/foot/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
//Sideways override for nanoform limbs (ugh)
/obj/item/organ/external/robotize(var/company, var/skip_prosthetics = FALSE, var/keep_organs = FALSE)
var/original_robotic = robotic
if(original_robotic >= ORGAN_NANOFORM)
var/o_encased = encased
var/o_max_damage = max_damage
var/o_min_broken_damage = min_broken_damage
robotic = FALSE
..(company = company, keep_organs = TRUE)
robotic = original_robotic
encased = o_encased
max_damage = o_max_damage
min_broken_damage = o_min_broken_damage
else
..()
// // // 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
/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(DEFAULT_WALL_MATERIAL = 0)
var/max_storage = 10000
/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
/obj/item/organ/internal/mmi_holder/posibrain/nano/update_from_mmi()
..()
icon = initial(icon)
icon_state = "posi1"
stored_mmi.brainmob.languages = owner.languages
+1 -1
View File
@@ -18,7 +18,7 @@
return 0
if (affected.status & ORGAN_DESTROYED)
return 0
if (!(affected.robotic >= ORGAN_ROBOT))
if (!(affected.robotic == ORGAN_ROBOT || affected.robotic == ORGAN_LIFELIKE)) //VOREStation Edit - No good on ORGAN_NANOFORM
return 0
return 1
+2
View File
@@ -19,6 +19,8 @@
var/absorbing_prey = 0 // Determines if the person is using the succubus drain or not. See station_special_abilities_vr.
var/drain_finalized = 0 // Determines if the succubus drain will be KO'd/absorbed. Can be toggled on at any time.
var/fuzzy = 1 // Preference toggle for sharp/fuzzy icon.
var/can_be_drop_prey = 0
var/can_be_drop_pred = 1 //Mobs are pred by default.
//
// Hook for generic creation of stuff on new creatures
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+4
View File
@@ -2019,6 +2019,9 @@
#include "code\modules\mob\living\carbon\human\species\station\station_special_abilities_vr.dm"
#include "code\modules\mob\living\carbon\human\species\station\station_special_vr.dm"
#include "code\modules\mob\living\carbon\human\species\station\station_vr.dm"
#include "code\modules\mob\living\carbon\human\species\station\protean_vr\protean_blob.dm"
#include "code\modules\mob\living\carbon\human\species\station\protean_vr\protean_powers.dm"
#include "code\modules\mob\living\carbon\human\species\station\protean_vr\protean_species.dm"
#include "code\modules\mob\living\carbon\human\species\station\traits_vr\negative.dm"
#include "code\modules\mob\living\carbon\human\species\station\traits_vr\neutral.dm"
#include "code\modules\mob\living\carbon\human\species\station\traits_vr\positive.dm"
@@ -2274,6 +2277,7 @@
#include "code\modules\organs\internal\organ_internal.dm"
#include "code\modules\organs\subtypes\diona.dm"
#include "code\modules\organs\subtypes\machine.dm"
#include "code\modules\organs\subtypes\nano.dm"
#include "code\modules\organs\subtypes\seromi.dm"
#include "code\modules\organs\subtypes\slime.dm"
#include "code\modules\organs\subtypes\standard.dm"