[MIRROR] Prot rig up port (#9585)

Co-authored-by: Heroman3003 <31296024+Heroman3003@users.noreply.github.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2024-12-09 14:51:31 -07:00
committed by GitHub
parent ce12ae569f
commit 9d1fa79b33
101 changed files with 1904 additions and 3547 deletions

View File

@@ -115,6 +115,7 @@
#define FACTION_WOLFTAUR "wolftaur"
#define FACTION_WORM "worm"
#define FACTION_XENO "xeno"
#define FACTION_CORGI "corgi"
#define FACTION_ZORGOIA "zorgoia" // CHOMPAdd
#define FACTION_PLANTS "plants"

View File

@@ -328,7 +328,7 @@
#define SPECIES_XENO_HUNTER "Xenomorph Hunter"
#define SPECIES_XENO_SENTINEL "Xenomorph Sentinel"
#define SPECIES_XENO_QUEEN "Xenomorph Queen"
#define SPECIES_XENOMORPH_HYBRID "Xenomorph Hybrid" // CHOMPedit: Playable Xeno species.
#define SPECIES_XENOMORPH_HYBRID "Xenomorph Hybrid"
// Misc species. Mostly unused but might as well be complete.
#define SPECIES_SHADOW "Shadow"

View File

@@ -0,0 +1,63 @@
var/list/talk_sound_map = rlist(
list(
"beep-boop",
"goon speak 1",
"goon speak 2",
"goon speak 3",
"goon speak 4",
"goon speak blub",
"goon speak bottalk",
"goon speak buwoo",
"goon speak cow",
"goon speak lizard",
"goon speak pug",
"goon speak pugg",
"goon speak roach",
"goon speak skelly",
"xeno speak" // CHOMPEnable
),
list(
talk_sound,
goon_speak_one_sound,
goon_speak_two_sound,
goon_speak_three_sound,
goon_speak_four_sound,
goon_speak_blub_sound,
goon_speak_bottalk_sound,
goon_speak_buwoo_sound,
goon_speak_cow_sound,
goon_speak_lizard_sound,
goon_speak_pug_sound,
goon_speak_pugg_sound,
goon_speak_roach_sound,
goon_speak_skelly_sound,
xeno_speak_sound // CHOMPEnable
)
)
/proc/get_talk_sound(var/voice_sound)
if(!voice_sound)
return talk_sound_map[1]
return talk_sound_map[2][voice_sound]
/proc/rlist(var/list/keys,var/list/values) //short for reversible list generator
var/list/rlist = list(list(),list(),FALSE,0)
var/i = 0
for(i = 1, i <= LAZYLEN(keys), i++)
to_chat(world,keys[i])
rlist[1] += keys[i]
rlist[2][keys[i]] = values[i]
rlist += TRUE
rlist += i
return rlist
/proc/arlist(var/list/altlist)
var/list/rlist = list(list(),list(),FALSE,0)
var/i = 0
for(i = 1, i <= LAZYLEN(altlist), i++)
rlist[(i % 2) +1] += altlist[i]
rlist += TRUE
rlist += i/2
return rlist

View File

@@ -206,7 +206,7 @@ It also makes it so a ghost wont know where all the goodies/mobs are.
name = "Corgi Lazy Spawner"
desc = "This is a proof of concept, not sure why you would use this one"
spawn_delay = 3 MINUTES
mob_faction = "Corgi"
mob_faction = FACTION_CORGI
spawn_types = list(
/mob/living/simple_mob/animal/passive/dog/corgi = 75,
/mob/living/simple_mob/animal/passive/dog/corgi/puppy = 50
@@ -223,7 +223,7 @@ It also makes it so a ghost wont know where all the goodies/mobs are.
spawn_delay = 10 MINUTES
range = 10
simultaneous_spawns = 1
mob_faction = "wild animal"
mob_faction = FACTION_WILD_ANIMAL
total_spawns = -1
destructible = 0
anchored = TRUE
@@ -240,7 +240,7 @@ It also makes it so a ghost wont know where all the goodies/mobs are.
spawn_delay = 10 MINUTES
range = 10
simultaneous_spawns = 1
mob_faction = "xeno"
mob_faction = FACTION_XENO
total_spawns = -1
destructible = 1
health = 50
@@ -259,7 +259,7 @@ It also makes it so a ghost wont know where all the goodies/mobs are.
spawn_delay = 10 MINUTES
range = 10
simultaneous_spawns = 1
mob_faction = "xeno"
mob_faction = FACTION_XENO
total_spawns = 1
destructible = 1
health = 50

View File

@@ -174,7 +174,7 @@
overwrite_hostility = 1
mob_faction = "malf_drone"
mob_faction = FACTION_MALF_DRONE
mob_returns_home = 1
mob_wander = 1
mob_wander_distance = 5
@@ -203,7 +203,7 @@
overwrite_hostility = 1
mob_faction = "malf_drone"
mob_faction = FACTION_MALF_DRONE
mob_returns_home = 1
mob_wander = 1
mob_wander_distance = 5
@@ -220,7 +220,7 @@
desc = "This is a random hivebot."
icon_state = "robot"
mob_faction = "hivebot"
mob_faction = FACTION_HIVEBOT
/obj/random/mob/robotic/hivebot/item_to_spawn()
return pick(prob(10);/mob/living/simple_mob/mechanical/hivebot,
@@ -292,7 +292,7 @@
desc = "This is a random PoI mercenary."
icon_state = "humanoid"
mob_faction = "syndicate"
mob_faction = FACTION_SYNDICATE
mob_returns_home = 1
mob_wander_distance = 7 // People like to wander, and these people probably have a lot of stuff to guard.

View File

@@ -348,7 +348,7 @@ var/list/xeno_speak_sound = list('modular_chomp/sound/talksounds/xeno/xenotalk.o
#define canine_sounds list("cough" = null, "sneeze" = null, "scream" = list('modular_chomp/sound/voice/scream/canine/wolf_scream.ogg', 'modular_chomp/sound/voice/scream/canine/wolf_scream2.ogg', 'modular_chomp/sound/voice/scream/canine/wolf_scream3.ogg', 'modular_chomp/sound/voice/scream/canine/wolf_scream4.ogg', 'modular_chomp/sound/voice/scream/canine/wolf_scream5.ogg', 'modular_chomp/sound/voice/scream/canine/wolf_scream6.ogg'), "pain" = list('modular_chomp/sound/voice/pain/canine/wolf_pain.ogg', 'modular_chomp/sound/voice/pain/canine/wolf_pain2.ogg', 'modular_chomp/sound/voice/pain/canine/wolf_pain3.ogg', 'modular_chomp/sound/voice/pain/canine/wolf_pain4.ogg'), "gasp" = list('modular_chomp/sound/voice/gasp/canine/wolf_gasp.ogg'), "death" = list('modular_chomp/sound/voice/death/canine/wolf_death1.ogg', 'modular_chomp/sound/voice/death/canine/wolf_death2.ogg', 'modular_chomp/sound/voice/death/canine/wolf_death3.ogg', 'modular_chomp/sound/voice/death/canine/wolf_death4.ogg', 'modular_chomp/sound/voice/death/canine/wolf_death5.ogg'))
#define feline_sounds list("cough" = null, "sneeze" = null, "scream" = list('modular_chomp/sound/voice/scream/feline/feline_scream.ogg'), "pain" = list('modular_chomp/sound/voice/pain/feline/feline_pain.ogg'), "gasp" = list('modular_chomp/sound/voice/gasp/feline/feline_gasp.ogg'), "death" = list('modular_chomp/sound/voice/death/feline/feline_death.ogg'))
#define cervine_sounds list("cough" = null, "sneeze" = null, "scream" = list('modular_chomp/sound/voice/scream/cervine/cervine_scream.ogg'), "pain" = null, "gasp" = null, "death" = list('modular_chomp/sound/voice/death/cervine/cervine_death.ogg'))
#define robot_sounds list("cough" = list('sound/effects/mob_effects/m_machine_cougha.ogg', 'sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg'), "sneeze" = list('sound/effects/mob_effects/machine_sneeze.ogg'), "scream" = list('modular_chomp/sound/voice/scream_silicon.ogg', 'modular_chomp/sound/voice/android_scream.ogg', 'modular_chomp/sound/voice/scream/robotic/robot_scream1.ogg', 'modular_chomp/sound/voice/scream/robotic/robot_scream2.ogg', 'modular_chomp/sound/voice/scream/robotic/robot_scream3.ogg'), "pain" = list('modular_chomp/sound/voice/pain/robotic/robot_pain1.ogg', 'modular_chomp/sound/voice/pain/robotic/robot_pain2.ogg', 'modular_chomp/sound/voice/pain/robotic/robot_pain3.ogg'), "gasp" = null, "death" = list('modular_chomp/sound/voice/borg_deathsound.ogg'))
#define robot_sounds list("cough" = list('sound/effects/mob_effects/m_machine_cougha.ogg', 'sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg'), "sneeze" = list('sound/effects/mob_effects/machine_sneeze.ogg'), "scream" = list('modular_chomp/sound/voice/scream_silicon.ogg', 'modular_chomp/sound/voice/android_scream.ogg', 'modular_chomp/sound/voice/scream/robotic/robot_scream1.ogg', 'modular_chomp/sound/voice/scream/robotic/robot_scream2.ogg', 'modular_chomp/sound/voice/scream/robotic/robot_scream3.ogg'), "pain" = list('modular_chomp/sound/voice/pain/robotic/robot_pain1.ogg', 'modular_chomp/sound/voice/pain/robotic/robot_pain2.ogg', 'modular_chomp/sound/voice/pain/robotic/robot_pain3.ogg'), "gasp" = null, "death" = list('sound/voice/borg_deathsound.ogg'))
#define male_generic_sounds list("cough" = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg'), "sneeze" = list('sound/effects/mob_effects/sneeze.ogg'), "scream" = list('modular_chomp/sound/voice/scream/generic/male/male_scream_1.ogg', 'modular_chomp/sound/voice/scream/generic/male/male_scream_2.ogg', 'modular_chomp/sound/voice/scream/generic/male/male_scream_3.ogg', 'modular_chomp/sound/voice/scream/generic/male/male_scream_4.ogg', 'modular_chomp/sound/voice/scream/generic/male/male_scream_5.ogg', 'modular_chomp/sound/voice/scream/generic/male/male_scream_6.ogg'), "pain" = list('modular_chomp/sound/voice/pain/generic/male/male_pain_1.ogg', 'modular_chomp/sound/voice/pain/generic/male/male_pain_2.ogg', 'modular_chomp/sound/voice/pain/generic/male/male_pain_3.ogg', 'modular_chomp/sound/voice/pain/generic/male/male_pain_4.ogg', 'modular_chomp/sound/voice/pain/generic/male/male_pain_5.ogg', 'modular_chomp/sound/voice/pain/generic/male/male_pain_6.ogg', 'modular_chomp/sound/voice/pain/generic/male/male_pain_7.ogg', 'modular_chomp/sound/voice/pain/generic/male/male_pain_8.ogg'), "gasp" = list('modular_chomp/sound/voice/gasp/generic/male/male_gasp1.ogg', 'modular_chomp/sound/voice/gasp/generic/male/male_gasp2.ogg', 'modular_chomp/sound/voice/gasp/generic/male/male_gasp3.ogg'), "death" = list('modular_chomp/sound/voice/death/generic/male/male_death_1.ogg', 'modular_chomp/sound/voice/death/generic/male/male_death_2.ogg', 'modular_chomp/sound/voice/death/generic/male/male_death_3.ogg', 'modular_chomp/sound/voice/death/generic/male/male_death_4.ogg', 'modular_chomp/sound/voice/death/generic/male/male_death_5.ogg', 'modular_chomp/sound/voice/death/generic/male/male_death_6.ogg', 'modular_chomp/sound/voice/death/generic/male/male_death_7.ogg'))
#define female_generic_sounds list("cough" = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg'), "sneeze" = list('sound/effects/mob_effects/f_sneeze.ogg'), "scream" = list('modular_chomp/sound/voice/scream/generic/female/female_scream_1.ogg', 'modular_chomp/sound/voice/scream/generic/female/female_scream_2.ogg', 'modular_chomp/sound/voice/scream/generic/female/female_scream_3.ogg', 'modular_chomp/sound/voice/scream/generic/female/female_scream_4.ogg', 'modular_chomp/sound/voice/scream/generic/female/female_scream_5.ogg'), "pain" = list('modular_chomp/sound/voice/pain/generic/female/female_pain_1.ogg', 'modular_chomp/sound/voice/pain/generic/female/female_pain_2.ogg', 'modular_chomp/sound/voice/pain/generic/female/female_pain_3.ogg'), "gasp" = list('modular_chomp/sound/voice/gasp/generic/female/female_gasp1.ogg', 'modular_chomp/sound/voice/gasp/generic/female/female_gasp2.ogg'), "death" = list('modular_chomp/sound/voice/death/generic/female/female_death_1.ogg', 'modular_chomp/sound/voice/death/generic/female/female_death_2.ogg', 'modular_chomp/sound/voice/death/generic/female/female_death_3.ogg', 'modular_chomp/sound/voice/death/generic/female/female_death_4.ogg', 'modular_chomp/sound/voice/death/generic/female/female_death_5.ogg', 'modular_chomp/sound/voice/death/generic/female/female_death_6.ogg'))
#define spider_sounds list("cough" = null, "sneeze" = null, "scream" = list('sound/voice/spiderchitter.ogg'), "pain" = list('sound/voice/spiderchitter.ogg'), "gasp" = null, "death" = list('modular_chomp/sound/voice/death/spider/spider_death.ogg'))

View File

@@ -86,39 +86,6 @@
character.voice_sounds_list = talk_sound
else
character.voice_sounds_list = get_talk_sound(pref.voice_sound)
/*if(!pref.voice_sound)
character.voice_sounds_list = talk_sound
else
switch(pref.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
*/ //CHOMPEDIT Global voice lookup
character.custom_speech_bubble = pref.custom_speech_bubble
character.custom_footstep = pref.custom_footstep

View File

@@ -482,3 +482,250 @@ var/list/preferences_datums = list()
save_preferences()
attempt_vr(user.client?.prefs_vr,"load_vore","")
ShowChoices(user)
/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_GET(flag/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
character.ear_secondary_style = ear_styles[ear_secondary_style]
character.ear_secondary_colors = SANITIZE_LIST(ear_secondary_colors)
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]
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" = body_markings[M][BP]["color"], "datum" = mark_datum, "priority" = priority, "on" = body_markings[M][BP]["on"])
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.ooc_notes_dislikes = metadata_dislikes
character.ooc_notes_likes = metadata_likes
// CHOMPAdd Start
character.ooc_notes_favs = metadata_favs
character.ooc_notes_maybes = metadata_maybes
character.ooc_notes_style = matadata_ooc_style
// CHOMPAdd End
character.weight = weight_vr
character.weight_gain = weight_gain
character.weight_loss = weight_loss
character.fuzzy = fuzzy
character.offset_override = offset_override
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
character.voice_sounds_list = get_talk_sound(voice_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

@@ -19,12 +19,12 @@
icon_state = "wahcap"
item_state_slots = list(slot_r_hand_str = "wahcap", slot_l_hand_str = "wahcap")
icon = 'icons/obj/clothing/hats_ch.dmi'
icon_override = 'modular_chomp/icons/mob/head_ch.dmi'
icon_override = 'icons/mob/head.dmi'
/obj/item/clothing/head/crown //Generic crown doesnt exist, no sprites
icon = 'icons/obj/clothing/hats_ch.dmi'
icon_override = 'modular_chomp/icons/mob/head_ch.dmi'
icon_override = 'icons/mob/head.dmi'
icon_state = "crown"
item_state = "crown"
name = "crown"
@@ -35,7 +35,7 @@
name = "Crown of the golden goose king"
desc = "It's the crown given to the goose king from the golden goose casino, what an honor!"
icon = 'icons/obj/clothing/hats_ch.dmi'
icon_override = 'modular_chomp/icons/mob/head_ch.dmi'
icon_override = 'icons/mob/head.dmi'
icon_state = "goose_king"
item_state = "goose_king"
@@ -48,7 +48,7 @@
name = "Crown of the golden goose queen"
desc = "It's the crown given to the goose queen from the golden goose casino, what an honor!"
icon = 'icons/obj/clothing/hats_ch.dmi'
icon_override = 'modular_chomp/icons/mob/head_ch.dmi'
icon_override = 'icons/mob/head.dmi'
icon_state = "goose_queen"
item_state = "goose_queen"
@@ -60,7 +60,7 @@
name = "Bear pelt"
desc = "A luxurious bear pelt, good to keep warm in winter. Or to sleep through winter."
icon = 'icons/obj/clothing/hats_ch.dmi'
icon_override = 'modular_chomp/icons/mob/head_ch.dmi'
icon_override = 'icons/mob/head.dmi'
icon_state = "bearpelt_brown"
item_state = "bearpelt_brown"

View File

@@ -101,6 +101,11 @@
// Action button
actions_types = list(/datum/action/item_action/hardsuit_interface)
// Protean
var/protean = 0
var/obj/item/storage/backpack/rig_storage
permeability_coefficient = 0 //Protect the squishies, after all this shit should be waterproof.
/obj/item/rig/New()
..()
@@ -539,7 +544,7 @@
offline = 0
if(istype(wearer) && !wearer.wearing_rig)
wearer.wearing_rig = src
if(!istype(src,/obj/item/rig/protean)) //CHOMPEdit - Stupid snowflake protean special check for rig assimilation code
if(!istype(src,/obj/item/rig/protean)) // Stupid snowflake protean special check for rig assimilation code
slowdown = initial(slowdown)
if(offline)
@@ -922,16 +927,16 @@
if(world.time < wearer_move_delay)
return
if(!wearer || !wearer.loc) //CHOMP Edit - Removed some stuff for protean living hardsuit
if(!wearer || !wearer.loc) // Removed some stuff for protean living hardsuit
return
//CHOMP Addition - Added this for protean living hardsuit
// Added this for protean living hardsuit
wearer_move_delay = world.time + 2
if(ai_moving)
if(!ai_can_move_suit(user, check_user_module = 1))
return
// AIs are a bit slower than regular and ignore move intent.
//CHOMPEdit - Moved this to where it's relevant
// 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

View File

@@ -24,7 +24,7 @@
//A second security suit. Comes with a grenade launcher that only accepts flashbangs and adds a new sprinter and flash modules.
/obj/item/rig/ch/pursuit
name = "pursuit hardsuit control module"
icon = 'icons/obj/rig_modules_ch.dmi'
icon = 'icons/obj/rig_modules.dmi'
icon_state = "pursuit_rig"
suit_type = "pursuit hardsuit"
desc = "A Security hardsuit designed for chasing down the grey tide."
@@ -78,21 +78,21 @@
/obj/item/clothing/head/helmet/space/rig/ch
sprite_sheets = list(
SPECIES_HUMAN = 'modular_chomp/icons/mob/head_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_UNATHI = 'modular_chomp/icons/mob/species/unathi/helmet_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/species/unathi/helmet_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/species/akula/helmet_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/species/sergal/helmet_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/species/sergal/helmet_ch.dmi',
SPECIES_VULPKANIN = 'modular_chomp/icons/mob/species/vulpkanin/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_PROMETHEAN = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi',
SPECIES_TESHARI = 'modular_chomp/icons/mob/species/teshari/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_HUMAN = 'icons/mob/head.dmi',
SPECIES_TAJ = 'icons/mob/species/tajaran/helmet.dmi',
SPECIES_SKRELL = 'icons/mob/species/skrell/helmet.dmi',
SPECIES_UNATHI = 'icons/mob/species/unathi/helmet.dmi',
SPECIES_XENOHYBRID = 'icons/mob/species/unathi/helmet.dmi',
SPECIES_AKULA = 'icons/mob/species/akula/helmet.dmi',
SPECIES_SERGAL = 'icons/mob/species/sergal/helmet.dmi',
SPECIES_NEVREAN = 'icons/mob/species/sergal/helmet.dmi',
SPECIES_VULPKANIN = 'icons/mob/species/vulpkanin/helmet.dmi',
SPECIES_ZORREN_HIGH = 'icons/mob/species/fox/helmet.dmi',
SPECIES_FENNEC = 'icons/mob/species/vulpkanin/helmet.dmi',
SPECIES_PROMETHEAN = 'icons/mob/species/skrell/helmet.dmi',
SPECIES_TESHARI = 'icons/mob/species/teshari/helmet.dmi',
SPECIES_VASILISSAN = 'icons/mob/species/skrell/helmet.dmi',
SPECIES_VOX = 'icons/mob/species/vox/head.dmi'
)
sprite_sheets_obj = list(
@@ -115,7 +115,7 @@
/obj/item/clothing/suit/space/rig/ch
sprite_sheets = list(
SPECIES_HUMAN = 'modular_chomp/icons/mob/spacesuit_ch.dmi',
SPECIES_HUMAN = 'icons/mob/spacesuit.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',
@@ -127,9 +127,9 @@
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 = 'modular_chomp/icons/mob/species/teshari/suit_ch.dmi',
SPECIES_TESHARI = 'icons/mob/species/teshari/suit.dmi',
SPECIES_VASILISSAN = 'modular_chomp/icons/mob/species/skrell/suit_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/suit_ch.dmi'
SPECIES_VOX = 'icons/mob/species/vox/suit.dmi'
)
sprite_sheets_obj = list(
@@ -152,21 +152,21 @@
/obj/item/clothing/gloves/gauntlets/rig/ch
sprite_sheets = list(
SPECIES_HUMAN = '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_UNATHI = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VULPKANIN = '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_PROMETHEAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_TESHARI = '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_HUMAN = 'icons/mob/hands.dmi',
SPECIES_TAJ = 'icons/mob/hands.dmi',
SPECIES_SKRELL = 'icons/mob/hands.dmi',
SPECIES_UNATHI = 'icons/mob/hands.dmi',
SPECIES_XENOHYBRID = 'icons/mob/hands.dmi',
SPECIES_AKULA = 'icons/mob/hands.dmi',
SPECIES_SERGAL = 'icons/mob/hands.dmi',
SPECIES_NEVREAN = 'icons/mob/hands.dmi',
SPECIES_VULPKANIN = 'icons/mob/hands.dmi',
SPECIES_ZORREN_HIGH = 'icons/mob/hands.dmi',
SPECIES_FENNEC = 'icons/mob/hands.dmi',
SPECIES_PROMETHEAN = 'icons/mob/hands.dmi',
SPECIES_TESHARI = 'icons/mob/hands.dmi',
SPECIES_VASILISSAN = 'icons/mob/hands.dmi',
SPECIES_VOX = 'icons/mob/species/vox/gloves.dmi'
)
sprite_sheets_obj = list(
@@ -189,21 +189,21 @@
/obj/item/clothing/shoes/magboots/rig/ch
sprite_sheets = list(
SPECIES_HUMAN = 'modular_chomp/icons/mob/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_HUMAN = 'icons/mob/feet.dmi',
SPECIES_TAJ = 'icons/mob/feet.dmi',
SPECIES_SKRELL = 'icons/mob/feet.dmi',
SPECIES_UNATHI = 'icons/mob/feet.dmi',
SPECIES_XENOHYBRID = 'icons/mob/feet.dmi',
SPECIES_AKULA = 'icons/mob/feet.dmi',
SPECIES_SERGAL = 'icons/mob/feet.dmi',
SPECIES_NEVREAN = 'icons/mob/feet.dmi',
SPECIES_VULPKANIN = 'icons/mob/feet.dmi',
SPECIES_ZORREN_HIGH = 'icons/mob/feet.dmi',
SPECIES_FENNEC = 'icons/mob/feet.dmi',
SPECIES_PROMETHEAN = 'icons/mob/feet.dmi',
SPECIES_TESHARI = 'icons/mob/feet.dmi',
SPECIES_VASILISSAN = 'icons/mob/feet.dmi',
SPECIES_VOX = 'icons/mob/species/vox/shoes.dmi'
)
sprite_sheets_obj = list(

View File

@@ -3,7 +3,7 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/security/santa
name = "Santa's coat"
icon = 'icons/inventory/uniform/item_ch.dmi'
icon_override = 'modular_chomp/icons/mob/suit_ch.dmi'
icon_override = 'icons/mob/suit.dmi'
icon_state = "santacoat"
item_state_slots = list(slot_r_hand_str = "coatsecurity", slot_l_hand_str = "coatsecurity")
hoodtype = /obj/item/clothing/head/hood/winter/security/santa

View File

@@ -395,3 +395,26 @@ var/list/holder_mob_icon_cache = list()
icon = 'icons/mob/holder_complex.dmi'
var/list/generate_for_slots = list(slot_l_hand_str, slot_r_hand_str, slot_back_str)
slot_flags = SLOT_BACK
/obj/item/holder/proc/sync(var/mob/living/M)
dir = 2
overlays.Cut()
if(M.item_state)
item_state = M.item_state
color = M.color
name = M.name
desc = M.desc
overlays |= M.overlays
/obj/item/holder/protoblob
slot_flags = SLOT_HEAD | SLOT_OCLOTHING | SLOT_HOLSTER | SLOT_ICLOTHING | SLOT_ID | SLOT_EARS
w_class = ITEMSIZE_TINY
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/melee/baton)
item_icons = list(
slot_l_hand_str = 'icons/mob/lefthand_holder.dmi',
slot_r_hand_str = 'icons/mob/righthand_holder.dmi',
slot_head_str = 'icons/mob/head.dmi',
slot_w_uniform_str = 'icons/mob/uniform.dmi',
slot_wear_suit_str = 'icons/mob/suit.dmi',
slot_r_ear_str = 'icons/mob/ears.dmi',
slot_l_ear_str = 'icons/mob/ears.dmi')

View File

@@ -126,11 +126,155 @@ var/static/icon/ingame_hud_med_vr = icon('icons/mob/hud_med_vr.dmi')
//does not really need to happen, that kinda thing will only happen when putting another person's limb onto your own body
return sorted
/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
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

@@ -255,6 +255,8 @@
var/rarity_value = 1 // Relative rarity/collector value for this species.
var/economic_modifier = 2 // How much money this species makes
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
var/vore_belly_default_variant = "H"
// Determines the organs that the species spawns with and

View File

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

View File

@@ -58,7 +58,7 @@
/mob/living/carbon/human/proc/shapeshifter_select_secondary_ears()
set name = "Select Secondary Ears"
set category = "Abilities"
set category = "Abilities.Shapeshift"
if(stat || world.time < last_special)
return
@@ -78,6 +78,7 @@
ear_secondary_style = ear_styles_list[pretty_ear_styles[new_ear_style]]
// Handle color picks
if(ear_secondary_style)
var/list/new_colors = list()
for(var/channel in 1 to ear_secondary_style.get_color_channel_count())
var/channel_name = GLOB.fancy_sprite_accessory_color_channel_names[channel]

View File

@@ -12,18 +12,16 @@
//appearance_flags = RADIATION_GLOWS
shock_resist = 0 // Lets not be immune to zaps.
friendly = list("nuzzles", "glomps", "snuggles", "cuddles", "squishes") // lets be cute :3
//ChompEdit begins Prommies are cute and all, but they're still slimes, and ought to be deadlier than even this. So far this part is just a direct copy of Protean_blob.dm
harm_intent_damage = 3
melee_damage_lower = 5
melee_damage_upper = 5
see_in_dark = 10
//Chomp Edit ends
see_in_dark = 10 // CHOMPAdd
player_msg = "You're a little squisher! Your cuteness level has increased tenfold."
heat_damage_per_tick = 20 // Hot and cold are bad, but cold is AS bad for prommies as it is for slimes.
cold_damage_per_tick = 20
//glow_range = 0
//glow_intensity = 0
has_hands = 1 //Chomp Addition, brings in line with Proteans' own blob form.
has_hands = 1 // brings in line with Proteans' own blob form.
var/mob/living/carbon/human/humanform
var/datum/modifier/healing
@@ -91,14 +89,13 @@
humanform.species.update_misc_tabs(src)
/mob/living/simple_mob/slime/promethean/handle_special() // Should disable default slime healing, we'll use nutrition based heals instead.
//ChompAdd Begins. They already heal from their carbon form while even in slime form, but this is for a small bonus healing for being unformed.
// They already heal from their carbon form while even in slime form, but this is for a small bonus healing for being unformed.
adjustOxyLoss(-0.2)
adjustToxLoss(-0.2)
adjustFireLoss(-0.2)
adjustCloneLoss(-0.2)
adjustBruteLoss(-0.2)
adjustHalLoss(-6) // HalLoss ticks down FAST
//ChompAdd Ends
if(rad_glow)
rad_glow = CLAMP(rad_glow,0,250)
set_light(max(1,min(5,rad_glow/15)), max(1,min(10,rad_glow/25)), color)
@@ -384,27 +381,14 @@
// for(var/obj/item/I in things_to_drop) //rip hoarders //Chompedit: Or not.
// drop_from_inventory(I)
// if(w_uniform && istype(w_uniform,/obj/item/clothing)) //No webbings tho. We do this after in case a suit was in the way
// var/obj/item/clothing/uniform = w_uniform
// if(LAZYLEN(uniform.accessories))
// for(var/obj/item/clothing/accessory/A in uniform.accessories)
// if(is_type_in_list(A, disallowed_protean_accessories))
// uniform.remove_accessory(null,A) //First param is user, but adds fingerprints and messages
//Chompremoval End
//Size update
blob.transform = matrix()*size_multiplier
blob.size_multiplier = size_multiplier
//ChompEdit Begins: Let's drop what's in our hands.
// if(l_hand) blob.prev_left_hand = l_hand //Won't save them if dropped above, but necessary if handdrop is disabled.
// if(r_hand) blob.prev_right_hand = r_hand
if(l_hand) drop_from_inventory(l_hand)
if(r_hand) drop_from_inventory(r_hand)
//ChompEdit Ends
//Put our owner in it (don't transfer var/mind)
// blob.Weaken(2) //ChompRemoval Not needed.
blob.transforming = TRUE
blob.ckey = ckey
blob.ooc_notes = ooc_notes
@@ -417,7 +401,7 @@
//CHOMPEdit End
blob.transforming = FALSE
blob.name = name
blob.real_name = real_name //CHOMPEdit
blob.real_name = real_name
blob.nutrition = nutrition
blob.color = rgb(r_skin, g_skin, b_skin)
playsound(src.loc, "sound/effects/slime_squish.ogg", 15)
@@ -436,7 +420,6 @@
remove_verb(blob, /mob/living/simple_mob/proc/set_name) // We already have a name.
temporary_form = blob
//ChompAdd begins Handles the ID and Radio, giving the blobform each of them.
var/obj/item/radio/R = null
if(isradio(l_ear))
R = l_ear
@@ -447,7 +430,6 @@
R.forceMove(blob)
if(wear_id)
blob.myid = wear_id.GetID()
//ChompAdd End
//Mail them to nullspace
moveToNullspace()
@@ -499,7 +481,6 @@
forceMove(reform_spot)
//Put our owner in it (don't transfer var/mind)
// Weaken(2) //Chompremoval again, not needed.
playsound(src.loc, "sound/effects/slime_squish.ogg", 15)
transforming = TRUE
ckey = blob.ckey
@@ -540,10 +521,6 @@
//vore_organs.Cut()
//ChompEdit begin. And let's drop them again.
// 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.l_hand) blob.drop_from_inventory(blob.l_hand)
if(blob.r_hand) blob.drop_from_inventory(blob.r_hand)
@@ -551,9 +528,7 @@
blob.mob_radio.forceMove(src)
blob.mob_radio = null
if(blob.myid)
blob.myid.forceMove(src)
blob.myid = null
//ChompEdit End
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.
@@ -581,3 +556,8 @@
else if(humanform.say_understands(other, speaking)) //So they're speaking something other than promethean or sign, let's just ask our original mob if it understands
return TRUE
else return FALSE
/mob/living/simple_mob/slime/promethean/character_directory_species()
if (humanform)
return "[humanform.custom_species ? humanform.custom_species : (humanform.species ? humanform.species.name : "Promethean Blob")]"
return "Promethean Blob"

View File

@@ -0,0 +1 @@
#define PROTEAN_EDIBLE_MATERIALS list(MAT_STEEL) // CHOMPEdit, removed MAT_SILVER, MAT_GOLD, MAT_URANIUM, MAT_METALHYDROGEN

View File

@@ -5,9 +5,9 @@
tt_desc = "Animated nanogoop"
icon = 'icons/mob/species/protean/protean.dmi'
icon_state = "to_puddle"
icon_living = "puddle2"
icon_rest = "rest"
icon_dead = "puddle"
icon_living = "puddle0-eyes" //Null icon, since we're made of overlays now.
icon_rest = "puddle0-eyes"
icon_dead = "puddle0-eyes"
faction = FACTION_NEUTRAL
maxHealth = 200
@@ -16,14 +16,15 @@
show_stat_health = FALSE //We will do it ourselves
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "hits"
response_help = "pets the"
response_disarm = "gently pushes aside the "
response_harm = "hits the"
harm_intent_damage = 2
harm_intent_damage = 3
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = list("slashed")
see_in_dark = 10 // CHOMPAdd
min_oxy = 0
max_oxy = 0
@@ -34,22 +35,32 @@
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 900
movement_cooldown = -0.5 // Should mean that the little blurb about being quicker in blobform rings true. May need further adjusting.
maxbodytemp = 1100
movement_cooldown = 0
hunger_rate = 0
var/mob/living/carbon/human/humanform
var/obj/item/organ/internal/nano/refactory/refactory
var/datum/modifier/healing
var/obj/prev_left_hand
var/obj/prev_right_hand
var/human_brute = 0
var/human_burn = 0
player_msg = "In this form, you can move a little faster, your health will regenerate as long as you have metal in you, and you can ventcrawl!"
player_msg = "In this form, your health will regenerate as long as you have metal in you."
can_buckle = TRUE //Blobsurfing
can_buckle = 1
buckle_lying = 1
mount_offset_x = 0
mount_offset_y = 0
has_hands = 1
shock_resist = 1
nameset = 1
holder_type = /obj/item/holder/protoblob
var/hiding = 0
vore_icons = 1
vore_active = 1
plane = ABOVE_MOB_PLANE //Necessary for overlay based icons
/datum/say_list/protean_blob
speak = list("Blrb?","Sqrsh.","Glrsh!")
@@ -63,14 +74,89 @@
humanform = H
updatehealth()
refactory = locate() in humanform.internal_organs
add_verb(src, /mob/living/proc/ventcrawl)
add_verb(src, /mob/living/proc/hide)
// add_verb(src,/mob/living/proc/ventcrawl) // CHOMPRemove
add_verb(src,/mob/living/proc/usehardsuit)
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_partswap)
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_regenerate)
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_metalnom)
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_blobform)
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_rig_transform)
add_verb(src,/mob/living/simple_mob/protean_blob/proc/appearance_switch)
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_latch)
remove_verb(src,/mob/living/simple_mob/proc/nutrition_heal) // CHOMPAdd
else
update_icon()
add_verb(src,/mob/living/simple_mob/proc/animal_mount)
add_verb(src,/mob/living/proc/toggle_rider_reins)
//Hidden verbs for macro hotkeying
/mob/living/simple_mob/protean_blob/proc/nano_partswap()
set name = "Ref - Single Limb"
set desc = "Allows you to replace and reshape your limbs as you see fit."
//set category = "Abilities.Protean"
set hidden = 1
humanform.nano_partswap()
/mob/living/simple_mob/protean_blob/proc/nano_regenerate()
set name = "Total Reassembly (wip)"
set desc = "Completely reassemble yourself from whatever save slot you have loaded in preferences. Assuming you meet the requirements."
//set category = "Abilities.Protean"
set hidden = 1
humanform.nano_regenerate()
/mob/living/simple_mob/protean_blob/proc/nano_blobform()
set name = "Toggle Blobform"
set desc = "Switch between amorphous and humanoid forms."
//set category = "Abilities.Protean"
set hidden = 1
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.Protean"
set hidden = 1
humanform.nano_metalnom()
/mob/living/simple_mob/protean_blob/proc/nano_rig_transform()
set name = "Modify Form - Hardsuit"
set desc = "Allows a protean to retract its mass into its hardsuit module at will."
//set category = "Abilities.Protean"
set hidden = 1
humanform.nano_rig_transform()
/mob/living/simple_mob/protean_blob/proc/appearance_switch()
set name = "Switch Blob Appearance"
set desc = "Allows a protean blob to switch its outwards appearance."
//set category = "Abilities.Protean"
set hidden = 1
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.Protean"
set hidden = 1
humanform.nano_latch()
/mob/living/simple_mob/protean_blob/Login()
. = ..()
copy_from_prefs_vr(bellies = FALSE) //Load vore prefs
..()
plane_holder.set_vis(VIS_AUGMENTED, 1)
plane_holder.set_vis(VIS_CH_HEALTH_VR, 1)
plane_holder.set_vis(VIS_CH_ID, 1)
plane_holder.set_vis(VIS_CH_STATUS_R, 1)
plane_holder.set_vis(VIS_CH_BACKUP, 1) //Gonna need these so we can see the status of our host. Could probably write it so this only happens when worn, but eeehhh
if(!riding_datum)
riding_datum = new /datum/riding/simple_mob/protean_blob(src)
/datum/riding/simple_mob/protean_blob/handle_vehicle_layer()
ridden.layer = OBJ_LAYER
/mob/living/simple_mob/protean_blob/MouseDrop_T()
return
/mob/living/simple_mob/protean_blob/runechat_y_offset(width, height)
return (..()) - (20*size_multiplier)
/mob/living/simple_mob/protean_blob/Destroy()
humanform = null
@@ -90,60 +176,44 @@
/mob/living/simple_mob/protean_blob/speech_bubble_appearance()
return "synthetic"
/mob/living/simple_mob/protean_blob/get_available_emotes()
return global._robot_default_emotes.Copy()
/mob/living/simple_mob/protean_blob/init_vore()
return //Don't make a random belly, don't waste your time
/mob/living/simple_mob/protean_blob/isSynthetic()
return TRUE // yup
/mob/living/simple_mob/protean_blob/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/update_misc_tabs()
. = ..()
if(humanform)
humanform.species.update_misc_tabs(src)
/mob/living/simple_mob/protean_blob/update_icon()
if(humanform)
//Still have a refactory
if(istype(refactory))
icon_living = "puddle2"
//Else missing one
else
icon_living = "puddle1"
//Not human-based
else
icon_living = "puddle0"
..()
/mob/living/simple_mob/protean_blob/updatehealth()
if(humanform.nano_dead_check(src))
return
if(!humanform)
return ..()
//Set the max
maxHealth = humanform.getMaxHealth()*2 //HUMANS, and their 'double health', bleh.
//Set us to their health, but, human health ignores robolimbs so we do it 'the hard way'
human_brute = humanform.getActualBruteLoss()
human_burn = humanform.getActualFireLoss()
health = maxHealth - humanform.getOxyLoss() - humanform.getToxLoss() - humanform.getCloneLoss() - human_brute - human_burn
health = maxHealth - humanform.getOxyLoss() - humanform.getToxLoss() - humanform.getCloneLoss() - humanform.getBruteLoss() - humanform.getFireLoss()
//Alive, becoming dead
if((stat < DEAD) && (health <= 0))
death()
humanform.death()
nutrition = humanform.nutrition
//Overhealth
if(health > getMaxHealth())
health = getMaxHealth()
//Grab any other interesting values
confused = humanform.confused
radiation = humanform.radiation
paralysis = humanform.paralysis
//Update our hud if we have one
if(healths)
if(stat != DEAD)
@@ -174,14 +244,12 @@
return ..()
/mob/living/simple_mob/protean_blob/adjustBruteLoss(var/amount,var/include_robo)
amount *= 1.5
if(humanform)
return humanform.adjustBruteLoss(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/adjustFireLoss(var/amount,var/include_robo)
amount *= 1.5
if(humanform)
return humanform.adjustFireLoss(amount)
else
@@ -211,6 +279,12 @@
else
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)
if(humanform)
return humanform.emp_act(severity)
@@ -224,8 +298,10 @@
return ..()
/mob/living/simple_mob/protean_blob/rad_act(severity)
if(istype(loc, /obj/item/rig))
return //Don't irradiate us while we're in rig mode
if(humanform)
return humanform.ex_act(severity)
return humanform.rad_act(severity)
else
return ..()
@@ -235,38 +311,55 @@
else
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)
humanform.death(gibbed, deathmessage)
else
animate(src, alpha = 0, time = 2 SECONDS)
sleep(2 SECONDS)
if(!QDELETED(src)) // Human's handle death should have taken us, but maybe we were adminspawned or something without a human counterpart
qdel(src)
/mob/living/simple_mob/protean_blob/Life()
. = ..()
if(!humanform.nano_dead_check(src))
if(. && istype(refactory) && humanform)
if(!healing && (human_brute || human_burn) && refactory.get_stored_material(MAT_STEEL) >= 100)
healing = humanform.add_modifier(/datum/modifier/protean/steel, origin = refactory)
else if(healing && !(human_brute || human_burn))
healing.expire()
healing = null
else
if(healing)
healing.expire()
healing = null
/mob/living/simple_mob/protean_blob/lay_down()
var/obj/item/rig/rig = src.get_rig()
if(rig)
rig.force_rest(src)
return
..()
if(resting)
animate(src,alpha = 40,time = 1 SECOND)
/mob/living/simple_mob/protean_blob/verb/prot_hide()
set name = "Hide Self"
set desc = "Disperses your mass into a thin veil, making a trap to snatch prey with, or simply hide."
set category = "Abilities.Protean"
if(!hiding)
cut_overlays()
icon = 'icons/mob/species/protean/protean.dmi'
icon_state = "hide"
sleep(7)
mouse_opacity = 0
plane = ABOVE_OBJ_PLANE
hiding = 1
else
icon = 'icons/mob/species/protean/protean.dmi'
mouse_opacity = 1
icon_state = "wake"
animate(src,alpha = 255,time = 1 SECOND)
plane = MOB_PLANE
plane = initial(plane)
sleep(7)
update_icon()
hiding = 0
//Potential glob noms
if(can_be_drop_pred) //Toggleable in vore panel
var/list/potentials = living_mobs(0)
@@ -276,21 +369,15 @@
if(target.buckled)
target.buckled.unbuckle_mob(target, force = TRUE)
target.forceMove(vore_selected)
to_chat(target,span_vwarning("\The [src] quickly engulfs you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!"))
to_chat(target,span_warning("\The [src] quickly engulfs you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!"))
update_canmove()
/mob/living/simple_mob/protean_blob/attack_target(var/atom/A)
if(refactory && istype(A,/obj/item/stack/material))
var/obj/item/stack/material/S = A
var/substance = S.material.name
var allowed = FALSE
for(var/material in PROTEAN_EDIBLE_MATERIALS)
if(material == substance) allowed = TRUE
if(!allowed)
return
if(refactory.add_stored_material(S.material.name,1*S.perunit) && S.use(1))
visible_message(span_infoplain(span_bold("[name]") + " gloms over some of \the [S], absorbing it."))
/mob/living/simple_mob/protean_blob/update_canmove()
if(hiding)
canmove = 0
return canmove
else
return ..()
..()
/mob/living/simple_mob/protean_blob/attackby(var/obj/item/O, var/mob/user)
if(refactory && istype(O,/obj/item/stack/material))
@@ -306,23 +393,36 @@
else
return ..()
/mob/living/simple_mob/protean_blob/attack_hand(mob/living/L)
if(L.get_effective_size() >= (src.get_effective_size() + 0.5) )
src.get_scooped(L)
else
..()
/mob/living/simple_mob/protean_blob/MouseDrop(var/atom/over_object)
if(ishuman(over_object) && usr == src && src.Adjacent(over_object))
var/mob/living/carbon/human/H = over_object
get_scooped(H, TRUE)
else
return ..()
/mob/living/simple_mob/protean_blob/MouseEntered(location,control,params)
if(resting)
return
..()
var/global/list/disallowed_protean_accessories = list(
/obj/item/clothing/accessory/holster,
/obj/item/clothing/accessory/storage,
/obj/item/clothing/accessory/armor
)
/mob/living/simple_mob/protean_blob/character_directory_species()
if (humanform)
return "[humanform.custom_species ? humanform.custom_species : (humanform.species ? humanform.species.name : "Protean")]"
return "Protean"
// Helpers - Unsafe, WILL perform change.
/mob/living/carbon/human/proc/nano_intoblob(force)
if(!force && !isturf(loc))
if(!force && !isturf(loc) && !loc == /obj/item/rig/protean)
to_chat(src,span_warning("You can't change forms while inside something."))
return
to_chat(src, span_notice("You rapidly disassociate your form."))
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)
@@ -334,57 +434,45 @@ var/global/list/disallowed_protean_accessories = list(
pulledby.stop_pulling()
stop_pulling()
var/client/C = client
//Record where they should go
var/atom/creation_spot = drop_location()
//Create our new blob
var/mob/living/simple_mob/protean_blob/blob = new(creation_spot,src)
//Drop all our things
var/list/things_to_drop = contents.Copy()
var/list/things_to_not_drop = list(w_uniform,nif,l_store,r_store,wear_id,l_ear,r_ear) //And whatever else we decide for balancing.
/* No for now, because insta-pepperspray or flash on unblob
if(l_hand && l_hand.w_class <= ITEMSIZE_SMALL) //Hands but only if small or smaller
things_to_not_drop += l_hand
if(r_hand && r_hand.w_class <= ITEMSIZE_SMALL)
things_to_not_drop += r_hand
*/
things_to_drop -= things_to_not_drop //Crunch the lists
things_to_drop -= organs //Mah armbs
things_to_drop -= internal_organs //Mah sqeedily spooch
for(var/obj/item/I in things_to_drop) //rip hoarders
if(I.protean_drop_whitelist)
continue
drop_from_inventory(I)
if(w_uniform && istype(w_uniform,/obj/item/clothing)) //No webbings tho. We do this after in case a suit was in the way
var/obj/item/clothing/uniform = w_uniform
if(LAZYLEN(uniform.accessories))
for(var/obj/item/clothing/accessory/A in uniform.accessories)
if(is_type_in_list(A, disallowed_protean_accessories))
uniform.remove_accessory(null,A) //First param is user, but adds fingerprints and messages
//Size update
blob.transform = matrix()*size_multiplier
blob.size_multiplier = size_multiplier
if(l_hand) blob.prev_left_hand = l_hand //Won't save them if dropped above, but necessary if handdrop is disabled.
if(r_hand) blob.prev_right_hand = r_hand
//dir update
blob.dir = dir
if(l_hand) drop_l_hand()
if(r_hand) drop_r_hand()
//Put our owner in it (don't transfer var/mind)
blob.ckey = ckey
blob.ooc_notes = ooc_notes
blob.ooc_notes_likes = ooc_notes_likes
blob.ooc_notes_dislikes = ooc_notes_dislikes
//CHOMPEdit Start
// CHOMPAdd Start
blob.ooc_notes_favs = ooc_notes_favs
blob.ooc_notes_maybes = ooc_notes_maybes
blob.ooc_notes_style = ooc_notes_style
//CHOMPEdit End
// CHOMPAdd End
temporary_form = blob
var/obj/item/radio/R = null
if(isradio(l_ear))
R = l_ear
if(isradio(r_ear))
R = r_ear
if(R)
blob.mob_radio = R
R.forceMove(blob)
if(wear_id)
blob.myid = wear_id.GetID()
//Mail them to nullspace
moveToNullspace()
@@ -397,20 +485,30 @@ var/global/list/disallowed_protean_accessories = list(
blob.update_icon() //Will remove the collapse anim
//Transfer vore organs
blob.vore_organs = vore_organs
blob.vore_organs = vore_organs.Copy()
blob.vore_selected = vore_selected
for(var/obj/belly/B as anything in vore_organs)
B.forceMove(blob)
B.owner = blob
vore_organs.Cut()
soulgem.owner = blob //CHOMPAdd
soulgem.owner = blob // CHOMPAdd
//We can still speak our languages!
blob.languages = languages.Copy()
blob.name = real_name
blob.real_name = real_name
blob.voice_name = name
blob.update_icon(1)
//Flip them to the protean panel
addtimer(CALLBACK(src, PROC_REF(nano_set_panel), C), 4)
//Return our blob in case someone wants it
return blob
else
to_chat(src, span_warning("You must remain still to blobform!"))
//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)
@@ -419,14 +517,28 @@ var/global/list/disallowed_protean_accessories = list(
if(istype(I, /obj/item/holder))
root.remove_from_mob(I)
/mob/living/proc/usehardsuit()
set name = "Utilize Hardsuit Interface"
set desc = "Allows a protean blob to open hardsuit interface."
set category = "Abilities.Protean"
if(istype(loc, /obj/item/rig/protean))
var/obj/item/rig/protean/prig = loc
to_chat(src, "You attempt to interface with the [prig].")
prig.tgui_interact(src)
else
to_chat(src, "You are not in RIG form.")
/mob/living/carbon/human/proc/nano_outofblob(var/mob/living/simple_mob/protean_blob/blob, force)
if(!istype(blob))
return
if(blob.loc == /obj/item/rig/protean)
return
if(!force && !isturf(blob.loc))
to_chat(blob,span_warning("You can't change forms while inside something."))
return
to_chat(src, span_notice("You rapidly reassemble your form."))
if(force || do_after(blob,20,exclusive = TASK_ALL_EXCLUSIVE))
if(buckled)
buckled.unbuckle_mob()
if(LAZYLEN(buckled_mobs))
@@ -436,64 +548,102 @@ var/global/list/disallowed_protean_accessories = list(
pulledby.stop_pulling()
stop_pulling()
var/client/C = blob.client
//Stop healing if we are
if(blob.healing)
blob.healing.expire()
if(blob.mob_radio)
blob.mob_radio.forceMove(src)
blob.mob_radio = null
if(blob.myid)
blob.myid = null
//Play the animation
blob.icon_state = "from_puddle"
//Message
blob.visible_message(span_infoplain(span_bold("[src.name]") + " reshapes into a humanoid appearance!"))
//Size update
resize(blob.size_multiplier, FALSE, TRUE, ignore_prefs = TRUE)
//Duration of above animation
sleep(8)
//Record where they should go
var/atom/reform_spot = blob.drop_location()
//Size update
resize(blob.size_multiplier, FALSE, ignore_prefs = TRUE)
//dir update
dir = blob.dir
//Move them back where the blob was
forceMove(reform_spot)
if(blob.l_hand) blob.drop_l_hand()
if(blob.r_hand) blob.drop_r_hand()
//Put our owner in it (don't transfer var/mind)
ckey = blob.ckey
ooc_notes = blob.ooc_notes // Lets give the protean any updated notes from blob form.
ooc_notes_likes = blob.ooc_notes_likes
ooc_notes_dislikes = blob.ooc_notes_dislikes
//CHOMPEdit Start
// CHOMPAdd Start
ooc_notes_favs = blob.ooc_notes_favs
ooc_notes_maybes = blob.ooc_notes_maybes
ooc_notes_style = blob.ooc_notes_style
//CHOMPEdit End
// CHOMPAdd End
temporary_form = null
//Transfer vore organs
vore_organs = blob.vore_organs.Copy()
vore_selected = blob.vore_selected
for(var/obj/belly/B as anything in blob.vore_organs)
B.forceMove(src)
B.owner = src
languages = blob.languages.Copy()
soulgem.owner = src //CHOMPAdd
if(blob.prev_left_hand) put_in_l_hand(blob.prev_left_hand) //The restore for when reforming.
if(blob.prev_right_hand) put_in_r_hand(blob.prev_right_hand)
soulgem.owner = src // CHOMPAdd
Life(1) //Fix my blindness right meow //Has to be moved up here, there exists a circumstance where blob could be deleted without vore organs moving right.
//Get rid of friend blob
qdel(blob)
//Flip them to the protean panel
addtimer(CALLBACK(src, PROC_REF(nano_set_panel), C), 4)
//Return ourselves in case someone wants it
return src
else
to_chat(src, span_warning("You must remain still to reshape yourself!"))
/mob/living/simple_mob/protean_blob/CanStumbleVore(mob/living/target)
if(target == humanform)
return FALSE
return ..()
/mob/living/carbon/human/proc/nano_set_panel(var/client/C)
if(C)
C.statpanel = "Protean"
/mob/living/simple_mob/protean_blob/ClickOn(var/atom/A, var/params)
if(istype(loc, /obj/item/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/rig/protean))
var/obj/item/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
@@ -505,3 +655,110 @@ var/global/list/disallowed_protean_accessories = list(
if(PB.humanform == src)
return FALSE
return ..()
/mob/living/simple_mob/protean_blob/handle_mutations_and_radiation()
humanform.handle_mutations_and_radiation()
/mob/living/simple_mob/protean_blob/update_icon()
..()
if(humanform)
vis_height = 32
cut_overlays()
var/list/wide_icons = list(
"lizard",
"rat",
"wolf"
)
var/list/tall_icons = list(
"drake",
"teppi",
"panther"
)
var/list/big_icons = list(
"robodrgn"
)
var/datum/species/protean/S = humanform.species
icon = 'icons/mob/species/protean/protean.dmi'
default_pixel_x = 0
pixel_x = 0
vore_capacity = 1
if(S.blob_appearance == "dragon")
vore_capacity = 2
icon = 'icons/mob/vore128x64.dmi'
mount_offset_y = 32
mount_offset_x = -16
var/image/I = image(icon, "[S.dragon_overlays[1]][resting? "-rest" : (vore_fullness? "-[vore_fullness]" : null)]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[1]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[2]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[2]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[3]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[3]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[4]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[4]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[5]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[5]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[6]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[6]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = PLANE_LIGHTING_ABOVE
add_overlay(I)
qdel(I)
//You know technically I could just put all the icons into the 128x64.dmi file and off-set them to fit..
if(S.blob_appearance in wide_icons)
icon = 'icons/mob/species/protean/protean64x32.dmi'
default_pixel_x = -16
pixel_x = -16
if(S.blob_appearance in tall_icons)
icon = 'icons/mob/species/protean/protean64x64.dmi'
default_pixel_x = -16
pixel_x = -16
vis_height = 64
if(S.blob_appearance in big_icons)
icon = 'icons/mob/species/protean/protean128x64.dmi'
default_pixel_x = -48
pixel_x = -48
vis_height = 64
var/image/I = image(icon, S.blob_appearance+"[resting? "_rest":null][vore_fullness? "-[vore_fullness]" : null]")
I.color = S.blob_color_1
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
eye_layer = image(icon, "[S.blob_appearance][resting? "_rest" : null]-eyes")
eye_layer.appearance_flags = appearance_flags
eye_layer.color = S.blob_color_2
eye_layer.plane = PLANE_LIGHTING_ABOVE
add_overlay(eye_layer)
qdel(eye_layer)

View File

@@ -1,3 +1,4 @@
//TODO: Replace ventcrawl with morphing. /mob/living/simple_mob/vore/hostile/morph
#define PER_LIMB_STEEL_COST SHEET_MATERIAL_AMOUNT
////
// One-part Refactor
@@ -5,33 +6,39 @@
/mob/living/carbon/human/proc/nano_partswap()
set name = "Ref - Single Limb"
set desc = "Allows you to replace and reshape your limbs as you see fit."
set category = "Abilities"
set hidden = TRUE
//set category = "Abilities.Protean"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
if(nano_dead_check(caller))
to_chat(caller, span_warning("You need to be repaired first before you can act!"))
return
if(stat)
to_chat(src,span_warning("You must be awake and standing to perform this action!"))
to_chat(caller,span_warning("You must be awake and standing to perform this action!"))
return
if(!isturf(loc))
to_chat(src,span_warning("You need more space to perform this action!"))
if(!isturf(caller.loc))
to_chat(caller,span_warning("You need more space to perform this action!"))
return
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this
if(!istype(refactory))
to_chat(src,span_warning("You don't have a working refactory module!"))
to_chat(caller,span_warning("You don't have a working refactory module!"))
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)
return
//Organ is missing, needs restoring
if(!organs_by_name[choice] || istype(organs_by_name[choice], /obj/item/organ/external/stump)) //allows limb stumps to regenerate like removed limbs.
if(refactory.get_stored_material(MAT_STEEL) < PER_LIMB_STEEL_COST)
to_chat(src,span_warning("You're missing that limb, and need to store at least [PER_LIMB_STEEL_COST] steel to regenerate it."))
to_chat(caller,span_warning("You're missing that limb, and need to store at least [PER_LIMB_STEEL_COST] steel to regenerate it."))
return
var/regen = tgui_alert(src,"That limb is missing, do you want to regenerate it in exchange for [PER_LIMB_STEEL_COST] steel?","Regenerate limb?",list("Yes","No"))
var/regen = tgui_alert(caller,"That limb is missing, do you want to regenerate it in exchange for [PER_LIMB_STEEL_COST] steel?","Regenerate limb?",list("Yes","No"))
if(regen != "Yes")
return
if(!refactory.use_stored_material(MAT_STEEL,PER_LIMB_STEEL_COST))
@@ -40,10 +47,13 @@
var/obj/item/organ/external/oldlimb = organs_by_name[choice]
oldlimb.removed()
qdel(oldlimb)
var/mob/living/simple_mob/protean_blob/blob = nano_intoblob()
active_regen = TRUE
if(do_after(blob,5 SECONDS))
var/mob/living/simple_mob/protean_blob/blob
if(!temporary_form)
blob = nano_intoblob()
else
blob = temporary_form
active_regen = 1
if(do_after(blob,50,exclusive = TASK_ALL_EXCLUSIVE))
var/list/limblist = species.has_limbs[choice]
var/limbpath = limblist["path"]
var/obj/item/organ/external/new_eo = new limbpath(src)
@@ -51,8 +61,7 @@
new_eo.robotize(synthetic ? synthetic.company : null) //Use the base we started with
new_eo.sync_colour_to_human(src)
regenerate_icons()
active_regen = FALSE
nano_outofblob(blob)
active_regen = 0
return
//Organ exists, let's reshape it
@@ -68,7 +77,7 @@
usable_manufacturers[company] = M
if(!usable_manufacturers.len)
return
var/manu_choice = tgui_input_list(src, "Which manufacturer do you wish to mimic for this limb?", "Manufacturer for [choice]", usable_manufacturers)
var/manu_choice = tgui_input_list(caller, "Which manufacturer do you wish to mimic for this limb?", "Manufacturer for [choice]", usable_manufacturers)
if(!manu_choice)
return //Changed mind
@@ -78,177 +87,199 @@
return //Lost it meanwhile
eo.robotize(manu_choice)
visible_message(span_infoplain(span_bold("[src]") + "'s [choice] loses its shape, then reforms."))
update_icons_body()
////
// Full Refactor
////
/mob/living/carbon/human/proc/nano_regenerate() //fixed the proc, it used to leave active_regen true.
set name = "Ref - Whole Body"
set desc = "Allows you to regrow limbs and replace organs, given you have enough materials."
set category = "Abilities"
set hidden = TRUE
if(stat)
to_chat(src,span_warning("You must be awake and standing to perform this action!"))
/mob/living/carbon/human/proc/nano_regenerate()
set name = "Total Reassembly"
set desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded."
//set category = "Abilities.Protean"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
var/input = tgui_alert(caller,{"Do you want to rebuild or reassemble yourself?
Rebuilding will cost 10,000 steel and will rebuild all of your limbs as well as repair all damage over a 40s period.
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)
return
if(!isturf(loc))
to_chat(src,span_warning("You need more space to perform this action!"))
return
if(input == "Rebuild")
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this
if(!istype(refactory))
to_chat(src,span_warning("You don't have a working refactory module!"))
return
//Already regenerating
if(active_regen)
to_chat(src, span_warning("You are already refactoring!"))
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 || 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_danger("Remain still while the process takes place! It will take 5 seconds."))
visible_message(span_infoplain(span_bold("[src]") + "'s form collapses into an amorphous blob of black ichor..."))
var/mob/living/simple_mob/protean_blob/blob = nano_intoblob()
active_regen = TRUE
if(do_after(blob,5 SECONDS))
synthetic = usable_manufacturers[manu_choice]
torso.robotize(manu_choice) //Will cascade to all other organs.
regenerate_icons()
visible_message(span_infoplain(span_bold("[src]") + "'s form reshapes into a new one..."))
active_regen = FALSE
nano_outofblob(blob)
return
//Not enough resources (AND spends the resources, should be the last check)
if(!refactory.use_stored_material(MAT_STEEL,refactory.max_storage))
to_chat(src, span_warning("You need to be maxed out on normal metal to do this!"))
return
var/delay_length = round(active_regen_delay * species.active_regen_mult)
to_chat(src, span_danger("Remain still while the process takes place! It will take [delay_length/10] seconds."))
visible_message(span_infoplain(span_bold("[src]") + "'s form begins to shift and ripple as if made of oil..."))
active_regen = TRUE
var/mob/living/simple_mob/protean_blob/blob = nano_intoblob()
if(do_after(blob, delay_length, null, 0))
if(stat != DEAD && refactory)
var/list/holder = refactory.materials
species.create_organs(src)
var/obj/item/organ/external/torso = organs_by_name[BP_TORSO]
torso.robotize() //synthetic wasn't defined here.
LAZYCLEARLIST(blood_DNA)
LAZYCLEARLIST(feet_blood_DNA)
blood_color = null
feet_blood_color = null
regenerate_icons() //Probably worth it, yeah.
var/obj/item/organ/internal/nano/refactory/new_refactory = locate() in internal_organs
if(!new_refactory)
log_debug("[src] protean-regen'd but lacked a refactory when done.")
if(refactory.get_stored_material(MAT_STEEL) >= 10000)
to_chat(caller, span_notify("You begin to rebuild. You will need to remain still."))
if(do_after(caller, 400,exclusive = TASK_ALL_EXCLUSIVE))
if(species?:OurRig) //Unsafe, but we should only ever be using this with a Protean
species?:OurRig?:make_alive(src,1) //Re-using this proc
refactory.use_stored_material(MAT_STEEL,refactory.get_stored_material(MAT_STEEL)) //Use all of our steel
else
new_refactory.materials = holder
to_chat(src, span_notice("Your refactoring is complete.")) //Guarantees the message shows no matter how bad the timing.
to_chat(blob, span_notice("Your refactoring is complete!"))
to_chat(caller, span_userdanger("Somehow, you are missing your protean rig. You are unable to rebuild without one."))
else
to_chat(src, span_critical("Your refactoring has failed."))
to_chat(blob, span_critical("Your refactoring has failed!"))
to_chat(caller, span_warning("You do not have enough steel stored for this operation."))
else
to_chat(src, span_critical("Your refactoring is interrupted."))
to_chat(blob, span_critical("Your refactoring is interrupted!"))
active_regen = FALSE
nano_outofblob(blob)
input = tgui_alert(caller,{"Include Flavourtext?"},"Reassembly",list("Yes","No","Cancel"))
if(input == "Cancel" || !input)
return
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_notify("You begin to reassemble. You will need to remain still."))
caller.visible_message(span_notify("[caller] rapidly contorts and shifts!"), span_danger("You begin to reassemble."))
if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE))
if(caller.client.prefs) //Make sure we didn't d/c
var/obj/item/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_notify("[caller] adopts a new form!"), span_danger("You have reassembled."))
/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.Protean"
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/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_warning("You need a better grip to do that!"))
else
to_chat(caller, span_notice("You need to be aggressively grabbing someone before you can copy their form."))
return
if (!istype(victim))
to_chat(caller, span_warning("You can only perform this on human mobs!"))
return
if (!victim.client)
to_chat(caller, span_notice("The person you try this on must have a client!"))
return
to_chat(caller, span_notice("Waiting for other person's consent."))
var/consent = tgui_alert(victim, "Allow [src] to copy what you look like?", "Consent", list("Yes", "No"))
if (consent != "Yes")
to_chat(caller, span_notice("They declined your request."))
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/grab/G in caller)
if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE)
checking = TRUE
if (!checking)
to_chat(caller, span_warning("You lost your grip on [victim]!"))
return
to_chat(caller, span_notify("You begin to reassemble into [victim]. You will need to remain still."))
caller.visible_message(span_notify("[caller] rapidly contorts and shifts!"), span_danger("You begin to reassemble into [victim]."))
if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE))
checking = FALSE
for(var/obj/item/grab/G in caller)
if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE)
checking = TRUE
if (!checking)
to_chat(caller, span_warning("You lost your grip on [victim]!"))
return
if(caller.client) //Make sure we didn't d/c
var/obj/item/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_notify("[caller] adopts the form of [victim]!"), span_danger("You have reassembled into [victim]."))
////
// Storing metal
////
/mob/living/carbon/human/proc/nano_metalnom()
set name = "Ref - Store Metals"
set desc = "If you're holding a stack of material, you can consume some and store it for later."
set category = "Abilities"
set hidden = TRUE
//set category = "Abilities.Protean"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
if(nano_dead_check(caller))
to_chat(caller, span_warning("You need to be repaired first before you can act!"))
return
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this
if(!istype(refactory))
to_chat(src,span_warning("You don't have a working refactory module!"))
to_chat(caller,span_warning("You don't have a working refactory module!"))
return
var/held = get_active_hand()
var/held = caller.get_active_hand()
if(!istype(held,/obj/item/stack/material))
to_chat(src,span_warning("You aren't holding a stack of materials in your active hand...!"))
to_chat(caller,span_warning("You aren't holding a stack of materials in your active hand!"))
return
var/obj/item/stack/material/matstack = held
var/substance = matstack.material.name
var allowed = FALSE
var allowed = 0
for(var/material in PROTEAN_EDIBLE_MATERIALS)
if(material == substance) allowed = TRUE
if(material == substance) allowed = 1
if(!allowed)
to_chat(src,span_warning("You can't process [substance]!"))
return //Only a few things matter, the rest are best not cluttering the lists.
to_chat(caller,span_warning("You can't process [substance]!"))
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)
if(!howmuch || matstack != get_active_hand() || howmuch > matstack.get_amount())
var/howmuch = tgui_input_number(caller,"How much do you want to store? (0-[matstack.get_amount()])","Select amount",null,matstack.get_amount())
if(!howmuch || matstack != caller.get_active_hand() || howmuch > matstack.get_amount())
return //Quietly fail
var/actually_added = refactory.add_stored_material(substance,howmuch*matstack.perunit)
matstack.use(CEILING((actually_added/matstack.perunit), 1))
if(actually_added && actually_added < howmuch)
to_chat(src,span_warning("Your refactory module is now full, so only [actually_added] units were stored."))
visible_message(span_notice("[src] nibbles some of the [substance] right off the stack!"))
to_chat(caller,span_warning("Your refactory module is now full, so only [actually_added] units were stored."))
visible_message(span_notice("[caller] nibbles some of the [substance] right off the stack!"))
else if(actually_added)
to_chat(src,span_notice("You store [actually_added] units of [substance]."))
visible_message(span_notice("[src] devours some of the [substance] right off the stack!"))
to_chat(caller,span_notice("You store [actually_added] units of [substance]."))
visible_message(span_notice("[caller] devours some of the [substance] right off the stack!"))
else
to_chat(src,span_notice("You're completely capped out on [substance]!"))
to_chat(caller,span_notice("You're completely capped out on [substance]!"))
////
// Blob Form
////
/mob/living/carbon/human/proc/nano_blobform()
/mob/living/carbon/human/proc/nano_blobform(var/forced)
set name = "Toggle Blobform"
set desc = "Switch between amorphous and humanoid forms."
set category = "Abilities"
set hidden = TRUE
//set category = "Abilities.Protean"
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
if(!isturf(to_locate.loc))
if(!isturf(to_locate.loc) && !forced)
to_chat(to_locate,span_warning("You need more space to perform this action!"))
return
//Blob form
if(temporary_form)
if(health < maxHealth*0.5)
to_chat(temporary_form,span_warning("You need to regenerate more nanites first!"))
else if(temporary_form.stat)
if(temporary_form.stat)
to_chat(temporary_form,span_warning("You can only do this while not stunned."))
else
nano_outofblob(temporary_form)
@@ -257,6 +288,9 @@
else if(stat)
to_chat(src,span_warning("You can only do this while not stunned."))
return
else if(handcuffed)
to_chat(src, span_warning("You can't do this while handcuffed!"))
return
else
nano_intoblob()
@@ -266,63 +300,302 @@
/mob/living/carbon/human/proc/nano_change_fitting()
set name = "Change Species Fit"
set desc = "Tweak your shape to change what suits you fit into (and their sprites!)."
set category = "Abilities"
set category = "Abilities.Protean"
if(stat)
to_chat(src,span_warning("You must be awake and standing to perform this action!"))
return
var/new_species = tgui_input_list(src, "Please select a species to emulate.", "Shapeshifter Body", GLOB.playable_species)
var/new_species = tgui_input_list(src, "Please select a species to emulate.", "Shapeshifter Body", list(species?.vanity_base_fit)|species?.get_valid_shapeshifter_forms())
if(new_species)
species?.base_species = new_species // Really though you better have a species
regenerate_icons() //Expensive, but we need to recrunch all the icons we're wearing
////
// Change size
// Rig Transform
////
/mob/living/carbon/human/proc/nano_set_size()
set name = "Adjust Volume"
set category = "Abilities"
set hidden = TRUE
/mob/living/carbon/human/proc/nano_rig_transform(var/forced)
set name = "Modify Form - Hardsuit"
set desc = "Allows a protean to retract its mass into its hardsuit module at will."
//set category = "Abilities.Protean"
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_warning("You don't have a working refactory module!"))
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
if(nano_dead_check(src))
to_chat(caller, span_warning("You need to be repaired first before you can act!"))
return
to_chat(caller, span_notice("You rapidly condense into your module."))
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."
var/new_size = tgui_input_number(user, nagmessage, "Pick a Size", user.size_multiplier*100, 600, 1)
if(!new_size || !size_range_check(new_size))
return
var/size_factor = new_size/100
//Will be: -1.75 for 200->25, and 1.75 for 25->200
var/sizediff = size_factor - user.size_multiplier
//Negative if shrinking, positive if growing
//Will be (PLSC*2)*-1.75 to 1.75
//For 2000 PLSC that's -7000 to 7000
var/cost = (PER_LIMB_STEEL_COST*2)*sizediff
//Sizing up
if(cost > 0)
if(refactory.use_stored_material(MAT_STEEL,cost))
user.resize(size_factor, ignore_prefs = TRUE)
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(ismob(S.OurRig.loc))
var/mob/m = S.OurRig.loc
m.drop_from_inventory(S.OurRig)
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
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 = src
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 || P.resting && !forced)
to_chat(P,span_warning("You can only do this while not stunned."))
else
to_chat(user,span_warning("That size change would cost [cost] steel, which you don't have."))
//Sizing down (or not at all)
else if(cost <= 0)
cost = abs(cost)
var/actually_added = refactory.add_stored_material(MAT_STEEL,cost)
user.resize(size_factor, ignore_prefs = TRUE)
if(actually_added != cost)
to_chat(user,span_warning("Unfortunately, [cost-actually_added] steel was lost due to lack of storage space."))
if(P.l_hand)
P.drop_l_hand()
if(P.r_hand)
P.drop_r_hand()
P.has_hands = 0
S.OurRig.myprotean = P
src.drop_from_inventory(S.OurRig)
P.forceMove(S.OurRig)
S.OurRig.canremove = 1
P.reset_view()
else //Make one if not
to_chat(temporary_form, span_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."))
new /obj/item/rig/protean(src,src)
else
to_chat(caller, span_warning("You must remain still to condense!"))
user.visible_message(span_notice("Black mist swirls around [user] as they change size."))
/mob/living/carbon/human/proc/appearance_switch()
set name = "Switch Blob Appearance"
set desc = "Allows a protean blob to switch its outwards appearance."
//set category = "Abilities.Protean"
set hidden = 1
var/datum/species/protean/S = src.species
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
var/list/icon_choices = list(
"Primary" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "primary"),
"Highlight" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "highlight"),
"puddle1" = image(icon = 'icons/mob/species/protean/protean_powers.dmi', icon_state = "blob"),
"puddle0" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "puddle"),
"shadow" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "shadow"),
"clean" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "clean"),
"swarm" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "swarm"),
"slime" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "slime"),
"chaos" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "chaos"),
"cloud" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "cloud"),
// CHOMPEnable Start
"catslug" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "catslug"),
"cat" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "cat"),
"mouse" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "mouse"),
"rabbit" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "rabbit"),
"bear" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "bear"),
"fen" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "fen"),
"fox" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "fox"),
"raptor" = image(icon = 'icons/mob/species/protean/protean.dmi', icon_state = "raptor"),
"rat" = image(icon = 'icons/mob/species/protean/protean64x32.dmi', icon_state = "rat", pixel_x = -16),
"lizard" = image(icon = 'icons/mob/species/protean/protean64x32.dmi', icon_state = "lizard", pixel_x = -16),
"wolf" = image(icon = 'icons/mob/species/protean/protean64x32.dmi', icon_state = "wolf", pixel_x = -16),
//"drake" = image(icon = 'modular_chomp/icons/mob/species/protean/protean64x64.dmi', icon_state = "drake", pixel_x = -16),
"teppi" = image(icon = 'icons/mob/species/protean/protean64x64.dmi', icon_state = "teppi", pixel_x = -16),
"panther" = image(icon = 'icons/mob/species/protean/protean64x64.dmi', icon_state = "panther", pixel_x = -16),
"robodrgn" = image(icon = 'icons/mob/species/protean/protean128x64.dmi', icon_state = "robodrgn", pixel_x = -48),
"Dragon" = image(icon = 'icons/mob/bigdragon_small.dmi', icon_state = "dragon_small")
//CHOMPEnable End
)
var/blobstyle = show_radial_menu(caller, caller, icon_choices, require_near = TRUE, tooltips = FALSE)
if(!blobstyle || QDELETED(caller) || caller.incapacitated())
return FALSE
switch(blobstyle)
if("Dragon") //Fuck it, we ball
var/list/options = list("Underbelly","Body","Ears","Mane","Horns","Eyes")
for(var/option in options)
LAZYSET(options, option, image('icons/effects/bigdragon_labels.dmi', option))
var/choice = show_radial_menu(caller, caller, options, radius = 60)
if(!choice || QDELETED(caller) || caller.incapacitated())
return FALSE
. = TRUE
var/list/underbelly_styles = list(
"dragon_underSmooth",
"dragon_underPlated"
)
var/list/body_styles = list(
"dragon_bodySmooth",
"dragon_bodyScaled"
)
var/list/ear_styles = list(
"dragon_earsNormal"
)
var/list/mane_styles = list(
"dragon_maneNone",
"dragon_maneShaggy",
"dragon_maneDorsalfin"
)
var/list/horn_styles = list(
"dragon_hornsPointy",
"dragon_hornsCurved",
"dragon_hornsCurved2",
"dragon_hornsJagged",
"dragon_hornsCrown",
"dragon_hornsSkull"
)
var/list/eye_styles = list(
"dragon_eyesNormal"
)
switch(choice)
if("Underbelly")
options = underbelly_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -48)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick underbelly color:","Underbelly Color", S.dragon_overlays[1]) as null|color
if(!new_color)
return 0
S.dragon_overlays[1] = choice
S.dragon_overlays[S.dragon_overlays[1]] = new_color
if("Body")
options = body_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -48)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick body color:","Body Color", S.dragon_overlays[2]) as null|color
if(!new_color)
return 0
S.dragon_overlays[2] = choice
S.dragon_overlays[S.dragon_overlays[2]] = new_color
if("Ears")
options = ear_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -76, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick ear color:","Ear Color", S.dragon_overlays[3]) as null|color
if(!new_color)
return 0
S.dragon_overlays[3] = choice
S.dragon_overlays[S.dragon_overlays[3]] = new_color
if("Mane")
options = mane_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -76, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick mane color:","Mane Color", S.dragon_overlays[4]) as null|color
if(!new_color)
return 0
S.dragon_overlays[4] = choice
S.dragon_overlays[S.dragon_overlays[4]] = new_color
if("Horns")
options = horn_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -86, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick horn color:","Horn Color", S.dragon_overlays[5]) as null|color
if(!new_color)
return 0
S.dragon_overlays[5] = choice
S.dragon_overlays[S.dragon_overlays[5]] = new_color
if("Eyes")
options = eye_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 2, pixel_x = -48, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick eye color:","Eye Color", S.dragon_overlays[6]) as null|color
if(!new_color)
return 0
S.dragon_overlays[6] = choice
S.dragon_overlays[S.dragon_overlays[6]] = new_color
S.blob_appearance = "dragon"
if("Primary")
var/new_color = input("Pick primary color:","Protean Primary", "#FF0000") as null|color
if(!new_color)
return
S.blob_color_1 = new_color
if("Highlight")
var/new_color = input("Pick highlight color:","Protean Highlight", "#FF0000") as null|color
if(!new_color)
return
S.blob_color_2 = new_color
else
S.blob_appearance = blobstyle
if(temporary_form)
if(blobstyle)
temporary_form.update_icon()
if(istype(temporary_form.loc, /obj/item/holder/protoblob))
var/obj/item/holder/protoblob/PB = temporary_form.loc
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.Protean"
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_notice("You detach from your host."))
else
to_chat(caller, span_warning("You aren't being worn, dummy."))
return
var/obj/held_item = caller.get_active_hand()
if(istype(held_item,/obj/item/grab))
var/obj/item/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_danger("You can't latch onto a fellow Protean!"))
return
if(G.loc == caller && G.state >= GRAB_AGGRESSIVE)
caller.visible_message(span_warning("[caller] is attempting to latch onto [target]!"), span_danger("You attempt to latch onto [target]!"))
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_danger("[caller] latched onto [target]!"), span_danger("You latch yourself onto [target]!"))
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_warning("You need a more aggressive grab to do this!"))
else
to_chat(caller, span_warning("You can only latch onto humanoid mobs!"))
else
to_chat(caller, span_warning("You need to be grabbing a humanoid mob aggressively to latch onto them."))
/// /// /// A helper to reuse
/mob/living/proc/nano_get_refactory(obj/item/organ/internal/nano/refactory/R)
@@ -340,7 +613,18 @@
/mob/living/carbon/human/nano_get_refactory()
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
/obj/effect/protean_ability
@@ -371,20 +655,20 @@
/obj/effect/protean_ability/proc/do_ability(var/mob/living/L)
if(istype(L))
call(L,to_call)()
return FALSE
return 0
/// The actual abilities
/obj/effect/protean_ability/into_blob
ability_name = "Toggle Blobform"
desc = "Discard your shape entirely, changing to a low-energy blob that can fit into small spaces. You'll consume steel to repair yourself in this form."
desc = "Discard your shape entirely, changing to a low-energy blob. You'll consume steel to repair yourself in this form."
icon_state = "blob"
to_call = /mob/living/carbon/human/proc/nano_blobform
/obj/effect/protean_ability/change_volume
ability_name = "Change Volume"
desc = "Alter your size by consuming steel to produce additional nanites, or regain steel by reducing your size and reclaiming them."
desc = "Alter your size between 25% and 200%."
icon_state = "volume"
to_call = /mob/living/carbon/human/proc/nano_set_size
to_call = /mob/living/proc/set_size
/obj/effect/protean_ability/reform_limb
ability_name = "Ref - Single Limb"
@@ -393,15 +677,80 @@
to_call = /mob/living/carbon/human/proc/nano_partswap
/obj/effect/protean_ability/reform_body
ability_name = "Ref - Whole Body"
desc = "Rebuild your entire body into whatever design you want, assuming you have 10,000 metal."
ability_name = "Total Reassembly"
desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded."
icon_state = "body"
to_call = /mob/living/carbon/human/proc/nano_regenerate
/obj/effect/protean_ability/metal_nom
ability_name = "Ref - Store Metals"
desc = "Store the metal you're holding. Your refactory can only store steel, and all other metals will be converted into nanites ASAP for various effects."
desc = "Store the metal you're holding. Your refactory can only store steel."
icon_state = "metal"
to_call = /mob/living/carbon/human/proc/nano_metalnom
/obj/effect/protean_ability/hardsuit
ability_name = "Hardsuit Transform"
desc = "Coalesce your nanite swarm into their control module, allowing others to wear you."
icon_state = "rig"
to_call = /mob/living/carbon/human/proc/nano_rig_transform
/obj/effect/protean_ability/appearance_switch
ability_name = "Blob Appearance"
desc = "Toggle your blob appearance. Also affects your worn appearance."
icon_state = "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
/mob/living/carbon/human/proc/chest_transparency_toggle()
set name = "transparency toggle (chest only)"
set category = "Abilities.Protean"
if(stat || world.time < last_special)
return
last_special = world.time + 50
for(var/obj/item/organ/external/proteanlimbs as anything in src.organs)
if(proteanlimbs.organ_tag == BP_HEAD)
continue
proteanlimbs.transparent = !proteanlimbs.transparent
visible_message(span_notice("\The [src]'s internal composition seems to change."))
update_icons_body()
update_hair()
/obj/effect/protean_ability/chest_transparency
ability_name = "body transparency toggle (All but head)"
desc = "Makes everything but your head transparent!"
icon = 'icons/obj/slimeborg/slimecore.dmi'
icon_state = "core"
to_call = /mob/living/carbon/human/proc/chest_transparency_toggle
/mob/living/carbon/human/proc/transparency_toggle()
set name = "Toggle Transparency"
set category = "Abilities.Protean"
if(stat || world.time < last_special)
return
last_special = world.time + 50
for(var/obj/item/organ/external/proteanlimbs as anything in src.organs)
proteanlimbs.transparent = !proteanlimbs.transparent
visible_message(span_notice("\The [src]'s internal composition seems to change."))
update_icons_body()
update_hair()
/obj/effect/protean_ability/transparency_for_entire_body
ability_name = "Toggle Transparency"
desc = "transparency toggle for your entire body"
icon = 'icons/obj/slimeborg/slimecore.dmi'
icon_state = "core"
to_call = /mob/living/carbon/human/proc/transparency_toggle

View File

@@ -4,7 +4,7 @@
/obj/item/rig/protean
name = "nanosuit control cluster"
suit_type = "nanomachine"
icon = 'icons/obj/rig_modules_ch.dmi'
icon = 'icons/obj/rig_modules_vr.dmi'
default_mob_icon = null //Actually having a forced sprite for Proteans is ugly af. I'm not gonna make this a toggle
icon_state = "nanomachine_rig"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
@@ -28,6 +28,7 @@
//ai_interface_path = "RIGSuit_protean"
var/sealed = 0
var/assimilated_rig
var/can_assimilate_rig = TRUE // CHOMPEdit
/obj/item/rig/protean/relaymove(mob/user, var/direction)
if(user.stat || user.stunned)
@@ -110,46 +111,46 @@
light_overlay = "should not use a light overlay"
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_XENOMORPH_HYBRID)
sprite_sheets = list(
SPECIES_PROTEAN = '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_SKRELL = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi',
SPECIES_UNATHI = 'modular_chomp/icons/mob/species/unathi/helmet_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/species/unathi/helmet_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/species/akula/helmet_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/species/sergal/helmet_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/species/sergal/helmet_ch.dmi',
SPECIES_VULPKANIN = 'modular_chomp/icons/mob/species/vulpkanin/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_PROMETHEAN = 'modular_chomp/icons/mob/species/skrell/helmet_ch.dmi',
SPECIES_TESHARI = 'modular_chomp/icons/mob/species/teshari/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_XENOMORPH_HYBRID = 'modular_chomp/icons/mob/species/xenomorph_hybrid/helmet_ch.dmi'
SPECIES_PROTEAN = 'icons/mob/head.dmi',
SPECIES_HUMAN = 'icons/mob/head.dmi',
SPECIES_TAJ = 'icons/mob/species/tajaran/helmet.dmi',
SPECIES_SKRELL = 'icons/mob/species/skrell/helmet.dmi',
SPECIES_UNATHI = 'icons/mob/species/unathi/helmet.dmi',
SPECIES_XENOHYBRID = 'icons/mob/species/unathi/helmet.dmi',
SPECIES_AKULA = 'icons/mob/species/akula/helmet.dmi',
SPECIES_SERGAL = 'icons/mob/species/sergal/helmet.dmi',
SPECIES_NEVREAN = 'icons/mob/species/sergal/helmet.dmi',
SPECIES_VULPKANIN = 'icons/mob/species/vulpkanin/helmet.dmi',
SPECIES_ZORREN_HIGH = 'icons/mob/species/fox/helmet.dmi',
SPECIES_FENNEC = 'icons/mob/species/vulpkanin/helmet.dmi',
SPECIES_PROMETHEAN = 'icons/mob/species/skrell/helmet.dmi',
SPECIES_TESHARI = 'icons/mob/species/teshari/helmet.dmi',
SPECIES_VASILISSAN = 'icons/mob/species/skrell/helmet.dmi',
SPECIES_VOX = 'icons/mob/species/vox/head.dmi',
SPECIES_XENOMORPH_HYBRID = 'icons/mob/species/xenomorph_hybrid/helmet.dmi'
)
sprite_sheets_obj = list(
SPECIES_PROTEAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_HUMAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_TAJ = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_SKRELL = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_UNATHI = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_VULPKANIN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_ZORREN_HIGH = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_FENNEC = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_PROMETHEAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_TESHARI = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_VASILISSAN = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/head_ch.dmi',
SPECIES_XENOMORPH_HYBRID = 'modular_chomp/icons/mob/head_ch.dmi'
SPECIES_PROTEAN = 'icons/mob/head.dmi',
SPECIES_HUMAN = 'icons/mob/head.dmi',
SPECIES_TAJ = 'icons/mob/head.dmi',
SPECIES_SKRELL = 'icons/mob/head.dmi',
SPECIES_UNATHI = 'icons/mob/head.dmi',
SPECIES_XENOHYBRID = 'icons/mob/head.dmi',
SPECIES_AKULA = 'icons/mob/head.dmi',
SPECIES_SERGAL = 'icons/mob/head.dmi',
SPECIES_NEVREAN = 'icons/mob/head.dmi',
SPECIES_VULPKANIN = 'icons/mob/head.dmi',
SPECIES_ZORREN_HIGH = 'icons/mob/head.dmi',
SPECIES_FENNEC = 'icons/mob/head.dmi',
SPECIES_PROMETHEAN = 'icons/mob/head.dmi',
SPECIES_TESHARI = 'icons/mob/head.dmi',
SPECIES_VASILISSAN = 'icons/mob/head.dmi',
SPECIES_VOX = 'icons/mob/head.dmi',
SPECIES_XENOMORPH_HYBRID = 'icons/mob/head.dmi'
)
icon = 'modular_chomp/icons/mob/head_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/head_ch.dmi'
icon = 'icons/mob/head.dmi'
default_worn_icon = 'icons/mob/head.dmi'
/obj/item/clothing/gloves/gauntlets/rig/protean
name = "mass"
@@ -157,58 +158,58 @@
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, SPECIES_XENOMORPH_HYBRID)
sprite_sheets = list(
SPECIES_PROTEAN = '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_SKRELL = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_UNATHI = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VULPKANIN = '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_PROMETHEAN = '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_VOX = 'modular_chomp/icons/mob/species/vox/gloves_ch.dmi',
SPECIES_XENOMORPH_HYBRID = 'modular_chomp/icons/mob/species/xenomorph_hybrid/gloves_ch.dmi'
SPECIES_PROTEAN = 'icons/mob/hands.dmi',
SPECIES_HUMAN = 'icons/mob/hands.dmi',
SPECIES_TAJ = 'icons/mob/hands.dmi',
SPECIES_SKRELL = 'icons/mob/hands.dmi',
SPECIES_UNATHI = 'icons/mob/hands.dmi',
SPECIES_XENOHYBRID = 'icons/mob/hands.dmi',
SPECIES_AKULA = 'icons/mob/hands.dmi',
SPECIES_SERGAL = 'icons/mob/hands.dmi',
SPECIES_NEVREAN = 'icons/mob/hands.dmi',
SPECIES_VULPKANIN = 'icons/mob/hands.dmi',
SPECIES_ZORREN_HIGH = 'icons/mob/hands.dmi',
SPECIES_FENNEC = 'icons/mob/hands.dmi',
SPECIES_PROMETHEAN = 'icons/mob/hands.dmi',
SPECIES_TESHARI = 'icons/mob/species/teshari/hands.dmi',
SPECIES_VASILISSAN = 'icons/mob/hands.dmi',
SPECIES_VOX = 'icons/mob/species/vox/gloves.dmi',
SPECIES_XENOMORPH_HYBRID = 'icons/mob/species/xenomorph_hybrid/gloves.dmi'
)
sprite_sheets_obj = list(
SPECIES_HUMAN = '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_UNATHI = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_XENOHYBRID = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_AKULA = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_SERGAL = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_NEVREAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VULPKANIN = '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_PROMETHEAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_TESHARI = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VASILISSAN = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/hands_ch.dmi',
SPECIES_XENOMORPH_HYBRID = 'modular_chomp/icons/mob/hands_ch.dmi'
SPECIES_HUMAN = 'icons/mob/hands.dmi',
SPECIES_TAJ = 'icons/mob/hands.dmi',
SPECIES_SKRELL = 'icons/mob/hands.dmi',
SPECIES_UNATHI = 'icons/mob/hands.dmi',
SPECIES_XENOHYBRID = 'icons/mob/hands.dmi',
SPECIES_AKULA = 'icons/mob/hands.dmi',
SPECIES_SERGAL = 'icons/mob/hands.dmi',
SPECIES_NEVREAN = 'icons/mob/hands.dmi',
SPECIES_VULPKANIN = 'icons/mob/hands.dmi',
SPECIES_ZORREN_HIGH = 'icons/mob/hands.dmi',
SPECIES_FENNEC = 'icons/mob/hands.dmi',
SPECIES_PROMETHEAN = 'icons/mob/hands.dmi',
SPECIES_TESHARI = 'icons/mob/hands.dmi',
SPECIES_VASILISSAN = 'icons/mob/hands.dmi',
SPECIES_VOX = 'icons/mob/hands.dmi',
SPECIES_XENOMORPH_HYBRID = 'icons/mob/hands.dmi'
)
icon = 'modular_chomp/icons/mob/hands_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/hands_ch.dmi'
icon = 'icons/mob/hands.dmi'
default_worn_icon = 'icons/mob/hands.dmi'
/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, SPECIES_XENOMORPH_HYBRID)
sprite_sheets = list(
SPECIES_TESHARI = 'modular_chomp/icons/mob/species/teshari/feet_ch.dmi',
SPECIES_VOX = 'modular_chomp/icons/mob/species/vox/shoes_ch.dmi',
SPECIES_XENOMORPH_HYBRID = 'modular_chomp/icons/mob/species/xenomorph_hybrid/shoes_ch.dmi'
SPECIES_TESHARI = 'icons/mob/species/teshari/feet.dmi',
SPECIES_VOX = 'icons/mob/species/vox/shoes.dmi',
SPECIES_XENOMORPH_HYBRID = 'icons/mob/species/xenomorph_hybrid/shoes.dmi'
)
sprite_sheets_obj = list()
icon = 'modular_chomp/icons/mob/feet_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/feet_ch.dmi'
icon = 'icons/mob/feet.dmi'
default_worn_icon = 'icons/mob/feet.dmi'
/obj/item/clothing/suit/space/rig/protean
name = "mass"
@@ -224,14 +225,14 @@
/obj/item/storage/backpack,
)
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',
SPECIES_XENOMORPH_HYBRID = 'modular_chomp/icons/mob/species/xenomorph_hybrid/suit_ch.dmi'
SPECIES_TESHARI = 'icons/mob/species/teshari/suit.dmi',
SPECIES_VOX = 'icons/mob/species/vox/suit.dmi',
SPECIES_XENOMORPH_HYBRID = 'icons/mob/species/xenomorph_hybrid/suit.dmi'
)
sprite_sheets_obj = list()
icon = 'modular_chomp/icons/mob/spacesuit_ch.dmi'
default_worn_icon = 'modular_chomp/icons/mob/spacesuit_ch.dmi'
icon = 'icons/mob/spacesuit.dmi'
default_worn_icon = 'icons/mob/spacesuit.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
/obj/item/rig/protean/attackby(obj/item/W as obj, mob/living/user as mob)
@@ -492,6 +493,9 @@
//Effectively a round about way of letting a Protean wear other rigs.
/obj/item/rig/protean/proc/AssimilateRig(mob/user, var/obj/item/rig/R)
if(!can_assimilate_rig)
to_chat(user, span_warning("You can not place a rig into \the [src]"))
return
if(!R || assimilated_rig)
return
if(istype(R, /obj/item/rig/protean))

View File

@@ -1,5 +1,4 @@
#define DAM_SCALE_FACTOR 0.01
#define METAL_PER_TICK 100
#define METAL_PER_TICK SHEET_MATERIAL_AMOUNT/20
/datum/species/protean
name = SPECIES_PROTEAN
name_plural = "Proteans"
@@ -7,7 +6,7 @@
" + span_italics("VERY") + " advanced civilizations have the option of 'nanoswarm' bodies. Effectively a single robot body comprised \
of millions of tiny nanites working in concert to maintain cohesion."
show_ssd = "totally quiescent"
death_message = "rapidly loses cohesion, dissolving into a cloud of gray dust..."
death_message = "rapidly loses cohesion, retreating into their hardened control module..."
knockout_message = "collapses inwards, forming a disordered puddle of gray goo."
remains_type = /obj/effect/decal/cleanable/ash
@@ -26,50 +25,53 @@
num_alternate_languages = 3
species_language = LANGUAGE_EAL
assisted_langs = list(LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
speech_bubble_appearance = "synthetic"
color_mult = TRUE
breath_type = null
poison_type = null
// male_scream_sound = null
// female_scream_sound = null
virus_immune = 1
blood_volume = 0
min_age = 18
max_age = 200
oxy_mod = 0
//radiation_mod = 0 //Can't be assed with fandangling rad protections while blob formed/suited
darksight = 10 // CHOMPAdd
siemens_coefficient = 2
brute_mod = 0.8
burn_mod = 1.5
oxy_mod = 0
item_slowdown_mod = 1.33
cold_level_1 = 280 //Default 260 - Lower is better
cold_level_2 = 220 //Default 200
cold_level_3 = 130 //Default 120
heat_level_1 = 320 //Default 360
heat_level_2 = 370 //Default 400
heat_level_3 = 600 //Default 1000
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_high_pressure = 200 //They can cope with slightly higher pressure
//Cold/heat does affect them, but it's done in special ways below
cold_level_1 = -INFINITY
cold_level_2 = -INFINITY
cold_level_3 = -INFINITY
heat_level_1 = INFINITY
heat_level_2 = INFINITY
heat_level_3 = INFINITY
heat_level_1 = 420
heat_level_2 = 480
heat_level_3 = 1100
body_temperature = 290
siemens_coefficient = 1.5 //Very bad zappy times
rarity_value = 5
species_sounds = "Robotic" // CHOMPEnable
crit_mod = 4 //Unable to go crit // CHOMPEnable
var/obj/item/rig/protean/OurRig
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list(
O_BRAIN = /obj/item/organ/internal/mmi_holder/posibrain/nano,
O_ORCH = /obj/item/organ/internal/nano/orchestrator,
O_FACT = /obj/item/organ/internal/nano/refactory
O_FACT = /obj/item/organ/internal/nano/refactory,
)
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable/nano),
@@ -85,7 +87,7 @@
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.")
//These verbs are hidden, for hotkey use only
@@ -94,7 +96,11 @@
/mob/living/carbon/human/proc/nano_partswap,
/mob/living/carbon/human/proc/nano_metalnom,
/mob/living/carbon/human/proc/nano_blobform,
/mob/living/carbon/human/proc/nano_set_size,
/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/nano_latch,
/mob/living/proc/set_size,
/mob/living/carbon/human/proc/nano_change_fitting, //These verbs are displayed normally,
/mob/living/carbon/human/proc/shapeshifter_select_hair,
/mob/living/carbon/human/proc/shapeshifter_select_hair_colors,
@@ -105,12 +111,29 @@
/mob/living/carbon/human/proc/shapeshifter_select_tail,
/mob/living/carbon/human/proc/shapeshifter_select_ears,
/mob/living/carbon/human/proc/shapeshifter_select_secondary_ears,
)
/mob/living/proc/flying_toggle,
/mob/living/proc/flying_vore_toggle,
/mob/living/proc/start_wings_hovering,
) //removed fetish verbs, since non-customs can pick neutral traits now. Also added flight, cause shapeshifter can grow wings.
var/global/list/abilities = list()
var/monochromatic = FALSE //IGNORE ME
var/blob_appearance = "puddle1"
var/blob_color_1 = "#363636"
var/blob_color_2 = "#ba3636"
var/list/dragon_overlays = list(
"dragon_underSmooth" = "#FFFFFF",
"dragon_bodySmooth" = "#FFFFFF",
"dragon_earsNormal" = "#FFFFFF",
"dragon_maneShaggy" = "#FFFFFF",
"dragon_hornsPointy" = "#FFFFFF",
"dragon_eyesNormal" = "#FFFFFF"
)
var/pseudodead = 0
/datum/species/protean/New()
..()
if(!LAZYLEN(abilities))
@@ -127,20 +150,62 @@
if(saved_nif)
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)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
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)
return GLOB.playable_species
var/static/list/protean_shapeshifting_forms = GLOB.playable_species.Copy() - SPECIES_PROMETHEAN
return protean_shapeshifting_forms
/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)
..()
H.synth_color = TRUE
/datum/species/protean/equip_survival_gear(var/mob/living/carbon/human/H)
var/obj/item/stack/material/steel/metal_stack = new(null, 3)
..()
var/obj/item/stack/material/steel/metal_stack = new()
metal_stack.set_amount(5)
var/obj/item/clothing/accessory/permit/nanotech/permit = new()
permit.set_name(H.real_name)
@@ -161,6 +226,8 @@
else
H.nif.durability = 25
new /obj/item/rig/protean(H,H)
/datum/species/protean/hug(var/mob/living/carbon/human/H, var/mob/living/target)
return ..() //Wut
@@ -172,23 +239,28 @@
/datum/species/protean/handle_death(var/mob/living/carbon/human/H)
if(!H)
return // Iono!
return //No body?
if(OurRig.dead)
return
OurRig.dead = 1
var/mob/temp = H
if(H.temporary_form)
H.forceMove(H.temporary_form.drop_location())
H.ckey = H.temporary_form.ckey
QDEL_NULL(H.temporary_form)
to_chat(H, span_warning("You died as a Protean. Please sit out of the round for at least 60 minutes before respawning, to represent the time it would take to ship a new-you to the station."))
spawn(1)
if(H)
H.gib()
temp = H.temporary_form
playsound(temp, 'sound/voice/borg_deathsound.ogg', 50, 1)
temp.visible_message(span_bold("[temp.name]") + " shudders and retreats inwards, coalescing into a single core componant!")
to_chat(temp, span_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."))
if(H.temporary_form)
if(!istype(H.temporary_form.loc, /obj/item/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)
if((H.getActualBruteLoss() + H.getActualFireLoss()) > H.maxHealth*0.5 && isturf(H.loc)) //So, only if we're not a blob (we're in nullspace) or in someone (or a locker, really, but whatever)
return ..() //Any instakill shot runtimes since there are no organs after this. No point to not skip these checks, going to nullspace anyway.
/*CHOMP Station removal start
var/obj/item/organ/internal/nano/refactory/refactory = locate() in H.internal_organs
if(refactory && !(refactory.status & ORGAN_DEAD))
@@ -209,6 +281,7 @@
H.add_modifier(/datum/modifier/protean/silver, origin = refactory)
return ..()
CHOMP Station removal end*/
/datum/species/protean/get_additional_examine_text(var/mob/living/carbon/human/H)
return ..() //Hmm, what could be done here?
@@ -270,6 +343,7 @@
if(!refactory.use_stored_material(material_name,material_use))
expire()
/*CHOMP Removal start
/datum/modifier/protean/mhydrogen
name = "Protean Effect - M.Hydrogen"
desc = "You're affected by the presence of metallic hydrogen."
@@ -314,6 +388,7 @@
accuracy = 30
evasion = 30
CHOMP Removal end*/
/datum/modifier/protean/steel
name = "Protean Effect - Steel"
@@ -325,14 +400,24 @@
material_name = MAT_STEEL
/datum/modifier/protean/steel/tick()
holder.adjustBruteLoss(-1,include_robo = TRUE) //Modified by species resistances
holder.adjustFireLoss(-0.5,include_robo = TRUE) //Modified by species resistances
var/mob/living/carbon/human/H = holder
//Heal a random damaged limb by 1,1 per tick
holder.adjustBruteLoss(-1,include_robo = TRUE)
holder.adjustFireLoss(-1,include_robo = TRUE)
holder.adjustToxLoss(-1)
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)
// Fix internal damage
if(O.damage > 0)
O.damage = max(0,O.damage-0.1)
// If not damaged, but dead, fix it
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
@@ -350,13 +435,11 @@
owner = 1
if(new_name)
name += " ([new_name])"
validstring += "[time2text(world.timeofday, "Month") +" "+ num2text(text2num(time2text(world.timeofday, "YYYY"))+300)]"
validstring += "[time2text(world.timeofday, "Month") +" "+ num2text(text2num(time2text(world.timeofday, "YYYY"))+544)]" // CHOMPEdit
registring += "[new_name]"
/obj/item/clothing/accessory/permit/nanotech/examine(mob/user)
. = ..()
. += validstring
. += registring
#undef DAM_SCALE_FACTOR
#undef METAL_PER_TICK

View File

@@ -170,7 +170,7 @@
update_canmove()
stunned = 2 // CHOMPEdit - Whoops, crawling is a thing now.
revive_ready = world.time + 10 MINUTES //set the cooldown CHOMPEdit: Reduced this to 10 minutes, you're playing with fire if you're reviving that often.
revive_ready = world.time + 10 MINUTES //set the cooldown, Reduced this to 10 minutes, you're playing with fire if you're reviving that often.
/datum/modifier/resleeving_sickness/chimera //near identical to the regular version, just with different flavortexts
name = "imperfect regeneration"

View File

@@ -26,7 +26,6 @@
newitem.forceMove(S)
return S
//CHOMPedit - protean rigsuit integrated backpack, behold, jank!
if(istype(src.back,/obj/item/rig)) //This would be much cooler if we had componentized storage datums
var/obj/item/rig/R = src.back
if(R.rig_storage)

View File

@@ -641,6 +641,11 @@
L += D.wrapped
if(istype(D.wrapped, /obj/item/storage)) //this should never happen
L += get_contents(D.wrapped)
for(var/obj/item/rig/R in src.contents) //Check rigsuit storage for items
if(R.rig_storage)
L += get_contents(R.rig_storage)
return L
/mob/living/proc/check_contents_for(A)

View File

@@ -186,56 +186,8 @@
set desc = "Sets your voice style!"
set category = "OOC.Game Settings"
//CHOMPEDIT START, Global Talk Sounds
var/list/possible_voice_types = get_talk_sound()/*list(
"beep-boop",
"goon speak 1",
"goon speak 2",
"goon speak 3",
"goon speak 4",
"goon speak blub",
"goon speak bottalk",
"goon speak buwoo",
"goon speak cow",
"goon speak lizard",
"goon speak pug",
"goon speak pugg",
"goon speak roach",
"goon speak skelly")
*/ //CHOMPEDIT END, Global Talk Sounds
var/list/possible_voice_types = get_talk_sound()
var/choice = tgui_input_list(usr, "Which set of sounds would you like to use for your character's speech sounds?", "Voice Sounds", possible_voice_types)
if(!choice)
voice_sounds_list = talk_sound
switch(choice)
if("beep-boop")
voice_sounds_list = talk_sound
if("goon speak 1")
voice_sounds_list = goon_speak_one_sound
if("goon speak 2")
voice_sounds_list = goon_speak_two_sound
if("goon speak 3")
voice_sounds_list = goon_speak_three_sound
if("goon speak 4")
voice_sounds_list = goon_speak_four_sound
if("goon speak blub")
voice_sounds_list = goon_speak_blub_sound
if("goon speak bottalk")
voice_sounds_list = goon_speak_bottalk_sound
if("goon speak buwoo")
voice_sounds_list = goon_speak_buwoo_sound
if("goon speak cow")
voice_sounds_list = goon_speak_cow_sound
if("goon speak lizard")
voice_sounds_list = goon_speak_lizard_sound
if("goon speak pug")
voice_sounds_list = goon_speak_pug_sound
if("goon speak pugg")
voice_sounds_list = goon_speak_pugg_sound
if("goon speak roach")
voice_sounds_list = goon_speak_roach_sound
if("goon speak skelly")
voice_sounds_list = goon_speak_skelly_sound
//CHOMPedit start.
if("xeno speak")
voice_sounds_list = xeno_speak_sound
//CHOMPedit end.
voice_sounds_list = get_talk_sound(choice)

View File

@@ -42,38 +42,7 @@
if(!voice_sounds_list.len || !voice_sounds_list)
if(client.prefs.voice_sound)
var/prefsound = client.prefs.voice_sound
voice_sounds_list = get_talk_sound(prefsound) //CHOMEPEDIT GLobal voice getter
/* CHOMPRemval, redundant voice selector
switch(prefsound)
if("beep-boop")
voice_sounds_list = talk_sound
if("goon speak 1")
voice_sounds_list = goon_speak_one_sound
if("goon speak 2")
voice_sounds_list = goon_speak_two_sound
if("goon speak 3")
voice_sounds_list = goon_speak_three_sound
if("goon speak 4")
voice_sounds_list = goon_speak_four_sound
if("goon speak blub")
voice_sounds_list = goon_speak_blub_sound
if("goon speak bottalk")
voice_sounds_list = goon_speak_bottalk_sound
if("goon speak buwoo")
voice_sounds_list = goon_speak_buwoo_sound
if("goon speak cow")
voice_sounds_list = goon_speak_cow_sound
if("goon speak lizard")
voice_sounds_list = goon_speak_lizard_sound
if("goon speak pug")
voice_sounds_list = goon_speak_pug_sound
if("goon speak pugg")
voice_sounds_list = goon_speak_pugg_sound
if("goon speak roach")
voice_sounds_list = goon_speak_roach_sound
if("goon speak skelly")
voice_sounds_list = goon_speak_skelly_sound
*/ //CHOMPRemval, redundant voice selector
voice_sounds_list = get_talk_sound(prefsound)
else
voice_sounds_list = talk_sound
//VOREStation Add End

View File

@@ -400,3 +400,6 @@
else
to_chat(usr, "You stop sensing creatures beyond the walls.")
sight -= SEE_MOBS
/mob/living/simple_mob/proc/character_directory_species()
return "simplemob"

View File

@@ -114,7 +114,7 @@
/obj/item/holder/armadillo
origin_tech = list(TECH_BIO = 1)
default_worn_icon = 'modular_chomp/icons/mob/head_ch.dmi'
default_worn_icon = 'icons/mob/head.dmi'
//item_state = "armadillo_rest" //Commented here as a reminder that holders will always set the item_state to icon_rest. You cannot override it like this.
/mob/living/simple_mob/animal/passive/armadillo/torta

View File

@@ -889,7 +889,7 @@
suit_sprites = 'icons/mob/taursuits_noodle_vr.dmi'
clip_mask_state = "taur_clip_mask_noodle"
icon_sprite_tag = "noodle"
/* CHOMPEdit - removed as a sprite accessory of the same name already exists for us, and having this here stops it from registering as a sprite accessory.
/datum/sprite_accessory/tail/taur/sect_drone
name = "Sect Drone (Taur)"
icon_state = "sect_drone"
@@ -910,7 +910,7 @@
msg_owner_grab_fail = "You step down onto %prey, squishing them and forcing them down to the ground!"
msg_prey_grab_fail = "%owner steps down and squishes you with their leg, forcing you down to the ground!"
*/
/datum/sprite_accessory/tail/taur/sect_drone/fat
name = "Fat Sect Drone (Taur)"
icon_state = "fat_sect_drone"

View File

@@ -1,7 +1,3 @@
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
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
@@ -105,4 +101,3 @@ GLOBAL_LIST_INIT(dsi_to_species, list(SPECIES_TAJARAN = "DSI - Tajaran", SPECIES
lifelike = 1
modular_bodyparts = MODULAR_BODYPART_PROSTHETIC
parts = list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)

View File

@@ -1,3 +1,7 @@
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"))
//CitRP Port
var/const/cyberbeast_monitor_styles = "blank=cyber_blank;\
default=cyber_default;\

View File

@@ -2,81 +2,84 @@
/obj/item/organ/external/chest/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 50 // <-- This is different from the rest
max_damage = 70 // <-- This is different from the rest
min_broken_damage = 1000
vital = TRUE // <-- This is different from the rest
vital = TRUE
model = "protean"
/obj/item/organ/external/groin/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 30 // <-- This is different from the rest
max_damage = 70
min_broken_damage = 1000 //Multiple
vital = FALSE
model = "protean"
/obj/item/organ/external/head/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 30
max_damage = 70
min_broken_damage = 1000 //Inheritance
vital = FALSE
model = "protean"
/obj/item/organ/external/arm/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000 //Please
vital = FALSE
model = "protean"
/obj/item/organ/external/arm/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000
vital = FALSE
model = "protean"
/obj/item/organ/external/leg/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000
vital = FALSE
model = "protean"
/obj/item/organ/external/leg/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000
vital = FALSE
model = "protean"
/obj/item/organ/external/hand/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000
vital = FALSE
model = "protean"
/obj/item/organ/external/hand/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000
vital = FALSE
model = "protean"
/obj/item/organ/external/foot/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000
vital = FALSE
model = "protean"
/obj/item/organ/external/foot/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 20
max_damage = 40
min_broken_damage = 1000
vital = FALSE
model = "protean"
/obj/item/organ/external/head/unbreakable/nano/disfigure()
return //No way to repair disfigured prots
// // // Internal Organs
/obj/item/organ/internal/nano
robotic = ORGAN_ROBOT
@@ -180,9 +183,11 @@
icon = initial(icon)
icon_state = "posi1"
stored_mmi.icon_state = "posi1"
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
/obj/item/mmi/digital/posibrain/nano
name = "protean posibrain"
@@ -209,3 +214,19 @@
/obj/item/mmi/digital/posibrain/nano/transfer_identity()
. = ..()
icon_state = "posi1"
/obj/item/organ/internal/nano/digest_act(atom/movable/item_storage = null)
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/protean_reboot
sort_string = "JVAAZ"
/obj/item/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 = 'icons/mob/species/protean/protean.dmi'
icon_state = "reboot"

View File

@@ -13,7 +13,8 @@ var/list/ventcrawl_machinery = list(
/obj/belly,
/obj/soulgem, // CHOMPAdd
/obj/screen,
/atom/movable/emissive_blocker
/atom/movable/emissive_blocker,
/obj/item/rig/protean
)
//VOREStation Edit : added /obj/belly, to this list, CI is complaining about this in his indentation check. Added mob_headset for those with radios so there's no weirdness.
//mob/living/simple_mob/borer, //VORESTATION AI TEMPORARY REMOVAL REPLACE BACK IN LIST WHEN RESOLVED //VOREStation Edit
@@ -67,11 +68,11 @@ var/list/ventcrawl_machinery = list(
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/carried_item)
//Ability master easy test for allowed (cheaper than istype)
if(carried_item == ability_master)
return 1
return TRUE
if(isanimal(src))
var/mob/living/simple_mob/S = src
if(carried_item == S.myid) //VOREStation Edit
return 1 //VOREStation Edit
if(carried_item == S.myid)
return TRUE
//Try to find it in our allowed list (istype includes subtypes)
var/listed = FALSE
for(var/test_type in can_enter_vent_with)
@@ -81,23 +82,23 @@ var/list/ventcrawl_machinery = list(
//Only allow it if it's "IN" the mob, not equipped on/being held. //Disabled, as it's very annoying that, for example, Pun Pun has no way to ventcrawl with his suit if given the verb, since the list of allowed items is ignored for worn items.
if(listed/* && !get_inventory_slot(carried_item)*/)
return 1
return TRUE
/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in internal_organs)
return 1
return TRUE
return ..()
/mob/living/carbon/human/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in organs)
return 1
return TRUE
if(species.name == SPECIES_REPLICANT_CREW)
if(istype(carried_item, /obj/item/clothing/under))
return 1 //Allow them to not vent crawl naked
return TRUE //Allow them to not vent crawl naked
if(istype(carried_item, /obj/item))
var/obj/item/I = carried_item
if(I.w_class <= 2)
return 1 //Allow them to carry items that fit in pockets
if(I.w_class <= ITEMSIZE_SMALL)
return TRUE //Allow them to carry items that fit in pockets
return ..()
/mob/living/proc/ventcrawl_carry()
@@ -107,6 +108,29 @@ var/list/ventcrawl_machinery = list(
return FALSE
return TRUE
/mob/living/simple_mob/protean_blob/ventcrawl_carry()
for(var/atom/A in contents)
if(!is_allowed_vent_crawl_item(A))
to_chat(src, span_warning("You can't carry \the [A] while ventcrawling!"))
return FALSE
if(humanform)
for(var/atom/B in humanform.get_contents())
if(!is_allowed_vent_crawl_item(B))
to_chat(src, span_warning("You can't carry \the [B] while ventcrawling!"))
return FALSE
return TRUE
/mob/living/simple_mob/protean_blob/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if((carried_item in humanform.organs) || (carried_item in humanform.internal_organs))
return TRUE
if(istype(carried_item, /obj/item/clothing/under))
return TRUE //Allow jumpsuits only
if(istype(carried_item, /obj/item))
var/obj/item/I = carried_item
if(I.w_class <= ITEMSIZE_SMALL)
return TRUE //Allow them to carry items that fit in pockets
return ..()
/mob/living/AltClickOn(var/atom/A)
if(is_type_in_list(A,ventcrawl_machinery))
handle_ventcrawl(A)
@@ -130,7 +154,7 @@ var/list/ventcrawl_machinery = list(
return pipe
/mob/living/carbon/alien/ventcrawl_carry()
return 1
return TRUE
/mob/living/var/ventcrawl_layer = 3

View File

@@ -139,6 +139,9 @@
if(!resizable && !ignore_prefs)
return 1
. = ..()
if(!ishuman(temporary_form) && isliving(temporary_form))
var/mob/living/temp_form = temporary_form
temp_form.resize(new_size, animate, uncapped, ignore_prefs, aura_animation)
if(LAZYLEN(hud_list) && has_huds)
var/new_y_offset = vis_height * (size_multiplier - 1)
for(var/index = 1 to hud_list.len)

View File

Before

Width:  |  Height:  |  Size: 556 B

After

Width:  |  Height:  |  Size: 556 B

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 263 KiB

View File

Before

Width:  |  Height:  |  Size: 357 B

After

Width:  |  Height:  |  Size: 357 B

View File

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 205 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 182 B

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 463 B

View File

Before

Width:  |  Height:  |  Size: 628 B

After

Width:  |  Height:  |  Size: 628 B

View File

Before

Width:  |  Height:  |  Size: 443 B

After

Width:  |  Height:  |  Size: 443 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 907 B

After

Width:  |  Height:  |  Size: 907 B

View File

Before

Width:  |  Height:  |  Size: 363 B

After

Width:  |  Height:  |  Size: 363 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 KiB

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -6,78 +6,3 @@ GLOBAL_LIST_EMPTY(latejoin_gatewaystation)
GLOBAL_LIST_EMPTY(latejoin_plainspath)
GLOBAL_LIST_EMPTY(latejoin_fueldepot)
GLOBAL_LIST_EMPTY(latejoin_tyrvillage)
var/list/talk_sound_map = rlist(
list(
"beep-boop",
"goon speak 1",
"goon speak 2",
"goon speak 3",
"goon speak 4",
"goon speak blub",
"goon speak bottalk",
"goon speak buwoo",
"goon speak cow",
"goon speak lizard",
"goon speak pug",
"goon speak pugg",
"goon speak roach",
"goon speak skelly",
"xeno speak" // CHOMPedit
),
list(
talk_sound,
goon_speak_one_sound,
goon_speak_two_sound,
goon_speak_three_sound,
goon_speak_four_sound,
goon_speak_blub_sound,
goon_speak_bottalk_sound,
goon_speak_buwoo_sound,
goon_speak_cow_sound,
goon_speak_lizard_sound,
goon_speak_pug_sound,
goon_speak_pugg_sound,
goon_speak_roach_sound,
goon_speak_skelly_sound,
xeno_speak_sound // CHOMPedit
)
)
/proc/get_talk_sound(var/voice_sound)
if(!voice_sound)
return talk_sound_map[1]
return talk_sound_map[2][voice_sound]
/proc/rlist(var/list/keys,var/list/values) //short for reversible list generator
var/list/rlist = list(list(),list(),FALSE,0)
var/i = 0
for(i = 1, i <= LAZYLEN(keys), i++)
to_chat(world,keys[i])
rlist[1] += keys[i]
rlist[2][keys[i]] = values[i]
rlist += TRUE
rlist += i
return rlist
/proc/arlist(var/list/altlist)
var/list/rlist = list(list(),list(),FALSE,0)
var/i = 0
for(i = 1, i <= LAZYLEN(altlist), i++)
rlist[(i % 2) +1] += altlist[i]
rlist += TRUE
rlist += i/2
return rlist
/*RLIST standard
/proc/read_rlist(var/list/rlist)
//Length
rlist[4]
//valid?
rlist[3]
//keys
rlist[1]
//Values
rlist[2]
*/

View File

@@ -7,271 +7,3 @@
var/job_other_low = 0
var/job_other_med = 0
var/job_other_high = 0
/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_GET(flag/humans_need_surnames)) // CHOMPEdit
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]
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" = body_markings[M][BP]["color"], "datum" = mark_datum, "priority" = priority, "on" = body_markings[M][BP]["on"])
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
/* CHOMPREMOVAL, redundant list
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
*/ //CHOMPREMOVAL, redundant list
character.voice_sounds_list = get_talk_sound(voice_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

@@ -3,4 +3,4 @@
desc = "A hat used by the mailman to show who's the delivery person here."
icon_state = "mailman2"
icon = 'icons/obj/clothing/hats_ch.dmi'
icon_override = 'modular_chomp/icons/mob/head_ch.dmi'
icon_override = 'icons/mob/head.dmi'

View File

@@ -1,4 +0,0 @@
/obj/item/rig
var/protean = 0
var/obj/item/storage/backpack/rig_storage
permeability_coefficient = 0 //Protect the squishies, after all this shit should be waterproof.

View File

@@ -1,22 +0,0 @@
/obj/item/holder/proc/sync(var/mob/living/M)
dir = 2
overlays.Cut()
if(M.item_state)
item_state = M.item_state
color = M.color
name = M.name
desc = M.desc
overlays |= M.overlays
/obj/item/holder/protoblob
slot_flags = SLOT_HEAD | SLOT_OCLOTHING | SLOT_HOLSTER | SLOT_ICLOTHING | SLOT_ID | SLOT_EARS
w_class = ITEMSIZE_TINY
allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/suit_cooling_unit,/obj/item/melee/baton)
item_icons = list(
slot_l_hand_str = 'modular_chomp/icons/mob/lefthand_holder.dmi',
slot_r_hand_str = 'modular_chomp/icons/mob/righthand_holder.dmi',
slot_head_str = 'modular_chomp/icons/mob/head_ch.dmi',
slot_w_uniform_str = 'modular_chomp/icons/mob/uniform_ch.dmi',
slot_wear_suit_str = 'modular_chomp/icons/mob/suit_ch.dmi',
slot_r_ear_str = 'modular_chomp/icons/mob/ears.dmi',
slot_l_ear_str = 'modular_chomp/icons/mob/ears.dmi')

View File

@@ -1,152 +0,0 @@
/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

@@ -14,7 +14,6 @@
var/grab_power_self = 0
var/waking_speed = 1
var/mudking = 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
var/lightweight_light = 0
// Handles non-standard eyes when using a species that utilizes a custom base icon set.

View File

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

View File

@@ -1,793 +0,0 @@
// Simple animal nanogoopeyness
/mob/living/simple_mob/protean_blob
name = "protean blob"
desc = "Some sort of big viscous pool of jelly."
tt_desc = "Animated nanogoop"
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "to_puddle"
icon_living = "puddle0-eyes" //Null icon, since we're made of overlays now.
icon_rest = "puddle0-eyes"
icon_dead = "puddle0-eyes"
faction = "neutral"
maxHealth = 200
health = 200
say_list_type = /datum/say_list/protean_blob
show_stat_health = FALSE //We will do it ourselves
response_help = "pets the"
response_disarm = "gently pushes aside the "
response_harm = "hits the"
harm_intent_damage = 3
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = list("slashed")
see_in_dark = 10
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 1100
movement_cooldown = 0
hunger_rate = 0
var/mob/living/carbon/human/humanform
var/obj/item/organ/internal/nano/refactory/refactory
var/datum/modifier/healing
var/human_brute = 0
var/human_burn = 0
player_msg = "In this form, your health will regenerate as long as you have metal in you."
can_buckle = 1
buckle_lying = 1
mount_offset_x = 0
mount_offset_y = 0
has_hands = 1
shock_resist = 1
nameset = 1
holder_type = /obj/item/holder/protoblob
var/hiding = 0
vore_icons = 1
vore_active = 1
plane = ABOVE_MOB_PLANE //Necessary for overlay based icons
/datum/say_list/protean_blob
speak = list("Blrb?","Sqrsh.","Glrsh!")
emote_hear = list("squishes softly","spluts quietly","makes wet noises")
emote_see = list("shifts wetly","undulates placidly")
//Constructor allows passing the human to sync damages
/mob/living/simple_mob/protean_blob/New(var/newloc, var/mob/living/carbon/human/H)
..()
if(H)
humanform = H
updatehealth()
refactory = locate() in humanform.internal_organs
add_verb(src,/mob/living/proc/usehardsuit) //CHOMPEdit TGPanel
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_partswap) //CHOMPEdit TGPanel
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_regenerate) //CHOMPEdit TGPanel
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_metalnom) //CHOMPEdit TGPanel
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_blobform) //CHOMPEdit TGPanel
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_rig_transform) //CHOMPEdit TGPanel
add_verb(src,/mob/living/simple_mob/protean_blob/proc/appearance_switch) //CHOMPEdit TGPanel
add_verb(src,/mob/living/simple_mob/protean_blob/proc/nano_latch) //CHOMPEdit TGPanel
remove_verb(src,/mob/living/simple_mob/proc/nutrition_heal) //CHOMPEdit TGPanel
else
update_icon()
add_verb(src,/mob/living/simple_mob/proc/animal_mount) //CHOMPEdit TGPanel
add_verb(src,/mob/living/proc/toggle_rider_reins) //CHOMPEdit TGPanel
//Hidden verbs for macro hotkeying
/mob/living/simple_mob/protean_blob/proc/nano_partswap()
set name = "Ref - Single Limb"
set desc = "Allows you to replace and reshape your limbs as you see fit."
//set category = "Abilities.Protean"
set hidden = 1
humanform.nano_partswap()
/mob/living/simple_mob/protean_blob/proc/nano_regenerate()
set name = "Total Reassembly (wip)"
set desc = "Completely reassemble yourself from whatever save slot you have loaded in preferences. Assuming you meet the requirements."
//set category = "Abilities.Protean"
set hidden = 1
humanform.nano_regenerate()
/mob/living/simple_mob/protean_blob/proc/nano_blobform()
set name = "Toggle Blobform"
set desc = "Switch between amorphous and humanoid forms."
//set category = "Abilities.Protean"
set hidden = 1
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.Protean"
set hidden = 1
humanform.nano_metalnom()
/mob/living/simple_mob/protean_blob/proc/nano_rig_transform()
set name = "Modify Form - Hardsuit"
set desc = "Allows a protean to retract its mass into its hardsuit module at will."
//set category = "Abilities.Protean"
set hidden = 1
humanform.nano_rig_transform()
/mob/living/simple_mob/protean_blob/proc/appearance_switch()
set name = "Switch Blob Appearance"
set desc = "Allows a protean blob to switch its outwards appearance."
//set category = "Abilities.Protean"
set hidden = 1
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.Protean"
set hidden = 1
humanform.nano_latch()
/mob/living/simple_mob/protean_blob/Login()
..()
plane_holder.set_vis(VIS_AUGMENTED, 1)
plane_holder.set_vis(VIS_CH_HEALTH_VR, 1)
plane_holder.set_vis(VIS_CH_ID, 1)
plane_holder.set_vis(VIS_CH_STATUS_R, 1)
plane_holder.set_vis(VIS_CH_BACKUP, 1) //Gonna need these so we can see the status of our host. Could probably write it so this only happens when worn, but eeehhh
if(!riding_datum)
riding_datum = new /datum/riding/simple_mob/protean_blob(src)
/datum/riding/simple_mob/protean_blob/handle_vehicle_layer()
ridden.layer = OBJ_LAYER
/mob/living/simple_mob/protean_blob/MouseDrop_T()
return
/mob/living/simple_mob/protean_blob/runechat_y_offset(width, height)
return (..()) - (20*size_multiplier)
/mob/living/simple_mob/protean_blob/Destroy()
humanform = null
refactory = null
vore_organs = null
vore_selected = null
if(healing)
healing.expire()
return ..()
/mob/living/simple_mob/protean_blob/say_understands(var/mob/other, var/datum/language/speaking = null)
// The parent of this proc and its parent are SHAMS and should be rewritten, but I'm not up to it right now.
if(!speaking)
return TRUE // can understand common, they're like, a normal person thing
return ..()
/mob/living/simple_mob/protean_blob/speech_bubble_appearance()
return "synthetic"
/mob/living/simple_mob/protean_blob/init_vore()
return //Don't make a random belly, don't waste your time
/mob/living/simple_mob/protean_blob/isSynthetic()
return TRUE // yup
/mob/living/simple_mob/protean_blob/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/update_misc_tabs()
. = ..()
if(humanform)
humanform.species.update_misc_tabs(src)
/mob/living/simple_mob/protean_blob/updatehealth()
if(humanform.nano_dead_check(src))
return
if(!humanform)
return ..()
//Set the max
maxHealth = humanform.getMaxHealth()*2 //HUMANS, and their 'double health', bleh.
human_brute = humanform.getActualBruteLoss()
human_burn = humanform.getActualFireLoss()
health = maxHealth - humanform.getOxyLoss() - humanform.getToxLoss() - humanform.getCloneLoss() - humanform.getBruteLoss() - humanform.getFireLoss()
//Alive, becoming dead
if((stat < DEAD) && (health <= 0))
humanform.death()
nutrition = humanform.nutrition
//Overhealth
if(health > getMaxHealth())
health = getMaxHealth()
//Update our hud if we have one
if(healths)
if(stat != DEAD)
var/heal_per = (health / getMaxHealth()) * 100
switch(heal_per)
if(100 to INFINITY)
healths.icon_state = "health0"
if(80 to 100)
healths.icon_state = "health1"
if(60 to 80)
healths.icon_state = "health2"
if(40 to 60)
healths.icon_state = "health3"
if(20 to 40)
healths.icon_state = "health4"
if(0 to 20)
healths.icon_state = "health5"
else
healths.icon_state = "health6"
else
healths.icon_state = "health7"
// All the damage and such to the blob translates to the human
/mob/living/simple_mob/protean_blob/apply_effect(var/effect = 0, var/effecttype = STUN, var/blocked = 0, var/check_protection = 1)
if(humanform)
return humanform.apply_effect(effect, effecttype, blocked, check_protection)
else
return ..()
/mob/living/simple_mob/protean_blob/adjustBruteLoss(var/amount,var/include_robo)
if(humanform)
return humanform.adjustBruteLoss(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/adjustFireLoss(var/amount,var/include_robo)
if(humanform)
return humanform.adjustFireLoss(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/adjustToxLoss(amount)
if(humanform)
return humanform.adjustToxLoss(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/adjustOxyLoss(amount)
if(humanform)
return humanform.adjustOxyLoss(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/adjustHalLoss(amount)
if(humanform)
return humanform.adjustHalLoss(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/adjustCloneLoss(amount)
if(humanform)
return humanform.adjustCloneLoss(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/adjust_nutrition(amount)
if(humanform)
return humanform.adjust_nutrition(amount)
else
return ..()
/mob/living/simple_mob/protean_blob/emp_act(severity)
if(humanform)
return humanform.emp_act(severity)
else
return ..()
/mob/living/simple_mob/protean_blob/ex_act(severity)
if(humanform)
return humanform.ex_act(severity)
else
return ..()
/mob/living/simple_mob/protean_blob/rad_act(severity)
if(istype(loc, /obj/item/rig))
return //Don't irradiate us while we're in rig mode
if(humanform)
return humanform.rad_act(severity)
else
return ..()
/mob/living/simple_mob/protean_blob/bullet_act(obj/item/projectile/P)
if(humanform)
return humanform.bullet_act(P)
else
return ..()
/mob/living/simple_mob/protean_blob/death(gibbed, deathmessage = "Coalesces inwards, retreating into their core componants")
if(humanform)
humanform.death(gibbed, deathmessage)
else
animate(src, alpha = 0, time = 2 SECONDS)
sleep(2 SECONDS)
/mob/living/simple_mob/protean_blob/Life()
. = ..()
if(!humanform.nano_dead_check(src))
if(. && istype(refactory) && humanform)
if(!healing && (human_brute || human_burn) && refactory.get_stored_material(MAT_STEEL) >= 100)
healing = humanform.add_modifier(/datum/modifier/protean/steel, origin = refactory)
else if(healing && !(human_brute || human_burn))
healing.expire()
healing = null
else
if(healing)
healing.expire()
healing = null
/mob/living/simple_mob/protean_blob/lay_down()
var/obj/item/rig/rig = src.get_rig()
if(rig)
rig.force_rest(src)
return
..()
/mob/living/simple_mob/protean_blob/verb/prot_hide()
set name = "Hide Self"
set desc = "Disperses your mass into a thin veil, making a trap to snatch prey with, or simply hide."
set category = "Abilities.Protean"
if(!hiding)
cut_overlays()
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "hide"
sleep(7)
mouse_opacity = 0
plane = ABOVE_OBJ_PLANE
hiding = 1
else
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
mouse_opacity = 1
icon_state = "wake"
plane = initial(plane)
sleep(7)
update_icon()
hiding = 0
//Potential glob noms
if(can_be_drop_pred) //Toggleable in vore panel
var/list/potentials = living_mobs(0)
if(potentials.len)
var/mob/living/target = pick(potentials)
if(istype(target) && target.devourable && target.can_be_drop_prey && vore_selected)
if(target.buckled)
target.buckled.unbuckle_mob(target, force = TRUE)
target.forceMove(vore_selected)
to_chat(target,span_warning("\The [src] quickly engulfs you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!"))
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)
if(refactory && istype(A,/obj/item/stack/material))
var/obj/item/stack/material/S = A
var/substance = S.material.name
var allowed = FALSE
for(var/material in PROTEAN_EDIBLE_MATERIALS)
if(material == substance) allowed = TRUE
if(!allowed)
return
if(refactory.add_stored_material(S.material.name,1*S.perunit) && S.use(1))
visible_message(span_infoplain(span_bold("[name]") + " gloms over some of \the [S], absorbing it."))
else if(isitem(A) && a_intent == "grab") //CHOMP Add all this block, down to I.forceMove.
var/obj/item/I = A
if(!vore_selected)
to_chat(src,span_warning("You either don't have a belly selected, or don't have a belly!"))
return FALSE
if(is_type_in_list(I,item_vore_blacklist) || I.anchored)
to_chat(src, span_warning("You can't eat this."))
return
if(is_type_in_list(I,edible_trash) | adminbus_trash)
if(I.hidden_uplink)
to_chat(src, span_warning("You really should not be eating this."))
message_admins("[key_name(src)] has attempted to ingest an uplink item. ([src ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>" : "null"])")
return
visible_message(span_infoplain(span_bold("[name]") + " stretches itself over the [I], engulfing it whole!"))
I.forceMove(vore_selected)
else
return ..()
*/
/mob/living/simple_mob/protean_blob/attackby(var/obj/item/O, var/mob/user)
if(refactory && istype(O,/obj/item/stack/material))
var/obj/item/stack/material/S = O
var/substance = S.material.name
var allowed = FALSE
for(var/material in PROTEAN_EDIBLE_MATERIALS)
if(material == substance) allowed = TRUE
if(!allowed)
return
if(refactory.add_stored_material(S.material.name,1*S.perunit) && S.use(1))
visible_message(span_infoplain(span_bold("[name]") + " gloms over some of \the [S], absorbing it."))
else
return ..()
/mob/living/simple_mob/protean_blob/attack_hand(mob/living/L)
if(L.get_effective_size() >= (src.get_effective_size() + 0.5) )
src.get_scooped(L)
else
..()
/mob/living/simple_mob/protean_blob/MouseDrop(var/atom/over_object)
if(ishuman(over_object) && usr == src && src.Adjacent(over_object))
var/mob/living/carbon/human/H = over_object
get_scooped(H, TRUE)
else
return ..()
/mob/living/simple_mob/protean_blob/MouseEntered(location,control,params)
if(resting)
return
..()
/mob/living/simple_mob/protean_blob/character_directory_species()
if (humanform)
return "[humanform.custom_species ? humanform.custom_species : (humanform.species ? humanform.species.name : "Protean")]"
return "Protean"
// Helpers - Unsafe, WILL perform change.
/mob/living/carbon/human/proc/nano_intoblob(force)
if(!force && !isturf(loc) && !loc == /obj/item/rig/protean)
to_chat(src,span_warning("You can't change forms while inside something."))
return
to_chat(src, span_notice("You rapidly disassociate your form."))
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()
var/client/C = client
//Record where they should go
var/atom/creation_spot = drop_location()
//Create our new blob
var/mob/living/simple_mob/protean_blob/blob = new(creation_spot,src)
//Size update
blob.transform = matrix()*size_multiplier
blob.size_multiplier = size_multiplier
//dir update
blob.dir = dir
if(l_hand) drop_l_hand()
if(r_hand) drop_r_hand()
//Put our owner in it (don't transfer var/mind)
blob.ckey = ckey
blob.ooc_notes = ooc_notes
blob.ooc_notes_likes = ooc_notes_likes
blob.ooc_notes_dislikes = ooc_notes_dislikes
blob.ooc_notes_favs = ooc_notes_favs
blob.ooc_notes_maybes = ooc_notes_maybes
blob.ooc_notes_style = ooc_notes_style
temporary_form = blob
var/obj/item/radio/R = null
if(isradio(l_ear))
R = l_ear
if(isradio(r_ear))
R = r_ear
if(R)
blob.mob_radio = R
R.forceMove(blob)
if(wear_id)
blob.myid = wear_id.GetID()
//Mail them to nullspace
moveToNullspace()
//Message
blob.visible_message(span_infoplain(span_bold("[src.name]") + " collapses into a gooey blob!"))
//Duration of the to_puddle iconstate that the blob starts with
sleep(13)
blob.update_icon() //Will remove the collapse anim
//Transfer vore organs
blob.vore_organs = vore_organs.Copy()
blob.vore_selected = vore_selected
for(var/obj/belly/B as anything in vore_organs)
B.forceMove(blob)
B.owner = blob
vore_organs.Cut()
soulgem.owner = blob
//We can still speak our languages!
blob.languages = languages.Copy()
blob.name = real_name
blob.real_name = real_name
blob.voice_name = name
blob.update_icon(1)
//Flip them to the protean panel
addtimer(CALLBACK(src, PROC_REF(nano_set_panel), C), 4)
//Return our blob in case someone wants it
return blob
else
to_chat(src, span_warning("You must remain still to blobform!"))
//For some reason, there's no way to force drop all the mobs grabbed. This ought to fix that. And be moved elsewhere. Call with caution, doesn't handle cycles.
/proc/remove_micros(var/src, var/mob/root)
for(var/obj/item/I in src)
remove_micros(I, root) //Recursion. I'm honestly depending on there being no containment loop, but at the cost of performance that can be fixed too.
if(istype(I, /obj/item/holder))
root.remove_from_mob(I)
/mob/living/proc/usehardsuit()
set name = "Utilize Hardsuit Interface"
set desc = "Allows a protean blob to open hardsuit interface."
set category = "Abilities.Protean"
if(istype(loc, /obj/item/rig/protean))
var/obj/item/rig/protean/prig = loc
to_chat(src, "You attempt to interface with the [prig].")
prig.tgui_interact(src)
else
to_chat(src, "You are not in RIG form.")
/mob/living/carbon/human/proc/nano_outofblob(var/mob/living/simple_mob/protean_blob/blob, force)
if(!istype(blob))
return
if(blob.loc == /obj/item/rig/protean)
return
if(!force && !isturf(blob.loc))
to_chat(blob,span_warning("You can't change forms while inside something."))
return
to_chat(src, span_notice("You rapidly reassemble your form."))
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()
var/client/C = blob.client
//Stop healing if we are
if(blob.healing)
blob.healing.expire()
if(blob.mob_radio)
blob.mob_radio.forceMove(src)
blob.mob_radio = null
if(blob.myid)
blob.myid.forceMove(src)
blob.myid = null
//Play the animation
blob.icon_state = "from_puddle"
//Message
blob.visible_message(span_infoplain(span_bold("[src.name]") + " reshapes into a humanoid appearance!"))
//Size update
resize(blob.size_multiplier, FALSE, TRUE, ignore_prefs = TRUE)
//Duration of above animation
sleep(8)
//Record where they should go
var/atom/reform_spot = blob.drop_location()
//dir update
dir = blob.dir
//Move them back where the blob was
forceMove(reform_spot)
if(blob.l_hand) blob.drop_l_hand()
if(blob.r_hand) blob.drop_r_hand()
//Put our owner in it (don't transfer var/mind)
ckey = blob.ckey
ooc_notes = blob.ooc_notes // Lets give the protean any updated notes from blob form.
ooc_notes_likes = blob.ooc_notes_likes
ooc_notes_dislikes = blob.ooc_notes_dislikes
ooc_notes_favs = blob.ooc_notes_favs
ooc_notes_maybes = blob.ooc_notes_maybes
ooc_notes_style = blob.ooc_notes_style
temporary_form = null
//Transfer vore organs
vore_organs = blob.vore_organs.Copy()
vore_selected = blob.vore_selected
for(var/obj/belly/B as anything in blob.vore_organs)
B.forceMove(src)
B.owner = src
languages = blob.languages.Copy()
soulgem.owner = src
Life(1) //Fix my blindness right meow //Has to be moved up here, there exists a circumstance where blob could be deleted without vore organs moving right.
//Get rid of friend blob
qdel(blob)
//Flip them to the protean panel
addtimer(CALLBACK(src, PROC_REF(nano_set_panel), C), 4)
//Return ourselves in case someone wants it
return src
else
to_chat(src, span_warning("You must remain still to reshape yourself!"))
/mob/living/carbon/human/proc/nano_set_panel(var/client/C)
if(C)
C.statpanel = "Protean"
/mob/living/simple_mob/protean_blob/ClickOn(var/atom/A, var/params)
if(istype(loc, /obj/item/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/rig/protean))
var/obj/item/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()
/mob/living/simple_mob/protean_blob/update_icon()
..()
if(humanform)
vis_height = 32
cut_overlays()
var/list/wide_icons = list(
"lizard",
"rat",
"wolf"
)
var/list/tall_icons = list(
"drake",
"teppi",
"panther"
)
var/list/big_icons = list(
"robodrgn"
)
var/datum/species/protean/S = humanform.species
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
default_pixel_x = 0
pixel_x = 0
vore_capacity = 1
if(S.blob_appearance == "dragon")
vore_capacity = 2
icon = 'icons/mob/vore128x64.dmi'
mount_offset_y = 32
mount_offset_x = -16
var/image/I = image(icon, "[S.dragon_overlays[1]][resting? "-rest" : (vore_fullness? "-[vore_fullness]" : null)]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[1]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[2]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[2]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[3]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[3]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[4]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[4]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[5]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[5]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
I = image(icon, "[S.dragon_overlays[6]][resting? "-rest" : null]", pixel_x = -48)
I.color = S.dragon_overlays[S.dragon_overlays[6]]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = PLANE_LIGHTING_ABOVE
add_overlay(I)
qdel(I)
//You know technically I could just put all the icons into the 128x64.dmi file and off-set them to fit..
if(S.blob_appearance in wide_icons)
icon = 'modular_chomp/icons/mob/species/protean/protean64x32.dmi'
default_pixel_x = -16
pixel_x = -16
if(S.blob_appearance in tall_icons)
icon = 'modular_chomp/icons/mob/species/protean/protean64x64.dmi'
default_pixel_x = -16
pixel_x = -16
vis_height = 64
if(S.blob_appearance in big_icons)
icon = 'modular_chomp/icons/mob/species/protean/protean128x64.dmi'
default_pixel_x = -48
pixel_x = -48
vis_height = 64
var/image/I = image(icon, S.blob_appearance+"[resting? "_rest":null][vore_fullness? "-[vore_fullness]" : null]")
I.color = S.blob_color_1
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
I.plane = MOB_PLANE
I.layer = MOB_LAYER
add_overlay(I)
qdel(I)
eye_layer = image(icon, "[S.blob_appearance][resting? "_rest" : null]-eyes")
eye_layer.appearance_flags = appearance_flags
eye_layer.color = S.blob_color_2
eye_layer.plane = PLANE_LIGHTING_ABOVE
add_overlay(eye_layer)
qdel(eye_layer)

View File

@@ -1,232 +0,0 @@
// // // External Organs
/obj/item/organ/external/chest/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 70 // <-- This is different from the rest
min_broken_damage = 1000
vital = 1
model = "protean"
/obj/item/organ/external/groin/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 70
min_broken_damage = 1000 //Multiple
vital = 0
model = "protean"
/obj/item/organ/external/head/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 70
min_broken_damage = 1000 //Inheritance
vital = 0
model = "protean"
/obj/item/organ/external/arm/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000 //Please
vital = 0
model = "protean"
/obj/item/organ/external/arm/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000
vital = 0
model = "protean"
/obj/item/organ/external/leg/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000
vital = 0
model = "protean"
/obj/item/organ/external/leg/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000
vital = 0
model = "protean"
/obj/item/organ/external/hand/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000
vital = 0
model = "protean"
/obj/item/organ/external/hand/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000
vital = 0
model = "protean"
/obj/item/organ/external/foot/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000
vital = 0
model = "protean"
/obj/item/organ/external/foot/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 40
min_broken_damage = 1000
vital = 0
model = "protean"
/obj/item/organ/external/head/unbreakable/nano/disfigure()
return //No way to repair disfigured prots
// // // Internal Organs
/obj/item/organ/internal/nano
robotic = ORGAN_ROBOT
/obj/item/organ/internal/nano/orchestrator
name = "orchestrator module"
desc = "A small computer, designed for highly parallel workloads."
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "orchestrator"
organ_tag = O_ORCH
parent_organ = BP_TORSO
vital = TRUE
organ_verbs = list(
/mob/living/carbon/human/proc/self_diagnostics
)
/obj/item/organ/internal/nano/orchestrator/robotize()
. = ..()
icon_state = "orchestrator"
/obj/item/organ/internal/nano/orchestrator/mechassist()
. = ..()
icon_state = "orchestrator"
/obj/item/organ/internal/nano/refactory
name = "refactory module"
desc = "A miniature metal processing unit and nanite factory."
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "refactory"
organ_tag = O_FACT
parent_organ = BP_TORSO
var/list/materials = list(MAT_STEEL = 0)
var/max_storage = 10000
organ_verbs = list(
/mob/living/carbon/human/proc/reagent_purge
)
/obj/item/organ/internal/nano/refactory/robotize()
. = ..()
icon_state = "refactory"
/obj/item/organ/internal/nano/refactory/mechassist()
. = ..()
icon_state = "refactory"
/obj/item/organ/internal/nano/refactory/proc/get_stored_material(var/material)
if(status & ORGAN_DEAD)
return 0
return materials[material] || 0
/obj/item/organ/internal/nano/refactory/proc/add_stored_material(var/material,var/amt)
if(status & ORGAN_DEAD)
return 0
var/increase = min(amt,max(max_storage-materials[material],0))
if(isnum(materials[material]))
materials[material] += increase
else
materials[material] = increase
return increase
/obj/item/organ/internal/nano/refactory/proc/use_stored_material(var/material,var/amt)
if(status & ORGAN_DEAD)
return 0
var/available = materials[material]
//Success
if(available >= amt)
var/new_amt = available-amt
if(new_amt == 0)
materials -= material
else
materials[material] = new_amt
return amt
//Failure
return 0
/obj/item/organ/internal/mmi_holder/posibrain/nano
name = "protean posibrain"
desc = "A more advanced version of the standard posibrain, typically found in protean bodies."
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "posi"
parent_organ = BP_TORSO
brain_type = /obj/item/mmi/digital/posibrain/nano
/obj/item/organ/internal/mmi_holder/posibrain/nano/robotize()
. = ..()
icon_state = "posi1"
/obj/item/organ/internal/mmi_holder/posibrain/nano/mechassist()
. = ..()
icon_state = "posi1"
/obj/item/organ/internal/mmi_holder/posibrain/nano/update_from_mmi()
. = ..()
icon = initial(icon)
icon_state = "posi1"
stored_mmi.icon_state = "posi1"
stored_mmi.brainmob.languages = owner.languages
/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
/obj/item/mmi/digital/posibrain/nano
name = "protean posibrain"
desc = "A more advanced version of the standard posibrain, typically found in protean bodies."
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "posi"
/obj/item/mmi/digital/posibrain/nano/Initialize()
. = ..()
icon_state = "posi"
/obj/item/mmi/digital/posibrain/nano/request_player()
icon_state = initial(icon_state)
return //We don't do this stuff
/obj/item/mmi/digital/posibrain/nano/reset_search()
icon_state = initial(icon_state)
return //Don't do this either because of the above
/obj/item/mmi/digital/posibrain/nano/transfer_personality()
. = ..()
icon_state = "posi1"
/obj/item/mmi/digital/posibrain/nano/transfer_identity()
. = ..()
icon_state = "posi1"
/obj/item/organ/internal/nano/digest_act(atom/movable/item_storage = null)
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/protean_reboot
sort_string = "JVAAZ"
/obj/item/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

@@ -1,748 +0,0 @@
//TODO: Replace ventcrawl with morphing. /mob/living/simple_mob/vore/hostile/morph
#define PER_LIMB_STEEL_COST SHEET_MATERIAL_AMOUNT
////
// One-part Refactor
////
/mob/living/carbon/human/proc/nano_partswap()
set name = "Ref - Single Limb"
set desc = "Allows you to replace and reshape your limbs as you see fit."
//set category = "Abilities.Protean"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
if(nano_dead_check(caller))
to_chat(caller, span_warning("You need to be repaired first before you can act!"))
return
if(stat)
to_chat(caller,span_warning("You must be awake and standing to perform this action!"))
return
if(!isturf(caller.loc))
to_chat(caller,span_warning("You need more space to perform this action!"))
return
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this
if(!istype(refactory))
to_chat(caller,span_warning("You don't have a working refactory module!"))
return
var/choice = tgui_input_list(caller,"Pick the bodypart to change:", "Refactor - One Bodypart", species.has_limbs)
if(!choice)
return
//Organ is missing, needs restoring
if(!organs_by_name[choice] || istype(organs_by_name[choice], /obj/item/organ/external/stump)) //allows limb stumps to regenerate like removed limbs.
if(refactory.get_stored_material(MAT_STEEL) < PER_LIMB_STEEL_COST)
to_chat(caller,span_warning("You're missing that limb, and need to store at least [PER_LIMB_STEEL_COST] steel to regenerate it."))
return
var/regen = tgui_alert(caller,"That limb is missing, do you want to regenerate it in exchange for [PER_LIMB_STEEL_COST] steel?","Regenerate limb?",list("Yes","No"))
if(regen != "Yes")
return
if(!refactory.use_stored_material(MAT_STEEL,PER_LIMB_STEEL_COST))
return
if(organs_by_name[choice])
var/obj/item/organ/external/oldlimb = organs_by_name[choice]
oldlimb.removed()
qdel(oldlimb)
var/mob/living/simple_mob/protean_blob/blob
if(!temporary_form)
blob = nano_intoblob()
else
blob = temporary_form
active_regen = 1
if(do_after(blob,50,exclusive = TASK_ALL_EXCLUSIVE))
var/list/limblist = species.has_limbs[choice]
var/limbpath = limblist["path"]
var/obj/item/organ/external/new_eo = new limbpath(src)
organs_by_name[choice] = new_eo
new_eo.robotize(synthetic ? synthetic.company : null) //Use the base we started with
new_eo.sync_colour_to_human(src)
regenerate_icons()
active_regen = 0
return
//Organ exists, let's reshape it
var/list/usable_manufacturers = list()
for(var/company in chargen_robolimbs)
var/datum/robolimb/M = chargen_robolimbs[company]
if(!(choice in M.parts))
continue
if(species?.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(caller, "Which manufacturer do you wish to mimic for this limb?", "Manufacturer for [choice]", usable_manufacturers)
if(!manu_choice)
return //Changed mind
var/obj/item/organ/external/eo = organs_by_name[choice]
if(!eo)
return //Lost it meanwhile
eo.robotize(manu_choice)
update_icons_body()
/mob/living/carbon/human/proc/nano_regenerate()
set name = "Total Reassembly"
set desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded."
//set category = "Abilities.Protean"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
var/input = tgui_alert(caller,{"Do you want to rebuild or reassemble yourself?
Rebuilding will cost 10,000 steel and will rebuild all of your limbs as well as repair all damage over a 40s period.
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)
return
if(input == "Rebuild")
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
if(refactory.get_stored_material(MAT_STEEL) >= 10000)
to_chat(caller, span_notify("You begin to rebuild. You will need to remain still."))
if(do_after(caller, 400,exclusive = TASK_ALL_EXCLUSIVE))
if(species?:OurRig) //Unsafe, but we should only ever be using this with a Protean
species?:OurRig?:make_alive(src,1) //Re-using this proc
refactory.use_stored_material(MAT_STEEL,refactory.get_stored_material(MAT_STEEL)) //Use all of our steel
else
to_chat(caller, span_userdanger("Somehow, you are missing your protean rig. You are unable to rebuild without one."))
else
to_chat(caller, span_warning("You do not have enough steel stored for this operation."))
else
input = tgui_alert(caller,{"Include Flavourtext?"},"Reassembly",list("Yes","No","Cancel"))
if(input == "Cancel" || !input)
return
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_notify("You begin to reassemble. You will need to remain still."))
caller.visible_message(span_notify("[caller] rapidly contorts and shifts!"), span_danger("You begin to reassemble."))
if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE))
if(caller.client.prefs) //Make sure we didn't d/c
var/obj/item/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_notify("[caller] adopts a new form!"), span_danger("You have reassembled."))
/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.Protean"
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/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_warning("You need a better grip to do that!"))
else
to_chat(caller, span_notice("You need to be aggressively grabbing someone before you can copy their form."))
return
if (!istype(victim))
to_chat(caller, span_warning("You can only perform this on human mobs!"))
return
if (!victim.client)
to_chat(caller, span_notice("The person you try this on must have a client!"))
return
to_chat(caller, span_notice("Waiting for other person's consent."))
var/consent = tgui_alert(victim, "Allow [src] to copy what you look like?", "Consent", list("Yes", "No"))
if (consent != "Yes")
to_chat(caller, span_notice("They declined your request."))
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/grab/G in caller)
if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE)
checking = TRUE
if (!checking)
to_chat(caller, span_warning("You lost your grip on [victim]!"))
return
to_chat(caller, span_notify("You begin to reassemble into [victim]. You will need to remain still."))
caller.visible_message(span_notify("[caller] rapidly contorts and shifts!"), span_danger("You begin to reassemble into [victim]."))
if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE))
checking = FALSE
for(var/obj/item/grab/G in caller)
if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE)
checking = TRUE
if (!checking)
to_chat(caller, span_warning("You lost your grip on [victim]!"))
return
if(caller.client) //Make sure we didn't d/c
var/obj/item/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_notify("[caller] adopts the form of [victim]!"), span_danger("You have reassembled into [victim]."))
////
// Storing metal
////
/mob/living/carbon/human/proc/nano_metalnom()
set name = "Ref - Store Metals"
set desc = "If you're holding a stack of material, you can consume some and store it for later."
//set category = "Abilities.Protean"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
if(nano_dead_check(caller))
to_chat(caller, span_warning("You need to be repaired first before you can act!"))
return
var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory()
//Missing the organ that does this
if(!istype(refactory))
to_chat(caller,span_warning("You don't have a working refactory module!"))
return
var/held = caller.get_active_hand()
if(!istype(held,/obj/item/stack/material))
to_chat(caller,span_warning("You aren't holding a stack of materials in your active hand!"))
return
var/obj/item/stack/material/matstack = held
var/substance = matstack.material.name
var allowed = 0
for(var/material in PROTEAN_EDIBLE_MATERIALS)
if(material == substance) allowed = 1
if(!allowed)
to_chat(caller,span_warning("You can't process [substance]!"))
return
var/howmuch = tgui_input_number(caller,"How much do you want to store? (0-[matstack.get_amount()])","Select amount",null,matstack.get_amount())
if(!howmuch || matstack != caller.get_active_hand() || howmuch > matstack.get_amount())
return //Quietly fail
var/actually_added = refactory.add_stored_material(substance,howmuch*matstack.perunit)
matstack.use(CEILING((actually_added/matstack.perunit), 1))
if(actually_added && actually_added < howmuch)
to_chat(caller,span_warning("Your refactory module is now full, so only [actually_added] units were stored."))
visible_message(span_notice("[caller] nibbles some of the [substance] right off the stack!"))
else if(actually_added)
to_chat(caller,span_notice("You store [actually_added] units of [substance]."))
visible_message(span_notice("[caller] devours some of the [substance] right off the stack!"))
else
to_chat(caller,span_notice("You're completely capped out on [substance]!"))
////
// Blob Form
////
/mob/living/carbon/human/proc/nano_blobform(var/forced)
set name = "Toggle Blobform"
set desc = "Switch between amorphous and humanoid forms."
//set category = "Abilities.Protean"
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
if(!isturf(to_locate.loc) && !forced)
to_chat(to_locate,span_warning("You need more space to perform this action!"))
return
//Blob form
if(temporary_form)
if(temporary_form.stat)
to_chat(temporary_form,span_warning("You can only do this while not stunned."))
else
nano_outofblob(temporary_form)
//Human form
else if(stat)
to_chat(src,span_warning("You can only do this while not stunned."))
return
else if(handcuffed)
to_chat(src, span_warning("You can't do this while handcuffed!"))
return
else
nano_intoblob()
////
// Change fitting
////
/mob/living/carbon/human/proc/nano_change_fitting()
set name = "Change Species Fit"
set desc = "Tweak your shape to change what suits you fit into (and their sprites!)."
set category = "Abilities.Protean"
if(stat)
to_chat(src,span_warning("You must be awake and standing to perform this action!"))
return
var/new_species = tgui_input_list(usr, "Please select a species to emulate.", "Shapeshifter Body", list(species?.vanity_base_fit)|species?.get_valid_shapeshifter_forms())
if(new_species)
species?.base_species = new_species // Really though you better have a species
regenerate_icons() //Expensive, but we need to recrunch all the icons we're wearing
////
// Rig Transform
////
/mob/living/carbon/human/proc/nano_rig_transform(var/forced)
set name = "Modify Form - Hardsuit"
set desc = "Allows a protean to retract its mass into its hardsuit module at will."
//set category = "Abilities.Protean"
set hidden = 1
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
if(nano_dead_check(src))
to_chat(caller, span_warning("You need to be repaired first before you can act!"))
return
to_chat(caller, span_notice("You rapidly condense into your module."))
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)
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(ismob(S.OurRig.loc))
var/mob/m = S.OurRig.loc
m.drop_from_inventory(S.OurRig)
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
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 = src
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 || P.resting && !forced)
to_chat(P,span_warning("You can only do this while not stunned."))
else
if(P.l_hand)
P.drop_l_hand()
if(P.r_hand)
P.drop_r_hand()
P.has_hands = 0
S.OurRig.myprotean = P
src.drop_from_inventory(S.OurRig)
P.forceMove(S.OurRig)
S.OurRig.canremove = 1
P.reset_view()
else //Make one if not
to_chat(temporary_form, span_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."))
new /obj/item/rig/protean(src,src)
else
to_chat(caller, span_warning("You must remain still to condense!"))
/mob/living/carbon/human/proc/appearance_switch()
set name = "Switch Blob Appearance"
set desc = "Allows a protean blob to switch its outwards appearance."
//set category = "Abilities.Protean"
set hidden = 1
var/datum/species/protean/S = src.species
var/mob/living/caller = src
if(temporary_form)
caller = temporary_form
var/list/icon_choices = list(
"Primary" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "primary"),
"Highlight" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "highlight"),
"puddle1" = image(icon = 'modular_chomp/icons/mob/species/protean/protean_powers.dmi', icon_state = "blob"),
"puddle0" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "puddle"),
"catslug" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "catslug"),
"cat" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "cat"),
"mouse" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "mouse"),
"rabbit" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "rabbit"),
"bear" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "bear"),
"fen" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "fen"),
"fox" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "fox"),
"raptor" = image(icon = 'modular_chomp/icons/mob/species/protean/protean.dmi', icon_state = "raptor"),
"rat" = image(icon = 'modular_chomp/icons/mob/species/protean/protean64x32.dmi', icon_state = "rat", pixel_x = -16),
"lizard" = image(icon = 'modular_chomp/icons/mob/species/protean/protean64x32.dmi', icon_state = "lizard", pixel_x = -16),
"wolf" = image(icon = 'modular_chomp/icons/mob/species/protean/protean64x32.dmi', icon_state = "wolf", pixel_x = -16),
//"drake" = image(icon = 'modular_chomp/icons/mob/species/protean/protean64x64.dmi', icon_state = "drake", pixel_x = -16),
"teppi" = image(icon = 'modular_chomp/icons/mob/species/protean/protean64x64.dmi', icon_state = "teppi", pixel_x = -16),
"panther" = image(icon = 'modular_chomp/icons/mob/species/protean/protean64x64.dmi', icon_state = "panther", pixel_x = -16),
"robodrgn" = image(icon = 'modular_chomp/icons/mob/species/protean/protean128x64.dmi', icon_state = "robodrgn", pixel_x = -48),
"Dragon" = image(icon = 'icons/mob/bigdragon_small.dmi', icon_state = "dragon_small")
)
var/blobstyle = show_radial_menu(caller, caller, icon_choices, require_near = TRUE, tooltips = FALSE)
if(!blobstyle || QDELETED(caller) || caller.incapacitated())
return FALSE
switch(blobstyle)
if("Dragon") //Fuck it, we ball
var/list/options = list("Underbelly","Body","Ears","Mane","Horns","Eyes")
for(var/option in options)
LAZYSET(options, option, image('icons/effects/bigdragon_labels.dmi', option))
var/choice = show_radial_menu(caller, caller, options, radius = 60)
if(!choice || QDELETED(caller) || caller.incapacitated())
return FALSE
. = TRUE
var/list/underbelly_styles = list(
"dragon_underSmooth",
"dragon_underPlated"
)
var/list/body_styles = list(
"dragon_bodySmooth",
"dragon_bodyScaled"
)
var/list/ear_styles = list(
"dragon_earsNormal"
)
var/list/mane_styles = list(
"dragon_maneNone",
"dragon_maneShaggy",
"dragon_maneDorsalfin"
)
var/list/horn_styles = list(
"dragon_hornsPointy",
"dragon_hornsCurved",
"dragon_hornsCurved2",
"dragon_hornsJagged",
"dragon_hornsCrown",
"dragon_hornsSkull"
)
var/list/eye_styles = list(
"dragon_eyesNormal"
)
switch(choice)
if("Underbelly")
options = underbelly_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -48)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick underbelly color:","Underbelly Color", S.dragon_overlays[1]) as null|color
if(!new_color)
return 0
S.dragon_overlays[1] = choice
S.dragon_overlays[S.dragon_overlays[1]] = new_color
if("Body")
options = body_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -48)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick body color:","Body Color", S.dragon_overlays[2]) as null|color
if(!new_color)
return 0
S.dragon_overlays[2] = choice
S.dragon_overlays[S.dragon_overlays[2]] = new_color
if("Ears")
options = ear_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -76, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick ear color:","Ear Color", S.dragon_overlays[3]) as null|color
if(!new_color)
return 0
S.dragon_overlays[3] = choice
S.dragon_overlays[S.dragon_overlays[3]] = new_color
if("Mane")
options = mane_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -76, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick mane color:","Mane Color", S.dragon_overlays[4]) as null|color
if(!new_color)
return 0
S.dragon_overlays[4] = choice
S.dragon_overlays[S.dragon_overlays[4]] = new_color
if("Horns")
options = horn_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 4, pixel_x = -86, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick horn color:","Horn Color", S.dragon_overlays[5]) as null|color
if(!new_color)
return 0
S.dragon_overlays[5] = choice
S.dragon_overlays[S.dragon_overlays[5]] = new_color
if("Eyes")
options = eye_styles
for(var/option in options)
var/image/I = image('icons/mob/vore128x64.dmi', option, dir = 2, pixel_x = -48, pixel_y = -50)
LAZYSET(options, option, I)
choice = show_radial_menu(caller, caller, options, radius = 90)
if(!choice || QDELETED(caller) || caller.incapacitated())
return 0
var/new_color = input("Pick eye color:","Eye Color", S.dragon_overlays[6]) as null|color
if(!new_color)
return 0
S.dragon_overlays[6] = choice
S.dragon_overlays[S.dragon_overlays[6]] = new_color
S.blob_appearance = "dragon"
if("Primary")
var/new_color = input("Pick primary color:","Protean Primary", "#FF0000") as null|color
if(!new_color)
return
S.blob_color_1 = new_color
if("Highlight")
var/new_color = input("Pick highlight color:","Protean Highlight", "#FF0000") as null|color
if(!new_color)
return
S.blob_color_2 = new_color
else
S.blob_appearance = blobstyle
if(temporary_form)
if(blobstyle)
temporary_form.update_icon()
if(istype(temporary_form.loc, /obj/item/holder/protoblob))
var/obj/item/holder/protoblob/PB = temporary_form.loc
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.Protean"
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_notice("You detach from your host."))
else
to_chat(caller, span_warning("You aren't being worn, dummy."))
return
var/obj/held_item = caller.get_active_hand()
if(istype(held_item,/obj/item/grab))
var/obj/item/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_danger("You can't latch onto a fellow Protean!"))
return
if(G.loc == caller && G.state >= GRAB_AGGRESSIVE)
caller.visible_message(span_warning("[caller] is attempting to latch onto [target]!"), span_danger("You attempt to latch onto [target]!"))
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_danger("[caller] latched onto [target]!"), span_danger("You latch yourself onto [target]!"))
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_warning("You need a more aggressive grab to do this!"))
else
to_chat(caller, span_warning("You can only latch onto humanoid mobs!"))
else
to_chat(caller, span_warning("You need to be grabbing a humanoid mob aggressively to latch onto them."))
/// /// /// A helper to reuse
/mob/living/proc/nano_get_refactory(obj/item/organ/internal/nano/refactory/R)
if(istype(R))
if(!(R.status & ORGAN_DEAD))
return R
return
/mob/living/simple_mob/protean_blob/nano_get_refactory()
if(refactory)
return ..(refactory)
if(humanform)
return humanform.nano_get_refactory()
/mob/living/carbon/human/nano_get_refactory()
return ..(locate(/obj/item/organ/internal/nano/refactory) in internal_organs)
//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
/obj/effect/protean_ability
name = "Activate"
desc = ""
icon = 'modular_chomp/icons/mob/species/protean/protean_powers.dmi'
var/ability_name
var/to_call
/obj/effect/protean_ability/proc/atom_button_text()
return src
/obj/effect/protean_ability/Click(var/location, var/control, var/params)
var/list/clickprops = params2list(params)
var/opts = clickprops["shift"]
if(opts)
to_chat(usr,span_notice(span_bold("[ability_name]") + " - [desc]"))
else
//Humanform using it
if(ishuman(usr))
do_ability(usr)
//Blobform using it
else
var/mob/living/simple_mob/protean_blob/blob = usr
do_ability(blob.humanform)
/obj/effect/protean_ability/proc/do_ability(var/mob/living/L)
if(istype(L))
call(L,to_call)()
return 0
/// The actual abilities
/obj/effect/protean_ability/into_blob
ability_name = "Toggle Blobform"
desc = "Discard your shape entirely, changing to a low-energy blob. You'll consume steel to repair yourself in this form."
icon_state = "blob"
to_call = /mob/living/carbon/human/proc/nano_blobform
/obj/effect/protean_ability/change_volume
ability_name = "Change Volume"
desc = "Alter your size between 25% and 200%."
icon_state = "volume"
to_call = /mob/living/proc/set_size
/obj/effect/protean_ability/reform_limb
ability_name = "Ref - Single Limb"
desc = "Rebuild or replace a single limb, assuming you have 2000 steel."
icon_state = "limb"
to_call = /mob/living/carbon/human/proc/nano_partswap
/obj/effect/protean_ability/reform_body
ability_name = "Total Reassembly"
desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded."
icon_state = "body"
to_call = /mob/living/carbon/human/proc/nano_regenerate
/obj/effect/protean_ability/metal_nom
ability_name = "Ref - Store Metals"
desc = "Store the metal you're holding. Your refactory can only store steel."
icon_state = "metal"
to_call = /mob/living/carbon/human/proc/nano_metalnom
/obj/effect/protean_ability/hardsuit
ability_name = "Hardsuit Transform"
desc = "Coalesce your nanite swarm into their control module, allowing others to wear you."
icon_state = "rig"
to_call = /mob/living/carbon/human/proc/nano_rig_transform
/obj/effect/protean_ability/appearance_switch
ability_name = "Blob Appearance"
desc = "Toggle your blob appearance. Also affects your worn appearance."
icon_state = "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
/mob/living/carbon/human/proc/chest_transparency_toggle()
set name = "transparency toggle (chest only)"
set category = "Abilities.Protean"
if(stat || world.time < last_special)
return
last_special = world.time + 50
for(var/obj/item/organ/external/proteanlimbs as anything in src.organs)
if(proteanlimbs.organ_tag == BP_HEAD)
continue
proteanlimbs.transparent = !proteanlimbs.transparent
visible_message(span_notice("\The [src]'s internal composition seems to change."))
update_icons_body()
update_hair()
/obj/effect/protean_ability/chest_transparency
ability_name = "body transparency toggle (All but head)"
desc = "Makes everything but your head transparent!"
icon = 'modular_chomp/icons/obj/slimeborg/slimecore.dmi'
icon_state = "core"
to_call = /mob/living/carbon/human/proc/chest_transparency_toggle
/mob/living/carbon/human/proc/transparency_toggle()
set name = "Toggle Transparency"
set category = "Abilities.Protean"
if(stat || world.time < last_special)
return
last_special = world.time + 50
for(var/obj/item/organ/external/proteanlimbs as anything in src.organs)
proteanlimbs.transparent = !proteanlimbs.transparent
visible_message(span_notice("\The [src]'s internal composition seems to change."))
update_icons_body()
update_hair()
/obj/effect/protean_ability/transparency_for_entire_body
ability_name = "Toggle Transparency"
desc = "transparency toggle for your entire body"
icon = 'modular_chomp/icons/obj/slimeborg/slimecore.dmi'
icon_state = "core"
to_call = /mob/living/carbon/human/proc/transparency_toggle

View File

@@ -1,444 +0,0 @@
#define METAL_PER_TICK SHEET_MATERIAL_AMOUNT/20
/datum/species/protean
name = SPECIES_PROTEAN
name_plural = "Proteans"
blurb = "Sometimes very advanced civilizations will produce the ability to swap into manufactured, robotic bodies. And sometimes \
" + span_italics("VERY") + " advanced civilizations have the option of 'nanoswarm' bodies. Effectively a single robot body comprised \
of millions of tiny nanites working in concert to maintain cohesion."
show_ssd = "totally quiescent"
death_message = "rapidly loses cohesion, retreating into their hardened control module..."
knockout_message = "collapses inwards, forming a disordered puddle of gray goo."
remains_type = /obj/effect/decal/cleanable/ash
selects_bodytype = SELECTS_BODYTYPE_SHAPESHIFTER
base_species = SPECIES_HUMAN
digi_allowed = TRUE
blood_color = "#505050" //This is the same as the 80,80,80 below, but in hex
flesh_color = "#505050"
base_color = "#FFFFFF" //Color mult, start out with this
flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT | NO_HALLUCINATION | NO_INFECT | NO_PAIN
appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | HAS_UNDERWEAR | HAS_LIPS
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE
health_hud_intensity = 2
num_alternate_languages = 3
species_language = LANGUAGE_EAL
assisted_langs = list(LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
speech_bubble_appearance = "synthetic"
color_mult = TRUE
breath_type = null
poison_type = null
// male_scream_sound = null
// female_scream_sound = null
virus_immune = 1
blood_volume = 0
min_age = 18
max_age = 200
oxy_mod = 0
//radiation_mod = 0 //Can't be assed with fandangling rad protections while blob formed/suited
darksight = 10
siemens_coefficient = 2
brute_mod = 0.8
burn_mod = 1.5
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
cold_level_1 = -INFINITY
cold_level_2 = -INFINITY
cold_level_3 = -INFINITY
heat_level_1 = 420
heat_level_2 = 480
heat_level_3 = 1100
body_temperature = 290
rarity_value = 5
species_sounds = "Robotic"
crit_mod = 4 //Unable to go crit
var/obj/item/rig/protean/OurRig
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list(
O_BRAIN = /obj/item/organ/internal/mmi_holder/posibrain/nano,
O_ORCH = /obj/item/organ/internal/nano/orchestrator,
O_FACT = /obj/item/organ/internal/nano/refactory,
)
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable/nano),
BP_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable/nano),
BP_HEAD = list("path" = /obj/item/organ/external/head/unbreakable/nano),
BP_L_ARM = list("path" = /obj/item/organ/external/arm/unbreakable/nano),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/unbreakable/nano),
BP_L_LEG = list("path" = /obj/item/organ/external/leg/unbreakable/nano),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/unbreakable/nano),
BP_L_HAND = list("path" = /obj/item/organ/external/hand/unbreakable/nano),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/unbreakable/nano),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot/unbreakable/nano),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable/nano)
)
heat_discomfort_strings = list("WARNING: Temperature exceeding acceptable thresholds!.")
cold_discomfort_strings = list("You feel too cool.")
//These verbs are hidden, for hotkey use only
inherent_verbs = list(
/mob/living/carbon/human/proc/nano_regenerate, //These verbs are hidden so you can macro them,
/mob/living/carbon/human/proc/nano_partswap,
/mob/living/carbon/human/proc/nano_metalnom,
/mob/living/carbon/human/proc/nano_blobform,
/mob/living/carbon/human/proc/nano_rig_transform,
/mob/living/carbon/human/proc/nano_copy_body,
/mob/living/carbon/human/proc/appearance_switch,
/mob/living/carbon/human/proc/nano_latch,
/mob/living/proc/set_size,
/mob/living/carbon/human/proc/nano_change_fitting, //These verbs are displayed normally,
/mob/living/carbon/human/proc/shapeshifter_select_hair,
/mob/living/carbon/human/proc/shapeshifter_select_hair_colors,
/mob/living/carbon/human/proc/shapeshifter_select_colour,
/mob/living/carbon/human/proc/shapeshifter_select_eye_colour,
/mob/living/carbon/human/proc/shapeshifter_select_gender,
/mob/living/carbon/human/proc/shapeshifter_select_wings,
/mob/living/carbon/human/proc/shapeshifter_select_tail,
/mob/living/carbon/human/proc/shapeshifter_select_ears,
/mob/living/proc/flying_toggle,
/mob/living/proc/flying_vore_toggle,
/mob/living/proc/start_wings_hovering,
) //removed fetish verbs, since non-customs can pick neutral traits now. Also added flight, cause shapeshifter can grow wings.
var/global/list/abilities = list()
var/monochromatic = FALSE //IGNORE ME
var/blob_appearance = "puddle1"
var/blob_color_1 = "#363636"
var/blob_color_2 = "#ba3636"
var/list/dragon_overlays = list(
"dragon_underSmooth" = "#FFFFFF",
"dragon_bodySmooth" = "#FFFFFF",
"dragon_earsNormal" = "#FFFFFF",
"dragon_maneShaggy" = "#FFFFFF",
"dragon_hornsPointy" = "#FFFFFF",
"dragon_eyesNormal" = "#FFFFFF"
)
var/pseudodead = 0
/datum/species/protean/New()
..()
if(!LAZYLEN(abilities))
var/list/powertypes = subtypesof(/obj/effect/protean_ability)
for(var/path in powertypes)
abilities += new path()
/datum/species/protean/create_organs(var/mob/living/carbon/human/H)
var/obj/item/nif/saved_nif = H.nif
if(saved_nif)
H.nif.unimplant(H) //Needs reference to owner to unimplant right.
H.nif.moveToNullspace()
..()
if(saved_nif)
saved_nif.quick_implant(H)
/datum/species/protean/get_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)
if(!H || base_species == name) return ..()
var/datum/species/S = GLOB.all_species[base_species]
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)
var/static/list/protean_shapeshifting_forms = GLOB.playable_species.Copy() - SPECIES_PROMETHEAN
return protean_shapeshifting_forms
/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)
..()
H.synth_color = TRUE
/datum/species/protean/equip_survival_gear(var/mob/living/carbon/human/H)
..()
var/obj/item/stack/material/steel/metal_stack = new()
metal_stack.set_amount(5)
var/obj/item/clothing/accessory/permit/nanotech/permit = new()
permit.set_name(H.real_name)
if(H.backbag == 1) //Somewhat misleading, 1 == no bag (not boolean)
H.equip_to_slot_or_del(permit, slot_l_hand)
H.equip_to_slot_or_del(metal_stack, slot_r_hand)
else
H.equip_to_slot_or_del(permit, slot_in_backpack)
H.equip_to_slot_or_del(metal_stack, slot_in_backpack)
spawn(0) //Let their real nif load if they have one
if(!H) //Human could have been deleted in this amount of time. Observing does this, mannequins, etc.
return
if(!H.nif)
var/obj/item/nif/protean/new_nif = new()
new_nif.quick_implant(H)
else
H.nif.durability = 25
new /obj/item/rig/protean(H,H)
/datum/species/protean/hug(var/mob/living/carbon/human/H, var/mob/living/target)
return ..() //Wut
/datum/species/protean/get_blood_colour(var/mob/living/carbon/human/H)
return rgb(80,80,80,230)
/datum/species/protean/get_flesh_colour(var/mob/living/carbon/human/H)
return rgb(80,80,80,230)
/datum/species/protean/handle_death(var/mob/living/carbon/human/H)
if(!H)
return //No body?
if(OurRig.dead)
return
OurRig.dead = 1
var/mob/temp = H
if(H.temporary_form)
temp = H.temporary_form
playsound(temp, 'modular_chomp/sound/voice/borg_deathsound.ogg', 50, 1)
temp.visible_message(span_bold("[temp.name]") + " shudders and retreats inwards, coalescing into a single core componant!")
to_chat(temp, span_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."))
if(H.temporary_form)
if(!istype(H.temporary_form.loc, /obj/item/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)
if((H.getActualBruteLoss() + H.getActualFireLoss()) > H.maxHealth*0.5 && isturf(H.loc)) //So, only if we're not a blob (we're in nullspace) or in someone (or a locker, really, but whatever)
return ..() //Any instakill shot runtimes since there are no organs after this. No point to not skip these checks, going to nullspace anyway.
/*CHOMP Station removal start
var/obj/item/organ/internal/nano/refactory/refactory = locate() in H.internal_organs
if(refactory && !(refactory.status & ORGAN_DEAD))
//MHydrogen adds speeeeeed
if(refactory.get_stored_material(MAT_METALHYDROGEN) >= METAL_PER_TICK)
H.add_modifier(/datum/modifier/protean/mhydrogen, origin = refactory)
//Uranium adds brute armor
if(refactory.get_stored_material(MAT_URANIUM) >= METAL_PER_TICK)
H.add_modifier(/datum/modifier/protean/uranium, origin = refactory)
//Gold adds burn armor
if(refactory.get_stored_material(MAT_GOLD) >= METAL_PER_TICK)
H.add_modifier(/datum/modifier/protean/gold, origin = refactory)
//Silver adds accuracy and evasion
if(refactory.get_stored_material(MAT_SILVER) >= METAL_PER_TICK)
H.add_modifier(/datum/modifier/protean/silver, origin = refactory)
return ..()
CHOMP Station removal end*/
/datum/species/protean/get_additional_examine_text(var/mob/living/carbon/human/H)
return ..() //Hmm, what could be done here?
/datum/species/protean/update_misc_tabs(var/mob/living/carbon/human/H)
..()
var/list/L = list()
var/obj/item/organ/internal/nano/refactory/refactory = H.nano_get_refactory()
if(refactory && !(refactory.status & ORGAN_DEAD))
L[++L.len] = list("- -- --- Refactory Metal Storage --- -- -", null, null, null, null)
var/max = refactory.max_storage
for(var/material in refactory.materials)
var/amount = refactory.get_stored_material(material)
L[++L.len] = list("[capitalize(material)]: [amount]/[max]", null, null, null, null)
else
L[++L.len] = list("- -- --- REFACTORY ERROR! --- -- -", null, null, null, null)
L[++L.len] = list("- -- --- Abilities (Shift+LMB Examines) --- -- -", null, null, null, null)
for(var/obj/effect/protean_ability/A as anything in abilities)
var/client/C = H.client
var/img
if(C && istype(C)) //sanity checks
if(A.ability_name in C.misc_cache)
img = C.misc_cache[A.ability_name]
else
img = icon2html(A,C,sourceonly=TRUE)
C.misc_cache[A.ability_name] = img
L[++L.len] = list("[A.ability_name]", A.ability_name, img, A.atom_button_text(), REF(A))
H.misc_tabs["Protean"] = L
// Various modifiers
/datum/modifier/protean
stacks = MODIFIER_STACK_FORBID
var/material_use = METAL_PER_TICK
var/material_name = MAT_STEEL
/datum/modifier/protean/on_applied()
. = ..()
if(holder.temporary_form)
to_chat(holder.temporary_form,on_created_text)
/datum/modifier/protean/on_expire()
. = ..()
if(holder.temporary_form)
to_chat(holder.temporary_form,on_expired_text)
/datum/modifier/protean/check_if_valid()
//No origin set
if(!istype(origin))
expire()
//No refactory
var/obj/item/organ/internal/nano/refactory/refactory = origin.resolve()
if(!istype(refactory) || refactory.status & ORGAN_DEAD)
expire()
//Out of materials
if(!refactory.use_stored_material(material_name,material_use))
expire()
/*CHOMP Removal start
/datum/modifier/protean/mhydrogen
name = "Protean Effect - M.Hydrogen"
desc = "You're affected by the presence of metallic hydrogen."
on_created_text = span_notice("You feel yourself accelerate, the metallic hydrogen increasing your speed temporarily.")
on_expired_text = span_notice("Your refactory finishes consuming the metallic hydrogen, and you return to normal speed.")
material_name = MAT_METALHYDROGEN
slowdown = -1
/datum/modifier/protean/uranium
name = "Protean Effect - Uranium"
desc = "You're affected by the presence of uranium."
on_created_text = span_notice("You feel yourself become nearly impervious to physical attacks as uranium is incorporated in your nanites.")
on_expired_text = span_notice("Your refactory finishes consuming the uranium, and you return to your normal nanites.")
material_name = MAT_URANIUM
incoming_brute_damage_percent = 0.8
/datum/modifier/protean/gold
name = "Protean Effect - Gold"
desc = "You're affected by the presence of gold."
on_created_text = span_notice("You feel yourself become more reflective, able to resist heat and fire better for a time.")
on_expired_text = span_notice("Your refactory finishes consuming the gold, and you return to your normal nanites.")
material_name = MAT_GOLD
incoming_fire_damage_percent = 0.8
/datum/modifier/protean/silver
name = "Protean Effect - Silver"
desc = "You're affected by the presence of silver."
on_created_text = span_notice("Your physical control is improved for a time, making it easier to hit targets, and avoid being hit.")
on_expired_text = span_notice("Your refactory finishes consuming the silver, and your motor control returns to normal.")
material_name = MAT_SILVER
accuracy = 30
evasion = 30
CHOMP Removal end*/
/datum/modifier/protean/steel
name = "Protean Effect - Steel"
desc = "You're affected by the presence of steel."
on_created_text = span_notice("You feel new nanites being produced from your stockpile of steel, healing you slowly.")
on_expired_text = span_notice("Your steel supply has either run out, or is no longer needed, and your healing stops.")
material_name = MAT_STEEL
/datum/modifier/protean/steel/tick()
//Heal a random damaged limb by 1,1 per tick
holder.adjustBruteLoss(-1,include_robo = TRUE)
holder.adjustFireLoss(-1,include_robo = TRUE)
holder.adjustToxLoss(-1)
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
/obj/item/clothing/accessory/permit/nanotech
name = "\improper P.A.N. card"
desc = "This is a 'Permit for Advanced Nanotechnology' card. It allows the owner to possess and operate advanced nanotechnology on NanoTrasen property. It must be renewed on a monthly basis."
icon = 'modular_chomp/icons/mob/species/protean/protean.dmi'
icon_state = "permit_pan"
var/validstring = "VALID THROUGH END OF: "
var/registring = "REGISTRANT: "
/obj/item/clothing/accessory/permit/nanotech/set_name(var/new_name)
owner = 1
if(new_name)
name += " ([new_name])"
validstring += "[time2text(world.timeofday, "Month") +" "+ num2text(text2num(time2text(world.timeofday, "YYYY"))+544)]" //YW EDIT
registring += "[new_name]"
/obj/item/clothing/accessory/permit/nanotech/examine(mob/user)
. = ..()
. += validstring
. += registring
#undef METAL_PER_TICK

View File

@@ -132,6 +132,3 @@
var/vs_fullness = vore_fullness_ex[belly_class]
if(vs_fullness > 0)
add_overlay("[icon_state]_[belly_class]-[vs_fullness]")
/mob/living/simple_mob/proc/character_directory_species()
return "simplemob"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Some files were not shown because too many files have changed in this diff Show More