Merge pull request #4176 from BlackMajor/protean-rework

Protean rework part 2 (WIP)
This commit is contained in:
Razgriz
2023-02-27 19:09:14 -07:00
committed by GitHub
51 changed files with 4821 additions and 705 deletions

11
_runtimestation.dm Normal file
View File

@@ -0,0 +1,11 @@
/*
Toggle this var to 1 to compile using runtime station instead.
Useful if you're constantly having to recompile to debug something.
*/
#define RUNTIME_STATION 0
#if RUNTIME_STATION
#include "modular_chomp/maps/runtime/runtime_station_defines.dm"
#include "modular_chomp/maps/runtime/runtime_station.dmm"
#define USING_MAP_DATUM /datum/map/runtime_station
#endif

View File

@@ -3,3 +3,14 @@
return FALSE return FALSE
return ..() return ..()
/*
/datum/ai_holder/can_see_target(atom/movable/the_target, view_range = vision_range)
log_world("TARGET: [the_target] and TARGET.LOC: [the_target.loc]")
if(the_target && !isturf(the_target.loc)) //CHOMPEdit, AI shouldn't be targetting people inside objects of any kind
if(ismecha(the_target.loc)) //Except mechs, of course
target = the_target.loc
else
return FALSE
return ..()
*/

View File

@@ -536,7 +536,8 @@
offline = 0 offline = 0
if(istype(wearer) && !wearer.wearing_rig) if(istype(wearer) && !wearer.wearing_rig)
wearer.wearing_rig = src wearer.wearing_rig = src
slowdown = initial(slowdown) if(!istype(src,/obj/item/weapon/rig/protean)) //CHOMPEdit - Stupid snowflake protean special check for rig assimilation code
slowdown = initial(slowdown)
if(offline) if(offline)
if(offline == 1) if(offline == 1)
@@ -921,9 +922,13 @@
return return
//CHOMP Addition - Added this for protean living hardsuit //CHOMP Addition - Added this for protean living hardsuit
wearer_move_delay = world.time + 2
if(ai_moving) if(ai_moving)
if(!ai_can_move_suit(user, check_user_module = 1)) if(!ai_can_move_suit(user, check_user_module = 1))
return return
// AIs are a bit slower than regular and ignore move intent.
//CHOMPEdit - Moved this to where it's relevant
wearer_move_delay = world.time + ai_controlled_move_delay
//This is sota the goto stop mobs from moving var //This is sota the goto stop mobs from moving var
if(wearer.transforming || !wearer.canmove) if(wearer.transforming || !wearer.canmove)
@@ -955,9 +960,6 @@
to_chat(src, "<span class='notice'>Your host is pinned to a wall by [wearer.pinned[1]]</span>!") to_chat(src, "<span class='notice'>Your host is pinned to a wall by [wearer.pinned[1]]</span>!")
return 0 return 0
// AIs are a bit slower than regular and ignore move intent.
wearer_move_delay = world.time + ai_controlled_move_delay
if(istype(wearer.buckled, /obj/vehicle)) if(istype(wearer.buckled, /obj/vehicle))
//manually set move_delay for vehicles so we don't inherit any mob movement penalties //manually set move_delay for vehicles so we don't inherit any mob movement penalties
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm //specific vehicle move delays are set in code\modules\vehicles\vehicle.dm

View File

@@ -10,7 +10,7 @@
var/total_burn = 0 var/total_burn = 0
var/total_brute = 0 var/total_brute = 0
for(var/obj/item/organ/external/O in organs) //hardcoded to streamline things a bit for(var/obj/item/organ/external/O in organs) //hardcoded to streamline things a bit
if((O.robotic >= ORGAN_ROBOT) && !O.vital) if((O.robotic >= ORGAN_ROBOT) && !O.vital && !(O.robotic ==ORGAN_NANOFORM)) //CHOMPEdit - Protean changes
continue //*non-vital* robot limbs don't count towards shock and crit continue //*non-vital* robot limbs don't count towards shock and crit
total_brute += O.brute_dam total_brute += O.brute_dam
total_burn += O.burn_dam total_burn += O.burn_dam
@@ -68,7 +68,7 @@
/mob/living/carbon/human/getBruteLoss() /mob/living/carbon/human/getBruteLoss()
var/amount = 0 var/amount = 0
for(var/obj/item/organ/external/O in organs) for(var/obj/item/organ/external/O in organs)
if(O.robotic >= ORGAN_ROBOT && !O.vital) if(O.robotic >= ORGAN_ROBOT && !O.vital && !(O.robotic ==ORGAN_NANOFORM)) //CHOMPEdit - Protean changes
continue //*non-vital*robot limbs don't count towards death, or show up when scanned continue //*non-vital*robot limbs don't count towards death, or show up when scanned
amount += O.brute_dam amount += O.brute_dam
return amount return amount
@@ -90,7 +90,7 @@
/mob/living/carbon/human/getFireLoss() /mob/living/carbon/human/getFireLoss()
var/amount = 0 var/amount = 0
for(var/obj/item/organ/external/O in organs) for(var/obj/item/organ/external/O in organs)
if(O.robotic >= ORGAN_ROBOT && !O.vital) if(O.robotic >= ORGAN_ROBOT && !O.vital && !(O.robotic ==ORGAN_NANOFORM)) //CHOMPEdit - Protean changes
continue //*non-vital*robot limbs don't count towards death, or show up when scanned continue //*non-vital*robot limbs don't count towards death, or show up when scanned
amount += O.burn_dam amount += O.burn_dam
return amount return amount
@@ -318,7 +318,7 @@
halloss = 0 halloss = 0
else else
..() ..()
/mob/living/carbon/human/Stun(var/amount) /mob/living/carbon/human/Stun(var/amount)
if(amount > 0) //only multiply it by the mod if it's positive, or else it takes longer to fade too! if(amount > 0) //only multiply it by the mod if it's positive, or else it takes longer to fade too!
amount = amount*species.stun_mod amount = amount*species.stun_mod
@@ -326,12 +326,12 @@
/mob/living/carbon/human/SetStunned(var/amount) /mob/living/carbon/human/SetStunned(var/amount)
..() ..()
/mob/living/carbon/human/AdjustStunned(var/amount) /mob/living/carbon/human/AdjustStunned(var/amount)
if(amount > 0) // Only multiply it if positive. if(amount > 0) // Only multiply it if positive.
amount = amount*species.stun_mod amount = amount*species.stun_mod
..(amount) ..(amount)
/mob/living/carbon/human/Weaken(var/amount) /mob/living/carbon/human/Weaken(var/amount)
if(amount > 0) //only multiply it by the mod if it's positive, or else it takes longer to fade too! if(amount > 0) //only multiply it by the mod if it's positive, or else it takes longer to fade too!
amount = amount*species.weaken_mod amount = amount*species.weaken_mod
@@ -339,7 +339,7 @@
/mob/living/carbon/human/SetWeakened(var/amount) /mob/living/carbon/human/SetWeakened(var/amount)
..() ..()
/mob/living/carbon/human/AdjustWeakened(var/amount) /mob/living/carbon/human/AdjustWeakened(var/amount)
if(amount > 0) // Only multiply it if positive. if(amount > 0) // Only multiply it if positive.
amount = amount*species.weaken_mod amount = amount*species.weaken_mod

View File

@@ -16,7 +16,7 @@ var/list/wrapped_species_by_ref = list()
//var/default_form = SPECIES_HUMAN //VOREStation edit //var/default_form = SPECIES_HUMAN //VOREStation edit
/datum/species/shapeshifter/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H) /datum/species/shapeshifter/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H)
return valid_transform_species return list(vanity_base_fit)|valid_transform_species //CHOMPEdit
/datum/species/shapeshifter/get_icobase(var/mob/living/carbon/human/H, var/get_deform) /datum/species/shapeshifter/get_icobase(var/mob/living/carbon/human/H, var/get_deform)
if(!H) return ..(null, get_deform) if(!H) return ..(null, get_deform)

View File

@@ -34,6 +34,7 @@
/mob/living/carbon/human/proc/prommie_blobform, /mob/living/carbon/human/proc/prommie_blobform,
/mob/living/proc/set_size, /mob/living/proc/set_size,
/mob/living/carbon/human/proc/promethean_select_opaqueness, /mob/living/carbon/human/proc/promethean_select_opaqueness,
/mob/living/carbon/human/proc/shapeshifter_reassemble //CHOMPEdit: reform verb
) )
/mob/living/carbon/human/proc/prommie_blobform() /mob/living/carbon/human/proc/prommie_blobform()

View File

@@ -404,6 +404,7 @@
blob.ooc_notes = ooc_notes blob.ooc_notes = ooc_notes
blob.transforming = FALSE blob.transforming = FALSE
blob.name = name blob.name = name
blob.real_name = real_name //CHOMPEdit
blob.nutrition = nutrition blob.nutrition = nutrition
blob.color = rgb(r_skin, g_skin, b_skin) blob.color = rgb(r_skin, g_skin, b_skin)
playsound(src.loc, "sound/effects/slime_squish.ogg", 15) playsound(src.loc, "sound/effects/slime_squish.ogg", 15)
@@ -514,9 +515,9 @@
B.owner = src B.owner = src
//vore_organs.Cut() //vore_organs.Cut()
//ChompEdit begin. And let's drop them again. //ChompEdit begin. And let's drop them again.
// if(blob.prev_left_hand) put_in_l_hand(blob.prev_left_hand) // if(blob.prev_left_hand) put_in_l_hand(blob.prev_left_hand)
// if(blob.prev_right_hand) put_in_r_hand(blob.prev_right_hand) // if(blob.prev_right_hand) put_in_r_hand(blob.prev_right_hand)
if(blob.l_hand) blob.drop_from_inventory(blob.l_hand) if(blob.l_hand) blob.drop_from_inventory(blob.l_hand)

View File

@@ -27,8 +27,9 @@
/mob/living/carbon/human/proc/reconstitute_form, /mob/living/carbon/human/proc/reconstitute_form,
/mob/living/carbon/human/proc/sonar_ping, /mob/living/carbon/human/proc/sonar_ping,
/mob/living/carbon/human/proc/tie_hair, /mob/living/carbon/human/proc/tie_hair,
/mob/living/carbon/human/proc/lick_wounds) //Xenochimera get all the special verbs since they can't select traits. /mob/living/carbon/human/proc/lick_wounds,
// CHOMPEdit: Lick Wounds Verb /mob/living/carbon/human/proc/shapeshifter_reassemble) //Xenochimera get all the special verbs since they can't select traits.
// CHOMPEdit: Lick Wounds Verb, reform verb
virus_immune = 1 // They practically ARE one. virus_immune = 1 // They practically ARE one.
min_age = 18 min_age = 18
@@ -445,7 +446,7 @@
catalogue_data = list(/datum/category_item/catalogue/fauna/vulpkanin) catalogue_data = list(/datum/category_item/catalogue/fauna/vulpkanin)
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE//Whitelisted as restricted is broken. ChompEdit;renable spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE//Whitelisted as restricted is broken. ChompEdit;renable
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#AFA59E" flesh_color = "#AFA59E"

View File

@@ -117,8 +117,7 @@
/obj/item/organ/external/emp_act(severity) /obj/item/organ/external/emp_act(severity)
for(var/obj/O as anything in src.contents) for(var/obj/O as anything in src.contents)
O.emp_act(severity) O.emp_act(severity)
if(!(robotic >= ORGAN_ROBOT) || robotic == ORGAN_NANOFORM) //CHOMPEdit - Proteans handle EMP's differently
if(!(robotic >= ORGAN_ROBOT))
return return
var/burn_damage = 0 var/burn_damage = 0
for(var/i = 1; i <= robotic; i++) for(var/i = 1; i <= robotic; i++)
@@ -1140,7 +1139,8 @@ Note that amputating the affected organ does in fact remove the infection from t
force_icon = R.icon force_icon = R.icon
brute_mod *= R.robo_brute_mod brute_mod *= R.robo_brute_mod
burn_mod *= R.robo_burn_mod burn_mod *= R.robo_burn_mod
prosthetic_digi = R.can_be_digitigrade //CHOMPStation edit skip_robo_icon = R.no_icon //CHOMPStation edit
digi_prosthetic = R.can_be_digitigrade //CHOMPStation edit
if(R.lifelike) if(R.lifelike)
robotic = ORGAN_LIFELIKE robotic = ORGAN_LIFELIKE
name = "[initial(name)]" name = "[initial(name)]"

View File

@@ -1,5 +1,10 @@
GLOBAL_LIST_INIT(dsi_to_species, list(SPECIES_TAJARAN = "DSI - Tajaran", SPECIES_UNATHI = "DSI - Lizard", SPECIES_SERGAL = "DSI - Sergal", SPECIES_NEVREAN = "DSI - Nevrean", \
SPECIES_VULPKANIN = "DSI - Vulpkanin", SPECIES_AKULA = "DSI - Akula", SPECIES_VASILISSAN = "DSI - Vasilissan", SPECIES_ZORREN = "DSI - Zorren",\
SPECIES_TESHARI = "DSI - Teshari", SPECIES_FENNEC = "DSI - Fennec"))
/datum/robolimb /datum/robolimb
var/can_be_digitigrade = FALSE //maybe move this over into more of a "does this have a custom digitigrade sprite, and if so, what is its icon file/icon name in the limb's file" when someone can be bothered making them var/no_icon = FALSE //specifically for DSI things, makes it so it doesn't override the species icons
var/can_be_digitigrade = FALSE //used for skipping the icon if it can be digitigrade - maybe turn this into more of a 'use this icon/iconstate' instead later, when actual prosthetic digi icons get made
/datum/robolimb/valehoundhead /datum/robolimb/valehoundhead
company = "VALE Hound- Head" company = "VALE Hound- Head"
@@ -37,4 +42,14 @@
/datum/robolimb/dsi_teshari/New() /datum/robolimb/dsi_teshari/New()
. = ..() . = ..()
species_cannot_use -= SPECIES_PROTEAN species_cannot_use -= SPECIES_PROTEAN
/datum/robolimb/dsi_other
company = "DSI - Adaptive"
desc = "This limb has a realistic design and squish. By Darkside Incorperated."
blood_color = "#ffe2ff"
lifelike = 1
unavailable_to_build = 1
skin_tone = 1
no_icon = TRUE

View File

@@ -65,7 +65,7 @@
/atom/movable/proc/has_large_resize_bounds() /atom/movable/proc/has_large_resize_bounds()
var/area/A = get_area(src) //Get the atom's area to check for size limit. var/area/A = get_area(src) //Get the atom's area to check for size limit.
return !A.limit_mob_size return A ? !A.limit_mob_size : FALSE //CHOMPEdit
/proc/is_extreme_size(size) /proc/is_extreme_size(size)
return (size < RESIZE_MINIMUM || size > RESIZE_MAXIMUM) return (size < RESIZE_MINIMUM || size > RESIZE_MAXIMUM)

View File

@@ -34,3 +34,269 @@
SScharacter_setup.queue_preferences_save(prefs) SScharacter_setup.queue_preferences_save(prefs)
feedback_add_details("admin_verb","TAutoTranscore") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! feedback_add_details("admin_verb","TAutoTranscore") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/preferences/proc/vanity_copy_to(var/mob/living/carbon/human/character, var/copy_name, var/copy_flavour = TRUE, var/copy_ooc_notes = FALSE, var/convert_to_prosthetics = FALSE)
//snowflake copy_to, does not copy anything but the vanity things
//does not check if the name is the same, do that in any proc that calls this proc
/*
name, nickname, flavour, OOC notes
gender, sex
custom species name, custom bodytype, weight, scale, scaling center, sound type, sound freq
custom say verbs
ears, wings, tail, hair, facial hair
ears colors, wings colors, tail colors
body color, prosthetics (if they're a protean) (convert to DSI if protean and not prosthetic), eye color, hair color etc
markings
custom synth markings toggle, custom synth color toggle
digitigrade
blood color
*/
if (copy_name)
if(config.humans_need_surnames)
var/firstspace = findtext(real_name, " ")
var/name_length = length(real_name)
if(!firstspace) //we need a surname
real_name += " [pick(last_names)]"
else if(firstspace == name_length)
real_name += "[pick(last_names)]"
character.real_name = real_name
character.name = character.real_name
if(character.dna)
character.dna.real_name = character.real_name
character.nickname = nickname
character.gender = biological_gender
character.identifying_gender = identifying_gender
character.r_eyes = r_eyes
character.g_eyes = g_eyes
character.b_eyes = b_eyes
character.h_style = h_style
character.r_hair = r_hair
character.g_hair = g_hair
character.b_hair = b_hair
character.r_grad = r_grad
character.g_grad = g_grad
character.b_grad = b_grad
character.f_style = f_style
character.r_facial = r_facial
character.g_facial = g_facial
character.b_facial = b_facial
character.r_skin = r_skin
character.g_skin = g_skin
character.b_skin = b_skin
character.s_tone = s_tone
character.h_style = h_style
character.grad_style= grad_style
character.f_style = f_style
character.grad_style= grad_style
character.b_type = b_type
character.synth_color = synth_color
character.r_synth = r_synth
character.g_synth = g_synth
character.b_synth = b_synth
character.synth_markings = synth_markings
var/list/ear_styles = get_available_styles(global.ear_styles_list)
character.ear_style = ear_styles[ear_style]
character.r_ears = r_ears
character.b_ears = b_ears
character.g_ears = g_ears
character.r_ears2 = r_ears2
character.b_ears2 = b_ears2
character.g_ears2 = g_ears2
character.r_ears3 = r_ears3
character.b_ears3 = b_ears3
character.g_ears3 = g_ears3
var/list/tail_styles = get_available_styles(global.tail_styles_list)
character.tail_style = tail_styles[tail_style]
character.r_tail = r_tail
character.b_tail = b_tail
character.g_tail = g_tail
character.r_tail2 = r_tail2
character.b_tail2 = b_tail2
character.g_tail2 = g_tail2
character.r_tail3 = r_tail3
character.b_tail3 = b_tail3
character.g_tail3 = g_tail3
var/list/wing_styles = get_available_styles(global.wing_styles_list)
character.wing_style = wing_styles[wing_style]
character.r_wing = r_wing
character.b_wing = b_wing
character.g_wing = g_wing
character.r_wing2 = r_wing2
character.b_wing2 = b_wing2
character.g_wing2 = g_wing2
character.r_wing3 = r_wing3
character.b_wing3 = b_wing3
character.g_wing3 = g_wing3
character.set_gender(biological_gender)
// Destroy/cyborgize organs and limbs.
if (convert_to_prosthetics) //should only really be run for proteans
var/list/organs_to_edit = list()
for (var/name in list(BP_TORSO, BP_HEAD, BP_GROIN, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT))
var/obj/item/organ/external/O = character.organs_by_name[name]
if (O)
var/x = organs_to_edit.Find(O.parent_organ)
if (x == 0)
organs_to_edit += name
else
organs_to_edit.Insert(x+(O.robotic == ORGAN_NANOFORM ? 1 : 0), name)
for(var/name in organs_to_edit)
var/status = organ_data[name]
var/obj/item/organ/external/O = character.organs_by_name[name]
if(O)
if(status == "amputated")
continue
else if(status == "cyborg")
O.robotize(rlimb_data[name])
else
var/bodytype
var/datum/species/selected_species = GLOB.all_species[species]
if(selected_species.selects_bodytype)
bodytype = custom_base
else
bodytype = selected_species.get_bodytype()
var/dsi_company = GLOB.dsi_to_species[bodytype]
if (!dsi_company)
dsi_company = "DSI - Adaptive"
O.robotize(dsi_company)
for(var/N in character.organs_by_name)
var/obj/item/organ/external/O = character.organs_by_name[N]
O.markings.Cut()
var/priority = 0
for(var/M in body_markings)
priority += 1
var/datum/sprite_accessory/marking/mark_datum = body_marking_styles_list[M]
var/mark_color = "[body_markings[M]]"
for(var/BP in mark_datum.body_parts)
var/obj/item/organ/external/O = character.organs_by_name[BP]
if(O)
O.markings[M] = list("color" = mark_color, "datum" = mark_datum, "priority" = priority)
character.markings_len = priority
var/list/last_descriptors = list()
if(islist(body_descriptors))
last_descriptors = body_descriptors.Copy()
body_descriptors = list()
var/datum/species/mob_species = GLOB.all_species[species]
if(LAZYLEN(mob_species.descriptors))
for(var/entry in mob_species.descriptors)
var/datum/mob_descriptor/descriptor = mob_species.descriptors[entry]
if(istype(descriptor))
if(isnull(last_descriptors[entry]))
body_descriptors[entry] = descriptor.default_value // Species datums have initial default value.
else
body_descriptors[entry] = CLAMP(last_descriptors[entry], 1, LAZYLEN(descriptor.standalone_value_descriptors))
character.descriptors = body_descriptors
if (copy_flavour)
character.flavor_texts["general"] = flavor_texts["general"]
character.flavor_texts["head"] = flavor_texts["head"]
character.flavor_texts["face"] = flavor_texts["face"]
character.flavor_texts["eyes"] = flavor_texts["eyes"]
character.flavor_texts["torso"] = flavor_texts["torso"]
character.flavor_texts["arms"] = flavor_texts["arms"]
character.flavor_texts["hands"] = flavor_texts["hands"]
character.flavor_texts["legs"] = flavor_texts["legs"]
character.flavor_texts["feet"] = flavor_texts["feet"]
if (copy_ooc_notes)
character.ooc_notes = metadata
character.weight = weight_vr
character.weight_gain = weight_gain
character.weight_loss = weight_loss
character.fuzzy = fuzzy
character.offset_override = offset_override //CHOMPEdit
character.voice_freq = voice_freq
character.resize(size_multiplier, animate = FALSE, ignore_prefs = TRUE)
var/list/traits_to_copy = list(/datum/trait/neutral/tall,
/datum/trait/neutral/taller,
/datum/trait/neutral/short,
/datum/trait/neutral/shorter,
/datum/trait/neutral/obese,
/datum/trait/neutral/fat,
/datum/trait/neutral/thin,
/datum/trait/neutral/thinner,
/datum/trait/neutral/micro_size_down,
/datum/trait/neutral/micro_size_up)
//reset all the above trait vars
if (character.species)
character.species.micro_size_mod = 0
character.species.icon_scale_x = 1
character.species.icon_scale_y = 1
for (var/trait in neu_traits)
if (trait in traits_to_copy)
var/datum/trait/instance = all_traits[trait]
if (!instance)
continue
for (var/to_edit in instance.var_changes)
character.species.vars[to_edit] = instance.var_changes[to_edit]
character.update_transform()
if(!voice_sound)
character.voice_sounds_list = talk_sound
else
switch(voice_sound)
if("beep-boop")
character.voice_sounds_list = talk_sound
if("goon speak 1")
character.voice_sounds_list = goon_speak_one_sound
if("goon speak 2")
character.voice_sounds_list = goon_speak_two_sound
if("goon speak 3")
character.voice_sounds_list = goon_speak_three_sound
if("goon speak 4")
character.voice_sounds_list = goon_speak_four_sound
if("goon speak blub")
character.voice_sounds_list = goon_speak_blub_sound
if("goon speak bottalk")
character.voice_sounds_list = goon_speak_bottalk_sound
if("goon speak buwoo")
character.voice_sounds_list = goon_speak_buwoo_sound
if("goon speak cow")
character.voice_sounds_list = goon_speak_cow_sound
if("goon speak lizard")
character.voice_sounds_list = goon_speak_lizard_sound
if("goon speak pug")
character.voice_sounds_list = goon_speak_pug_sound
if("goon speak pugg")
character.voice_sounds_list = goon_speak_pugg_sound
if("goon speak roach")
character.voice_sounds_list = goon_speak_roach_sound
if("goon speak skelly")
character.voice_sounds_list = goon_speak_skelly_sound
character.species?.blood_color = blood_color
var/datum/species/selected_species = GLOB.all_species[species]
var/bodytype_selected
if(selected_species.selects_bodytype)
bodytype_selected = custom_base
else
bodytype_selected = selected_species.get_bodytype(character)
character.dna.base_species = bodytype_selected
character.species.base_species = bodytype_selected
character.species.vanity_base_fit = bodytype_selected
if (istype(character.species, /datum/species/shapeshifter))
wrapped_species_by_ref["\ref[character]"] = bodytype_selected
character.custom_species = custom_species
character.custom_say = lowertext(trim(custom_say))
character.custom_ask = lowertext(trim(custom_ask))
character.custom_whisper = lowertext(trim(custom_whisper))
character.custom_exclaim = lowertext(trim(custom_exclaim))
character.digitigrade = selected_species.digi_allowed ? digitigrade : 0
character.dna.ResetUIFrom(character)
character.force_update_limbs()
character.regenerate_icons()

View File

@@ -0,0 +1,24 @@
/obj/item/rig_module/device/defib
name = "mounted defib"
desc = "A rig mounted defib unit. Has expanded functionality to function on both organics and FBP's."
icon_state = "flash"
interface_name = "mounted defib"
interface_desc = "Toggle to swap between FBP and Organic compatability."
device_type = /obj/item/weapon/shockpaddles/standalone/rig
usable = 1
engage_string = "Toggle Mode"
/obj/item/weapon/shockpaddles/standalone/rig
name = "mounted defib"
desc = "Rig mounted defib. How are you seeing this? Stop that."
wielded = 1
/obj/item/weapon/shockpaddles/standalone/rig/emp_act(severity)
return
/obj/item/weapon/shockpaddles/standalone/rig/checked_use(var/charge_amt)
return 1
/obj/item/weapon/shockpaddles/standalone/rig/attack_self()
use_on_synthetic = !use_on_synthetic
to_chat(usr, "<span class='notice'>You switch the [src] to [use_on_synthetic ? "FBP" : "organic"] compatability.</span>")

View File

@@ -0,0 +1,8 @@
/obj/item/rig_module/mounted/phase
name = "mounted phase rifle"
desc = "A forearm-mounted phase rifle."
icon_state = "taser"
usable = 0
interface_name = "mounted phase rifle"
interface_desc = "A forearm-mounted suit-powered phase rifle."
gun_type = /obj/item/weapon/gun/energy/locked/phasegun/rifle/unlocked/mounted

View File

@@ -0,0 +1,209 @@
/*
A collection of Protean rigsuit modules, intended to encourage Symbiotic relations with a host.
All of these should require someone else to be wearing the Protean to function.
These should come standard with the Protean rigsuit, unless you want them to work for some upgrades.
*/
//This rig module feeds nutrition directly from the wearer to the Protean, to help them stay charged while worn.
/obj/item/rig_module/protean
permanent = 1
/obj/item/rig_module/protean/syphon
name = "Protean Metabolic Syphon"
desc = "This should never be outside of a RIG."
icon_state = "flash"
interface_name = "Protean Metabolic Syphon"
interface_desc = "Toggle to drain nutrition/power from the user directly into the Protean's own energy stores."
toggleable = 1
activate_string = "Enable Syphon"
deactivate_string = "Disable Syphon"
/obj/item/rig_module/protean/syphon/activate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, "<font color='blue'><b>You activate the suit's energy syphon.</b></font>")
to_chat(H, "<span class='warning'>Your suit begins to sap at your own energy stores.</span>")
active = 1
else
return 0
/obj/item/rig_module/protean/syphon/deactivate(var/forced)
if(!..())
return 0
if(forced)
active = 0
return
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, "<font color='blue'><b>You deactivate the suit's energy syphon.</b></font>")
to_chat(H, "<span class='warning'>Your suit ceases from sapping your own energy.</span>")
active = 0
else
return 0
/obj/item/rig_module/protean/syphon/process()
if(active)
var/mob/living/carbon/human/H = holder.wearer
var/mob/living/P = holder?:myprotean
if(istype(H.species, /datum/species/protean))
to_chat(H, "<span class='warning'>Your Protean modules do not function on yourself.</span>")
deactivate(1)
else
P = P?:humanform
if((H.nutrition >= 100) && (P.nutrition <= 5000))
H.nutrition -= 10
P.nutrition += 10
//This rig module allows a worn Protean to toggle and configure its armor settings.
/obj/item/rig_module/protean/armor
name = "Protean Adaptive Armor"
desc = "This should never be outside of a RIG."
interface_name = "Protean Adaptive Armor"
interface_desc = "Adjusts the proteans deployed armor values to fit the needs of the wearer."
usable = 1
toggleable = 1
activate_string = "Enable Armor"
deactivate_string = "Disable Armor"
engage_string = "Configure Armor"
var/list/armor_settings = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0)
var/armor_weight_ratio = 0.01 //This amount of slowdown per 1% of armour. 3 slowdown at the max armour.
/obj/item/rig_module/protean/armor/engage()
var/armor_chosen = input(usr, "Which armor to adjust?", "Protean Armor") as null|anything in armor_settings
if(armor_chosen)
var/armorvalue = tgui_input_number(usr, "Set armour reduction value (Max of 60%)", "Protean Armor",0,60,0,0,1)
if(isnum(armorvalue))
armor_settings[armor_chosen] = armorvalue
interface_desc = initial(interface_desc)
slowdown = 0
for(var/entry in armor_settings) //This is dumb and ugly but I dont feel like rewriting rig TGUI just to make this a pretty list
interface_desc += " [entry]: [armor_settings[entry]]"
slowdown += armor_settings[entry]*armor_weight_ratio
interface_desc += " Slowdown: [slowdown]"
/obj/item/rig_module/protean/armor/activate()
if(holder?:assimilated_rig)
to_chat(usr, "<font color='red'><b>Armor module non-functional while a RIG is assimilated.</b></font>")
return
if(!..(1))
return 0
var/mob/living/carbon/human/H = holder.wearer
if(H)
var/list/temparmor = list("bio" = 100, "rad" = 100)
temparmor = armor_settings + temparmor
to_chat(usr, "<font color='blue'><b>You signal the suit to harden.</b></font>")
to_chat(H, "<span class='notice'>Your suit hardens in response to physical trauma.</span>")
holder.armor = temparmor.Copy()
for(var/obj/item/piece in list(holder.gloves,holder.helmet,holder.boots,holder.chest))
piece.armor = temparmor.Copy()
holder.slowdown = slowdown
active = 1
else
return 0
/obj/item/rig_module/protean/armor/deactivate(var/forced)
if(!..(1))
return 0
if(forced)
holder.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
for(var/obj/item/piece in list(holder.gloves,holder.helmet,holder.boots,holder.chest))
piece.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
holder.slowdown = initial(slowdown)
active = 0
return
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, "<font color='blue'><b>You signal the suit to relax.</b></font>")
to_chat(H, "<span class='warning'>Your suit softens.</span>")
holder.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
for(var/obj/item/piece in list(holder.gloves,holder.helmet,holder.boots,holder.chest))
piece.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
holder.slowdown = initial(slowdown)
active = 0
else
return 0
/obj/item/rig_module/protean/armor/process()
if(active)
var/mob/living/carbon/human/H = holder.wearer
if(istype(H.species, /datum/species/protean))
to_chat(H, "<span class='warning'>Your Protean modules do not function on yourself.</span>")
deactivate(1)
//This rig module lets a Protean expend its metal stores to heal its host
/obj/item/rig_module/protean/healing
name = "Protean Restorative Nanites"
desc = "This should never be outside of a RIG."
interface_name = "Protean Restorative Nanites"
interface_desc = "Utilises stored steel from the Protean to slowly heal and repair the wearer."
toggleable = 1
activate_string = "Enable Healing"
deactivate_string = "Disable Healing"
var/datum/modifier/healing
/obj/item/rig_module/protean/healing/activate()
if(!..(1))
return 0
var/mob/living/carbon/human/H = holder.wearer
var/mob/living/P = holder?:myprotean
if(H && P)
if(istype(H.species, /datum/species/protean))
to_chat(H, "<span class='warning'>Your Protean modules do not function on yourself.</span>")
return 0
var/obj/item/organ/internal/nano/refactory/R = P.nano_get_refactory()
if(R.get_stored_material(MAT_STEEL) >= 100)
healing = holder.wearer.add_modifier(/datum/modifier/protean/steel, origin = R)
to_chat(usr, "<font color='blue'><b>You activate the suit's restorative nanites.</b></font>")
to_chat(H, "<span class='warning'>Your suit begins mend your injuries.</span>")
active = 1
return 1
return 0
/obj/item/rig_module/protean/healing/deactivate()
if(!..(1))
return 0
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, "<font color='blue'><b>You deactivate the suit's restorative nanites.</b></font>")
to_chat(H, "<span class='warning'>Your suit is no longer mending your injuries.</span>")
active = 0
if(healing)
healing.expire()
healing = null
return 1
else
return 0
/obj/item/rig_module/protean/healing/process()
if(active)
var/mob/living/carbon/human/H = holder.wearer
var/mob/living/P = holder?:myprotean
if((istype(H.species, /datum/species/protean)) || !H || !P)
to_chat(H, "<span class='warning'>Your Protean modules do not function on yourself.</span>")
deactivate()
return
var/obj/item/organ/internal/nano/refactory/R = P.nano_get_refactory()
if((!R.get_stored_material(MAT_STEEL)))
to_chat(H, "<span class='warning'>Your [holder] is out of steel.</span>")
deactivate()
return
/obj/item/rig_module/protean/healing/accepts_item(var/obj/item/stack/material/steel/S, var/mob/living/user)
if(!istype(S) || !istype(user))
return 0
var/mob/living/P = holder?:myprotean
var/obj/item/organ/internal/nano/refactory/R = P?.nano_get_refactory()
if(R?.add_stored_material(S.material.name,1*S.perunit) && S.use(1))
to_chat(user, "<font color='blue'><b>You directly feed some steel to the [holder].</b></font>")
return 1
return 0

View File

@@ -0,0 +1,152 @@
/mob/living/carbon/human/proc/transform_into_other_human(var/mob/living/carbon/human/character, var/copy_name, var/copy_flavour = TRUE, var/convert_to_prosthetics = FALSE)
/*
name, nickname, flavour, OOC notes
gender, sex
custom species name, custom bodytype, weight, scale, scaling center, sound type, sound freq
custom say verbs
ears, wings, tail, hair, facial hair
ears colors, wings colors, tail colors
body color, prosthetics (if they're a protean) (convert to DSI if protean and not prosthetic), eye color, hair color etc
markings
custom synth markings toggle, custom synth color toggle
digitigrade
blood color
*/
if (copy_name)
name = character.name
nickname = character.nickname
gender = character.gender
identifying_gender = character.identifying_gender
r_eyes = character.r_eyes
g_eyes = character.g_eyes
b_eyes = character.b_eyes
h_style = character.h_style
r_hair = character.r_hair
g_hair = character.g_hair
b_hair = character.b_hair
r_grad = character.r_grad
g_grad = character.g_grad
b_grad = character.b_grad
f_style = character.f_style
r_facial = character.r_facial
g_facial = character.g_facial
b_facial = character.b_facial
r_skin = character.r_skin
g_skin = character.g_skin
b_skin = character.b_skin
s_tone = character.s_tone
h_style = character.h_style
grad_style = character.grad_style
f_style = character.f_style
grad_style = character.grad_style
b_type = character.b_type
synth_color = character.synth_color
r_synth = character.r_synth
g_synth = character.g_synth
b_synth = character.b_synth
synth_markings = character.synth_markings
ear_style = character.ear_style
r_ears = character.r_ears
b_ears = character.b_ears
g_ears = character.g_ears
r_ears2 = character.r_ears2
b_ears2 = character.b_ears2
g_ears2 = character.g_ears2
r_ears3 = character.r_ears3
b_ears3 = character.b_ears3
g_ears3 = character.g_ears3
tail_style = character.tail_style
r_tail = character.r_tail
b_tail = character.b_tail
g_tail = character.g_tail
r_tail2 = character.r_tail2
b_tail2 = character.b_tail2
g_tail2 = character.g_tail2
r_tail3 = character.r_tail3
b_tail3 = character.b_tail3
g_tail3 = character.g_tail3
wing_style = character.wing_style
r_wing = character.r_wing
b_wing = character.b_wing
g_wing = character.g_wing
r_wing2 = character.r_wing2
b_wing2 = character.b_wing2
g_wing2 = character.g_wing2
r_wing3 = character.r_wing3
b_wing3 = character.b_wing3
g_wing3 = character.g_wing3
var/bodytype = character.species?.get_bodytype()
if (convert_to_prosthetics) //should only really be run for proteans
var/list/organs_to_edit = list()
for (var/name in list(BP_TORSO, BP_HEAD, BP_GROIN, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT))
var/obj/item/organ/external/O = character.organs_by_name[name]
if (O)
var/x = organs_to_edit.Find(O.parent_organ)
if (x == 0)
organs_to_edit += name
else
organs_to_edit.Insert(x+(O.robotic == ORGAN_NANOFORM ? 1 : 0), name)
for(var/name in organs_to_edit)
var/obj/item/organ/external/I = character.organs_by_name[name]
var/obj/item/organ/external/O = organs_by_name[name]
if(O)
if(I.robotic >= ORGAN_ROBOT)
O.robotize(I.model)
else
var/dsi_company = GLOB.dsi_to_species[bodytype]
if (!dsi_company)
dsi_company = "DSI - Adaptive"
O.robotize(dsi_company)
for(var/N in character.organs_by_name)
var/obj/item/organ/external/O = organs_by_name[N]
var/obj/item/organ/external/I = character.organs_by_name[N]
O.markings = I.markings.Copy()
markings_len = character.markings_len
descriptors = character.descriptors?.Copy()
if (copy_flavour)
flavor_texts = character.flavor_texts?.Copy()
weight = character.weight
weight_gain = character.weight_gain
weight_loss = character.weight_loss
fuzzy = character.fuzzy
offset_override = character.offset_override //CHOMPEdit
voice_freq = character.voice_freq
if (species && character.species)
species.micro_size_mod = character.species.micro_size_mod
species.icon_scale_x = character.species.icon_scale_x
species.icon_scale_y = character.species.icon_scale_y
update_transform()
resize(character.size_multiplier, animate = TRUE, ignore_prefs = TRUE)
voice_sounds_list = character.voice_sounds_list
species?.blood_color = character.species?.blood_color
dna?.base_species = bodytype
species?.base_species = bodytype
species?.vanity_base_fit = bodytype
if (istype(species, /datum/species/shapeshifter))
wrapped_species_by_ref["\ref[src]"] = bodytype
custom_species = character.custom_species
custom_say = character.custom_say
custom_ask = character.custom_ask
custom_whisper = character.custom_whisper
custom_exclaim = character.custom_exclaim
digitigrade = character.digitigrade
dna?.ResetUIFrom(src)
force_update_limbs()
regenerate_icons()

View File

@@ -17,6 +17,7 @@
var/mudking = FALSE var/mudking = FALSE
var/icodigi = 'modular_chomp/icons/mob/human_races/r_digi.dmi' var/icodigi = 'modular_chomp/icons/mob/human_races/r_digi.dmi'
var/digi_allowed = FALSE var/digi_allowed = FALSE
var/vanity_base_fit //when shapeshifting using vanity_copy_to, this allows you to have add something so they can go back to their original species fit
// Handles non-standard eyes when using a species that utilizes a custom base icon set. // Handles non-standard eyes when using a species that utilizes a custom base icon set.
// Eye data is stored in the head organ, and this needs to be handled specially. // Eye data is stored in the head organ, and this needs to be handled specially.

View File

@@ -0,0 +1,31 @@
/mob/living/carbon/human/proc/shapeshifter_reassemble()
set name = "Complete Reform"
set category = "Abilities"
if(stat || world.time < last_special)
return
last_special = world.time + 50
if (tgui_alert(src, "Are you sure you want to reform yourself? This will reset you to what you look like in your current preferences slot.", "Reform", list("Yes","Cancel")) != "Yes")
return
var/input = tgui_alert(src,{"Include Flavourtext?"},"Reformation",list("Yes","No","Cancel"))
if(input == "Cancel" || !input)
return
var/flavour = 0
if(input == "Yes")
flavour = 1
input = tgui_alert(src,{"Include OOC notes?"},"Reformation",list("Yes","No","Cancel"))
if(input == "Cancel" || !input)
return
var/oocnotes = 0
if(input == "Yes")
oocnotes = 1
to_chat(src, "<span class='notify'>You begin to reform. You will need to remain still.</span>")
visible_message("<span class='notify'>[src] rapidly contorts and shifts!</span>", "<span class='danger'>You begin to reform.</span>")
if (do_after(src, 40,exclusive = TASK_ALL_EXCLUSIVE))
if (client?.prefs)
client.prefs.vanity_copy_to(src, FALSE, flavour, oocnotes, FALSE)
visible_message("<span class='notify'>[src] adopts a new form!</span>", "<span class='danger'>You have reformed.</span>")

View File

@@ -1 +1 @@
#define PROTEAN_EDIBLE_MATERIALS list(MAT_STEEL,MAT_GLASS) #define PROTEAN_EDIBLE_MATERIALS list(MAT_STEEL)

View File

@@ -35,8 +35,9 @@
min_n2 = 0 min_n2 = 0
max_n2 = 0 max_n2 = 0
minbodytemp = 0 minbodytemp = 0
maxbodytemp = INFINITY maxbodytemp = 1100
movement_cooldown = 2 movement_cooldown = 2
hunger_rate = 0
var/mob/living/carbon/human/humanform var/mob/living/carbon/human/humanform
var/obj/item/organ/internal/nano/refactory/refactory var/obj/item/organ/internal/nano/refactory/refactory
@@ -55,6 +56,9 @@
shock_resist = 1 shock_resist = 1
nameset = 1 nameset = 1
holder_type = /obj/item/weapon/holder/protoblob holder_type = /obj/item/weapon/holder/protoblob
var/hiding = 0
vore_icons = 1
vore_active = 1
/datum/say_list/protean_blob /datum/say_list/protean_blob
speak = list("Blrb?","Sqrsh.","Glrsh!") speak = list("Blrb?","Sqrsh.","Glrsh!")
@@ -71,9 +75,11 @@
verbs |= /mob/living/proc/usehardsuit verbs |= /mob/living/proc/usehardsuit
verbs |= /mob/living/simple_mob/protean_blob/proc/nano_partswap verbs |= /mob/living/simple_mob/protean_blob/proc/nano_partswap
verbs |= /mob/living/simple_mob/protean_blob/proc/nano_regenerate verbs |= /mob/living/simple_mob/protean_blob/proc/nano_regenerate
verbs |= /mob/living/simple_mob/protean_blob/proc/nano_metalnom
verbs |= /mob/living/simple_mob/protean_blob/proc/nano_blobform verbs |= /mob/living/simple_mob/protean_blob/proc/nano_blobform
verbs |= /mob/living/simple_mob/protean_blob/proc/nano_rig_transform verbs |= /mob/living/simple_mob/protean_blob/proc/nano_rig_transform
verbs |= /mob/living/simple_mob/protean_blob/proc/appearance_switch verbs |= /mob/living/simple_mob/protean_blob/proc/appearance_switch
verbs |= /mob/living/simple_mob/protean_blob/proc/nano_latch
verbs -= /mob/living/simple_mob/proc/nutrition_heal verbs -= /mob/living/simple_mob/proc/nutrition_heal
else else
update_icon() update_icon()
@@ -103,6 +109,13 @@
set hidden = 1 set hidden = 1
humanform.nano_blobform() humanform.nano_blobform()
/mob/living/simple_mob/protean_blob/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 = 1
humanform.nano_metalnom()
/mob/living/simple_mob/protean_blob/proc/nano_rig_transform() /mob/living/simple_mob/protean_blob/proc/nano_rig_transform()
set name = "Modify Form - Hardsuit" set name = "Modify Form - Hardsuit"
set desc = "Allows a protean to retract its mass into its hardsuit module at will." set desc = "Allows a protean to retract its mass into its hardsuit module at will."
@@ -117,6 +130,13 @@
set hidden = 1 set hidden = 1
humanform.appearance_switch() humanform.appearance_switch()
/mob/living/simple_mob/protean_blob/proc/nano_latch()
set name = "Latch/Unlatch host"
set desc = "Allows a protean to forcibly latch or unlatch from a host."
set category = "Abilities"
set hidden = 1
humanform.nano_latch()
/mob/living/simple_mob/protean_blob/Login() /mob/living/simple_mob/protean_blob/Login()
..() ..()
plane_holder.set_vis(VIS_AUGMENTED, 1) plane_holder.set_vis(VIS_AUGMENTED, 1)
@@ -154,21 +174,25 @@
/mob/living/simple_mob/protean_blob/speech_bubble_appearance() /mob/living/simple_mob/protean_blob/speech_bubble_appearance()
return "synthetic" return "synthetic"
/mob/living/simple_mob/protean_blob/get_available_emotes()
return global._robot_default_emotes.Copy()
/mob/living/simple_mob/protean_blob/init_vore() /mob/living/simple_mob/protean_blob/init_vore()
return //Don't make a random belly, don't waste your time return //Don't make a random belly, don't waste your time
/mob/living/simple_mob/protean_blob/isSynthetic() /mob/living/simple_mob/protean_blob/isSynthetic()
return TRUE // yup return TRUE // yup
/mob/living/simple_mob/protean_blob/get_available_emotes()
var/list/fulllist = global._robot_default_emotes.Copy()
fulllist |= global._human_default_emotes //they're living nanites, they can make whatever sounds they want
return fulllist
/mob/living/simple_mob/protean_blob/Stat() /mob/living/simple_mob/protean_blob/Stat()
..() ..()
if(humanform) if(humanform)
humanform.species.Stat(humanform) humanform.species.Stat(humanform)
/mob/living/simple_mob/protean_blob/updatehealth() /mob/living/simple_mob/protean_blob/updatehealth()
if(humanform.nano_dead_check(src))
return
if(!humanform) if(!humanform)
return ..() return ..()
@@ -180,7 +204,7 @@
//Alive, becoming dead //Alive, becoming dead
if((stat < DEAD) && (health <= 0)) if((stat < DEAD) && (health <= 0))
death() humanform.death()
nutrition = humanform.nutrition nutrition = humanform.nutrition
@@ -253,6 +277,12 @@
else else
return ..() return ..()
/mob/living/simple_mob/protean_blob/adjust_nutrition(amount)
if(humanform)
return humanform.adjust_nutrition(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/emp_act(severity) /mob/living/simple_mob/protean_blob/emp_act(severity)
if(humanform) if(humanform)
return humanform.emp_act(severity) return humanform.emp_act(severity)
@@ -266,6 +296,8 @@
return ..() return ..()
/mob/living/simple_mob/protean_blob/rad_act(severity) /mob/living/simple_mob/protean_blob/rad_act(severity)
if(istype(loc, /obj/item/weapon/rig))
return //Don't irradiate us while we're in rig mode
if(humanform) if(humanform)
return humanform.rad_act(severity) return humanform.rad_act(severity)
else else
@@ -277,36 +309,52 @@
else else
return ..() return ..()
/mob/living/simple_mob/protean_blob/death(gibbed, deathmessage = "dissolves away, leaving only a few spare parts!") /mob/living/simple_mob/protean_blob/death(gibbed, deathmessage = "Coalesces inwards, retreating into their core componants")
if(humanform) if(humanform)
humanform.death(gibbed, deathmessage) humanform.death(gibbed, deathmessage)
else else
animate(src, alpha = 0, time = 2 SECONDS) animate(src, alpha = 0, time = 2 SECONDS)
sleep(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() /mob/living/simple_mob/protean_blob/Life()
. = ..() . = ..()
if(. && istype(refactory) && humanform) if(!humanform.nano_dead_check(src))
if(!healing && (human_brute || human_burn) && refactory.get_stored_material(MAT_STEEL) >= 100) if(. && istype(refactory) && humanform)
healing = humanform.add_modifier(/datum/modifier/protean/steel, origin = refactory) if(!healing && (human_brute || human_burn) && refactory.get_stored_material(MAT_STEEL) >= 100)
else if(healing && !(human_brute || human_burn)) healing = humanform.add_modifier(/datum/modifier/protean/steel, origin = refactory)
else if(healing && !(human_brute || human_burn))
healing.expire()
healing = null
else
if(healing)
healing.expire() healing.expire()
healing = null healing = null
/mob/living/simple_mob/protean_blob/lay_down() /mob/living/simple_mob/protean_blob/lay_down()
var/obj/item/weapon/rig/rig = src.get_rig()
if(rig)
rig.force_rest(src)
return
..() ..()
if(resting)
/mob/living/simple_mob/protean_blob/verb/prot_hide()
set name = "Hide Self"
set desc = "Disperses your mass into a thin viel, making a trap to snatch prey with, or simply hide."
set category = "Abilities"
if(!hiding)
icon_state = "hide"
sleep(7)
mouse_opacity = 0 mouse_opacity = 0
plane = ABOVE_OBJ_PLANE plane = ABOVE_OBJ_PLANE
hiding = 1
else else
mouse_opacity = 1 mouse_opacity = 1
icon_state = "wake" icon_state = "wake"
plane = MOB_PLANE plane = MOB_PLANE
sleep(7) sleep(7)
update_icon() update_icon()
hiding = 0
//Potential glob noms //Potential glob noms
if(can_be_drop_pred) //Toggleable in vore panel if(can_be_drop_pred) //Toggleable in vore panel
var/list/potentials = living_mobs(0) var/list/potentials = living_mobs(0)
@@ -317,7 +365,17 @@
target.buckled.unbuckle_mob(target, force = TRUE) target.buckled.unbuckle_mob(target, force = TRUE)
target.forceMove(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>") to_chat(target,"<span class='warning'>\The [src] quickly engulfs you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!</span>")
update_canmove()
/mob/living/simple_mob/protean_blob/update_canmove()
if(hiding)
canmove = 0
return canmove
else
..()
/* Don't need this block anymore since our Prots have hands
/mob/living/simple_mob/protean_blob/attack_target(var/atom/A) /mob/living/simple_mob/protean_blob/attack_target(var/atom/A)
if(refactory && istype(A,/obj/item/stack/material)) if(refactory && istype(A,/obj/item/stack/material))
var/obj/item/stack/material/S = A var/obj/item/stack/material/S = A
@@ -347,6 +405,7 @@
I.forceMove(vore_selected) I.forceMove(vore_selected)
else else
return ..() return ..()
*/
/mob/living/simple_mob/protean_blob/attackby(var/obj/item/O, var/mob/user) /mob/living/simple_mob/protean_blob/attackby(var/obj/item/O, var/mob/user)
if(refactory && istype(O,/obj/item/stack/material)) if(refactory && istype(O,/obj/item/stack/material))
@@ -385,94 +444,94 @@
return "[humanform.custom_species ? humanform.custom_species : (humanform.species ? humanform.species.name : "Protean")]" return "[humanform.custom_species ? humanform.custom_species : (humanform.species ? humanform.species.name : "Protean")]"
return "Protean" return "Protean"
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. // Helpers - Unsafe, WILL perform change.
/mob/living/carbon/human/proc/nano_intoblob(force) /mob/living/carbon/human/proc/nano_intoblob(force)
if(loc == /obj/item/weapon/rig/protean) if(!force && !isturf(loc) && !loc == /obj/item/weapon/rig/protean)
return
if(!force && !isturf(loc))
to_chat(src,"<span class='warning'>You can't change forms while inside something.</span>") to_chat(src,"<span class='warning'>You can't change forms while inside something.</span>")
return return
to_chat(src, "<span class='notice'>You rapidly disassociate your form</span>")
if(force || do_after(src,20,exclusive = TASK_ALL_EXCLUSIVE))
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()
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. var/client/C = client
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()
var/client/C = client //Record where they should go
var/atom/creation_spot = drop_location()
//Record where they should go //Create our new blob
var/atom/creation_spot = drop_location() var/mob/living/simple_mob/protean_blob/blob = new(creation_spot,src)
//Create our new blob //Size update
var/mob/living/simple_mob/protean_blob/blob = new(creation_spot,src) blob.transform = matrix()*size_multiplier
blob.size_multiplier = size_multiplier
//Size update //dir update
blob.transform = matrix()*size_multiplier blob.dir = dir
blob.size_multiplier = size_multiplier
if(l_hand) drop_from_inventory(l_hand) if(l_hand) drop_l_hand()
if(r_hand) drop_from_inventory(r_hand) if(r_hand) drop_r_hand()
//Put our owner in it (don't transfer var/mind) //Put our owner in it (don't transfer var/mind)
blob.ckey = ckey blob.ckey = ckey
blob.ooc_notes = ooc_notes blob.ooc_notes = ooc_notes
temporary_form = blob temporary_form = blob
var/obj/item/device/radio/R = null var/obj/item/device/radio/R = null
if(isradio(l_ear)) if(isradio(l_ear))
R = l_ear R = l_ear
if(isradio(r_ear)) if(isradio(r_ear))
R = r_ear R = r_ear
if(R) if(R)
blob.mob_radio = R blob.mob_radio = R
R.forceMove(blob) R.forceMove(blob)
if(wear_id) if(wear_id)
blob.myid = wear_id blob.myid = wear_id
wear_id.forceMove(blob) wear_id.forceMove(blob)
//Mail them to nullspace //Mail them to nullspace
moveToNullspace() moveToNullspace()
//Message //Message
blob.visible_message("<b>[src.name]</b> collapses into a gooey blob!") blob.visible_message("<b>[src.name]</b> collapses into a gooey blob!")
//Duration of the to_puddle iconstate that the blob starts with //Duration of the to_puddle iconstate that the blob starts with
sleep(13) sleep(13)
blob.update_icon() //Will remove the collapse anim blob.update_icon() //Will remove the collapse anim
//Transfer vore organs //Transfer vore organs
blob.vore_organs = vore_organs.Copy() blob.vore_organs = vore_organs.Copy()
blob.vore_selected = vore_selected blob.vore_selected = vore_selected
for(var/obj/belly/B as anything in vore_organs) for(var/obj/belly/B as anything in vore_organs)
B.forceMove(blob) B.forceMove(blob)
B.owner = blob B.owner = blob
vore_organs.Cut() vore_organs.Cut()
//We can still speak our languages! //We can still speak our languages!
blob.languages = languages.Copy() blob.languages = languages.Copy()
blob.name = real_name blob.name = real_name
blob.voice_name = name blob.real_name = real_name
var/datum/species/protean/S = src.species blob.voice_name = name
blob.icon_living = S.blob_appearance var/datum/species/protean/S = src.species
blob.item_state = S.blob_appearance blob.icon_living = S.blob_appearance
blob.update_icon() blob.item_state = S.blob_appearance
blob.icon_rest = S.blob_appearance + "_rest"
blob.update_icon()
//Flip them to the protean panel //Flip them to the protean panel
addtimer(CALLBACK(src, .proc/nano_set_panel, C), 4) addtimer(CALLBACK(src, .proc/nano_set_panel, C), 4)
//Return our blob in case someone wants it //Return our blob in case someone wants it
return blob return blob
else
to_chat(src, "<span class='warning'>You must remain still to blobform!</span>")
//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. //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) /proc/remove_micros(var/src, var/mob/root)
@@ -489,87 +548,128 @@ var/global/list/disallowed_protean_accessories = list(
if(istype(loc, /obj/item/weapon/rig/protean)) if(istype(loc, /obj/item/weapon/rig/protean))
var/obj/item/weapon/rig/protean/prig = loc var/obj/item/weapon/rig/protean/prig = loc
to_chat(src, "You attempt to interface with the [prig].") to_chat(src, "You attempt to interface with the [prig].")
prig.ui_interact(src, interactive_state) prig.tgui_interact(src)
else else
to_chat(src, "You are not in RIG form.") 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) /mob/living/carbon/human/proc/nano_outofblob(var/mob/living/simple_mob/protean_blob/blob, force)
if(!istype(blob)) if(!istype(blob))
return return
if(blob.loc == /obj/item/weapon/rig/protean) //CHOMP Add if(blob.loc == /obj/item/weapon/rig/protean)
return //CHOMP Add return
if(!force && !isturf(blob.loc)) if(!force && !isturf(blob.loc))
to_chat(blob,"<span class='warning'>You can't change forms while inside something.</span>") to_chat(blob,"<span class='warning'>You can't change forms while inside something.</span>")
return return
to_chat(src, "<span class='notice'>You rapidly reassemble your form</span>")
if(force || do_after(blob,20,exclusive = TASK_ALL_EXCLUSIVE))
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()
if(buckled) var/client/C = blob.client
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()
var/client/C = blob.client //Stop healing if we are
if(blob.healing)
blob.healing.expire()
//Stop healing if we are if(blob.mob_radio)
if(blob.healing) blob.mob_radio.forceMove(src)
blob.healing.expire() blob.mob_radio = null
if(blob.myid)
blob.myid.forceMove(src)
blob.myid = null
if(blob.l_hand) blob.drop_from_inventory(blob.l_hand) //Play the animation
if(blob.r_hand) blob.drop_from_inventory(blob.r_hand) blob.icon_state = "from_puddle"
if(blob.mob_radio) //Message
blob.mob_radio.forceMove(src) blob.visible_message("<b>[src.name]</b> reshapes into a humanoid appearance!")
blob.mob_radio = null
if(blob.myid)
blob.myid.forceMove(src)
blob.myid = null
//Play the animation //Size update
blob.icon_state = "from_puddle" resize(blob.size_multiplier, FALSE, TRUE, ignore_prefs = TRUE)
//Message //Duration of above animation
blob.visible_message("<b>[src.name]</b> reshapes into a humanoid appearance!") sleep(8)
//Duration of above animation //Record where they should go
sleep(8) var/atom/reform_spot = blob.drop_location()
//Record where they should go //dir update
var/atom/reform_spot = blob.drop_location() dir = blob.dir
//Size update //Move them back where the blob was
resize(blob.size_multiplier, FALSE, ignore_prefs = TRUE) forceMove(reform_spot)
//Move them back where the blob was if(blob.l_hand) blob.drop_l_hand()
forceMove(reform_spot) if(blob.r_hand) blob.drop_r_hand()
//Put our owner in it (don't transfer var/mind) //Put our owner in it (don't transfer var/mind)
ckey = blob.ckey ckey = blob.ckey
ooc_notes = blob.ooc_notes // Lets give the protean any updated notes from blob form. ooc_notes = blob.ooc_notes // Lets give the protean any updated notes from blob form.
temporary_form = null temporary_form = null
//Transfer vore organs //Transfer vore organs
vore_organs = blob.vore_organs.Copy() vore_organs = blob.vore_organs.Copy()
vore_selected = blob.vore_selected vore_selected = blob.vore_selected
for(var/obj/belly/B as anything in blob.vore_organs) for(var/obj/belly/B as anything in blob.vore_organs)
B.forceMove(src) B.forceMove(src)
B.owner = src B.owner = src
languages = blob.languages.Copy() languages = blob.languages.Copy()
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. 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 //Get rid of friend blob
qdel(blob) qdel(blob)
//Flip them to the protean panel //Flip them to the protean panel
addtimer(CALLBACK(src, .proc/nano_set_panel, C), 4) addtimer(CALLBACK(src, .proc/nano_set_panel, C), 4)
//Return ourselves in case someone wants it //Return ourselves in case someone wants it
return src return src
else
to_chat(src, "<span class='warning'>You must remain still to reshape yourself!</span>")
/mob/living/carbon/human/proc/nano_set_panel(var/client/C) /mob/living/carbon/human/proc/nano_set_panel(var/client/C)
if(C) if(C)
C.statpanel = "Protean" C.statpanel = "Protean"
/mob/living/simple_mob/protean_blob/ClickOn(var/atom/A, var/params)
if(istype(loc, /obj/item/weapon/rig/protean))
HardsuitClickOn(A)
..()
/mob/living/simple_mob/protean_blob/can_use_rig()
return 1
/mob/living/simple_mob/protean_blob/HardsuitClickOn(var/atom/A, var/alert_ai = 0)
if(istype(loc, /obj/item/weapon/rig/protean))
var/obj/item/weapon/rig/protean/prig = loc
if(istype(prig) && !prig.offline && prig.selected_module)
if(!prig.ai_can_move_suit(src))
return 0
prig.selected_module.engage(A, alert_ai)
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
setClickCooldown(get_attack_speed())
return 1
return 0
//Don't eat yourself, idiot
/mob/living/simple_mob/protean_blob/CanStumbleVore(mob/living/target)
if(target == humanform)
return FALSE
return ..()
/mob/living/carbon/human/CanStumbleVore(mob/living/target)
if(istype(target, /mob/living/simple_mob/protean_blob))
var/mob/living/simple_mob/protean_blob/PB = target
if(PB.humanform == src)
return FALSE
return ..()
/mob/living/simple_mob/protean_blob/handle_mutations_and_radiation()
humanform.handle_mutations_and_radiation()

View File

@@ -4,79 +4,82 @@
encased = FALSE encased = FALSE
max_damage = 100 // <-- This is different from the rest max_damage = 100 // <-- This is different from the rest
min_broken_damage = 1000 min_broken_damage = 1000
vital = TRUE // <-- This is different from the rest vital = 1
model = "protean" model = "protean"
/obj/item/organ/external/groin/unbreakable/nano /obj/item/organ/external/groin/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 // <-- This is different from the rest max_damage = 100
min_broken_damage = 1000 //Multiple min_broken_damage = 1000 //Multiple
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/head/unbreakable/nano /obj/item/organ/external/head/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 100
min_broken_damage = 1000 //Inheritance min_broken_damage = 1000 //Inheritance
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/arm/unbreakable/nano /obj/item/organ/external/arm/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 //Please min_broken_damage = 1000 //Please
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/arm/right/unbreakable/nano /obj/item/organ/external/arm/right/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 min_broken_damage = 1000
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/leg/unbreakable/nano /obj/item/organ/external/leg/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 min_broken_damage = 1000
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/leg/right/unbreakable/nano /obj/item/organ/external/leg/right/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 min_broken_damage = 1000
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/hand/unbreakable/nano /obj/item/organ/external/hand/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 min_broken_damage = 1000
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/hand/right/unbreakable/nano /obj/item/organ/external/hand/right/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 min_broken_damage = 1000
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/foot/unbreakable/nano /obj/item/organ/external/foot/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 min_broken_damage = 1000
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/foot/right/unbreakable/nano /obj/item/organ/external/foot/right/unbreakable/nano
robotic = ORGAN_NANOFORM robotic = ORGAN_NANOFORM
encased = FALSE encased = FALSE
max_damage = 100 max_damage = 65
min_broken_damage = 1000 min_broken_damage = 1000
vital = FALSE vital = 0
model = "protean" model = "protean"
/obj/item/organ/external/head/unbreakable/nano/disfigure()
return //No way to repair disfigured prots
// // // Internal Organs // // // Internal Organs
/obj/item/organ/internal/nano /obj/item/organ/internal/nano
robotic = ORGAN_ROBOT robotic = ORGAN_ROBOT
@@ -101,7 +104,7 @@
organ_tag = O_FACT organ_tag = O_FACT
parent_organ = BP_TORSO parent_organ = BP_TORSO
var/list/materials = list(MAT_STEEL = 0, MAT_GLASS = 0) var/list/materials = list(MAT_STEEL = 0)
var/max_storage = 10000 var/max_storage = 10000
organ_verbs = list( organ_verbs = list(
/mob/living/carbon/human/proc/reagent_purge /mob/living/carbon/human/proc/reagent_purge
@@ -164,9 +167,11 @@
icon = initial(icon) icon = initial(icon)
icon_state = "posi1" icon_state = "posi1"
stored_mmi.icon_state = "posi1" stored_mmi.icon_state = "posi1"
stored_mmi.brainmob.languages = owner.languages stored_mmi.brainmob.languages = owner.languages
/obj/item/organ/internal/mmi_holder/posibrain/nano/emp_act()
return //Proteans handle EMP's differently
// The 'out on the ground' object, not the organ holder // The 'out on the ground' object, not the organ holder
/obj/item/device/mmi/digital/posibrain/nano /obj/item/device/mmi/digital/posibrain/nano
name = "protean posibrain" name = "protean posibrain"
@@ -195,4 +200,17 @@
icon_state = "posi1" icon_state = "posi1"
/obj/item/organ/internal/nano/digest_act(atom/movable/item_storage = null) /obj/item/organ/internal/nano/digest_act(atom/movable/item_storage = null)
return FALSE return FALSE
/datum/design/item/protean_reboot
name = "Protean Reboot Programmer"
id = "protean_reboot"
materials = list(MAT_STEEL = 2000, MAT_GLASS = 1000, MAT_PLASTEEL = 10000)
build_path = /obj/item/device/protean_reboot
sort_string = "JVAAZ"
/obj/item/device/protean_reboot
name = "Protean Reboot Programmer"
desc = "A small, highly specialized programmer used to form the basis of a Protean swarm. A necessary component in reconstituting a Protean who has lost total body cohesion."
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "reboot"

View File

@@ -12,6 +12,9 @@
var/mob/living/caller = src var/mob/living/caller = src
if(temporary_form) if(temporary_form)
caller = temporary_form caller = temporary_form
if(nano_dead_check(caller))
to_chat(caller, "<span class='warning'>You need to be repaired first before you can act!</span>")
return
if(stat) if(stat)
to_chat(caller,"<span class='warning'>You must be awake and standing to perform this action!</span>") to_chat(caller,"<span class='warning'>You must be awake and standing to perform this action!</span>")
return return
@@ -26,7 +29,7 @@
to_chat(caller,"<span class='warning'>You don't have a working refactory module!</span>") to_chat(caller,"<span class='warning'>You don't have a working refactory module!</span>")
return return
var/choice = tgui_input_list(src,"Pick the bodypart to change:", "Refactor - One Bodypart", species.has_limbs) var/choice = tgui_input_list(caller,"Pick the bodypart to change:", "Refactor - One Bodypart", species.has_limbs)
if(!choice) if(!choice)
return return
@@ -50,7 +53,7 @@
else else
blob = temporary_form blob = temporary_form
active_regen = 1 active_regen = 1
if(do_after(blob,5 SECONDS)) if(do_after(blob,50,exclusive = TASK_ALL_EXCLUSIVE))
var/list/limblist = species.has_limbs[choice] var/list/limblist = species.has_limbs[choice]
var/limbpath = limblist["path"] var/limbpath = limblist["path"]
var/obj/item/organ/external/new_eo = new limbpath(src) var/obj/item/organ/external/new_eo = new limbpath(src)
@@ -87,113 +90,120 @@
update_icons_body() update_icons_body()
/mob/living/carbon/human/proc/nano_regenerate() /mob/living/carbon/human/proc/nano_regenerate()
set name = "Total Reassembly (wip)" set name = "Total Reassembly"
set desc = "Completely reassemble yourself from whatever save slot you have loaded in preferences. Assuming you meet the requirements." set desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded."
set category = "Abilities" set category = "Abilities"
set hidden = 1 set hidden = 1
var/mob/living/caller = src var/mob/living/caller = src
if(temporary_form) if(temporary_form)
caller = temporary_form caller = temporary_form
to_chat(caller,"<span class ='warning'>This function isn't coded yet. Soon, my child.</span>") var/input = tgui_alert(caller,{"Do you want to rebuild or reassemble yourself?
else Rebuilding will cost 10,000 steel and will rebuild all of your limbs as well as repair all damage over a 40s period.
to_chat(src,"<span class ='warning'>This function isn't coded yet. Soon, my child.</span>") Reassembling costs no steel and will copy the appearance data of your currently loaded save slot."},"Reassembly",list("Rebuild","Reassemble","Cancel"))
if(input == "Cancel" || !input)
/*if(stat)
to_chat(src,"<span class='warning'>You must be awake and standing to perform this action!</span>")
return return
if(input == "Rebuild")
if(!isturf(loc)) var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
to_chat(src,"<span class='warning'>You need more space to perform this action!</span>") if(refactory.get_stored_material(MAT_STEEL) >= 10000)
return to_chat(caller, "<span class='notify'>You begin to rebuild. You will need to remain still.</span>")
if(do_after(caller, 400,exclusive = TASK_ALL_EXCLUSIVE))
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory() if(species?:OurRig) //Unsafe, but we should only ever be using this with a Protean
//Missing the organ that does this species?:OurRig?:make_alive(src,1) //Re-using this proc
if(!istype(refactory)) refactory.use_stored_material(MAT_STEEL,refactory.get_stored_material(MAT_STEEL)) //Use all of our steel
to_chat(src,"<span class='warning'>You don't have a working refactory module!</span>") else
return to_chat(caller, "<span class='usrdanger'>Somehow, you are missing your protean rig. You are unable to rebuild without one.</span>")
//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(species?.base_species 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 = 1
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 = 0
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 = 1
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 else
to_chat(src, "<span class='critical'>Your refactoring has failed.</span>") to_chat(caller, "<span class='warning'>You do not have enough steel stored for this operation.</span>")
to_chat(blob, "<span class='critical'>Your refactoring has failed!</span>")
else else
to_chat(src, "<span class='critical'>Your refactoring is interrupted.</span>") input = tgui_alert(caller,{"Include Flavourtext?"},"Reassembly",list("Yes","No","Cancel"))
to_chat(blob, "<span class='critical'>Your refactoring is interrupted!</span>") if(input == "Cancel" || !input)
active_regen = 0 return
nano_outofblob(blob)*/ var/flavour = 0
if(input == "Yes")
flavour = 1
input = tgui_alert(caller,{"Include OOC notes?"},"Reassembly",list("Yes","No","Cancel"))
if(input == "Cancel" || !input)
return
var/oocnotes = 0
if(input == "Yes")
oocnotes = 1
to_chat(caller, "<span class='notify'>You begin to reassemble. You will need to remain still.</span>")
caller.visible_message("<span class='notify'>[caller] rapidly contorts and shifts!</span>", "<span class='danger'>You begin to reassemble.</span>")
if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE))
if(caller.client.prefs) //Make sure we didn't d/c
var/obj/item/weapon/rig/protean/Rig = species?:OurRig
caller.client.prefs.vanity_copy_to(src, FALSE, flavour, oocnotes, TRUE)
species?:OurRig = Rig //Get a reference to our Rig and put it back after reassembling
caller.visible_message("<span class='notify'>[caller] adopts a new form!</span>", "<span class='danger'>You have reassembled.</span>")
/mob/living/carbon/human/proc/nano_copy_body()
set name = "Copy Form"
set desc = "If you are aggressively grabbing someone, with their consent, you can turn into a copy of them. (Without their name)."
set category = "Abilities"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
var/grabbing_but_not_enough
var/mob/living/carbon/human/victim = null
for(var/obj/item/weapon/grab/G in caller)
if(G.state < GRAB_AGGRESSIVE)
grabbing_but_not_enough = TRUE
return
else
victim = G.affecting
if (!victim)
if (grabbing_but_not_enough)
to_chat(caller, "<span class='warning'>You need a better grip to do that!</span>")
else
to_chat(caller, "<span class='notice'>You need to be aggressively grabbing someone before you can copy their form.</span>")
return
if (!istype(victim))
to_chat(caller, "<span class='warning'>You can only perform this on human mobs!</span>")
return
if (!victim.client)
to_chat(caller, "<span class='notice'>The person you try this on must have a client!</span>")
return
to_chat(caller, "<span class='notice'>Waiting for other person's consent.</span>")
var/consent = tgui_alert(victim, "Allow [src] to copy what you look like?", "Consent", list("Yes", "No"))
if (consent != "Yes")
to_chat(caller, "<span class='notice'>They declined your request.</span>")
return
var/input = tgui_alert(caller,{"Copy [victim]'s flavourtext?"},"Copy Form",list("Yes","No","Cancel"))
if(input == "Cancel" || !input)
return
var/flavour = 0
if(input == "Yes")
flavour = 1
var/checking = FALSE
for(var/obj/item/weapon/grab/G in caller)
if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE)
checking = TRUE
if (!checking)
to_chat(caller, "<span class='warning'>You lost your grip on [victim]!</span>")
return
to_chat(caller, "<span class='notify'>You begin to reassemble into [victim]. You will need to remain still.</span>")
caller.visible_message("<span class='notify'>[caller] rapidly contorts and shifts!</span>", "<span class='danger'>You begin to reassemble into [victim].</span>")
if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE))
checking = FALSE
for(var/obj/item/weapon/grab/G in caller)
if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE)
checking = TRUE
if (!checking)
to_chat(caller, "<span class='warning'>You lost your grip on [victim]!</span>")
return
if(caller.client) //Make sure we didn't d/c
var/obj/item/weapon/rig/protean/Rig = species?:OurRig
transform_into_other_human(victim, FALSE, flavour, TRUE)
species?:OurRig = Rig //Get a reference to our Rig and put it back after reassembling
caller.visible_message("<span class='notify'>[caller] adopts the form of [victim]!</span>", "<span class='danger'>You have reassembled into [victim].</span>")
//// ////
// Storing metal // Storing metal
@@ -204,15 +214,22 @@
set category = "Abilities" set category = "Abilities"
set hidden = 1 set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
if(nano_dead_check(caller))
to_chat(caller, "<span class='warning'>You need to be repaired first before you can act!</span>")
return
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory() var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this //Missing the organ that does this
if(!istype(refactory)) if(!istype(refactory))
to_chat(src,"<span class='warning'>You don't have a working refactory module!</span>") to_chat(caller,"<span class='warning'>You don't have a working refactory module!</span>")
return return
var/held = get_active_hand() var/held = caller.get_active_hand()
if(!istype(held,/obj/item/stack/material)) 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>") to_chat(caller,"<span class='warning'>You aren't holding a stack of materials in your active hand!</span>")
return return
var/obj/item/stack/material/matstack = held var/obj/item/stack/material/matstack = held
@@ -221,38 +238,45 @@
for(var/material in PROTEAN_EDIBLE_MATERIALS) for(var/material in PROTEAN_EDIBLE_MATERIALS)
if(material == substance) allowed = 1 if(material == substance) allowed = 1
if(!allowed) if(!allowed)
to_chat(src,"<span class='warning'>You can't process [substance]!</span>") to_chat(caller,"<span class='warning'>You can't process [substance]!</span>")
return //Only a few things matter, the rest are best not cluttering the lists. return
var/howmuch = tgui_input_number(src,"How much do you want to store? (0-[matstack.get_amount()])","Select amount",null,matstack.get_amount(),0) var/howmuch = tgui_input_number(caller,"How much do you want to store? (0-[matstack.get_amount()])","Select amount",null,matstack.get_amount(),0)
if(!howmuch || matstack != get_active_hand() || howmuch > matstack.get_amount()) if(!howmuch || matstack != caller.get_active_hand() || howmuch > matstack.get_amount())
return //Quietly fail return //Quietly fail
var/actually_added = refactory.add_stored_material(substance,howmuch*matstack.perunit) var/actually_added = refactory.add_stored_material(substance,howmuch*matstack.perunit)
matstack.use(CEILING((actually_added/matstack.perunit), 1)) matstack.use(CEILING((actually_added/matstack.perunit), 1))
if(actually_added && actually_added < howmuch) 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>") to_chat(caller,"<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>") visible_message("<span class='notice'>[caller] nibbles some of the [substance] right off the stack!</span>")
else if(actually_added) else if(actually_added)
to_chat(src,"<span class='notice'>You store [actually_added] units of [substance].</span>") to_chat(caller,"<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>") visible_message("<span class='notice'>[caller] devours some of the [substance] right off the stack!</span>")
else else
to_chat(src,"<span class='notice'>You're completely capped out on [substance]!</span>") to_chat(caller,"<span class='notice'>You're completely capped out on [substance]!</span>")
//// ////
// Blob Form // Blob Form
//// ////
/mob/living/carbon/human/proc/nano_blobform() /mob/living/carbon/human/proc/nano_blobform(var/forced)
set name = "Toggle Blobform" set name = "Toggle Blobform"
set desc = "Switch between amorphous and humanoid forms." set desc = "Switch between amorphous and humanoid forms."
set category = "Abilities" set category = "Abilities"
set hidden = 1 set hidden = 1
if(nano_dead_check(src))
return
if(forced)
if(temporary_form)
nano_outofblob(temporary_form, forced)
else
nano_intoblob(forced)
return
var/atom/movable/to_locate = temporary_form || src var/atom/movable/to_locate = temporary_form || src
if(!isturf(to_locate.loc)) if(!isturf(to_locate.loc) && !forced)
to_chat(to_locate,"<span class='warning'>You need more space to perform this action!</span>") to_chat(to_locate,"<span class='warning'>You need more space to perform this action!</span>")
return return
//Blob form //Blob form
if(temporary_form) if(temporary_form)
if(temporary_form.stat) if(temporary_form.stat)
@@ -282,7 +306,7 @@
to_chat(src,"<span class='warning'>You must be awake and standing to perform this action!</span>") to_chat(src,"<span class='warning'>You must be awake and standing to perform this action!</span>")
return return
var/new_species = tgui_input_list(usr, "Please select a species to emulate.", "Shapeshifter Body", GLOB.playable_species) var/new_species = tgui_input_list(usr, "Please select a species to emulate.", "Shapeshifter Body", list(species?.vanity_base_fit)|GLOB.playable_species)
if(new_species) if(new_species)
species?.base_species = new_species // Really though you better have a 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 regenerate_icons() //Expensive, but we need to recrunch all the icons we're wearing
@@ -290,98 +314,62 @@
//// ////
// Rig Transform // Rig Transform
//// ////
/mob/living/carbon/human/proc/nano_rig_transform() /mob/living/carbon/human/proc/nano_rig_transform(var/forced)
set name = "Modify Form - Hardsuit" set name = "Modify Form - Hardsuit"
set desc = "Allows a protean to retract its mass into its hardsuit module at will." set desc = "Allows a protean to retract its mass into its hardsuit module at will."
set category = "Abilities" set category = "Abilities"
set hidden = 1 set hidden = 1
if(!temporary_form) //If you're human, force you into blob form before rig'ing var/mob/living/caller = src
nano_blobform() if(temporary_form)
spawn(2) caller = temporary_form
if(nano_dead_check(src))
to_chat(caller, "<span class='warning'>You need to be repaired first before you can act!</span>")
if(istype(src.species, /datum/species/protean))
var/datum/species/protean/S = src.species
var/mob/living/simple_mob/protean_blob/P = temporary_form
if(S.OurRig) //Do we even have a RIG?
if(P.loc == S.OurRig) //we're inside our own RIG
if(S.OurRig.wearer) //We're being worn. Engulf em', if prefs align.. otherwise just drop off.
var/mob/living/carbon/human/victim = S.OurRig.wearer
victim.drop_from_inventory(S.OurRig)
if(P.can_be_drop_pred && victim.devourable && victim.can_be_drop_prey)
if(P.vore_selected)
perform_the_nom(P,victim,P,P.vore_selected,1)
P.forceMove(get_turf(S.OurRig))
S.OurRig.forceMove(src)
S.OurRig.myprotean = null
src.equip_to_slot_if_possible(S.OurRig, slot_back)
S.OurRig.Moved()
P.has_hands = 1
else //We're not in our own RIG
if(P.stat)
to_chat(P,"<span class='warning'>You can only do this while not stunned.</span>")
else
if(P.l_hand)
drop_from_inventory(P.l_hand)
if(P.r_hand)
drop_from_inventory(P.r_hand)
S.OurRig.myprotean = P
src.drop_from_inventory(S.OurRig)
P.forceMove(S.OurRig)
P.reset_view()
else //Make one if not
to_chat(temporary_form, "<span class='warning'>Somehow, your RIG got disconnected from your species. A new one has been created for you, contact a coder.</span>")
new /obj/item/weapon/rig/protean(src,src)
////
// 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 = 1
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 return
to_chat(caller, "<span class='notice'>You rapidly condense into your module.</span>")
if(forced || do_after(caller,20,exclusive = TASK_ALL_EXCLUSIVE))
if(!temporary_form) //If you're human, force you into blob form before rig'ing
nano_blobform(forced)
spawn(2)
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." if(istype(src.species, /datum/species/protean))
var/new_size = tgui_input_number(user, nagmessage, "Pick a Size", user.size_multiplier*100, 600, 1) var/datum/species/protean/S = src.species
if(!new_size || !size_range_check(new_size)) var/mob/living/simple_mob/protean_blob/P = temporary_form
return if(S.OurRig) //Do we even have a RIG?
if(P.loc == S.OurRig) //we're inside our own RIG
var/size_factor = new_size/100 if(ismob(S.OurRig.loc))
var/mob/m = S.OurRig.loc
//Will be: -1.75 for 200->25, and 1.75 for 25->200 m.drop_from_inventory(S.OurRig)
var/sizediff = size_factor - user.size_multiplier if(S.OurRig.wearer) //We're being worn. Engulf em', if prefs align.. otherwise just drop off.
var/mob/living/carbon/human/victim = S.OurRig.wearer
//Negative if shrinking, positive if growing if(P.can_be_drop_pred && victim.devourable && victim.can_be_drop_prey)
//Will be (PLSC*2)*-1.75 to 1.75 if(P.vore_selected)
//For 2000 PLSC that's -7000 to 7000 perform_the_nom(P,victim,P,P.vore_selected,1)
var/cost = (PER_LIMB_STEEL_COST*2)*sizediff P.forceMove(get_turf(S.OurRig))
S.OurRig.forceMove(src)
//Sizing up S.OurRig.myprotean = src
if(cost > 0) src.equip_to_slot_if_possible(S.OurRig, slot_back)
if(refactory.use_stored_material(MAT_STEEL,cost)) S.OurRig.Moved()
user.resize(size_factor, ignore_prefs = 1) P.has_hands = 1
else else //We're not in our own RIG
to_chat(user,"<span class='warning'>That size change would cost [cost] steel, which you don't have.</span>") if(P.stat || P.resting && !forced)
//Sizing down (or not at all) to_chat(P,"<span class='warning'>You can only do this while not stunned.</span>")
else if(cost <= 0) else
cost = abs(cost) if(P.l_hand)
var/actually_added = refactory.add_stored_material(MAT_STEEL,cost) P.drop_l_hand()
user.resize(size_factor, ignore_prefs = 1) if(P.r_hand)
if(actually_added != cost) P.drop_r_hand()
to_chat(user,"<span class='warning'>Unfortunately, [cost-actually_added] steel was lost due to lack of storage space.</span>") P.has_hands = 0
S.OurRig.myprotean = P
user.visible_message("<span class='notice'>Black mist swirls around [user] as they change size.</span>") src.drop_from_inventory(S.OurRig)
CHOMP Removal end*/ P.forceMove(S.OurRig)
S.OurRig.canremove = 1
P.reset_view()
else //Make one if not
to_chat(temporary_form, "<span class='warning'>Somehow, your RIG got disconnected from your species. This may have been caused by an admin heal. A new one has been created for you, contact a coder.</span>")
new /obj/item/weapon/rig/protean(src,src)
else
to_chat(caller, "<span class='warning'>You must remain still to condense!</span>")
/mob/living/carbon/human/proc/appearance_switch() /mob/living/carbon/human/proc/appearance_switch()
set name = "Switch Blob Appearance" set name = "Switch Blob Appearance"
@@ -389,10 +377,10 @@ CHOMP Removal end*/
set category = "Abilities" set category = "Abilities"
set hidden = 1 set hidden = 1
var/datum/species/protean/S = src.species var/datum/species/protean/S = src.species
var/mob/M = src var/mob/living/caller = src
if(temporary_form) if(temporary_form)
M = temporary_form caller = temporary_form
var/blobstyle = input(M, "Which blob style would you like?") in list("Red and Blue Stars", "Blue Star", "Plain") var/blobstyle = input(caller, "Which blob style would you like?") in list("Red and Blue Stars", "Blue Star", "Plain", "Catslug", "Pai Cat")
switch(blobstyle) switch(blobstyle)
if("Red and Blue Stars") if("Red and Blue Stars")
S.blob_appearance = "puddle2" S.blob_appearance = "puddle2"
@@ -400,15 +388,69 @@ CHOMP Removal end*/
S.blob_appearance = "puddle1" S.blob_appearance = "puddle1"
if("Plain") if("Plain")
S.blob_appearance = "puddle0" S.blob_appearance = "puddle0"
if("Catslug")
S.blob_appearance = "catslug"
if("Pai Cat")
S.blob_appearance = "pai-cat"
if(temporary_form) if(temporary_form)
if(blobstyle) if(blobstyle)
temporary_form.icon_living = S.blob_appearance temporary_form.icon_living = S.blob_appearance
temporary_form.item_state = S.blob_appearance temporary_form.item_state = S.blob_appearance
temporary_form.icon_rest = S.blob_appearance + "_rest"
temporary_form.update_icon() temporary_form.update_icon()
if(istype(temporary_form.loc, /obj/item/weapon/holder/protoblob)) if(istype(temporary_form.loc, /obj/item/weapon/holder/protoblob))
var/obj/item/weapon/holder/protoblob/PB = temporary_form.loc var/obj/item/weapon/holder/protoblob/PB = temporary_form.loc
PB.item_state = S.blob_appearance PB.item_state = S.blob_appearance
/mob/living/carbon/human/proc/nano_latch()
set name = "Latch/Unlatch host"
set desc = "Allows a protean to forcibly latch or unlatch from a host."
set category = "Abilities"
set hidden = 1
var/mob/living/caller = src
var/mob/living/carbon/human/target
var/datum/species/protean/S = src.species
if(nano_dead_check(src))
return
if(temporary_form)
caller = temporary_form
if(caller.loc == S.OurRig)
target = S.OurRig.wearer
if(target)
target.drop_from_inventory(S.OurRig)
to_chat(caller, "<span class='notice'>You detach from your host.</span>")
else
to_chat(caller, "<span class='warning'>You aren't being worn, dummy.</span>")
return
var/obj/held_item = caller.get_active_hand()
if(istype(held_item,/obj/item/weapon/grab))
var/obj/item/weapon/grab/G = held_item
if(istype(G.affecting, /mob/living/carbon/human))
target = G.affecting
if(istype(target.species, /datum/species/protean))
to_chat(caller, "<span class='danger'>You can't latch onto a fellow Protean!</span>")
return
if(G.loc == caller && G.state >= GRAB_AGGRESSIVE)
caller.visible_message("<span class='warning'>[caller] is attempting to latch onto [target]!</span>", "<span class='danger'>You attempt to latch onto [target]!</span>")
if(do_after(caller, 50, target,exclusive = TASK_ALL_EXCLUSIVE))
if(G.loc == caller && G.state >= GRAB_AGGRESSIVE)
target.drop_from_inventory(target.back)
caller.visible_message("<span class='danger'>[caller] latched onto [target]!</span>", "<span class='danger'>You latch yourself onto [target]!</span>")
target.Weaken(3)
nano_rig_transform(1)
spawn(5) //Have to give time for the above proc to resolve
//S.OurRig.forceMove(target)
target.equip_to_slot(S.OurRig, slot_back)
S.OurRig.Moved()
spawn(1) //Same here :(
S.OurRig.wearer = target
else
to_chat(caller, "<span class='warning'>You need a more aggressive grab to do this!</span>")
else
to_chat(caller, "<span class='warning'>You can only latch onto humanoid mobs!</span>")
else
to_chat(caller, "<span class='warning'>You need to be grabbing a humanoid mob aggressively to latch onto them.</span>")
/// /// /// A helper to reuse /// /// /// A helper to reuse
/mob/living/proc/nano_get_refactory(obj/item/organ/internal/nano/refactory/R) /mob/living/proc/nano_get_refactory(obj/item/organ/internal/nano/refactory/R)
if(istype(R)) if(istype(R))
@@ -425,7 +467,18 @@ CHOMP Removal end*/
/mob/living/carbon/human/nano_get_refactory() /mob/living/carbon/human/nano_get_refactory()
return ..(locate(/obj/item/organ/internal/nano/refactory) in internal_organs) return ..(locate(/obj/item/organ/internal/nano/refactory) in internal_organs)
//I hate this whole bit but I want proteans to be able to "die" and still be "alive" in their blob as a suit
/mob/living/carbon/human/proc/nano_dead_check(var/mob/living/caller)
if(istype(src.species, /datum/species/protean))
var/datum/species/protean/S = src.species
if(S.pseudodead)
return 1
return 0
/mob/living/carbon/human/proc/nano_set_dead(var/num)
if(istype(src.species, /datum/species/protean))
var/datum/species/protean/S = src.species
S.pseudodead = num
/// /// /// Ability objects for stat panel /// /// /// Ability objects for stat panel
/obj/effect/protean_ability /obj/effect/protean_ability
@@ -461,7 +514,7 @@ CHOMP Removal end*/
/// The actual abilities /// The actual abilities
/obj/effect/protean_ability/into_blob /obj/effect/protean_ability/into_blob
ability_name = "Toggle Blobform" 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." desc = "Discard your shape entirely, changing to a low-energy blob. You'll consume steel to repair yourself in this form."
icon_state = "blob" icon_state = "blob"
to_call = /mob/living/carbon/human/proc/nano_blobform to_call = /mob/living/carbon/human/proc/nano_blobform
@@ -478,27 +531,39 @@ CHOMP Removal end*/
to_call = /mob/living/carbon/human/proc/nano_partswap to_call = /mob/living/carbon/human/proc/nano_partswap
/obj/effect/protean_ability/reform_body /obj/effect/protean_ability/reform_body
ability_name = "Total Reassembly (wip)" ability_name = "Total Reassembly"
desc = "Completely reassemble yourself from whatever save slot you have loaded in preferences. Assuming you meet the requirements." desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded."
icon_state = "body" icon_state = "body"
to_call = /mob/living/carbon/human/proc/nano_regenerate to_call = /mob/living/carbon/human/proc/nano_regenerate
/obj/effect/protean_ability/metal_nom /obj/effect/protean_ability/metal_nom
ability_name = "Ref - Store Metals" 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." desc = "Store the metal you're holding. Your refactory can only store steel."
icon_state = "metal" icon_state = "metal"
to_call = /mob/living/carbon/human/proc/nano_metalnom to_call = /mob/living/carbon/human/proc/nano_metalnom
/obj/effect/protean_ability/hardsuit /obj/effect/protean_ability/hardsuit
ability_name = "Hardsuit Transform" ability_name = "Hardsuit Transform"
desc = "Coalesce your naniteswarm into their control module, allowing others to wear you." desc = "Coalesce your nanite swarm into their control module, allowing others to wear you."
icon_state = "rig" icon_state = "rig"
to_call = /mob/living/carbon/human/proc/nano_rig_transform to_call = /mob/living/carbon/human/proc/nano_rig_transform
/obj/effect/protean_ability/appearance_switch /obj/effect/protean_ability/appearance_switch
ability_name = "Blob Appearance" ability_name = "Blob Appearance"
desc = "Toggle your blob appearance. Also affects your worn appearance." desc = "Toggle your blob appearance. Also affects your worn appearance."
icon_state = "rig" icon_state = "switch"
to_call = /mob/living/carbon/human/proc/appearance_switch to_call = /mob/living/carbon/human/proc/appearance_switch
/obj/effect/protean_ability/latch_host
ability_name = "Latch Host"
desc = "Forcibly latch or unlatch your RIG from a host mob."
icon_state = "latch"
to_call = /mob/living/carbon/human/proc/nano_latch
/obj/effect/protean_ability/copy_form
ability_name = "Copy Form"
desc = "If you are aggressively grabbing someone, with their consent, you can turn into a copy of them. (Without their name)."
icon_state = "copy_form"
to_call = /mob/living/carbon/human/proc/nano_copy_body
#undef PER_LIMB_STEEL_COST #undef PER_LIMB_STEEL_COST

View File

@@ -13,30 +13,37 @@
offline_slowdown = 0 offline_slowdown = 0
seal_delay = 1 seal_delay = 1
var/mob/living/myprotean var/mob/living/myprotean
//initial_modules = list(/obj/item/rig_module/power_sink) //Commented out unless I end up needing roundstart modules initial_modules = list(/obj/item/rig_module/protean/syphon, /obj/item/rig_module/protean/armor, /obj/item/rig_module/protean/healing)
helm_type = /obj/item/clothing/head/helmet/space/rig/protean //These are important for sprite pointers 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 boot_type = /obj/item/clothing/shoes/magboots/rig/protean
chest_type = /obj/item/clothing/suit/space/rig/protean chest_type = /obj/item/clothing/suit/space/rig/protean
glove_type = /obj/item/clothing/gloves/gauntlets/rig/protean glove_type = /obj/item/clothing/gloves/gauntlets/rig/protean
canremove = 0
protean = 1 protean = 1
offline_vision_restriction = 0 offline_vision_restriction = 0
open = 1 open = 1
cell_type = /obj/item/weapon/cell/protean cell_type = /obj/item/weapon/cell/protean
var/dead = 0
//interface_path = "RIGSuit_protean"
//ai_interface_path = "RIGSuit_protean"
var/sealed = 0
var/assimilated_rig
/obj/item/weapon/rig/protean/relaymove(mob/user, var/direction) /obj/item/weapon/rig/protean/relaymove(mob/user, var/direction)
if(user.stat || user.stunned) if(user.stat || user.stunned)
return return
forced_move(direction, user, FALSE) forced_move(direction, user, 0)
/obj/item/weapon/rig/protean/check_suit_access(mob/living/user) /obj/item/weapon/rig/protean/check_suit_access(mob/living/user)
if(user == myprotean) if(user == myprotean)
return TRUE return 1
return ..() return ..()
/obj/item/weapon/rig/protean/digest_act(atom/movable/item_storage = null) /obj/item/weapon/rig/protean/digest_act(atom/movable/item_storage = null)
return FALSE return 0
/obj/item/weapon/rig/protean/ex_act(severity)
return
/obj/item/weapon/rig/protean/New(var/newloc, var/mob/living/carbon/human/P) /obj/item/weapon/rig/protean/New(var/newloc, var/mob/living/carbon/human/P)
if(P) if(P)
@@ -44,7 +51,7 @@
S.OurRig = src S.OurRig = src
if(P.back) if(P.back)
addtimer(CALLBACK(src, .proc/AssimilateBag, P, 1, P.back), 3) addtimer(CALLBACK(src, .proc/AssimilateBag, P, 1, P.back), 3)
myprotean = P
else else
to_chat(P, "<span class='notice'>You should have spawned with a backpack to assimilate into your RIG. Try clicking it with a backpack.</span>") to_chat(P, "<span class='notice'>You should have spawned with a backpack to assimilate into your RIG. Try clicking it with a backpack.</span>")
..(newloc) ..(newloc)
@@ -56,18 +63,28 @@
P.unEquip(P.back) P.unEquip(P.back)
B.forceMove(src) B.forceMove(src)
rig_storage = B rig_storage = B
rig_storage.max_w_class = ITEMSIZE_LARGE
rig_storage.max_storage_space = INVENTORY_STANDARD_SPACE
P.drop_item(B) P.drop_item(B)
to_chat(P, "<span class='notice'>Your [B] has been integrated into your rigsuit.</span>") to_chat(P, "<span class='notice'>[B] has been integrated into the [src].</span>")
P.equip_to_slot_if_possible(src, slot_back) if(spawned) //This feels very dumb to have a second if but I'm lazy
P.equip_to_slot_if_possible(src, slot_back)
src.Moved() src.Moved()
else else
to_chat(P,"<span class ='warning'>Your rigsuit can only assimilate a backpack into itself. If you are seeing this message, and you do not have a rigsuit, tell a coder.</span>") to_chat(P,"<span class ='warning'>Your rigsuit can only assimilate a backpack into itself. If you are seeing this message, and you do not have a rigsuit, tell a coder.</span>")
/obj/item/weapon/rig/protean/verb/RemoveBag()
set name = "Remove Stored Bag"
set category = "Object"
if(rig_storage)
usr.put_in_hands(rig_storage)
rig_storage = null
else
to_chat(usr, "This Rig does not have a bag installed. Use a bag on it to install one.")
/obj/item/weapon/rig/protean/attack_hand(mob/user as mob) /obj/item/weapon/rig/protean/attack_hand(mob/user as mob)
if (src.loc == user) if (src.loc == user)
src.rig_storage.open(user) if(rig_storage)
src.rig_storage.open(user)
else else
..() ..()
for(var/mob/M in range(1)) for(var/mob/M in range(1))
@@ -79,43 +96,10 @@
/obj/item/clothing/head/helmet/space/rig/protean /obj/item/clothing/head/helmet/space/rig/protean
name = "mass" name = "mass"
desc = "A helmet-shaped clump of nanomachines." desc = "A helmet-shaped clump of nanomachines."
siemens_coefficient= 0
light_overlay = "should not use a light overlay" 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 species_restricted = list(SPECIES_PROTEAN, 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)
/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( sprite_sheets = list(
SPECIES_PROTEAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_HUMAN = 'modular_chomp/icons/mob/head_ch.dmi', SPECIES_HUMAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_TAJ = 'modular_chomp/icons/mob/species/tajaran/helmet_ch.dmi', SPECIES_TAJ = 'modular_chomp/icons/mob/species/tajaran/helmet_ch.dmi',
SPECIES_SKRELL = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi', SPECIES_SKRELL = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi',
@@ -128,68 +112,39 @@
SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/species/fox/helmet_ch.dmi', SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/species/fox/helmet_ch.dmi',
SPECIES_FENNEC = 'modular_chomp/icons/mob/species/vulpkanin/helmet_ch.dmi', SPECIES_FENNEC = 'modular_chomp/icons/mob/species/vulpkanin/helmet_ch.dmi',
SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi', SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi',
SPECIES_TESHARI = 'icons/inventory/head/mob_ch_teshari.dmi', SPECIES_TESHARI = 'modular_chomp/icons/mob/species/teshari/helmet_ch.dmi',
SPECIES_VASILISSAN = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi', SPECIES_VASILISSAN = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/head_ch.dmi' SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/head_ch.dmi'
) )
sprite_sheets_obj = list( sprite_sheets_obj = list(
SPECIES_HUMAN = 'icons/obj/clothing/hats_ch.dmi', SPECIES_PROTEAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_TAJ = 'icons/obj/clothing/hats_ch.dmi', SPECIES_HUMAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_SKRELL = 'icons/obj/clothing/hats_ch.dmi', SPECIES_TAJ = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_UNATHI = 'icons/obj/clothing/hats_ch.dmi', SPECIES_SKRELL = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_XENOHYBRID = 'icons/obj/clothing/hats_ch.dmi', SPECIES_UNATHI = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_AKULA = 'icons/obj/clothing/hats_ch.dmi', SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_SERGAL = 'icons/obj/clothing/hats_ch.dmi', SPECIES_AKULA = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_NEVREAN = 'icons/obj/clothing/hats_ch.dmi', SPECIES_SERGAL = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_VULPKANIN = 'icons/obj/clothing/hats_ch.dmi', SPECIES_NEVREAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_ZORREN_HIGH = 'icons/obj/clothing/hats_ch.dmi', SPECIES_VULPKANIN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_FENNEC = 'icons/obj/clothing/hats_ch.dmi', SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_PROMETHEAN = 'icons/obj/clothing/hats_ch.dmi', SPECIES_FENNEC = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_TESHARI = 'icons/obj/clothing/hats_ch.dmi', SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_VASILISSAN = 'icons/obj/clothing/hats_ch.dmi', SPECIES_TESHARI = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_VOX = 'icons/obj/clothing/hats_ch.dmi' SPECIES_VASILISSAN = 'modular_chomp/icons/mob/head_ch.dmi',
) SPECIES_VOX = 'modular_chomp/icons/mob/head_ch.dmi'
/obj/item/clothing/suit/space/rig/protean
sprite_sheets = list(
SPECIES_HUMAN = 'modular_chomp/icons/mob/spacesuit_ch.dmi',
SPECIES_TAJ = 'modular_chomp/icons/mob/species/tajaran/suit_ch.dmi',
SPECIES_SKRELL = 'modular_chomp/icons/mob/species/skrell/suit_ch.dmi',
SPECIES_UNATHI = 'modular_chomp/icons/mob/species/unathi/suit_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/species/unathi/suit_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/species/akula/suit_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/species/sergal/suit_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/species/sergal/suit_ch.dmi',
SPECIES_VULPKANIN = 'modular_chomp/icons/mob/species/vulpkanin/suit_ch.dmi',
SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/species/fox/suit_ch.dmi',
SPECIES_FENNEC = 'modular_chomp/icons/mob/species/vulpkanin/suit_ch.dmi',
SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/species/skrell/suit_ch.dmi',
SPECIES_TESHARI = 'icons/inventory/suit/mob_ch_teshari.dmi',
SPECIES_VASILISSAN = 'modular_chomp/icons/mob/species/skrell/suit_ch.dmi',
SPECIES_VOX = 'modular_chomp/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'
) )
icon = 'modular_chomp/icons/mob/head_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/head_ch.dmi'
/obj/item/clothing/gloves/gauntlets/rig/protean /obj/item/clothing/gloves/gauntlets/rig/protean
name = "mass"
desc = "Glove-shaped clusters of nanomachines."
siemens_coefficient= 0
species_restricted = list(SPECIES_PROTEAN, 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)
sprite_sheets = list( sprite_sheets = list(
SPECIES_PROTEAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_HUMAN = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_HUMAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_TAJ = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_TAJ = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_SKRELL = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_SKRELL = 'modular_chomp/icons/mob/hands_ch.dmi',
@@ -202,70 +157,110 @@
SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_FENNEC = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_FENNEC = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_TESHARI = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_TESHARI = 'modular_chomp/icons/mob/species/teshari/hands_ch.dmi',
SPECIES_VASILISSAN = 'modular_chomp/icons/mob/hands_ch.dmi', SPECIES_VASILISSAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/gloves_ch.dmi' SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/gloves_ch.dmi'
) )
sprite_sheets_obj = list( sprite_sheets_obj = list(
SPECIES_HUMAN = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_HUMAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_TAJ = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_TAJ = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_SKRELL = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_SKRELL = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_UNATHI = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_UNATHI = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_XENOHYBRID = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_AKULA = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_AKULA = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_SERGAL = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_SERGAL = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_NEVREAN = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_NEVREAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VULPKANIN = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_VULPKANIN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_ZORREN_HIGH = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_FENNEC = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_FENNEC = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_PROMETHEAN = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_TESHARI = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_TESHARI = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VASILISSAN = 'icons/obj/clothing/gloves_ch.dmi', SPECIES_VASILISSAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VOX = 'icons/obj/clothing/gloves_ch.dmi' SPECIES_VOX = 'modular_chomp/icons/mob/hands_ch.dmi'
) )
icon = 'modular_chomp/icons/mob/hands_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/hands_ch.dmi'
/obj/item/clothing/shoes/magboots/rig/protean /obj/item/clothing/shoes/magboots/rig/protean
name = "mass"
desc = "Boot-shaped clusters of nanomachines."
species_restricted = list(SPECIES_PROTEAN, 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)
sprite_sheets = list( sprite_sheets = list(
SPECIES_HUMAN = 'modular_chomp/icons/mob/feet_ch.dmi', SPECIES_TESHARI = 'modular_chomp/icons/mob/species/teshari/feet_ch.dmi',
SPECIES_TAJ = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_SKRELL = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_UNATHI = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_VULPKANIN = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_FENNEC = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_TESHARI = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_VASILISSAN = 'modular_chomp/icons/mob/feet_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/shoes_ch.dmi' SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/shoes_ch.dmi'
) )
sprite_sheets_obj = list()
icon = 'modular_chomp/icons/mob/feet_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/feet_ch.dmi'
sprite_sheets_obj = list( /obj/item/clothing/suit/space/rig/protean
SPECIES_HUMAN = 'icons/obj/clothing/shoes_ch.dmi', name = "mass"
SPECIES_TAJ = 'icons/obj/clothing/shoes_ch.dmi', desc = "A body-hugging mass of nanomachines."
SPECIES_SKRELL = 'icons/obj/clothing/shoes_ch.dmi', can_breach = 0
SPECIES_UNATHI = 'icons/obj/clothing/shoes_ch.dmi', species_restricted = list(SPECIES_PROTEAN, 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)
SPECIES_XENOHYBRID = 'icons/obj/clothing/shoes_ch.dmi', allowed = list(
SPECIES_AKULA = 'icons/obj/clothing/shoes_ch.dmi', /obj/item/weapon/gun,
SPECIES_SERGAL = 'icons/obj/clothing/shoes_ch.dmi', /obj/item/device/flashlight,
SPECIES_NEVREAN = 'icons/obj/clothing/shoes_ch.dmi', /obj/item/weapon/tank,
SPECIES_VULPKANIN = 'icons/obj/clothing/shoes_ch.dmi', /obj/item/device/suit_cooling_unit,
SPECIES_ZORREN_HIGH = 'icons/obj/clothing/shoes_ch.dmi', /obj/item/weapon/melee/baton,
SPECIES_FENNEC = 'icons/obj/clothing/shoes_ch.dmi', /obj/item/weapon/storage/backpack,
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'
) )
sprite_sheets = list(
SPECIES_TESHARI = 'modular_chomp/icons/mob/species/teshari/suit_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/suit_ch.dmi'
)
sprite_sheets_obj = list()
icon = 'modular_chomp/icons/mob/spacesuit_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/spacesuit_ch.dmi'
//Copy pasted most of this proc from base because I don't feel like rewriting the base proc with a shit load of exceptions //Copy pasted most of this proc from base because I don't feel like rewriting the base proc with a shit load of exceptions
/obj/item/weapon/rig/protean/attackby(obj/item/W as obj, mob/living/user as mob) /obj/item/weapon/rig/protean/attackby(obj/item/W as obj, mob/living/user as mob)
if(!istype(user)) if(!istype(user))
return 0 return 0
if(dead)
switch(dead)
if(1)
if(W.is_screwdriver())
playsound(src, W.usesound, 50, 1)
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
to_chat(user, "<span class='notice'>You unscrew the maintenace panel on the [src].</span>")
dead +=1
return
if(2)
if(istype(W, /obj/item/device/protean_reboot))//placeholder
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
to_chat(user, "<span class='notice'>You carefully slot [W] in the [src].</span>")
dead +=1
qdel(W)
return
if(3)
if(istype(W, /obj/item/stack/nanopaste))
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
playsound(src, 'sound/effects/ointment.ogg', 50, 1)
to_chat(user, "<span class='notice'>You slather the interior confines of the [src] with the [W].</span>")
dead +=1
W?:use(1)
return
if(4)
if(istype(W, /obj/item/weapon/shockpaddles))
if(W?:can_use(user))
to_chat(user, "<span class='notice'>You hook up the [W] to the contact points in the maintenance assembly</span>")
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
playsound(src, 'sound/machines/defib_charge.ogg', 50, 0)
if(do_after(user,10,src))
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
playsound(src, 'sound/machines/defib_success.ogg', 50, 0)
new /obj/effect/gibspawner/robot(src.loc)
src.atom_say("Contact received! Reassembly nanites calibrated. Estimated time to resucitation: 1 minute 30 seconds")
addtimer(CALLBACK(src, .proc/make_alive, myprotean?:humanform), 900)
return
if(istype(W,/obj/item/weapon/rig))
if(!assimilated_rig)
AssimilateRig(user,W)
if(istype(W,/obj/item/weapon/tank)) //Todo, some kind of check for suits without integrated air supplies. if(istype(W,/obj/item/weapon/tank)) //Todo, some kind of check for suits without integrated air supplies.
if(air_supply) if(air_supply)
to_chat(user, "\The [src] already has a tank installed.") to_chat(user, "\The [src] already has a tank installed.")
@@ -349,6 +344,58 @@
AssimilateBag(user,0,W) AssimilateBag(user,0,W)
..() ..()
/obj/item/weapon/rig/protean/proc/make_alive(var/mob/living/carbon/human/H, var/partial)
if(H)
H.setToxLoss(0)
H.setOxyLoss(0)
H.setCloneLoss(0)
H.setBrainLoss(0)
H.SetParalysis(0)
H.SetStunned(0)
H.SetWeakened(0)
H.blinded = 0
H.SetBlinded(0)
H.eye_blurry = 0
H.ear_deaf = 0
H.ear_damage = 0
H.heal_overall_damage(H.getActualBruteLoss(), H.getActualFireLoss(), 1)
for(var/I in H.organs_by_name)
if(!H.organs_by_name[I] || istype(H.organs_by_name[I], /obj/item/organ/external/stump))
if(H.organs_by_name[I])
var/obj/item/organ/external/oldlimb = H.organs_by_name[I]
oldlimb.removed()
qdel(oldlimb)
var/list/organ_data = H.species.has_limbs[I]
var/limb_path = organ_data["path"]
var/obj/item/organ/external/new_eo = new limb_path(H)
new_eo.robotize(H.synthetic ? H.synthetic.company : null)
new_eo.sync_colour_to_human(H)
if(!partial)
dead_mob_list.Remove(H)
living_mob_list += H
H.tod = null
H.timeofdeath = 0
H.set_stat(CONSCIOUS)
if(istype(H.species, /datum/species/protean))
var/datum/species/protean/S
S = H.species
S.pseudodead = 0
to_chat(myprotean, "<span class='notice'>You have finished reconstituting.</span>")
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
dead = 0
/obj/item/weapon/rig/protean/take_hit(damage, source, is_emp=0)
return //We don't do that here
/obj/item/weapon/rig/protean/emp_act(severity_class)
return //Same here
/obj/item/weapon/rig/protean/cut_suit()
return //nope
/obj/item/weapon/rig/protean/force_rest(var/mob/user)
wearer.lay_down()
to_chat(user, "<span class='notice'>\The [wearer] is now [wearer.resting ? "resting" : "getting up"].</span>")
/obj/item/weapon/cell/protean /obj/item/weapon/cell/protean
name = "Protean power cell" name = "Protean power cell"
@@ -376,4 +423,154 @@
give(charge_amount) give(charge_amount)
charger.nutrition -= ((1/200)*(charge - C)) //Take nutrition relative to charge. Change the 1/200 if you want to alter the nutrition to charge ratio charger.nutrition -= ((1/200)*(charge - C)) //Take nutrition relative to charge. Change the 1/200 if you want to alter the nutrition to charge ratio
else else
return PROCESS_KILL return PROCESS_KILL
/obj/item/weapon/rig/protean/equipped(mob/living/carbon/human/M)
..()
if(dead)
canremove = 1
else
canremove = 0
/obj/item/weapon/rig/protean/ai_can_move_suit(mob/user, check_user_module = 0, check_for_ai = 0)
if(check_for_ai)
return 0 //We don't do that here.
if(offline || !cell || !cell.charge || locked_down)
if(user)
to_chat(user, "<span class='warning'>Your host rig is unpowered and unresponsive.</span>")
return 0
if(!wearer || (wearer.back != src && wearer.belt != src))
if(user)
to_chat(user, "<span class='warning'>Your host rig is not being worn.</span>")
return 0
return 1
/obj/item/weapon/rig/protean/toggle_seals(mob/living/carbon/human/M, instant)
M = src.wearer
..()
/obj/item/weapon/rig/protean/toggle_cooling(mob/user)
user = src.wearer
..()
/obj/item/weapon/rig/protean/toggle_piece(piece, mob/living/carbon/human/H, deploy_mode, forced)
H = src.wearer
..()
/obj/item/weapon/rig/protean/get_description_interaction()
if(dead)
var/list/results = list()
switch(dead)
if(1)
results += "Use a screwdriver to start repairs."
if(2)
results += "Insert a Protean Reboot Programmer, printed from a protolathe."
if(3)
results += "Use some Nanopaste."
if(4)
results += "Use either a defib or jumper cables to start the reboot sequence."
return results
//Effectively a round about way of letting a Protean wear other rigs.
/obj/item/weapon/rig/protean/proc/AssimilateRig(mob/user, var/obj/item/weapon/rig/R)
if(!R || assimilated_rig)
return
if(istype(R, /obj/item/weapon/rig/protean))
to_chat(user, "<span class='warning'>The world is not ready for such a technological singularity.</span>")
return
to_chat(user, "<span class='notice'>You assimilate the [R] into the [src]. Mimicking its stats and appearance.</span>")
for(var/obj/item/piece in list(gloves,helmet,boots,chest))
piece.armor = R.armor.Copy()
piece.max_pressure_protection = R.max_pressure_protection
piece.max_heat_protection_temperature = R.max_heat_protection_temperature
//I dislike this piece of code, but not every rig has the full set of parts
if(R.gloves)
gloves.sprite_sheets = R.gloves.sprite_sheets.Copy()
gloves.sprite_sheets_obj = R.gloves.sprite_sheets.Copy()
gloves.icon = R.gloves.icon
gloves.icon_state = R.gloves.icon_state
if(R.helmet)
helmet.sprite_sheets = R.helmet.sprite_sheets.Copy()
helmet.sprite_sheets_obj = R.helmet.sprite_sheets.Copy()
helmet.icon = R.helmet.icon
helmet.icon_state = R.helmet.icon_state
if(R.boots)
boots.sprite_sheets = R.boots.sprite_sheets.Copy()
boots.sprite_sheets_obj = R.boots.sprite_sheets.Copy()
boots.icon = R.boots.icon
boots.icon_state = R.boots.icon_state
if(R.chest)
chest.sprite_sheets = R.chest.sprite_sheets.Copy()
chest.sprite_sheets_obj = R.chest.sprite_sheets.Copy()
chest.icon = R.chest.icon
chest.icon_state = R.chest.icon_state
suit_state = R.suit_state
user.drop_item(R)
contents += R
assimilated_rig = R
slowdown = (initial(R.slowdown) *0.5)
offline_slowdown = slowdown
/obj/item/weapon/rig/protean/verb/RemoveRig()
set name = "Remove Assimilated Rig"
set category = "Object"
if(assimilated_rig)
for(var/obj/item/piece in list(gloves,helmet,boots,chest))
piece.armor = armor.Copy()
piece.max_pressure_protection = initial(piece.max_pressure_protection)
piece.max_heat_protection_temperature = initial(piece.max_heat_protection_temperature)
piece.icon_state = src.icon_state
piece.icon = initial(piece.icon)
//Byond at this time does not support initial() on lists
//So we have to create a new rig, just so we can copy the lists we're after
//If someone figures out a smarter way to do this, please tell me
var/obj/item/weapon/rig/tempRig = new /obj/item/weapon/rig/protean()
gloves.sprite_sheets = tempRig.gloves.sprite_sheets.Copy()
gloves.sprite_sheets_obj = tempRig.gloves.sprite_sheets.Copy()
helmet.sprite_sheets = tempRig.helmet.sprite_sheets.Copy()
helmet.sprite_sheets_obj = tempRig.helmet.sprite_sheets.Copy()
boots.sprite_sheets = tempRig.boots.sprite_sheets.Copy()
boots.sprite_sheets_obj = tempRig.boots.sprite_sheets.Copy()
chest.sprite_sheets = tempRig.chest.sprite_sheets.Copy()
chest.sprite_sheets_obj = tempRig.chest.sprite_sheets.Copy()
slowdown = initial(slowdown)
suit_state = icon_state
offline_slowdown = initial(offline_slowdown)
usr.put_in_hands(assimilated_rig)
assimilated_rig = null
qdel(tempRig)
else
to_chat(usr, "[src] has not assimilated a RIG. Use one on it to assimilate.")
/obj/item/weapon/rig/protean/MouseDrop(obj/over_object as obj)
if(!canremove)
return
if (isliving(usr) || isobserver(usr))
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
return
if (!( istype(over_object, /obj/screen) ))
return ..()
if (!(src.loc == usr) || (src.loc && src.loc.loc == usr))
return
if (( usr.restrained() ) || ( usr.stat ))
return
if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src))
return
switch(over_object.name)
if("r_hand")
usr.unEquip(src)
usr.put_in_r_hand(src)
if("l_hand")
usr.unEquip(src)
usr.put_in_l_hand(src)
src.add_fingerprint(usr)

View File

@@ -0,0 +1,128 @@
/*
It's a bit snowflake, but some rigsuit rewriting was necessary to achieved what I wanted
for protean rigsuits, and rolling these changes into the base RIGsuit code would definitely create
merge conflicts down the line.
So here it sits, snowflake code for a single item.
*/
/obj/item/weapon/rig/protean/tgui_state(mob/user)
return GLOB.tgui_always_state
/obj/item/weapon/rig/protean/tgui_data(mob/user)
var/list/data = list()
if(selected_module)
data["primarysystem"] = "[selected_module.interface_name]"
else
data["primarysystem"] = null
if(loc != user)
data["ai"] = TRUE
else
data["ai"] = FALSE
data["cooling"] = cooling_on
data["sealed"] = !sealed
data["sealing"] = sealing
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
data["boots"] = (boots ? "[boots.name]" : "None.")
data["chest"] = (chest ? "[chest.name]" : "None.")
data["helmetDeployed"] = (helmet && helmet.loc == loc)
data["gauntletsDeployed"] = (gloves && gloves.loc == loc)
data["bootsDeployed"] = (boots && boots.loc == loc)
data["chestDeployed"] = (chest && chest.loc == loc)
data["charge"] = cell ? round(cell.charge,1) : 0
data["maxcharge"] = cell ? cell.maxcharge : 0
data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0
data["emagged"] = subverted
data["coverlock"] = locked
data["interfacelock"] = interface_locked
data["aicontrol"] = control_overridden
data["aioverride"] = ai_override_enabled
data["securitycheck"] = security_check_enabled
data["malf"] = malfunction_delay
var/list/module_list = list()
if(!canremove && !sealing)
var/i = 1
for(var/obj/item/rig_module/module in installed_modules)
var/list/module_data = list(
"index" = i,
"name" = "[module.interface_name]",
"desc" = "[module.interface_desc]",
"can_use" = module.usable,
"can_select" = module.selectable,
"can_toggle" = module.toggleable,
"is_active" = module.active,
"engagecost" = module.use_power_cost*10,
"activecost" = module.active_power_cost*10,
"passivecost" = module.passive_power_cost*10,
"engagestring" = module.engage_string,
"activatestring" = module.activate_string,
"deactivatestring" = module.deactivate_string,
"damage" = module.damage
)
if(module.charges && module.charges.len)
module_data["charges"] = list()
var/datum/rig_charge/selected = module.charges["[module.charge_selected]"]
module_data["realchargetype"] = module.charge_selected
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
for(var/chargetype in module.charges)
var/datum/rig_charge/charge = module.charges[chargetype]
module_data["charges"] += list(list("caption" = "[charge.display_name] ([charge.charges])", "index" = "[chargetype]"))
module_list += list(module_data)
i++
if(module_list.len)
data["modules"] = module_list
else
data["modules"] = list()
return data
/*
/obj/item/weapon/rig/protean/tgui_act(action, params)
switch(action)
if("toggle_seals")
toggle_seals(wearer)
. = TRUE
if("toggle_cooling")
toggle_cooling(wearer)
. = TRUE
if("toggle_ai_control")
to_chat(usr, "<span class='notice'>Proteans cannot be AI controlled.</span>")
. = TRUE
if("toggle_suit_lock")
locked = !locked
. = TRUE
if("toggle_piece")
toggle_piece(params["piece"], wearer)
. = TRUE
if("interact_module")
var/module_index = text2num(params["module"])
if(module_index > 0 && module_index <= installed_modules.len)
var/obj/item/rig_module/module = installed_modules[module_index]
switch(params["module_mode"])
if("select")
selected_module = module
. = TRUE
if("engage")
module.engage()
. = TRUE
if("toggle")
if(module.active)
module.deactivate()
else
module.activate()
. = TRUE
if("select_charge_type")
module.charge_selected = params["charge_type"]
. = TRUE
*/

View File

@@ -17,7 +17,7 @@
flesh_color = "#505050" flesh_color = "#505050"
base_color = "#FFFFFF" //Color mult, start out with this base_color = "#FFFFFF" //Color mult, start out with this
flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT | NO_HALLUCINATION | NO_INFECT 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 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 spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE
health_hud_intensity = 2 health_hud_intensity = 2
@@ -33,28 +33,33 @@
male_scream_sound = null male_scream_sound = null
female_scream_sound = null female_scream_sound = null
virus_immune = 1 virus_immune = 1
blood_volume = 0 blood_volume = 0
min_age = 18 min_age = 18
max_age = 200 max_age = 200
oxy_mod = 0 oxy_mod = 0
radiation_mod = 0 //Can't be assed with fandangling rad protections while blob formed/suited //radiation_mod = 0 //Can't be assed with fandangling rad protections while blob formed/suited
darksight = 10 darksight = 10
siemens_coefficient = 2
emp_dmg_mod = 0.8
emp_sensitivity = EMP_BLIND | EMP_DEAFEN | EMP_BRUTE_DMG | EMP_BURN_DMG
item_slowdown_mod = 1.5 //Gentle encouragement to let others wear you
hazard_low_pressure = -1 //Space doesn't bother them hazard_low_pressure = -1 //Space doesn't bother them
hazard_high_pressure = INFINITY //consistency
//Cold/heat does affect them, but it's done in special ways below - //No it isn't?
cold_level_1 = -INFINITY cold_level_1 = -INFINITY
cold_level_2 = -INFINITY cold_level_2 = -INFINITY
cold_level_3 = -INFINITY cold_level_3 = -INFINITY
heat_level_1 = INFINITY heat_level_1 = 420
heat_level_2 = INFINITY heat_level_2 = 480
heat_level_3 = INFINITY heat_level_3 = 1100
body_temperature = 290 body_temperature = 290
rarity_value = 5 rarity_value = 5
female_scream_sound = 'modular_chomp/sound/voice/scream_silicon.ogg'
male_scream_sound = 'modular_chomp/sound/voice/scream_silicon.ogg'
crit_mod = 4 //Unable to go crit crit_mod = 4 //Unable to go crit
var/obj/item/weapon/rig/protean/OurRig var/obj/item/weapon/rig/protean/OurRig
@@ -80,7 +85,7 @@
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable/nano) BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable/nano)
) )
heat_discomfort_strings = list("You feel too warm.") heat_discomfort_strings = list("WARNING: Temperature exceeding acceptable thresholds!.")
cold_discomfort_strings = list("You feel too cool.") cold_discomfort_strings = list("You feel too cool.")
//These verbs are hidden, for hotkey use only //These verbs are hidden, for hotkey use only
@@ -90,7 +95,9 @@
/mob/living/carbon/human/proc/nano_metalnom, /mob/living/carbon/human/proc/nano_metalnom,
/mob/living/carbon/human/proc/nano_blobform, /mob/living/carbon/human/proc/nano_blobform,
/mob/living/carbon/human/proc/nano_rig_transform, /mob/living/carbon/human/proc/nano_rig_transform,
/mob/living/carbon/human/proc/nano_copy_body,
/mob/living/carbon/human/proc/appearance_switch, /mob/living/carbon/human/proc/appearance_switch,
/mob/living/carbon/human/proc/nano_latch,
/mob/living/proc/set_size, /mob/living/proc/set_size,
/mob/living/carbon/human/proc/nano_change_fitting, //These verbs are displayed normally, /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,
@@ -112,6 +119,8 @@
var/blob_appearance = "puddle2" var/blob_appearance = "puddle2"
var/pseudodead = 0
/datum/species/protean/New() /datum/species/protean/New()
..() ..()
if(!LAZYLEN(abilities)) if(!LAZYLEN(abilities))
@@ -128,14 +137,53 @@
if(saved_nif) if(saved_nif)
saved_nif.quick_implant(H) saved_nif.quick_implant(H)
/datum/species/protean/get_race_key()
var/datum/species/real = GLOB.all_species[base_species]
return real.race_key
/datum/species/protean/get_bodytype(var/mob/living/carbon/human/H) /datum/species/protean/get_bodytype(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..() if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species] var/datum/species/S = GLOB.all_species[base_species]
return S.get_bodytype(H) return S.get_bodytype(H)
/datum/species/protean/get_icobase(var/mob/living/carbon/human/H, var/get_deform)
if(!H || base_species == name) return ..(null, get_deform)
var/datum/species/S = GLOB.all_species[base_species]
return S.get_icobase(H, get_deform)
/datum/species/protean/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H) /datum/species/protean/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H)
return GLOB.playable_species return GLOB.playable_species
/datum/species/protean/get_tail(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_tail(H)
/datum/species/protean/get_tail_animation(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_tail_animation(H)
/datum/species/protean/get_tail_hair(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_tail_hair(H)
/datum/species/protean/get_blood_mask(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_blood_mask(H)
/datum/species/protean/get_damage_mask(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_damage_mask(H)
/datum/species/protean/get_damage_overlays(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_damage_overlays(H)
/datum/species/protean/handle_post_spawn(var/mob/living/carbon/human/H) /datum/species/protean/handle_post_spawn(var/mob/living/carbon/human/H)
..() ..()
H.synth_color = TRUE H.synth_color = TRUE
@@ -177,14 +225,22 @@
/datum/species/protean/handle_death(var/mob/living/carbon/human/H) /datum/species/protean/handle_death(var/mob/living/carbon/human/H)
if(!H) if(!H)
return // Iono! return //No body?
if(OurRig.dead)
return
OurRig.dead = 1
var/mob/temp = H
if(H.temporary_form) if(H.temporary_form)
H.forceMove(H.temporary_form.drop_location()) temp = H.temporary_form
H.ckey = H.temporary_form.ckey playsound(temp, 'modular_chomp/sound/voice/borg_deathsound.ogg', 50, 1)
QDEL_NULL(H.temporary_form) temp.visible_message("<b>[temp.name]</b> shudders and retreats inwards, coalescing into a single core componant!")
to_chat(temp, "<span class='warning'>You've died as a Protean! While dead, you will be locked to your core RIG control module until you can be repaired. Instructions to your revival can be found in the Examine tab when examining your module..</span>")
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>") if(H.temporary_form)
if(!istype(H.temporary_form.loc, /obj/item/weapon/rig/protean))
H.nano_rig_transform(1)
else
H.nano_rig_transform(1)
pseudodead = 1
/datum/species/protean/handle_environment_special(var/mob/living/carbon/human/H) /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) 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)
@@ -320,17 +376,26 @@ CHOMP Removal end*/
material_name = MAT_STEEL material_name = MAT_STEEL
/datum/modifier/protean/steel/tick() /datum/modifier/protean/steel/tick()
holder.adjustBruteLoss(-1,include_robo = TRUE) //Modified by species resistances //Heal a random damaged limb by 1,1 per tick
holder.adjustFireLoss(-1,include_robo = TRUE) //Modified by species resistances holder.adjustBruteLoss(-1,include_robo = TRUE)
var/mob/living/carbon/human/H = holder holder.adjustFireLoss(-1,include_robo = TRUE)
for(var/obj/item/organ/O as anything in H.internal_organs) holder.adjustToxLoss(-1)
// 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
var/mob/living/carbon/human/H
if(ishuman(holder))
H = holder
//Then heal every damaged limb by a smaller amount
if(H)
for(var/obj/item/organ/external/O in H.organs)
O.heal_damage(0.5, 0.5, 0, 1)
//Heal the organs a little bit too, as a treat
for(var/obj/item/organ/O as anything in H.internal_organs)
if(O.damage > 0)
O.damage = max(0,O.damage-0.3)
else if(O.status & ORGAN_DEAD)
O.status &= ~ORGAN_DEAD //Unset dead if we repaired it entirely
// PAN Card // PAN Card
/obj/item/clothing/accessory/permit/nanotech /obj/item/clothing/accessory/permit/nanotech

View File

@@ -0,0 +1,39 @@
/datum/species/xenochimera/get_bodytype(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_bodytype(H)
/datum/species/xenochimera/get_icobase(var/mob/living/carbon/human/H, var/get_deform)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_icobase(H, get_deform)
/datum/species/xenochimera/get_tail(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_tail(H)
/datum/species/xenochimera/get_tail_animation(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_tail_animation(H)
/datum/species/xenochimera/get_tail_hair(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_tail_hair(H)
/datum/species/xenochimera/get_blood_mask(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_blood_mask(H)
/datum/species/xenochimera/get_damage_mask(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_damage_mask(H)
/datum/species/xenochimera/get_damage_overlays(var/mob/living/carbon/human/H)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
return S.get_damage_overlays(H)

View File

@@ -105,6 +105,57 @@
struggle_anim_taur = FALSE struggle_anim_taur = FALSE
update_vore_tail_sprite() update_vore_tail_sprite()
/mob/living/carbon/human/proc/GetAppearanceFromPrefs(var/flavourtext, var/oocnotes)
/* Jank code that effectively creates the client's mob from save, then copies its appearance to our current mob.
Intended to be used with shapeshifter species so we don't reset their organs in doing so.*/
var/mob/living/carbon/human/dummy/mannequin/Dummy = new
if(client.prefs)
client.prefs.copy_to(Dummy)
//Important, since some sprites only work for specific species
/* Probably not needed anymore since impersonate_bodytype no longer exists
if(Dummy.species.base_species == "Promethean")
impersonate_bodytype = "Human"
else
impersonate_bodytype = Dummy.species.base_species
*/
custom_species = Dummy.custom_species
var/list/traits = dna.species_traits.Copy()
dna = Dummy.dna.Clone()
dna.species_traits.Cut()
dna.species_traits = traits.Copy()
UpdateAppearance()
icon = Dummy.icon
if(flavourtext)
flavor_texts = client.prefs.flavor_texts.Copy()
if(oocnotes)
ooc_notes = client.prefs.metadata
qdel(Dummy)
/* Alternative version of the above proc, incase it turns out cloning our dummy mob's DNA is an awful, terrible bad idea.
Would need to fix this proc up to work as smoothly as the above proc, though.
/mob/living/carbon/human/proc/GetAppearanceFromPrefs()
/* Jank code that effectively creates the client's mob from save, then copies its appearance to our current mob.
Intended to be used with shapeshifter species so we don't reset their organs in doing so.*/
var/mob/living/carbon/human/dummy/mannequin/Dummy = new
if(client.prefs)
client.prefs.copy_to(Dummy)
//Important, since some sprites only work for specific species
if(Dummy.species.base_species == "Promethean")
impersonate_bodytype = "Human"
else
impersonate_bodytype = Dummy.species.base_species
custom_species = Dummy.custom_species
for(var/tag in Dummy.dna.body_markings)
var/obj/item/organ/external/E = organs_by_name[tag]
if(E)
E.markings.Cut()
var/list/marklist = Dummy.dna.body_markings[tag]
E.markings = marklist.Copy()
UpdateAppearance(Dummy.dna.UI.Copy())
icon = Dummy.icon
qdel(Dummy)
*/
/mob/living/carbon/human/update_tail_showing() /mob/living/carbon/human/update_tail_showing()
. = ..() . = ..()
update_vore_tail_sprite() update_vore_tail_sprite()

View File

@@ -1,2 +1,17 @@
/mob/living/proc/vs_animate(var/belly_to_animate) /mob/living/proc/vs_animate(var/belly_to_animate)
return return
/*
Maybe later, gotta figure out a way to click yourself when in a locker etc.
/mob/living/proc/click_self()
set name = "Click Self"
set desc = "Clicks yourself. Useful when you can't see yourself."
set category = "IC"
ClickOn(src)
/mob/living/New(var/newloc)
..()
verbs |= /mob/living/proc/click_self
*/

View File

@@ -98,6 +98,31 @@
// This from original living.dm update_transforms too // This from original living.dm update_transforms too
handle_status_indicators() handle_status_indicators()
/mob/living/simple_mob/proc/use_headset()
set name = "Use Headset"
set desc = "Opens your headset's GUI, if you have one."
set category = "IC"
if(istype(mob_radio, /obj/item/device/radio/headset))
mob_radio.tgui_interact(src)
else
to_chat(src, "<span class='warning'>Your mob does not have a radio in its radio slot.</span>")
/mob/living/simple_mob/proc/use_pda()
set name = "Use PDA"
set desc = "Opens your PDA's GUI, if you have one."
set category = "IC"
if(istype(myid, /obj/item/device/pda))
myid.tgui_interact(src)
else
to_chat(src, "<span class='warning'>Your mob does not have a PDA in its ID slot.</span>")
/mob/living/simple_mob/New(var/newloc)
..()
verbs |= /mob/living/simple_mob/proc/use_headset
verbs |= /mob/living/simple_mob/proc/use_pda
/mob/living/simple_mob/update_icon() /mob/living/simple_mob/update_icon()
. = ..() . = ..()
for(var/belly_class in vore_fullness_ex) for(var/belly_class in vore_fullness_ex)

View File

@@ -1,5 +1,6 @@
/obj/item/organ/external /obj/item/organ/external
var/prosthetic_digi = FALSE //CHOMPStation edit - when it's prosthetic, can it be a digitigrade var/skip_robo_icon = FALSE //CHOMPStation edit - to force it to use the normal species icon
var/digi_prosthetic = FALSE //is it a prosthetic that can be digitigrade
//new function to check for markings //new function to check for markings
/obj/item/organ/external/proc/is_hidden_by_markings() /obj/item/organ/external/proc/is_hidden_by_markings()

View File

@@ -10,9 +10,8 @@
else if(dna) else if(dna)
digitigrade = check_digi && dna.digitigrade digitigrade = check_digi && dna.digitigrade
var/robotic_digi = prosthetic_digi && digitigrade //could make it so the prosthetic digi var is more of a "does this limb have a custom digitigrade sprite for its robospriting" but this is fine for now
var/gender = "m" var/gender = "m"
var/skip_forced_icon = skip_robo_icon || (digi_prosthetic && digitigrade)
if(owner && owner.gender == FEMALE) if(owner && owner.gender == FEMALE)
gender = "f" gender = "f"
@@ -21,7 +20,7 @@
else else
icon_cache_key = "[icon_name]_[force_icon_key]" icon_cache_key = "[icon_name]_[force_icon_key]"
if(force_icon && !robotic_digi) if(force_icon && !skip_forced_icon)
mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]") mob_icon = new /icon(force_icon, "[icon_name][gendered_icon ? "_[gender]" : ""]")
else else
if(!dna) if(!dna)
@@ -38,7 +37,7 @@
if(skeletal) if(skeletal)
mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]") mob_icon = new /icon('icons/mob/human_races/r_skeleton.dmi', "[icon_name][gender ? "_[gender]" : ""]")
else if (robotic >= ORGAN_ROBOT && !robotic_digi) else if (robotic >= ORGAN_ROBOT && !skip_forced_icon)
mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]") mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
apply_colouration(mob_icon) apply_colouration(mob_icon)
else else
@@ -49,13 +48,13 @@
mob_icon = new /icon(digitigrade ? species.icodigi : species.get_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]") mob_icon = new /icon(digitigrade ? species.icodigi : species.get_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]")
apply_colouration(mob_icon) apply_colouration(mob_icon)
if (model && !robotic_digi) if (model && !skip_forced_icon)
icon_cache_key += "_model_[model]" icon_cache_key += "_model_[model]"
apply_colouration(mob_icon) apply_colouration(mob_icon)
//Code here is copied from organ_icon.dm line 118 at time of writing (9/20/21), VOREStation edits are left in intentionally, because I think it's worth keeping track of the fact that the code is from Virgo's edits. //Code here is copied from organ_icon.dm line 118 at time of writing (9/20/21), VOREStation edits are left in intentionally, because I think it's worth keeping track of the fact that the code is from Virgo's edits.
//Body markings, actually does not include head this time. Done separately above. //Body markings, actually does not include head this time. Done separately above.
if((!istype(src,/obj/item/organ/external/head) && !(force_icon && !robotic_digi)) || (model && owner && owner.synth_markings)) if((!istype(src,/obj/item/organ/external/head) && !(force_icon && !skip_forced_icon)) || (model && owner && owner.synth_markings))
for(var/M in markings) for(var/M in markings)
var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"]
var/isdigitype = mark_style.digitigrade_acceptance var/isdigitype = mark_style.digitigrade_acceptance
@@ -76,7 +75,7 @@
mob_icon.Blend(limb_icon_cache[cache_key], ICON_OVERLAY) mob_icon.Blend(limb_icon_cache[cache_key], ICON_OVERLAY)
// VOREStation edit start // VOREStation edit start
if(nail_polish && (force_icon && !robotic_digi)) if(nail_polish && !(force_icon && !skip_forced_icon))
var/icon/I = new(nail_polish.icon, nail_polish.icon_state) var/icon/I = new(nail_polish.icon, nail_polish.icon_state)
I.Blend(nail_polish.color, ICON_MULTIPLY) I.Blend(nail_polish.color, ICON_MULTIPLY)
add_overlay(I) add_overlay(I)

View File

@@ -0,0 +1,6 @@
/obj/item/weapon/gun/energy/locked/phasegun/rifle/unlocked/mounted
name = "mounted phase rifle"
self_recharge = 1
use_external_power = 1
recharge_time = 10
one_handed_penalty = 0

View File

@@ -1,121 +1,137 @@
/datum/design/item/mecha/phoron_bore /datum/design/item/mechfab/rigsuit/phase
name = "PB-23 \"Phobos\" Phoron Bore" name = "hardsuit phase rifle"
category = list("Exosuit Equipment") desc = "A compact phase rifle for a hardsuit."
id ="mech_phoron_bore" id = "rig_gun_phase"
req_tech = list(TECH_POWER = 5, TECH_PHORON = 5, TECH_MATERIAL = 5) req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_MAGNET = 3, TECH_POWER = 4, TECH_COMBAT = 4)
materials = list(MAT_PLASTEEL = 4000, "phoron" = 10000, "silver" = 2000) materials = list(DEFAULT_WALL_MATERIAL = 2000, "glass" = 1250)
build_path =/obj/item/mecha_parts/mecha_equipment/weapon/phoron_bore build_path = /obj/item/rig_module/mounted/phase
/datum/design/item/mechfab/scarab /datum/design/item/mechfab/rigsuit/defib
category = list("Scarab") name = "hardsuit defib unit"
desc = "A rig mounted defib and jumper kit combo."
/datum/design/item/mechfab/scarab/chassis id = "rig_defib"
name = "Scarab Chassis" req_tech = list(TECH_BIO = 5, TECH_MAGNET = 2, TECH_POWER = 3)
id = "scarab_chassis" materials = list(DEFAULT_WALL_MATERIAL = 6000, "glass" = 2000)
build_path = /obj/item/mecha_parts/chassis/scarab build_path = /obj/item/rig_module/device/defib
time = 10
materials = list(DEFAULT_WALL_MATERIAL = 15000) /datum/design/item/mecha/phoron_bore
name = "PB-23 \"Phobos\" Phoron Bore"
/datum/design/item/mechfab/scarab/torso category = list("Exosuit Equipment")
name = "Scarab Torso" id ="mech_phoron_bore"
id = "scarab_torso" req_tech = list(TECH_POWER = 5, TECH_PHORON = 5, TECH_MATERIAL = 5)
build_path = /obj/item/mecha_parts/part/scarab_torso materials = list(MAT_PLASTEEL = 4000, "phoron" = 10000, "silver" = 2000)
time = 30 build_path =/obj/item/mecha_parts/mecha_equipment/weapon/phoron_bore
materials = list(DEFAULT_WALL_MATERIAL = 30000, "glass" = 10000)
/datum/design/item/mechfab/scarab
/datum/design/item/mechfab/scarab/head category = list("Scarab")
name = "Scarab Head"
id = "scarab_head" /datum/design/item/mechfab/scarab/chassis
build_path = /obj/item/mecha_parts/part/scarab_head name = "Scarab Chassis"
time = 20 id = "scarab_chassis"
materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 5000) build_path = /obj/item/mecha_parts/chassis/scarab
time = 10
/datum/design/item/mechfab/scarab/left_arm materials = list(DEFAULT_WALL_MATERIAL = 15000)
name = "Scarab Left Arm"
id = "scarab_left_arm" /datum/design/item/mechfab/scarab/torso
build_path = /obj/item/mecha_parts/part/scarab_left_arm name = "Scarab Torso"
time = 20 id = "scarab_torso"
materials = list(DEFAULT_WALL_MATERIAL = 10000) build_path = /obj/item/mecha_parts/part/scarab_torso
time = 30
/datum/design/item/mechfab/scarab/right_arm materials = list(DEFAULT_WALL_MATERIAL = 30000, "glass" = 10000)
name = "Scarab Right Arm"
id = "scarab_right_arm" /datum/design/item/mechfab/scarab/head
build_path = /obj/item/mecha_parts/part/scarab_right_arm name = "Scarab Head"
time = 20 id = "scarab_head"
materials = list(DEFAULT_WALL_MATERIAL = 10000) build_path = /obj/item/mecha_parts/part/scarab_head
time = 20
/datum/design/item/mechfab/scarab/left_leg materials = list(DEFAULT_WALL_MATERIAL = 12500, "glass" = 5000)
name = "Scarab Left Legs"
id = "scarab_left_legs" /datum/design/item/mechfab/scarab/left_arm
build_path = /obj/item/mecha_parts/part/scarab_left_legs name = "Scarab Left Arm"
time = 20 id = "scarab_left_arm"
materials = list(DEFAULT_WALL_MATERIAL = 30000) build_path = /obj/item/mecha_parts/part/scarab_left_arm
time = 20
/datum/design/item/mechfab/scarab/right_leg materials = list(DEFAULT_WALL_MATERIAL = 10000)
name = "Scarab Right Legs"
id = "scarab_right_legs" /datum/design/item/mechfab/scarab/right_arm
build_path = /obj/item/mecha_parts/part/scarab_right_legs name = "Scarab Right Arm"
time = 20 id = "scarab_right_arm"
materials = list(DEFAULT_WALL_MATERIAL = 30000) build_path = /obj/item/mecha_parts/part/scarab_right_arm
time = 20
/datum/design/item/mechfab/phazon materials = list(DEFAULT_WALL_MATERIAL = 10000)
category = list("Phazon")
req_tech = list(TECH_MATERIAL = 7, TECH_BLUESPACE = 5, TECH_MAGNET = 6, TECH_PHORON = 3, TECH_ARCANE = 1) /datum/design/item/mechfab/scarab/left_leg
name = "Scarab Left Legs"
/datum/design/item/mechfab/phazon/chassis id = "scarab_left_legs"
name = "Phazon Chassis" build_path = /obj/item/mecha_parts/part/scarab_left_legs
id = "phazon_chassis" time = 20
build_path = /obj/item/mecha_parts/chassis/phazon materials = list(DEFAULT_WALL_MATERIAL = 30000)
time = 10
materials = list(DEFAULT_WALL_MATERIAL = 30000, MAT_DURASTEEL = 4000, MAT_PHORON = 4000, MAT_GOLD = 5000, MAT_VERDANTIUM = 4000) /datum/design/item/mechfab/scarab/right_leg
name = "Scarab Right Legs"
/datum/design/item/mechfab/phazon/torso id = "scarab_right_legs"
name = "Phazon Torso" build_path = /obj/item/mecha_parts/part/scarab_right_legs
id = "phazon_torso" time = 20
build_path = /obj/item/mecha_parts/part/phazon_torso materials = list(DEFAULT_WALL_MATERIAL = 30000)
time = 30
materials = list(DEFAULT_WALL_MATERIAL = 30000, MAT_DURASTEEL = 2000, MAT_PHORON = 6000, MAT_GOLD = 6000, MAT_VERDANTIUM = 2000) /datum/design/item/mechfab/phazon
category = list("Phazon")
/datum/design/item/mechfab/phazon/head req_tech = list(TECH_MATERIAL = 7, TECH_BLUESPACE = 5, TECH_MAGNET = 6, TECH_PHORON = 3, TECH_ARCANE = 1)
name = "Phazon Head"
id = "phazon_head" /datum/design/item/mechfab/phazon/chassis
build_path = /obj/item/mecha_parts/part/phazon_head name = "Phazon Chassis"
time = 20 id = "phazon_chassis"
materials = list(DEFAULT_WALL_MATERIAL = 10000, MAT_DURASTEEL = 1000, MAT_PHORON = 4000, MAT_GOLD = 4000, MAT_VERDANTIUM = 500) build_path = /obj/item/mecha_parts/chassis/phazon
time = 10
/datum/design/item/mechfab/phazon/left_arm materials = list(DEFAULT_WALL_MATERIAL = 30000, MAT_DURASTEEL = 4000, MAT_PHORON = 4000, MAT_GOLD = 5000, MAT_VERDANTIUM = 4000)
name = "Phazon Left Arm"
id = "phazon_left_arm" /datum/design/item/mechfab/phazon/torso
build_path = /obj/item/mecha_parts/part/phazon_left_arm name = "Phazon Torso"
time = 20 id = "phazon_torso"
materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500) build_path = /obj/item/mecha_parts/part/phazon_torso
time = 30
/datum/design/item/mechfab/phazon/right_arm materials = list(DEFAULT_WALL_MATERIAL = 30000, MAT_DURASTEEL = 2000, MAT_PHORON = 6000, MAT_GOLD = 6000, MAT_VERDANTIUM = 2000)
name = "Phazon Right Arm"
id = "phazon_right_arm" /datum/design/item/mechfab/phazon/head
build_path = /obj/item/mecha_parts/part/phazon_right_arm name = "Phazon Head"
time = 20 id = "phazon_head"
materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500) build_path = /obj/item/mecha_parts/part/phazon_head
time = 20
/datum/design/item/mechfab/phazon/left_leg materials = list(DEFAULT_WALL_MATERIAL = 10000, MAT_DURASTEEL = 1000, MAT_PHORON = 4000, MAT_GOLD = 4000, MAT_VERDANTIUM = 500)
name = "Phazon Left Leg"
id = "phazon_left_leg" /datum/design/item/mechfab/phazon/left_arm
build_path = /obj/item/mecha_parts/part/phazon_left_leg name = "Phazon Left Arm"
time = 20 id = "phazon_left_arm"
materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500) build_path = /obj/item/mecha_parts/part/phazon_left_arm
time = 20
/datum/design/item/mechfab/phazon/right_leg materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500)
name = "Phazon Right Leg"
id = "phazon_right_leg" /datum/design/item/mechfab/phazon/right_arm
build_path = /obj/item/mecha_parts/part/phazon_right_leg name = "Phazon Right Arm"
time = 20 id = "phazon_right_arm"
materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500) build_path = /obj/item/mecha_parts/part/phazon_right_arm
time = 20
/datum/design/item/mechfab/rigsuit/precursor materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500)
name = "Xenotech Rig"
desc = "A rig made of alien tech and materials." /datum/design/item/mechfab/phazon/left_leg
id = "rigmodule_precursor" name = "Phazon Left Leg"
time = 30 id = "phazon_left_leg"
req_tech = list(TECH_MATERIAL = 9, TECH_ENGINEERING = 6, TECH_PHORON = 5, TECH_MAGNET = 6, TECH_POWER = 6, TECH_ILLEGAL = 8, TECH_PRECURSOR = 3) build_path = /obj/item/mecha_parts/part/phazon_left_leg
materials = list(MAT_PLASTEEL = 12000, MAT_GOLD = 5000, MAT_GRAPHITE = 8000, MAT_OSMIUM = 3000, MAT_PLASTIC = 6000, MAT_VERDANTIUM = 7500, MAT_MORPHIUM = 20000) time = 20
build_path = /obj/item/weapon/rig/ch/precursor materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500)
/datum/design/item/mechfab/phazon/right_leg
name = "Phazon Right Leg"
id = "phazon_right_leg"
build_path = /obj/item/mecha_parts/part/phazon_right_leg
time = 20
materials = list(DEFAULT_WALL_MATERIAL = 15000, MAT_PHORON = 2000, MAT_GOLD = 2000, MAT_VERDANTIUM = 500)
/datum/design/item/mechfab/rigsuit/precursor
name = "Xenotech Rig"
desc = "A rig made of alien tech and materials."
id = "rigmodule_precursor"
time = 30
req_tech = list(TECH_MATERIAL = 9, TECH_ENGINEERING = 6, TECH_PHORON = 5, TECH_MAGNET = 6, TECH_POWER = 6, TECH_ILLEGAL = 8, TECH_PRECURSOR = 3)
materials = list(MAT_PLASTEEL = 12000, MAT_GOLD = 5000, MAT_GRAPHITE = 8000, MAT_OSMIUM = 3000, MAT_PLASTIC = 6000, MAT_VERDANTIUM = 7500, MAT_MORPHIUM = 20000)
build_path = /obj/item/weapon/rig/ch/precursor

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 KiB

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 837 B

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
#define Z_LEVEL_STATION_ONE 1
/datum/map/runtime_station
name = "Runtime Station"
full_name = "Southern Cross"
path = "modular_chomp/maps/runtime/runtime_station"
lobby_icon = 'icons/misc/CHOMPSTATION.gif' //CHOMPStation Edit
lobby_screens = list() //CHOMPStation Edit - CHOMPStation image
id_hud_icons = 'icons/mob/hud_jobs_vr.dmi' //CHOMPStation Edit - Job icons for off-duty/exploration
zlevel_datum_type = /datum/map_z_level/runtime_station
station_name = "NLS Southern Cross"
station_short = "Southern Cross"
dock_name = "NCS Northern Star" // Now we're the centcom!
boss_name = "Central Command"
boss_short = "Centcom"
company_name = "NanoTrasen"
company_short = "NT"
starsys_name = "Vir"
use_overmap = FALSE
shuttle_docked_message = "The scheduled shuttle to the %dock_name% has docked with the station at docks one and two. It will depart in approximately %ETD%."
shuttle_leaving_dock = "The Crew Transfer Shuttle has left the station. Estimate %ETA% until the shuttle docks at %dock_name%."
shuttle_called_message = "A crew transfer to %dock_name% has been scheduled. The shuttle has been called. Those leaving should proceed to docks one and two in approximately %ETA%."
shuttle_recall_message = "The scheduled crew transfer has been cancelled."
emergency_shuttle_docked_message = "The Emergency Shuttle has docked with the station at docks one and two. You have approximately %ETD% to board the Emergency Shuttle."
emergency_shuttle_leaving_dock = "The Emergency Shuttle has left the station. Estimate %ETA% until the shuttle docks at %dock_name%."
emergency_shuttle_called_message = "An emergency evacuation shuttle has been called. It will arrive at docks one and two in approximately %ETA%."
emergency_shuttle_recall_message = "The emergency shuttle has been recalled."
usable_email_tlds = list("freemail.nt")
allowed_spawns = list("Arrivals Shuttle","Gateway", "Cryogenic Storage", "Cyborg Storage", "Station gateway", "Sif plains")
default_skybox = /datum/skybox_settings/southern_cross
map_levels = list(
Z_LEVEL_STATION_ONE
)
lateload_gateway = null
/datum/skybox_settings/southern_cross
icon_state = "dyable"
random_color = TRUE
/datum/map_z_level/runtime_station
z = Z_LEVEL_STATION_ONE
name = "Deck 1"
base_turf = /turf/space

Binary file not shown.

Binary file not shown.

View File

@@ -10,6 +10,7 @@
#define DEBUG #define DEBUG
// END_PREFERENCES // END_PREFERENCES
// BEGIN_INCLUDE // BEGIN_INCLUDE
#include "_runtimestation.dm"
#include "code\__spaceman_dmm.dm" #include "code\__spaceman_dmm.dm"
#include "code\_away_mission_tests.dm" #include "code\_away_mission_tests.dm"
#include "code\_macros.dm" #include "code\_macros.dm"
@@ -4030,7 +4031,6 @@
#include "code\modules\research\designs.dm" #include "code\modules\research\designs.dm"
#include "code\modules\research\destructive_analyzer.dm" #include "code\modules\research\destructive_analyzer.dm"
#include "code\modules\research\mechfab_designs.dm" #include "code\modules\research\mechfab_designs.dm"
#include "code\modules\research\mechfab_designs_ch.dm"
#include "code\modules\research\message_server.dm" #include "code\modules\research\message_server.dm"
#include "code\modules\research\prosfab_designs.dm" #include "code\modules\research\prosfab_designs.dm"
#include "code\modules\research\prosfab_designs_vr.dm" #include "code\modules\research\prosfab_designs_vr.dm"
@@ -4556,6 +4556,9 @@
#include "modular_chomp\code\modules\clothing\spacesuits\rig\clockwork_ch.dm" #include "modular_chomp\code\modules\clothing\spacesuits\rig\clockwork_ch.dm"
#include "modular_chomp\code\modules\clothing\spacesuits\rig\precursor.dm" #include "modular_chomp\code\modules\clothing\spacesuits\rig\precursor.dm"
#include "modular_chomp\code\modules\clothing\spacesuits\rig\rig.dm" #include "modular_chomp\code\modules\clothing\spacesuits\rig\rig.dm"
#include "modular_chomp\code\modules\clothing\spacesuits\rig\modules\specific\defib.dm"
#include "modular_chomp\code\modules\clothing\spacesuits\rig\modules\specific\mounted_gun.dm"
#include "modular_chomp\code\modules\clothing\spacesuits\rig\modules\specific\protean.dm"
#include "modular_chomp\code\modules\datums\supplypacks\contraband.dm" #include "modular_chomp\code\modules\datums\supplypacks\contraband.dm"
#include "modular_chomp\code\modules\datums\supplypacks\engineering.dm" #include "modular_chomp\code\modules\datums\supplypacks\engineering.dm"
#include "modular_chomp\code\modules\datums\supplypacks\hydrophonic.dm" #include "modular_chomp\code\modules\datums\supplypacks\hydrophonic.dm"
@@ -4576,17 +4579,21 @@
#include "modular_chomp\code\modules\mob\living\carbon\human\emote.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\emote.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\human.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\human.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\human_defines.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\human_defines.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\human_helpers.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\update_icons.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\update_icons.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\species.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\species.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\species_shapeshift_ch.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\outsider\vox.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\outsider\vox.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\prommie_blob.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\prommie_blob.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\station.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\station.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\station_special_ch.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\teshari.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\teshari.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\_protean_defines.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\_protean_defines.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_blob.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_blob.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_organs.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_organs.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_powers.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_powers.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_rig.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_rig.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_rig_tgui.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_species.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\protean\protean_species.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\traits\negative.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\traits\negative.dm"
#include "modular_chomp\code\modules\mob\living\carbon\human\species\station\traits\positive.dm" #include "modular_chomp\code\modules\mob\living\carbon\human\species\station\traits\positive.dm"
@@ -4626,11 +4633,13 @@
#include "modular_chomp\code\modules\power\cells\power_cells.dm" #include "modular_chomp\code\modules\power\cells\power_cells.dm"
#include "modular_chomp\code\modules\projectiles\gun.dm" #include "modular_chomp\code\modules\projectiles\gun.dm"
#include "modular_chomp\code\modules\projectiles\clockwork\clockwork_guns_ch.dm" #include "modular_chomp\code\modules\projectiles\clockwork\clockwork_guns_ch.dm"
#include "modular_chomp\code\modules\projectiles\guns\phase.dm"
#include "modular_chomp\code\modules\reagents\machinery\dispenser\chem_synthesizer_ch.dm" #include "modular_chomp\code\modules\reagents\machinery\dispenser\chem_synthesizer_ch.dm"
#include "modular_chomp\code\modules\reagents\reactions\instant\drinks.dm" #include "modular_chomp\code\modules\reagents\reactions\instant\drinks.dm"
#include "modular_chomp\code\modules\reagents\reactions\instant\instant.dm" #include "modular_chomp\code\modules\reagents\reactions\instant\instant.dm"
#include "modular_chomp\code\modules\reagents\reagents\food_drinks.dm" #include "modular_chomp\code\modules\reagents\reagents\food_drinks.dm"
#include "modular_chomp\code\modules\reagents\reagents\medicine.dm" #include "modular_chomp\code\modules\reagents\reagents\medicine.dm"
#include "modular_chomp\code\modules\research\mechfab_designs.dm"
#include "modular_chomp\code\modules\research\designs\power_cells.dm" #include "modular_chomp\code\modules\research\designs\power_cells.dm"
#include "modular_chomp\code\modules\research\designs\weapons.dm" #include "modular_chomp\code\modules\research\designs\weapons.dm"
#include "modular_chomp\code\modules\resleeving\machines.dm" #include "modular_chomp\code\modules\resleeving\machines.dm"