Merge branch 'master' into reagentToDefines

This commit is contained in:
Kashargul
2024-12-06 21:57:14 +01:00
committed by GitHub
212 changed files with 5049 additions and 1312 deletions
-1
View File
@@ -18,7 +18,6 @@
#define CONTACT_GENERAL (1<<5)
#define AIRBORNE (1<<6)
//Severity Defines
#define NONTHREAT "No threat"
#define MINOR "Minor"
+1
View File
@@ -111,6 +111,7 @@
#define FACTION_WOLFTAUR "wolftaur"
#define FACTION_WORM "worm"
#define FACTION_XENO "xeno"
#define FACTION_CORGI "corgi"
#define FACTION_PLANTS "plants"
+7 -5
View File
@@ -40,11 +40,12 @@
//VOREStation Add
#define BE_LOSTDRONE 0x10000
#define BE_MAINTPRED 0x20000
#define BE_MORPH 0x40000
#define BE_CORGI 0x80000
#define BE_CURSEDSWORD 0x100000
#define BE_SURVIVOR 0x200000
#define BE_EVENT 0x400000
#define BE_MAINTLURKER 0x40000
#define BE_MORPH 0x80000
#define BE_CORGI 0x100000
#define BE_CURSEDSWORD 0x200000
#define BE_SURVIVOR 0x400000
#define BE_EVENT 0x800000
//VOREStation Add End
var/list/be_special_flags = list(
@@ -67,6 +68,7 @@ var/list/be_special_flags = list(
//VOREStation Add
"Lost Drone" = BE_LOSTDRONE,
"Maint Pred" = BE_MAINTPRED,
"Maint Lurker" = BE_MAINTLURKER,
"Morph" = BE_MORPH,
"Corgi" = BE_CORGI,
"Cursed Sword" = BE_CURSEDSWORD,
+1
View File
@@ -420,3 +420,4 @@
#define JOB_XENOMORPH "Xenomorph"
#define JOB_BORER "Borer"
#define JOB_EMERGENCY_RESPONSE_TEAM "Emergency Response Team"
#define JOB_MAINT_LURKER "Maintenance Lurker"
+13 -5
View File
@@ -48,10 +48,6 @@
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (isclient(I) ? I : null))
//Persistence
#define AREA_FLAG_IS_NOT_PERSISTENT 8 // SSpersistence will not track values from this area.
// Shuttles.
// These define the time taken for the shuttle to get to the space station, and the time before it leaves again.
@@ -99,7 +95,19 @@
#define DEFAULT_JOB_TYPE /datum/job/assistant
//Area flags, possibly more to come
#define RAD_SHIELDED 1 //shielded from radiation, clearly
#define RAD_SHIELDED 0x1 //shielded from radiation, clearly
#define BLUE_SHIELDED 0x2 // Shield from bluespace teleportation (telescience)
#define AREA_SECRET_NAME 0x4 // This tells certain things that display areas' names that they shouldn't display this area's name.
#define AREA_FLAG_IS_NOT_PERSISTENT 0x8 // SSpersistence will not track values from this area.
#define AREA_FORBID_EVENTS 0x10 // random events will not start inside this area.
#define AREA_FORBID_SINGULO 0x20 // singulo will not move in.
#define AREA_NO_SPOILERS 0x40 // makes it much more difficult to see what is inside an area with things like mesons.
#define AREA_SOUNDPROOF 0x80 // blocks sounds from other areas and prevents hearers on other areas from hearing the sounds within.
#define AREA_BLOCK_PHASE_SHIFT 0x100 // Stops phase shifted mobs from entering
#define AREA_BLOCK_GHOSTS 0x200 // Stops ghosts from entering
#define AREA_ALLOW_LARGE_SIZE 0x400 // If mob size is limited in the area.
#define AREA_BLOCK_SUIT_SENSORS 0x800 // If suit sensors are blocked in the area.
#define AREA_BLOCK_TRACKING 0x1000 // If camera tracking is blocked in the area.
// OnTopic return values
#define TOPIC_NOACTION 0
-2
View File
@@ -40,8 +40,6 @@
//Shuttle madness!
#define SHUTTLE_CRASHED 3 // Yup that can happen now
#define BLUE_SHIELDED 2 // Shield from bluespace teleportation (telescience)
//Herm Gender
#define HERM "herm"
+4
View File
@@ -328,6 +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"
// Misc species. Mostly unused but might as well be complete.
#define SPECIES_SHADOW "Shadow"
@@ -456,3 +457,6 @@
#define VISIBLE_GENDER_FORCE_PLURAL 1 // Used by get_visible_gender to return PLURAL
#define VISIBLE_GENDER_FORCE_IDENTIFYING 2 // Used by get_visible_gender to return the mob's identifying gender
#define VISIBLE_GENDER_FORCE_BIOLOGICAL 3 // Used by get_visible_gender to return the mob's biological gender
// Default name for accesories
#define DEVELOPER_WARNING_NAME "you should not see this..."
+1
View File
@@ -15,6 +15,7 @@
#define LANGUAGE_ANIMAL "Animal"
#define LANGUAGE_TEPPI "Teppi"
#define LANGUAGE_MOUSE "Mouse"
#define LANNGUAGE_DRAKE "Drake"
#define LANGUAGE_SHADEKIN "Shadekin Empathy"
#define LANGUAGE_LLEILL "Glamour Speak"
+63
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" // Does not exist on virgo
),
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 // Does not exist on virgo
)
)
/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
+1 -1
View File
@@ -19,7 +19,7 @@
if(vent.welded)
continue
var/area/A = get_area(vent)
if(A.forbid_events)
if(A.flag_check(AREA_FORBID_EVENTS))
continue
vent_list += vent
if(!vent_list.len)
+1 -1
View File
@@ -33,7 +33,7 @@ SUBSYSTEM_DEF(persistence)
return
var/area/A = get_area(T)
if(!A || (A.flags & AREA_FLAG_IS_NOT_PERSISTENT))
if(!A || (A.flag_check(AREA_FLAG_IS_NOT_PERSISTENT)))
return
if(!(T.z in using_map.persist_levels))
+1 -1
View File
@@ -73,7 +73,7 @@ SUBSYSTEM_DEF(radiation)
if(source.respect_maint)
var/area/A = T.loc
if(A.flags & RAD_SHIELDED)
if(A.flag_check(RAD_SHIELDED))
continue // In shielded area
var/dist = get_dist(source.source_turf, T)
+5 -4
View File
@@ -13,7 +13,8 @@
/datum/component/resize_guard/proc/check_resize()
var/area/A = get_area(parent)
if(A?.limit_mob_size)
var/mob/living/L = parent
L.resize(L.size_multiplier, ignore_prefs = TRUE)
qdel(src)
if(A?.flag_check(AREA_ALLOW_LARGE_SIZE))
return
var/mob/living/L = parent
L.resize(L.size_multiplier, ignore_prefs = TRUE)
qdel(src)
+9 -2
View File
@@ -3,8 +3,8 @@ GLOBAL_LIST_EMPTY(archive_diseases)
GLOBAL_LIST_INIT(advance_cures, list(
REAGENT_ID_SODIUMCHLORIDE, REAGENT_ID_SUGAR, "orangejuice",
"spaceacillin", "glucose", REAGENT_ID_ETHANOL,
"dyloteane", "impedrezene", "hepanephrodaxon",
"gold", "silver"
"leporazine", "impedrezene", "hepanephrodaxon",
"silver", "gold"
))
/datum/disease/advance
@@ -236,6 +236,13 @@ GLOBAL_LIST_INIT(advance_cures, list(
Refresh(1)
return
/datum/disease/advance/proc/PickyEvolve(var/list/datum/symptom/D)
var/s = safepick(D)
if(s)
AddSymptom(new s)
Refresh(1)
return
// Randomly remove a symptom.
/datum/disease/advance/proc/Devolve()
if(length(symptoms) > 1)
@@ -0,0 +1,38 @@
/*
//////////////////////////////////////
Deafness
Slightly hidden.
Lowers resistance.
Increases stage speed slightly.
Decreases transmittablity.
Intense Level.
Bonus
Causes intermittent loss of hearing.
//////////////////////////////////////
*/
/datum/symptom/deafness
name = "Deafness"
stealth = 1
resistance = -2
stage_speed = 1
transmittable = -3
level = 4
severity = 3
/datum/symptom/deafness/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3, 4)
to_chat(M, span_warning("[pick("you hear a ringing in your ear.", "You ears pop.")]"))
if(5)
to_chat(M, span_userdanger("You ear pop and begin ringing loudly!"))
M.ear_deaf += 20
return
@@ -6,7 +6,7 @@ Necrotizing Fasciitis (AKA Flesh-Eating Disease)
Very very noticable.
Lowers resistance tremendously.
No changes to stage speed.
Decreases transmittablity temrendously.
Decreases transmittablity tremendously.
Fatal Level.
Bonus
@@ -0,0 +1,33 @@
/*
//////////////////////////////////////
Flippinov
Slightly hidden.
No change to resistance.
Increases stage speed.
Little transmittable.
Low Level.
BONUS
Makes the host FLIP.
Should be used for buffing your disease.
//////////////////////////////////////
*/
/datum/symptom/spyndrome
name = "Flippinov"
stealth = 2
resistance = 0
stage_speed = 3
transmittable = 1
level = 1
severity = 1
/datum/symptom/spyndrome/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/L = A.affected_mob
L.emote("flip")
@@ -0,0 +1,56 @@
/*
//////////////////////////////////////
Alopecia
Noticable.
Decreases resistance slightly.
Reduces stage speed slightly.
Transmittable.
Intense Level.
BONUS
Makes the mob lose hair.
//////////////////////////////////////
*/
/datum/symptom/shedding
name = "Alopecia"
stealth = -1
resistance = -1
stage_speed = -1
transmittable = 2
level = 4
severity = 1
/datum/symptom/shedding/Activate(datum/disease/advance/A)
..()
if(!prob(SYMPTOM_ACTIVATION_PROB))
return
if(ishuman(A.affected_mob))
return
var/mob/living/carbon/human/H = A.affected_mob
var/obj/item/organ/external/head/head_organ = H.get_organ(BP_HEAD)
if(!istype(head_organ))
return
to_chat(H, span_warning("[pick("Your scalp itches.", "Your skin feels flakey.")]"))
switch(A.stage)
if(3, 4)
if(H.h_style != "Bald" && H.h_style != "Balding Hair")
to_chat(H, span_warning("Your hair starts to fall out in clumps..."))
addtimer(CALLBACK(src, PROC_REF(change_hair), H, null, "Balding Hair"), 5 SECONDS)
if(5)
if(H.h_style != "Shaved" && H.h_style != "Bald")
to_chat(H, span_warning("Your hair starts to fall out in clumps..."))
addtimer(CALLBACK(src, PROC_REF(change_hair), H, "Shaved", "Bald"), 5 SECONDS)
return
/datum/symptom/shedding/proc/change_hair(var/mob/living/carbon/human/H, f_style, h_style)
if(!H)
return
if(f_style)
H.f_style = f_style
if(h_style)
H.h_style = h_style
return
@@ -130,7 +130,7 @@ Bonus
Very high level.
Bonus
Heals brain damage, treats radiation.
Heals clone damage, treats radiation.
//////////////////////////////////////
*/
@@ -0,0 +1,42 @@
/*
//////////////////////////////////////
Hematophagy
Little bit hidden.
Decreases resistance slightly.
Decreases stage speed tremendously.
Slightly increased transmittablity.
Intense level.
BONUS
The host must feed on BLOOD
//////////////////////////////////////
*/
/datum/symptom/hematophagy
name = "Hematophagy"
stealth = 1
resistance = -1
resistance = -4
transmittable = 1
level = 4
/datum/symptom/hematophagy/Start(datum/disease/advance/A)
if(ishuman(A.affected_mob))
var/mob/living/carbon/human/H = A.affected_mob
H.species.organic_food_coeff = 0
H.species.bloodsucker = TRUE
add_verb(H, /mob/living/carbon/human/proc/bloodsuck)
/datum/symptom/hematophagy/End(datum/disease/advance/A)
if(ishuman(A.affected_mob))
var/mob/living/carbon/human/H = A.affected_mob
H.species.organic_food_coeff = initial(H.species.organic_food_coeff)
H.species.bloodsucker = initial(H.species.bloodsucker)
remove_verb(H, /mob/living/carbon/human/proc/bloodsuck)
@@ -0,0 +1,41 @@
/*
//////////////////////////////////////
Photosensitivity
Noticable.
Increases resistance.
Increases stage speed slightly.
Decreases transmittablity tremendously.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/photosensitivity
name = "Photosensitivity"
stealth = -2
resistance = 2
stage_speed = 1
transmittable = -4
level = 6
severity = 5
/datum/symptom/photosensitivity/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/human/H = A.affected_mob
var/turf/T = get_turf(H)
switch(A.stage)
if(3)
if(T.get_lumcount() > 0.5)
to_chat(H, span_danger("Your skin itches under the light..."))
if(4, 5)
if(T.get_lumcount() > 0.5)
to_chat(H, span_danger("Your skin feels like burning!"))
H.adjustFireLoss(T.get_lumcount())
return
@@ -0,0 +1,46 @@
/*
//////////////////////////////////////
Pica
Not noticable or unnoticable.
Decreases resistance.
Increases stage speed.
Little transmittable.
Low Level.
BONUS
The host gains hunger for any kind of object.
//////////////////////////////////////
*/
/datum/symptom/pica
name = "Pica"
stealth = 0
resistance = -2
stage_speed = 3
transmittable = 1
level = 1
severity = 1
/datum/symptom/pica/Start(datum/disease/advance/A)
add_verb(A.affected_mob, /mob/living/proc/eat_trash)
add_verb(A.affected_mob, /mob/living/proc/toggle_trash_catching)
/datum/symptom/pica/End(datum/disease/advance/A)
remove_verb(A.affected_mob, /mob/living/proc/eat_trash)
remove_verb(A.affected_mob, /mob/living/proc/toggle_trash_catching)
/datum/symptom/pica/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/list/nearby = oview(5, A.affected_mob)
to_chat(A.affected_mob, span_warning("You could go fo a bite of [pick(nearby)]..."))
else if (prob(SYMPTOM_ACTIVATION_PROB))
if(ishuman(A.affected_mob))
var/mob/living/carbon/human/H = A.affected_mob
var/list/item = H.get_equipped_items()
to_chat(H, span_warning("[pick(item)] looks oddly [pick("delicious", "tasty", "scrumptious", "inviting")]..."))
return
@@ -0,0 +1,98 @@
/*
//////////////////////////////////////
Mass Revectoring
Very noticeable.
Increases resistance slightly.
Increases stage speed.
Decreases transmittablity
Intense level.
BONUS
Changes the size of the host.
//////////////////////////////////////
*/
/datum/symptom/size
name = "Mass Revectoring"
stealth = -4
resistance = 1
stage_speed = 2
transmittable = -2
level = 4
severity = 1
/datum/symptom/size/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.emote("twitch")
Resize(M, rand(25, 200))
/datum/symptom/size/proc/Resize(mob/living/M, var/size)
M.resize(size+M.size_multiplier/100)
/*
//////////////////////////////////////
Enlargement Disorder
Very noticeable.
Increases resistance slightly.
Increases stage speed.
Decreases transmittablity
Intense level.
BONUS
Grows the host to bigger sizes
//////////////////////////////////////
*/
/datum/symptom/size/grow
name = "Enlargement Disorder"
/datum/symptom/size/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.emote("twitch")
Resize(M, rand(100, 200))
/*
//////////////////////////////////////
Dwindling Malady
Very noticeable.
Increases resistance slightly.
Increases stage speed.
Decreases transmittablity
Intense level.
BONUS
Shrinks the host to small sizes
//////////////////////////////////////
*/
/datum/symptom/size/shrink
name = "Dwindling Malady"
/datum/symptom/size/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.emote("twitch")
Resize(M, rand(25, 100))
@@ -42,3 +42,78 @@ Bonus
icky.viruses |= A.Copy()
return
/*
//////////////////////////////////////
Bluespace Sneezing
Very Noticable.
Resistant
Doesn't increase stage speed.
Little transmittable.
Low Level.
Bonus
Forces a spread type of AIRBORNE
with extra range AND teleports the mob
//////////////////////////////////////
*/
/datum/symptom/sneeze/bluespace
name = "Bluespace Sneezing"
stealth = -2
resistance = 3
stage_speed = 0
transmittable = 1
level = 4
severity = 1
/datum/symptom/sneeze/bluespace/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3)
M.emote("sniff")
else
SneezeTeleport(A, M)
A.spread(A.stage)
if(prob(30))
var/obj/effect/decal/cleanable/mucus/icky = new(get_turf(M))
icky.viruses |= A.Copy()
return
/datum/symptom/sneeze/bluespace/proc/SneezeTeleport(datum/disease/advance/A, var/mob/living/M)
var/list/destination = list()
var/mob/living/carbon/human/H = M
var/place
for(var/mob/living/carbon/human/B in range(A.stage, M))
if(B.can_be_drop_pred && H.can_be_drop_prey && H.devourable)
destination += B.vore_selected
for(var/turf/T in range(A.stage, H))
if(istype(T, /turf/space)) // No danger, this is just a fun/vore symptom
continue
destination += T
if(isemptylist(destination))
to_chat(H, span_warning("You go to sneeze, but can't."))
return FALSE
place = safepick(destination)
var/mob/living/carbon/human/unlucky = locate() in place
if(unlucky)
if(unlucky.can_be_drop_pred && H.can_be_drop_prey && H.devourable)
place = unlucky.vore_selected
else if(unlucky.devourable && unlucky.can_be_drop_prey && H.can_be_drop_pred)
unlucky.forceMove(H.vore_selected)
H.emote("sneeze")
do_teleport(H, place)
return TRUE
@@ -16,7 +16,7 @@ BONUS
//////////////////////////////////////
*/
/datum/symptom/mlem
/datum/symptom/spyndrome
name = "Spyndrome"
stealth = 2
resistance = 0
@@ -24,9 +24,8 @@ BONUS
transmittable = 1
level = 1
severity = 1
var/list/directions = list(2,4,1,8,2,4,1,8,2,4,1,8,2,4,1,8,2,4,1,8)
/datum/symptom/mlem/Activate(var/datum/disease/advance/A)
/datum/symptom/spyndrome/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
@@ -34,7 +33,5 @@ BONUS
to_chat(viewers(A.affected_mob), span_warning("[A.affected_mob.name] struggles violently against their restraints!"))
else
to_chat(viewers(A.affected_mob), span_warning("[A.affected_mob.name] spins around violently!"))
for(var/D in directions)
A.affected_mob.dir = D
A.affected_mob.dir = pick(2,4,1,8)
A.affected_mob.emote("spin")
return
@@ -0,0 +1,43 @@
/*
//////////////////////////////////////
Healing
No change to stealth.
Slightly decreases resistance.
Increases stage speed.
Decreases transmittablity considerably.
Moderate Level.
Bonus
Heals toxins in the affected mob's blood stream.
//////////////////////////////////////
*/
/datum/symptom/stimulant
name = "Overactive Adrenal Gland"
stealth = 0
resistance = -1
stage_speed = 2
transmittable = -3
level = 3
severity = 1
/datum/symptom/stimulant/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/L = A.affected_mob
to_chat(L, span_notice("You feel a rush of energy inside you!"))
switch(A.stage)
if(1, 2)
L.jitteriness += 5
if(3, 4)
L.jitteriness += 10
else
if(L.reagents.get_reagent_amount("hyperzine" < 10))
L.reagents.add_reagent("hyperzine", 5)
if(prob(30))
L.jitteriness += 15
return
@@ -1,7 +1,7 @@
/*
//////////////////////////////////////
Sneezing
Synthetic Infection
Slightly hidden.
Increases resistance.
@@ -23,7 +23,6 @@ Bonus
transmittable = 1
level = 5
severity = 3
id = "synthetic_infection"
/datum/symptom/infect_synthetics/Start(datum/disease/advance/A)
A.infect_synthetics = TRUE
+45
View File
@@ -0,0 +1,45 @@
/datum/disease/appendicitis
form = "Condition"
name = "Appendicitis"
max_stages = 3
spread_text = "Non-contagius"
spread_flags = NON_CONTAGIOUS
cure_text = "Surgery"
agent = "Shitty Appendix"
viable_mobtypes = list(/mob/living/carbon/human)
desc = "If left untreated the subject will become very weak, and may vomit often."
severity = MINOR
disease_flags = CAN_CARRY|CAN_CARRY
visibility_flags = HIDDEN_PANDEMIC
required_organs = list(/obj/item/organ/internal/appendix)
bypasses_immunity = TRUE
virus_heal_resistant = TRUE
/datum/disease/appendicitis/stage_act()
if(!..())
return
switch(stage)
if(1)
if(prob(5))
affected_mob.adjustToxLoss(1)
if(2)
var/obj/item/organ/internal/appendix/A = affected_mob.internal_organs_by_name[O_APPENDIX]
if(A)
A.inflamed = TRUE
if(prob(3))
to_chat(affected_mob, span_warning("You feel a stabbing pain in your abdomen!"))
affected_mob.custom_emote(VISIBLE_MESSAGE, "winces painfully.")
affected_mob.Stun(rand(4, 6))
affected_mob.adjustToxLoss(1)
if(3)
if(prob(1))
to_chat(affected_mob, span_danger("Your abdomen is a world of pain!"))
affected_mob.custom_emote(VISIBLE_MESSAGE, "winces painfully.")
affected_mob.Weaken(10)
if(prob(1))
affected_mob.vomit(95)
if(prob(5))
to_chat(affected_mob, span_warning("You feel a stabbing pain in your abdomen!"))
affected_mob.custom_emote(VISIBLE_MESSAGE, "winces painfully.")
affected_mob.Stun(rand(4, 6))
affected_mob.adjustToxLoss(2)
+32
View File
@@ -0,0 +1,32 @@
/datum/disease/fake_gbs
name = "GBS"
max_stages = 5
spread_text = "On contact"
spread_flags = CONTACT_GENERAL
cure_text = "Adranol & Sulfur"
cures = list("adranol", "sulfur")
agent = "Gravitokinetic Bipotential SADS-"
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/human/monkey)
desc = "if left untreated death will occur."
severity = BIOHAZARD // Mimics real GBS
/datum/disease/fake_gbs/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(prob(1))
affected_mob.emote("sneeze")
if(3)
if(prob(5))
affected_mob.emote("cough")
else if(prob(5))
affected_mob.emote("gasp")
if(prob(10))
to_chat(span_danger("You're starting to feel very weak..."))
if(4)
if(prob(10))
affected_mob.emote("cough")
if(5)
if(prob(10))
affected_mob.emote("cough")
+49
View File
@@ -0,0 +1,49 @@
/datum/disease/gbs
name = "GBS"
max_stages = 5
spread_text = "On contact"
spread_flags = CONTACT_GENERAL
cure_text = "Adranol & Sulfur"
cures = list("adranol", "sulfur")
cure_chance = 15
agent = "Gravitokinetic Bipotential SADS+"
viable_mobtypes = list(/mob/living/carbon/human)
severity = BIOHAZARD
/datum/disease/gbs/stage_act()
if(!..())
return FALSE
switch(stage)
if(2)
if(prob(45))
affected_mob.adjustToxLoss(5)
if(prob(1))
affected_mob.emote("sneeze")
if(3)
if(prob(5))
affected_mob.emote("cough")
else if(prob(5))
affected_mob.emote("gasp")
if(prob(10))
to_chat(affected_mob, span_danger("You're starting to feel very weak..."))
if(4)
if(prob(10))
affected_mob.emote("cough")
affected_mob.adjustToxLoss(5)
if(5)
to_chat(affected_mob, span_danger("Your body feels as if it's trying to rip itself open..."))
if(prob(50))
affected_mob.delayed_gib()
else
return
/datum/disease/gbs/curable
name = "Non-Contagious GBS"
stage_prob = 5
spread_text = "Non-contagious"
spread_flags = NON_CONTAGIOUS
cure_text = "Cryoxadone"
cures = list("cryoxadone")
cure_chance = 10
agent = "gibbis"
disease_flags = CURABLE
+8 -2
View File
@@ -7,5 +7,11 @@
/datum/ghost_query/maints_pred
role_name = "Maintenance Predator"
be_special_flag = BE_MAINTPRED
question = "It appears a predatory critter is lurking in the maintenance. Do you want to play as it? ((You get to choose type of critter. Expect to be treated as vore predator.))"
cutoff_number = 1
question = "It appears a predatory critter is lurking in maintenance. Do you want to play as it? ((You get to choose type of critter. Expect to be treated as vore predator.))"
cutoff_number = 1
/datum/ghost_query/maints_lurker
role_name = "Maintenance Lurker"
be_special_flag = BE_MAINTLURKER
question = "It appears a strange individual is lurking in maintenance. Do you want to play as them? ((You can spawn as your currently loaded character slot. Expect to be treated as vore predator.))"
cutoff_number = 1
+13 -1
View File
@@ -63,4 +63,16 @@
/decl/hierarchy/outfit/zaddat
name = "Zaddat Suit"
suit = /obj/item/clothing/suit/space/void/zaddat/
mask = /obj/item/clothing/mask/gas/zaddat
mask = /obj/item/clothing/mask/gas/zaddat
/decl/hierarchy/outfit/maint_lurker
name = "Maintenance Lurker Outfit"
id_slot = slot_wear_id
id_type = /obj/item/card/id/civilian/lurker
pda_slot = slot_belt
pda_type = /obj/item/pda
id_pda_assignment = "NO DATA"
headset = /obj/item/radio/headset
headset_alt = /obj/item/radio/headset/alt
headset_earbud = /obj/item/radio/headset/earbud
+1 -1
View File
@@ -25,7 +25,7 @@ var/global/datum/repository/crew/crew_repository = new()
for(var/obj/item/clothing/under/C in tracked)
var/turf/pos = get_turf(C)
var/area/B = pos?.loc //VOREStation Add: No sensor in Dorm
if((C.has_sensor) && (pos?.z == zLevel) && (C.sensor_mode != SUIT_SENSOR_OFF) && !(B.block_suit_sensors) && !(is_jammed(C)) && !(is_vore_jammed(C))) //VOREStation Edit
if((C.has_sensor) && (pos?.z == zLevel) && (C.sensor_mode != SUIT_SENSOR_OFF) && !(B.flag_check(AREA_BLOCK_SUIT_SENSORS)) && !(is_jammed(C)) && !(is_vore_jammed(C))) //VOREStation Edit
if(istype(C.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C.loc
if(H.w_uniform != C)
+1 -2
View File
@@ -13,9 +13,8 @@
//////// Abductor Areas ////////
/area/unknown
requires_power = 0
flags = RAD_SHIELDED
flags = RAD_SHIELDED | AREA_ALLOW_LARGE_SIZE
icon_state = "red2"
limit_mob_size = FALSE
/area/unknown/dorm1
name = "Unknown Dorm 1"
+10 -14
View File
@@ -69,10 +69,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/shuttle
requires_power = 0
flags = RAD_SHIELDED | AREA_FLAG_IS_NOT_PERSISTENT
flags = RAD_SHIELDED | AREA_FLAG_IS_NOT_PERSISTENT | AREA_FORBID_EVENTS
sound_env = SMALL_ENCLOSED
base_turf = /turf/space
forbid_events = TRUE
/area/shuttle/arrival
name = "\improper Arrival Shuttle"
@@ -830,7 +829,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "construction"
/area/hallway/secondary/entry
forbid_events = TRUE
flags = AREA_FORBID_EVENTS
/area/hallway/secondary/entry/fore
name = "\improper Shuttle Dock Hallway - Mid"
@@ -1007,10 +1006,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
/area/crew_quarters
name = "\improper Dormitories"
icon_state = "Sleep"
flags = RAD_SHIELDED
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
ambience = AMBIENCE_GENERIC
forbid_events = TRUE
forbid_singulo = TRUE
/area/crew_quarters/toilet
name = "\improper Dormitory Toilets"
@@ -1313,8 +1310,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "Holodeck"
dynamic_lighting = 0
sound_env = LARGE_ENCLOSED
forbid_events = TRUE
flags = AREA_FLAG_IS_NOT_PERSISTENT
flags = AREA_FLAG_IS_NOT_PERSISTENT | AREA_FORBID_EVENTS
/area/holodeck/alphadeck
name = "\improper Holodeck Alpha"
@@ -1390,10 +1386,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
ambience = AMBIENCE_ENGINEERING
/area/engineering/atmos
name = "\improper Atmospherics"
icon_state = "atmos"
sound_env = LARGE_ENCLOSED
ambience = AMBIENCE_ATMOS
name = "\improper Atmospherics"
icon_state = "atmos"
sound_env = LARGE_ENCLOSED
ambience = AMBIENCE_ATMOS
/area/engineering/atmos/monitoring
name = "\improper Atmospherics Monitoring Room"
@@ -1419,7 +1415,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "\improper Engine Room"
icon_state = "engine"
sound_env = LARGE_ENCLOSED
forbid_events = TRUE
flags = AREA_FORBID_EVENTS
/area/engineering/engine_airlock
name = "\improper Engine Room Airlock"
@@ -2633,4 +2629,4 @@ var/list/the_station_areas = list (
icon_state = "yellow"
luminosity = 1
dynamic_lighting = 0
requires_power = 0
requires_power = 0
+9 -11
View File
@@ -40,7 +40,6 @@ GLOBAL_LIST_EMPTY(areas_by_type)
var/music = null
var/has_gravity = 1 // Don't check this var directly; use get_gravity() instead
var/secret_name = FALSE // This tells certain things that display areas' names that they shouldn't display this area's name.
var/obj/machinery/power/apc/apc = null
var/no_air = null
// var/list/lights // list of all lights on this area
@@ -52,12 +51,6 @@ GLOBAL_LIST_EMPTY(areas_by_type)
var/list/forced_ambience = null
var/sound_env = STANDARD_STATION
var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf
var/forbid_events = FALSE // If true, random events will not start inside this area.
var/forbid_singulo = FALSE // If true singulo will not move in.
var/no_spoilers = FALSE // If true, makes it much more difficult to see what is inside an area with things like mesons.
var/soundproofed = FALSE // If true, blocks sounds from other areas and prevents hearers on other areas from hearing the sounds within.
var/block_phase_shift = FALSE //Stops phase shifted mobs from entering // RS Port #658
var/block_ghosts = FALSE //Stops ghosts from entering //RS Port #658
/area/New()
// Used by the maploader, this must be done in New, not init
@@ -76,7 +69,7 @@ GLOBAL_LIST_EMPTY(areas_by_type)
power_equip = 0
power_environ = 0
power_change() // all machines set to current power level, also updates lighting icon
if(no_spoilers)
if(flag_check(AREA_NO_SPOILERS))
set_spoiler_obfuscation(TRUE)
// Changes the area of T to A. Do not do this manually.
@@ -398,7 +391,7 @@ var/list/mob/living/forced_ambiance_list = new
L.lastarea = src
L.lastareachange = world.time
play_ambience(L, initial = TRUE)
if(no_spoilers)
if(flag_check(AREA_NO_SPOILERS))
L.disable_spoiler_vision()
check_phase_shift(M) //RS Port #658
@@ -542,7 +535,7 @@ var/list/ghostteleportlocs = list()
return 1
/area/proc/get_name()
if(secret_name)
if(flag_check(AREA_SECRET_NAME))
return "Unknown Area"
return name
@@ -558,9 +551,14 @@ GLOBAL_DATUM(spoiler_obfuscation_image, /image)
else
cut_overlay(GLOB.spoiler_obfuscation_image)
/area/proc/flag_check(var/flag, var/match_all = FALSE)
if(match_all)
return (flags & flag) == flag
return flags & flag
// RS Port #658 Start
/area/proc/check_phase_shift(var/mob/ourmob)
if(!block_phase_shift || !ourmob.incorporeal_move)
if(!flag_check(AREA_BLOCK_PHASE_SHIFT) || !ourmob.incorporeal_move)
return
if(!isliving(ourmob))
return
+1 -4
View File
@@ -1,9 +1,6 @@
/area
var/enter_message
var/exit_message
var/limit_mob_size = TRUE //If mob size is limited in the area.
var/block_suit_sensors = FALSE //If suit sensors are blocked in the area.
var/block_tracking = FALSE //If camera tracking is blocked in the area.
var/turf/ceiling_type
// Size of the area in open turfs, only calculated for indoors areas.
@@ -71,5 +68,5 @@
power_equip = 0
power_environ = 0
power_change() // all machines set to current power level, also updates lighting icon
if(no_spoilers)
if(flag_check(AREA_NO_SPOILERS))
set_spoiler_obfuscation(TRUE)
+2 -2
View File
@@ -350,8 +350,8 @@
title_blurb = "A " + JOB_ALT_COMEDIAN + " will focus on making people laugh with the power of wit! Telling jokes, stand-up comedy, you are here to make others smile!"
/datum/alt_title/tragedian
title = JOB_ALT_ARTIST
title_blurb = "A " + JOB_ALT_ARTIST + " will focus on making people think about life and world around them! Life is a tragedy, and who's better to convey its emotions than you?"
title = JOB_ALT_TRAGEDIAN
title_blurb = "A " + JOB_ALT_TRAGEDIAN + " will focus on making people think about life and world around them! Life is a tragedy, and who's better to convey its emotions than you?"
/datum/alt_title/artist
title = JOB_ALT_ARTIST
+22
View File
@@ -108,3 +108,25 @@
return list(access_maint_tunnels, access_entertainment, access_tomfoolery, access_mime)
else
return list(access_entertainment, access_tomfoolery, access_mime)
/obj/item/card/id/civilian/lurker
desc = "A rather old and scuffed-looking ID. It seems legit, but something also seems very off somehow. Say, what's the issue/expiry date..?"
assignment = "NO DATA"
rank = JOB_MAINT_LURKER
/datum/job/maint_lurker
title = JOB_MAINT_LURKER
departments = list(DEPARTMENT_CIVILIAN)
faction = FACTION_STATION
total_positions = -1
spawn_positions = -1
supervisors = "nobody save your own common sense and good judgement, though Security may get upset if you're not careful"
selection_color = "#515151"
account_allowed = FALSE //let's not give the game away by creating accounts that someone might stumble across
job_description = "You are a maintenance lurker! You shouldn't be able to see this description anyway! Go prank the CMO or eat the RD's hat or something instead of looking at this."
whitelist_only = 1
latejoin_only = 1
requestable = FALSE
outfit_type = /decl/hierarchy/outfit/maint_lurker
access = list(access_maint_tunnels)
minimal_access = list(access_maint_tunnels)
+5 -5
View File
@@ -801,7 +801,7 @@
apply_danger_level(0)
update_icon()
/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob)
/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user)
add_fingerprint(user)
if(alarm_deconstruction_screwdriver(user, W))
return
@@ -809,10 +809,10 @@
return
if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))// trying to unlock the interface with an ID card
togglelock()
togglelock(user)
return ..()
/obj/machinery/alarm/verb/togglelock(mob/user as mob)
/obj/machinery/alarm/proc/togglelock(mob/user)
if(stat & (NOPOWER|BROKEN))
to_chat(user, "It does nothing.")
return
@@ -824,9 +824,9 @@
to_chat(user, span_warning("Access denied."))
return
/obj/machinery/alarm/AltClick()
/obj/machinery/alarm/AltClick(mob/user)
..()
togglelock()
togglelock(user)
/obj/machinery/alarm/power_change()
..()
+1 -1
View File
@@ -230,7 +230,7 @@
return TRACKING_TERMINATE
var/turf/pos = get_turf(src)
var/area/B = pos?.loc // No cam tracking in dorms!
if(InvalidPlayerTurf(pos) || B.block_tracking)
if(InvalidPlayerTurf(pos) || B.flag_check(AREA_BLOCK_TRACKING))
return TRACKING_TERMINATE
if(invisibility >= INVISIBILITY_LEVEL_ONE) //cloaked
return TRACKING_TERMINATE
+2 -1
View File
@@ -1,6 +1,7 @@
/obj/machinery/computer/pandemic
name = "PanD.E.M.I.C 2200"
desc = "Used to work with viruses."
circuit = /obj/item/circuitboard/pandemic
density = TRUE
anchored = TRUE
icon = 'icons/obj/pandemic.dmi'
@@ -325,7 +326,7 @@
printing = 1
var/obj/item/paper/P = new /obj/item/paper(loc)
visible_message(span_notice("[src] rattles and prints out a sheet of paper."))
// playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1)
playsound(loc, 'sound/machines/printer.ogg', 50, 1)
P.info = "<U><font size=\"4\"><B><center> Releasing Virus </B></center></font></U>"
P.info += "<HR>"
+4 -4
View File
@@ -145,7 +145,7 @@
if(in_use)
return
var/area/A = get_area(usr)
if(A.flags & BLUE_SHIELDED)
if(A.flag_check(BLUE_SHIELDED))
to_chat(usr, span_warning("You cannot edit restricted areas."))
return
in_use = TRUE
@@ -156,7 +156,7 @@
return
in_use = TRUE
var/area/A = create_area_whole(usr, src)
if(A && (A.flags & BLUE_SHIELDED))
if(A?.flag_check(BLUE_SHIELDED))
to_chat(usr, span_warning("You cannot edit restricted areas."))
in_use = FALSE
return
@@ -485,7 +485,7 @@
var/area/place = get_area(turfs[i])
if(blacklisted_areas[place.type])
continue
if(!place.requires_power || (place.flags & BLUE_SHIELDED))
if(!place.requires_power || (place.flag_check(BLUE_SHIELDED)))
continue // No expanding powerless rooms etc
areas[place.name] = place
@@ -587,7 +587,7 @@
continue
if(!BUILDABLE_AREA_TYPES[place.type]) //TODOTODOTODO
can_make_new_area = 0
if(!place.requires_power || (place.flags & BLUE_SHIELDED))
if(!place.requires_power || (place.flag_check(BLUE_SHIELDED)))
continue // No expanding powerless rooms etc
areas[place.name] = place
@@ -539,7 +539,7 @@
//Misc belts. Admin-spawn only atm.
/obj/item/personal_shield_generator/belt/adminbus
desc = "You should not see this. You REALLY should not see this. If you do, you have either been blessed or are about to be the target of some sick prank."
desc = DEVELOPER_WARNING_NAME + " You REALLY should not see this. If you do, you have either been blessed or are about to be the target of some sick prank."
modifier_type = /datum/modifier/shield_projection/admin
generator_hit_cost = 0
generator_active_cost = 0
@@ -466,6 +466,7 @@
/obj/item/radio/headset/alt/ert
name = "emergency response team bowman headset"
icon_state = "com_headset_alt"
centComm = 1
ks2type = /obj/item/encryptionkey/ert
/obj/item/radio/headset/ia
@@ -493,6 +494,8 @@
/obj/item/radio/headset/alt/centcom
name = "centcom bowman headset"
icon_state = "com_headset_alt"
centComm = 1
ks2type = /obj/item/encryptionkey/ert
/obj/item/radio/headset/nanotrasen
name = "\improper NT radio headset"
@@ -503,6 +506,8 @@
/obj/item/radio/headset/alt/nanotrasen
name = "\improper NT bowman headset"
icon_state = "nt_headset_alt"
centComm = 1
ks2type = /obj/item/encryptionkey/ert
/obj/item/radio/headset/pathfinder
name = "pathfinder's headset"
@@ -513,6 +518,8 @@
/obj/item/radio/headset/alt/pathfinder
name = "pathfinder's bowman headset"
icon_state = "exp_headset_alt"
adhoc_fallback = TRUE
ks2type = /obj/item/encryptionkey/pathfinder
/obj/item/radio/headset/pilot
name = "pilot's headset"
@@ -522,6 +529,7 @@
/obj/item/radio/headset/alt/pilot
name = "pilot's bowman headset"
icon_state = "pilot_headset_alt"
adhoc_fallback = TRUE
/obj/item/radio/headset/explorer
name = "away team member's headset"
@@ -532,6 +540,8 @@
/obj/item/radio/headset/alt/explorer
name = "away team's bowman headset"
icon_state = "exp_headset_alt"
adhoc_fallback = TRUE
ks2type = /obj/item/encryptionkey/explorer
/obj/item/radio/headset/sar
name = "search and rescue headset"
@@ -635,4 +645,4 @@
/obj/item/radio/headset/heads/ai_integrated/receive_range(freq, level)
if (disabledAi)
return -1 //Transciever Disabled.
return ..(freq, level, 1)
return ..(freq, level, 1)
+1 -1
View File
@@ -1,5 +1,5 @@
/obj/effect/falling_effect
name = "you should not see this"
name = DEVELOPER_WARNING_NAME
desc = "no data"
invisibility = 101
anchored = TRUE
@@ -0,0 +1,16 @@
#ifndef T_BOARD
#error T_BOARD macro is not defined but we need it!
#endif
/obj/item/circuitboard/pandemic
name = T_BOARD("pandemic")
build_path = /obj/machinery/computer/pandemic
board_type = new /datum/frame/frame_types/computer
origin_tech = list(TECH_DATA = 2, TECH_BIO = 2)
req_components = list(
/obj/item/stock_parts/matter_bin = 2,
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/cable_coil = 5,
/obj/item/stock_parts/capacitor = 1
)
@@ -336,3 +336,9 @@
/obj/item/card/id/syndicate/officer
name = "Syndicate Officer ID"
initial_sprite_stack = list("base-stamp-dark", "top-syndicate", "stamp-s", "pips-gold", "stripe-gold")
//Special
/obj/item/card/id/civilian/lurker
name = "Outdated ID"
initial_sprite_stack = list("base-stamp", "stamp-silhouette", "top-olive", "digested")
+4 -4
View File
@@ -133,7 +133,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
@@ -150,7 +150,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
@@ -167,7 +167,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
@@ -186,7 +186,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
+4 -4
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.
+8
View File
@@ -26,6 +26,14 @@
toggle()
..()
/obj/structure/curtain/attack_ai(mob/user)
if(!Adjacent(user))
return
if(!isrobot((user)))
return
playsound(src, "rustle", 15, 1, -5)
toggle()
/obj/structure/curtain/proc/toggle()
set_opacity(!opacity)
if(opacity)
@@ -108,7 +108,7 @@
//newPred.movement_cooldown = 0 // The "needless artificial speed cap" exists for a reason
if(M.mind)
M.mind.transfer_to(newPred)
to_chat(M, span_notice("You are <b>[newPred]</b>, somehow having gotten aboard the station in search of food. \
to_chat(M, span_notice("You are " + span_bold(newPred) + ", somehow having gotten aboard the station in search of food. \
You are wary of environment around you, but you do feel rather peckish. Stick around dark, secluded places to avoid danger or, \
if you are cute enough, try to make friends with this place's inhabitants."))
to_chat(M, span_critical("Please be advised, this role is NOT AN ANTAGONIST."))
@@ -144,7 +144,7 @@
var/mob/living/simple_mob/vore/morph/newMorph = new /mob/living/simple_mob/vore/morph(get_turf(src))
if(M.mind)
M.mind.transfer_to(newMorph)
to_chat(M, span_notice("You are a <b>Morph</b>, somehow having gotten aboard the station in your wandering. \
to_chat(M, span_notice("You are a " + span_bold("Morph") + ", somehow having gotten aboard the station in your wandering. \
You are wary of environment around you, but your primal hunger still calls for you to find prey. Seek a convincing disguise, \
using your amorphous form to traverse vents to find and consume weak prey."))
to_chat(M, span_notice("You can use shift + click on objects to disguise yourself as them, but your strikes are nearly useless when you are disguised. \
@@ -172,3 +172,82 @@
..()
if(!(src in active_ghost_pods))
active_ghost_pods += src
/obj/structure/ghost_pod/ghost_activated/maint_lurker
name = "strange maintenance hole"
desc = "This is my hole! It was made for me!"
icon = 'icons/effects/effects.dmi'
icon_state = "tunnel_hole"
icon_state_opened = "tunnel_hole"
density = FALSE
ghost_query_type = /datum/ghost_query/maints_lurker
anchored = TRUE
invisibility = INVISIBILITY_OBSERVER
spawn_active = TRUE
//override the standard attack_ghost proc for custom messages
/obj/structure/ghost_pod/ghost_activated/maint_lurker/attack_ghost(var/mob/observer/dead/user)
if(jobban_isbanned(user, JOB_GHOSTROLES))
to_chat(user, span_warning("You cannot use this spawnpoint because you are banned from playing ghost roles."))
return
//No whitelist
if(!is_alien_whitelisted(user, GLOB.all_species[user.client.prefs.species]))
to_chat(user, span_warning("You cannot use this spawnpoint to spawn as a species you are not whitelisted for!"))
return
//No OOC notes/FT
if(not_has_ooc_text(user))
//to_chat(user, span_warning("You must have proper out-of-character notes and flavor text configured for your current character slot to use this spawnpoint."))
return
var/choice = tgui_alert(user, "Using this spawner will spawn you as your currently loaded character slot in a special role. It should not be used with characters you regularly play on station. Are you absolutely sure you wish to continue?", "Maint Lurker Spawner", list("Yes", "No"))
if(!choice || choice == "No")
return
create_occupant(user)
/obj/structure/ghost_pod/ghost_activated/maint_lurker/create_occupant(var/mob/M)
..()
var/picked_ckey = M.ckey
var/picked_slot = M.client.prefs.default_slot
var/mob/living/carbon/human/new_character = new(src.loc)
if(!new_character)
to_chat(M, span_warning("Something went wrong and spawning failed. Please check your character slot doesn't have any obvious errors, then either try again or send an adminhelp!"))
reset_ghostpod()
return
log_and_message_admins("successfully used a Maintenance Lurker spawnpoint and became their loaded character.")
M.client.prefs.copy_to(new_character)
new_character.dna.ResetUIFrom(new_character)
new_character.sync_organ_dna()
new_character.key = M.key
new_character.mind.loaded_from_ckey = picked_ckey
new_character.mind.loaded_from_slot = picked_slot
job_master.EquipRank(new_character, JOB_MAINT_LURKER, 1)
for(var/lang in new_character.client.prefs.alternate_languages)
var/datum/language/chosen_language = GLOB.all_languages[lang]
if(chosen_language)
if(is_lang_whitelisted(src,chosen_language) || (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
new_character.add_language(lang)
new_character.regenerate_icons()
new_character.update_transform()
to_chat(new_character, span_notice("You are a " + span_bold(JOB_MAINT_LURKER) + ", a loose end... you have no special advantages compared to the rest of the crew, so be cautious! You have spawned with an ID that will allow you free access to maintenance areas along with any of your chosen loadout items that are not role restricted, and can make use of anything you can find in maintenance."))
to_chat(new_character, span_critical("Please be advised, this role is " + span_bold("NOT AN ANTAGONIST.")))
to_chat(new_character, span_notice("Whoever or whatever your chosen character slot is, your role is to facilitate roleplay focused around that character; this role is not free license to attack and murder people without provocation or explicit out-of-character consent. You should probably be cautious around high-traffic and highly sensitive areas (e.g. Telecomms) as Security personnel would be well within their rights to treat you as a trespasser. That said, good luck!"))
new_character.visible_message(span_warning("[new_character] appears to crawl out of somewhere."))
qdel(src)
/obj/structure/ghost_pod/ghost_activated/maint_lurker/Initialize()
..()
if(!(src in active_ghost_pods))
active_ghost_pods += src
+10 -4
View File
@@ -11,7 +11,7 @@
var/glass = 1
var/datum/tgui_module/appearance_changer/mirror/M
/obj/structure/mirror/Initialize(mapload, var/dir, var/building = 0, mob/user as mob)
/obj/structure/mirror/Initialize(mapload, var/dir, var/building = 0)
M = new(src, null)
if(building)
glass = 0
@@ -24,12 +24,18 @@
QDEL_NULL(M)
. = ..()
/obj/structure/mirror/attack_hand(mob/user as mob)
/obj/structure/mirror/attack_hand(mob/user)
if(!glass) return
if(shattered) return
if(ishuman(user))
M.tgui_interact(user)
M.tgui_interact(user)
/obj/structure/mirror/attack_ai(mob/user)
if(!glass) return
if(shattered) return
if(!Adjacent(user)) return
M.tgui_interact(user)
/obj/structure/mirror/proc/shatter()
if(!glass) return
+1 -1
View File
@@ -25,7 +25,7 @@
if(!T)
continue
var/area/A = T.loc
if((A.soundproofed || area_source.soundproofed) && (A != area_source))
if((A.flag_check(AREA_SOUNDPROOF) || area_source.flag_check(AREA_SOUNDPROOF)) && (A != area_source))
continue
var/distance = get_dist(T, turf_source)
@@ -92,6 +92,13 @@
toggle_open(user)
return 0
/turf/simulated/wall/attack_ai(var/mob/user)
if(!Adjacent(user))
return
if(!isrobot((user)))
return
var/rotting = (locate(/obj/effect/overlay/wallrot) in src)
try_touch(user, rotting)
/turf/simulated/wall/attack_hand(var/mob/user)
+4 -2
View File
@@ -196,7 +196,8 @@ var/list/admin_verbs_spawn = list(
/client/proc/create_gm_message,
/client/proc/remove_gm_message,
/client/proc/AdminCreateVirus,
/client/proc/ReleaseVirus
/client/proc/ReleaseVirus,
/client/proc/spawn_reagent
)
var/list/admin_verbs_server = list(
@@ -283,7 +284,8 @@ var/list/admin_verbs_debug = list(
/client/proc/admin_give_modifier,
/client/proc/simple_DPS,
/datum/admins/proc/view_feedback,
/client/proc/stop_sounds
/client/proc/stop_sounds,
/client/proc/spawn_reagent
)
var/list/admin_verbs_paranoid_debug = list(
+15
View File
@@ -535,3 +535,18 @@
set category = "Debug.Misc"
src.stat_panel.send_message("create_debug")
/client/proc/spawn_reagent()
set name = "Spawn Reagent"
set category = "Debug.Game"
if(!check_rights(R_ADMIN|R_EVENT)) return
var/datum/reagent/R = tgui_input_list(usr, "Select a reagent to spawn", "Reagent Spawner", subtypesof(/datum/reagent))
if(!R)
return
var/obj/item/reagent_containers/glass/bottle/B = new(usr.loc)
B.icon_state = "bottle-1"
B.reagents.add_reagent(R.id, 60)
B.name = "[B.name] of [R.name]"
+8 -6
View File
@@ -662,12 +662,14 @@ Traitors and the like can also be revived with the previous role mostly intact.
//New message handling
post_comm_message(customname, replacetext(input, "\n", "<br/>"))
switch(tgui_alert(usr, "Should this be announced to the general population?","Show world?",list("Yes","No")))
if("Yes")
command_announcement.Announce(input, customname, new_sound = 'sound/AI/commandreport.ogg', msg_sanitized = 1);
if("No")
to_world(span_red("New [using_map.company_name] Update available at all communication consoles."))
world << sound('sound/AI/commandreport.ogg')
var/confirm = tgui_alert(usr, "Should this be announced to the general population?","Show world?",list("Yes","No"))
if(!confirm)
return
if(confirm == "Yes")
command_announcement.Announce(input, customname, new_sound = 'sound/AI/commandreport.ogg', msg_sanitized = 1);
else
to_world(span_red("New [using_map.company_name] Update available at all communication consoles."))
world << sound('sound/AI/commandreport.ogg')
log_admin("[key_name(src)] has created a command report: [input]")
message_admins("[key_name_admin(src)] has created a command report", 1)
+5 -1
View File
@@ -3,14 +3,18 @@
desc = "An updated, modular intercom that fits over the head with extra comfortable for the hardworking casino luxury crew. Has encryption key for scamm-... Kind casino staff channel."
icon = 'icons/obj/casino.dmi'
icon_state = "headset"
adhoc_fallback = TRUE
origin_tech = list(TECH_ILLEGAL = 1)
ks1type = /obj/item/encryptionkey/casino
/obj/item/radio/headset/casino/bowman
/obj/item/radio/headset/alt/casino
name = "casino bowman headset"
desc = "An updated, modular intercom that fits over the head with extra comfortable for the hardworking casino luxury crew. Has encryption key for scamm-... Kind casino staff channel."
icon = 'icons/obj/casino.dmi'
icon_state = "headset_alt"
adhoc_fallback = TRUE
origin_tech = list(TECH_ILLEGAL = 2)
ks1type = /obj/item/encryptionkey/casino
/obj/item/encryptionkey/casino
icon = 'icons/obj/casino.dmi'
@@ -20,10 +20,11 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
//VOREStation Add
"lost drone" = 1, // 16
"maint pred" = 1, // 17
"morph" = 1, // 18
"corgi" = 1, // 19
"cursed sword" = 1, // 20
"Ship Survivor" = 1, // 21
"maint lurker" = 1, // 18
"morph" = 1, // 19
"corgi" = 1, // 20
"cursed sword" = 1, // 21
"Ship Survivor" = 1, // 22
//VOREStation Add End
)
@@ -68,35 +68,7 @@
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
character.voice_sounds_list = get_talk_sound(pref.voice_sound)
character.custom_speech_bubble = pref.custom_speech_bubble
/datum/category_item/player_setup_item/vore/size/content(var/mob/user)
+240
View File
@@ -482,3 +482,243 @@ var/list/preferences_datums = list()
save_character()
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.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()
+1 -1
View File
@@ -48,7 +48,7 @@ BLIND // can't see anything
// Prevent people from just turning their goggles back on.
if(!active && (vision_flags & (SEE_TURFS|SEE_OBJS)))
var/area/A = get_area(src)
if(A.no_spoilers)
if(A.flag_check(AREA_NO_SPOILERS))
return FALSE
return TRUE
@@ -0,0 +1,209 @@
/*
A collection of Protean rigsuit modules, intended to encourage Symbiotic relations with a host.
All of these should require someone else to be wearing the Protean to function.
These should come standard with the Protean rigsuit, unless you want them to work for some upgrades.
*/
//This rig module feeds nutrition directly from the wearer to the Protean, to help them stay charged while worn.
/obj/item/rig_module/protean
permanent = 1
/obj/item/rig_module/protean/syphon
name = "Protean Metabolic Syphon"
desc = "This should never be outside of a RIG."
icon_state = "flash"
interface_name = "Protean Metabolic Syphon"
interface_desc = "Toggle to drain nutrition/power from the user directly into the Protean's own energy stores."
toggleable = 1
activate_string = "Enable Syphon"
deactivate_string = "Disable Syphon"
/obj/item/rig_module/protean/syphon/activate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, span_boldnotice("You activate the suit's energy syphon."))
to_chat(H, span_warning("Your suit begins to sap at your own energy stores."))
active = 1
else
return 0
/obj/item/rig_module/protean/syphon/deactivate(var/forced)
if(!..())
return 0
if(forced)
active = 0
return
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, span_boldnotice("You deactivate the suit's energy syphon."))
to_chat(H, span_warning("Your suit ceases from sapping your own energy."))
active = 0
else
return 0
/obj/item/rig_module/protean/syphon/process()
if(active)
var/mob/living/carbon/human/H = holder.wearer
var/mob/living/P = holder?:myprotean
if(istype(H.species, /datum/species/protean))
to_chat(H, span_warning("Your Protean modules do not function on yourself."))
deactivate(1)
else
P = P?:humanform
if((H.nutrition >= 100) && (P.nutrition <= 5000))
H.nutrition -= 10
P.nutrition += 10
//This rig module allows a worn Protean to toggle and configure its armor settings.
/obj/item/rig_module/protean/armor
name = "Protean Adaptive Armor"
desc = "This should never be outside of a RIG."
interface_name = "Protean Adaptive Armor"
interface_desc = "Adjusts the proteans deployed armor values to fit the needs of the wearer."
usable = 1
toggleable = 1
activate_string = "Enable Armor"
deactivate_string = "Disable Armor"
engage_string = "Configure Armor"
var/list/armor_settings = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0)
var/armor_weight_ratio = 0.01 //This amount of slowdown per 1% of armour. 3 slowdown at the max armour.
/obj/item/rig_module/protean/armor/engage()
var/armor_chosen = input(usr, "Which armor to adjust?", "Protean Armor") as null|anything in armor_settings
if(armor_chosen)
var/armorvalue = tgui_input_number(usr, "Set armour reduction value (Max of 60%)", "Protean Armor",0,60)
if(isnum(armorvalue))
armor_settings[armor_chosen] = armorvalue
interface_desc = initial(interface_desc)
slowdown = 0
for(var/entry in armor_settings) //This is dumb and ugly but I dont feel like rewriting rig TGUI just to make this a pretty list
interface_desc += " [entry]: [armor_settings[entry]]"
slowdown += armor_settings[entry]*armor_weight_ratio
interface_desc += " Slowdown: [slowdown]"
/obj/item/rig_module/protean/armor/activate()
if(holder?:assimilated_rig)
to_chat(usr, span_bolddanger("Armor module non-functional while a RIG is assimilated."))
return
if(!..(1))
return 0
var/mob/living/carbon/human/H = holder.wearer
if(H)
var/list/temparmor = list("bio" = 100, "rad" = 100)
temparmor = armor_settings + temparmor
to_chat(usr, span_boldnotice("You signal the suit to harden."))
to_chat(H, span_notice("Your suit hardens in response to physical trauma."))
holder.armor = temparmor.Copy()
for(var/obj/item/piece in list(holder.gloves,holder.helmet,holder.boots,holder.chest))
piece.armor = temparmor.Copy()
holder.slowdown = slowdown
active = 1
else
return 0
/obj/item/rig_module/protean/armor/deactivate(var/forced)
if(!..(1))
return 0
if(forced)
holder.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
for(var/obj/item/piece in list(holder.gloves,holder.helmet,holder.boots,holder.chest))
piece.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
holder.slowdown = initial(slowdown)
active = 0
return
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, span_boldnotice("You signal the suit to relax."))
to_chat(H, span_warning("Your suit softens."))
holder.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
for(var/obj/item/piece in list(holder.gloves,holder.helmet,holder.boots,holder.chest))
piece.armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100)
holder.slowdown = initial(slowdown)
active = 0
else
return 0
/obj/item/rig_module/protean/armor/process()
if(active)
var/mob/living/carbon/human/H = holder.wearer
if(istype(H.species, /datum/species/protean))
to_chat(H, span_warning("Your Protean modules do not function on yourself."))
deactivate(1)
//This rig module lets a Protean expend its metal stores to heal its host
/obj/item/rig_module/protean/healing
name = "Protean Restorative Nanites"
desc = "This should never be outside of a RIG."
interface_name = "Protean Restorative Nanites"
interface_desc = "Utilises stored steel from the Protean to slowly heal and repair the wearer."
toggleable = 1
activate_string = "Enable Healing"
deactivate_string = "Disable Healing"
var/datum/modifier/healing
/obj/item/rig_module/protean/healing/activate()
if(!..(1))
return 0
var/mob/living/carbon/human/H = holder.wearer
var/mob/living/P = holder?:myprotean
if(H && P)
if(istype(H.species, /datum/species/protean))
to_chat(H, span_warning("Your Protean modules do not function on yourself."))
return 0
var/obj/item/organ/internal/nano/refactory/R = P.nano_get_refactory()
if(R.get_stored_material(MAT_STEEL) >= 100)
healing = holder.wearer.add_modifier(/datum/modifier/protean/steel, origin = R)
to_chat(usr, span_boldnotice("You activate the suit's restorative nanites."))
to_chat(H, span_warning("Your suit begins mending your injuries."))
active = 1
return 1
return 0
/obj/item/rig_module/protean/healing/deactivate()
if(!..(1))
return 0
var/mob/living/carbon/human/H = holder.wearer
if(H)
to_chat(usr, span_boldnotice("You deactivate the suit's restorative nanites."))
to_chat(H, span_warning("Your suit is no longer mending your injuries."))
active = 0
if(healing)
healing.expire()
healing = null
return 1
else
return 0
/obj/item/rig_module/protean/healing/process()
if(active)
var/mob/living/carbon/human/H = holder.wearer
var/mob/living/P = holder?:myprotean
if((istype(H.species, /datum/species/protean)) || !H || !P)
to_chat(H, span_warning("Your Protean modules do not function on yourself."))
deactivate()
return
var/obj/item/organ/internal/nano/refactory/R = P.nano_get_refactory()
if((!R.get_stored_material(MAT_STEEL)))
to_chat(H, span_warning("Your [holder] is out of steel."))
deactivate()
return
/obj/item/rig_module/protean/healing/accepts_item(var/obj/item/stack/material/steel/S, var/mob/living/user)
if(!istype(S) || !istype(user))
return 0
var/mob/living/P = holder?:myprotean
var/obj/item/organ/internal/nano/refactory/R = P?.nano_get_refactory()
if(R?.add_stored_material(S.material.name,1*S.perunit) && S.use(1))
to_chat(user, span_boldnotice("You directly feed some steel to the [holder]."))
return 1
return 0
+22 -7
View File
@@ -100,6 +100,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()
..()
@@ -538,7 +543,8 @@
offline = 0
if(istype(wearer) && !wearer.wearing_rig)
wearer.wearing_rig = src
slowdown = initial(slowdown)
if(!istype(src,/obj/item/rig/protean)) // Stupid snowflake protean special check for rig assimilation code
slowdown = initial(slowdown)
if(offline)
if(offline == 1)
@@ -914,15 +920,24 @@
wearer.lay_down()
to_chat(user, span_notice("\The [wearer] is now [wearer.resting ? "resting" : "getting up"]."))
/obj/item/rig/proc/forced_move(var/direction, var/mob/user)
/obj/item/rig/proc/forced_move(var/direction, var/mob/user, var/ai_moving = TRUE)
// Why is all this shit in client/Move()? Who knows?
if(world.time < wearer_move_delay)
return
if(!wearer || !wearer.loc || !ai_can_move_suit(user, check_user_module = 1))
if(!wearer || !wearer.loc) // Removed some stuff for protean living hardsuit
return
// 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.
// 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
if(wearer.transforming || !wearer.canmove)
return
@@ -953,9 +968,6 @@
to_chat(src, span_notice("Your host is pinned to a wall by [wearer.pinned[1]]!"))
return 0
// AIs are a bit slower than regular and ignore move intent.
wearer_move_delay = world.time + ai_controlled_move_delay
if(istype(wearer.buckled, /obj/vehicle))
//manually set move_delay for vehicles so we don't inherit any mob movement penalties
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm
@@ -980,7 +992,10 @@
wearer_move_delay += 2
return wearer.buckled.relaymove(wearer,direction)
cell.use(200) //Arbitrary, TODO
var/power_cost = 200
if(!ai_moving)
power_cost = 20
cell.use(power_cost) //Arbitrary, TODO
wearer.Move(get_step(get_turf(wearer),direction),direction)
// This returns the rig if you are contained inside one, but not if you are wearing it
+1 -1
View File
@@ -8,7 +8,7 @@ var/global/list/env_messages = list()
mouse_opacity = TRUE
anchored = TRUE
var/list/message_list = list()
var/combined_message = "You should not see this"
var/combined_message = DEVELOPER_WARNING_NAME
/obj/effect/env_message/Initialize(mapload)
.=..()
+3 -2
View File
@@ -3,7 +3,8 @@ GLOBAL_LIST_EMPTY(current_pending_diseases)
var/datum/disease/chosen_disease
var/list/disease_blacklist = list(
/datum/disease/advance,
/datum/disease/food_poisoning
/datum/disease/food_poisoning,
/datum/disease/gbs // Terrible. It's only in the code to scare people.
)
var/static/list/transmissable_symptoms = list()
var/static/list/diseases_minor = list()
@@ -44,7 +45,7 @@ GLOBAL_LIST_EMPTY(current_pending_diseases)
continue
if(!(A.z in using_map.station_levels))
continue
if(A.flags & RAD_SHIELDED)
if(A.flag_check(RAD_SHIELDED))
continue
if(isbelly(G.loc))
continue
+1 -1
View File
@@ -12,7 +12,7 @@
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
var/area/A = get_area(temp_vent)
if(A.forbid_events)
if(A.flag_check(AREA_FORBID_EVENTS))
continue
if(!temp_vent.welded && temp_vent.network && (temp_vent.loc.z in using_map.station_levels))
if(temp_vent.network.normal_members.len > 50)
+1 -1
View File
@@ -17,7 +17,7 @@
if(!(T.z in using_map.station_levels))
continue
var/area/A = get_area(T)
if(A.flags & RAD_SHIELDED || A.flags & BLUE_SHIELDED)
if(A.flag_check(RAD_SHIELDED | BLUE_SHIELDED))
continue
place_ian(T)
+1 -1
View File
@@ -37,7 +37,7 @@
if(!(S.z in affecting_z))
continue
var/area/A = get_area(S)
if(!A || A.flags & RAD_SHIELDED) // Rad shielding will protect from ions too
if(!A || A.flag_check(RAD_SHIELDED)) // Rad shielding will protect from ions too
continue
to_chat(S, span_warning("Your integrated sensors detect an ionospheric anomaly. Your systems will be impacted as you begin a partial restart."))
var/ionbug = rand(3, 9)
+22
View File
@@ -0,0 +1,22 @@
/datum/event/maintenance_lurker
startWhen = 1
endWhen = 30
/datum/event/maintenance_lurker/start()
var/obj/effect/landmark/spawnspot = null
var/list/possibleSpawnspots = list()
for(var/obj/effect/landmark/L in landmarks_list)
if(L.name == "maint_pred")
possibleSpawnspots += L
if(possibleSpawnspots.len)
spawnspot = pick(possibleSpawnspots)
else
kill() // To prevent fake announcements
return
if(!spawnspot)
kill() // To prevent fake announcements
return
new /obj/structure/ghost_pod/ghost_activated/maint_lurker(get_turf(spawnspot))
+1 -1
View File
@@ -39,7 +39,7 @@
var/area/A = get_area(C)
if(!A)
continue
if(A.flags & RAD_SHIELDED)
if(A.flag_check(RAD_SHIELDED))
continue
if(istype(C,/mob/living/carbon/human))
var/mob/living/carbon/human/H = C
+1 -1
View File
@@ -20,7 +20,7 @@
if(!temp_vent.welded && temp_vent.network && (temp_vent.loc.z in using_map.station_levels))
if(temp_vent.network.normal_members.len > 50)
var/area/A = get_area(temp_vent)
if(!(A.forbid_events))
if(!(A.flag_check(AREA_FORBID_EVENTS)))
vents += temp_vent
while((spawncount >= 1) && vents.len)
@@ -5,7 +5,7 @@
continue
if(!(A.z in using_map.station_levels))
continue
if(A.flags & RAD_SHIELDED)
if(A.flag_check(RAD_SHIELDED))
continue
if(isbelly(H.loc))
continue
+2 -2
View File
@@ -12,7 +12,7 @@
if(istype(candidate, /turf/simulated/wall))
center = candidate
var/area/A = get_area(candidate)
if(!A.forbid_events)
if(!A.flag_check(AREA_FORBID_EVENTS))
return 1
return 0
@@ -35,4 +35,4 @@
// Only rot up to severity walls
if(rotcount >= actual_severity)
break
break
+13 -1
View File
@@ -81,4 +81,16 @@
/obj/item/storage/box/glasses/coffeemug
name = "box of coffee mugs"
starts_with = list(/obj/item/reagent_containers/food/drinks/glass2/coffeemug = 7)
starts_with = list(/obj/item/reagent_containers/food/drinks/glass2/coffeemug = 7)
/obj/item/storage/box/glasses/coffeecup_tall
name = "box of tall cups"
starts_with = list(/obj/item/reagent_containers/food/drinks/tall = 7)
/obj/item/storage/box/glasses/coffeecup_grande
name = "box of grande cups"
starts_with = list(/obj/item/reagent_containers/food/drinks/grande = 7)
/obj/item/storage/box/glasses/coffeecup_venti
name = "box of venti cups"
starts_with = list(/obj/item/reagent_containers/food/drinks/venti = 7)
+6 -1
View File
@@ -17,7 +17,12 @@
icon_state = "cup_brown"
if(R.cup_name)
name = R.cup_name
var/prefix = " "
for(var/datum/reagent/S in reagents.reagent_list)
if(S.cup_prefix)
var/current_prefix = prefix
prefix = "[current_prefix][S.cup_prefix] "
name = "cup of[prefix][R.cup_name]"
else
name = "Cup of.. what?"
+150 -1
View File
@@ -67,7 +67,12 @@
icon_state = "cup_brown"
if(R.cup_name)
name = R.cup_name
var/prefix = " "
for(var/datum/reagent/S in reagents.reagent_list)
if(S.cup_prefix)
var/current_prefix = prefix
prefix = "[current_prefix][S.cup_prefix] "
name = "cup of[prefix][R.cup_name]"
else
name = "Cup of.. what?"
@@ -161,3 +166,147 @@
reagents.add_reagent(REAGENT_ID_IRON, 10)
reagents.add_reagent("protein", 15)
reagents.add_reagent(REAGENT_ID_WATER, 45)
////////////////Fancy coffee cups
/obj/item/reagent_containers/food/drinks/tall
name = "tall cup"
desc = "A larger coffee cup."
icon_state = "tall_cup_empty"
amount_per_transfer_from_this = 5
volume = 40
center_of_mass = list("x"=16, "y"=16)
/obj/item/reagent_containers/food/drinks/tall/on_reagent_change()
if (!length(reagents?.reagent_list))
icon_state = "tall_cup_empty"
name = "tall cup"
desc = "A larger coffee cup."
center_of_mass = list("x"=16, "y"=16)
return
var/datum/reagent/R = reagents.get_master_reagent()
if(R.cup_icon_state)
icon_state = "tall_[R.cup_icon_state]"
else
icon_state = "tall_cup_brown"
if(R.cup_name)
var/prefix = " "
for(var/datum/reagent/S in reagents.reagent_list)
if(S.cup_prefix)
var/current_prefix = prefix
prefix = "[current_prefix][S.cup_prefix] "
name = "tall[prefix][R.cup_name]"
else
name = "tall.. what?"
if(R.cup_desc)
desc = R.cup_desc
else
desc = "You can't really tell what this is."
if(R.cup_center_of_mass)
center_of_mass = R.cup_center_of_mass
else
center_of_mass = list("x"=16, "y"=16)
if(R.price_tag)
price_tag = R.price_tag
else
price_tag = null
/obj/item/reagent_containers/food/drinks/grande
name = "grande cup"
desc = "A much taller coffee cup for people who really need their coffee."
icon_state = "grande_cup_empty"
amount_per_transfer_from_this = 5
volume = 50
center_of_mass = list("x"=16, "y"=16)
/obj/item/reagent_containers/food/drinks/grande/on_reagent_change()
if (!length(reagents?.reagent_list))
icon_state = "grande_cup_empty"
name = "grande cup"
desc = "A much taller coffee cup for people who really need their coffee."
center_of_mass = list("x"=16, "y"=16)
return
var/datum/reagent/R = reagents.get_master_reagent()
if(R.cup_icon_state)
icon_state = "grande_[R.cup_icon_state]"
else
icon_state = "grande_cup_brown"
if(R.cup_name)
var/prefix = " "
for(var/datum/reagent/S in reagents.reagent_list)
if(S.cup_prefix)
var/current_prefix = prefix
prefix = "[current_prefix][S.cup_prefix] "
name = "grande[prefix][R.cup_name]"
else
name = "grande.. what?"
if(R.cup_desc)
desc = R.cup_desc
else
desc = "You can't really tell what this is."
if(R.cup_center_of_mass)
center_of_mass = R.cup_center_of_mass
else
center_of_mass = list("x"=16, "y"=16)
if(R.price_tag)
price_tag = R.price_tag
else
price_tag = null
/obj/item/reagent_containers/food/drinks/venti
name = "venti cup"
desc = "A huge coffee cup for people who literally cannot function without it."
icon_state = "venti_cup_empty"
amount_per_transfer_from_this = 5
volume = 60
center_of_mass = list("x"=16, "y"=16)
/obj/item/reagent_containers/food/drinks/venti/on_reagent_change()
if (!length(reagents?.reagent_list))
icon_state = "venti_cup_empty"
name = "venti cup"
desc = "A huge coffee cup for people who literally cannot function without it."
center_of_mass = list("x"=16, "y"=16)
return
var/datum/reagent/R = reagents.get_master_reagent()
if(R.cup_icon_state)
icon_state = "venti_[R.cup_icon_state]"
else
icon_state = "venti_cup_brown"
if(R.cup_name)
var/prefix = " "
for(var/datum/reagent/S in reagents.reagent_list)
if(S.cup_prefix)
var/current_prefix = prefix
prefix = "[current_prefix][S.cup_prefix] "
name = "venti[prefix][R.cup_name]"
else
name = "venti.. what?"
if(R.cup_desc)
desc = R.cup_desc
else
desc = "You can't really tell what this is."
if(R.cup_center_of_mass)
center_of_mass = R.cup_center_of_mass
else
center_of_mass = list("x"=16, "y"=16)
if(R.price_tag)
price_tag = R.price_tag
else
price_tag = null
+1 -1
View File
@@ -107,7 +107,7 @@ This allows for events that have their announcement happen after the end itself.
var/list/area/grand_list_of_areas = get_all_existing_areas_of_types(specific_areas)
. = list()
for(var/area/A as anything in shuffle(grand_list_of_areas))
if(A.forbid_events)
if(A.flag_check(AREA_FORBID_EVENTS))
continue
if(!(A.z in get_location_z_levels()))
continue
+2 -2
View File
@@ -196,7 +196,7 @@ Works together with spawning an observer, noted above.
if(!isturf(loc))
return
var/area/A = get_area(src)
if(A.block_ghosts)
if(A.flag_check(AREA_BLOCK_GHOSTS))
to_chat(src, span_warning("Ghosts can't enter this location."))
return_to_spawn()
@@ -452,7 +452,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
//RS Port #658 Start
var/area/A = get_area(destination)
if(A.block_ghosts)
if(A.flag_check(AREA_BLOCK_GHOSTS))
to_chat(src,span_warning("Sorry, that area does not allow ghosts."))
if(following)
stop_following()
+23
View File
@@ -373,3 +373,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')
+2 -2
View File
@@ -296,9 +296,9 @@
if(href_list["default_lang"])
if(href_list["default_lang"] == "reset")
if (species_language)
set_default_language(GLOB.all_languages[species_language])
apply_default_language(GLOB.all_languages[species_language])
else
set_default_language(GLOB.all_languages[LANGUAGE_GIBBERISH])
apply_default_language(GLOB.all_languages[LANGUAGE_GIBBERISH])
else
var/datum/language/L = locate(href_list["default_lang"])
if(L && (L in languages))
@@ -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()
+1 -1
View File
@@ -1631,7 +1631,7 @@
// Do this early so certain stuff gets turned off before vision is assigned.
var/area/A = get_area(src)
if(A?.no_spoilers)
if(A?.flag_check(AREA_NO_SPOILERS))
disable_spoiler_vision()
if(XRAY in mutations)
@@ -33,7 +33,7 @@
//RS Port #658 Start
var/area/A = get_area(src)
if(!client?.holder && A.block_phase_shift)
if(!client?.holder && A.flag_check(AREA_BLOCK_PHASE_SHIFT))
to_chat(src, span_warning("You can't do that here!"))
return
//RS Port #658 End
@@ -225,6 +225,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
@@ -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 valid_transform_species
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)
@@ -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,12 +78,13 @@
ear_secondary_style = ear_styles_list[pretty_ear_styles[new_ear_style]]
// Handle color picks
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]
var/default = LAZYACCESS(ear_secondary_colors, channel) || "#ffffff"
var/new_color = input(usr, "Pick [channel_name]", "Ear Color ([channel_name])", default) as color | null
new_colors += new_color || default
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]
var/default = LAZYACCESS(ear_secondary_colors, channel) || "#ffffff"
var/new_color = input(usr, "Pick [channel_name]", "Ear Color ([channel_name])", default) as color | null
new_colors += new_color || default
update_hair()
@@ -12,13 +12,15 @@
//appearance_flags = RADIATION_GLOWS
shock_resist = 0 // Lets not be immune to zaps.
friendly = list("nuzzles", "glomps", "snuggles", "cuddles", "squishes") // lets be cute :3
melee_damage_upper = 0
melee_damage_lower = 0
harm_intent_damage = 3
melee_damage_lower = 5
melee_damage_upper = 5
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 // brings in line with Proteans' own blob form.
var/mob/living/carbon/human/humanform
var/datum/modifier/healing
@@ -86,6 +88,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.
// 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
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)
@@ -368,25 +377,14 @@
drop_from_inventory(H)
things_to_drop -= H
for(var/obj/item/I in things_to_drop) //rip hoarders
drop_from_inventory(I)
if(w_uniform && istype(w_uniform,/obj/item/clothing)) //No webbings tho. We do this after in case a suit was in the way
var/obj/item/clothing/uniform = w_uniform
if(LAZYLEN(uniform.accessories))
for(var/obj/item/clothing/accessory/A in uniform.accessories)
if(is_type_in_list(A, disallowed_protean_accessories))
uniform.remove_accessory(null,A) //First param is user, but adds fingerprints and messages
//Size update
blob.transform = matrix()*size_multiplier
blob.size_multiplier = size_multiplier
if(l_hand) blob.prev_left_hand = l_hand //Won't save them if dropped above, but necessary if handdrop is disabled.
if(r_hand) blob.prev_right_hand = r_hand
if(l_hand) drop_from_inventory(l_hand)
if(r_hand) drop_from_inventory(r_hand)
//Put our owner in it (don't transfer var/mind)
blob.Weaken(2)
blob.transforming = TRUE
blob.ckey = ckey
blob.ooc_notes = ooc_notes
@@ -394,6 +392,7 @@
blob.ooc_notes_dislikes = ooc_notes_dislikes
blob.transforming = FALSE
blob.name = name
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)
@@ -411,6 +410,18 @@
remove_verb(blob, /mob/living/proc/ventcrawl) // Absolutely not.
remove_verb(blob, /mob/living/simple_mob/proc/set_name) // We already have a name.
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()
@@ -460,7 +471,6 @@
forceMove(reform_spot)
//Put our owner in it (don't transfer var/mind)
Weaken(2)
playsound(src.loc, "sound/effects/slime_squish.ogg", 15)
transforming = TRUE
ckey = blob.ckey
@@ -493,8 +503,15 @@
B.owner = src
//vore_organs.Cut()
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)
if(blob.l_hand) blob.drop_from_inventory(blob.l_hand)
if(blob.r_hand) blob.drop_from_inventory(blob.r_hand)
if(blob.mob_radio)
blob.mob_radio.forceMove(src)
blob.mob_radio = null
if(blob.myid)
blob.myid = null
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.
@@ -522,3 +539,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"
@@ -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,11 +16,11 @@
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")
@@ -34,22 +34,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 +73,88 @@
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)
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)
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 +174,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 +242,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 +277,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 +296,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 +309,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(. && 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))
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 +367,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,104 +391,115 @@
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)
buckled.unbuckle_mob()
if(LAZYLEN(buckled_mobs))
for(var/buckledmob in buckled_mobs)
riding_datum.force_dismount(buckledmob)
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
handle_grasp() //It's possible to blob out before some key parts of the life loop. This results in things getting dropped at null. TODO: Fix the code so this can be done better.
remove_micros(src, src) //Living things don't fare well in roblobs.
if(buckled)
buckled.unbuckle_mob()
if(LAZYLEN(buckled_mobs))
for(var/buckledmob in buckled_mobs)
riding_datum.force_dismount(buckledmob)
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
var/client/C = client
//Record where they should go
var/atom/creation_spot = drop_location()
//Record where they should go
var/atom/creation_spot = drop_location()
//Create our new blob
var/mob/living/simple_mob/protean_blob/blob = new(creation_spot,src)
//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.
//Size update
blob.transform = matrix()*size_multiplier
blob.size_multiplier = size_multiplier
/* 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
*/
//dir update
blob.dir = dir
things_to_drop -= things_to_not_drop //Crunch the lists
things_to_drop -= organs //Mah armbs
things_to_drop -= internal_organs //Mah sqeedily spooch
if(l_hand) drop_l_hand()
if(r_hand) drop_r_hand()
for(var/obj/item/I in things_to_drop) //rip hoarders
if(I.protean_drop_whitelist)
continue
drop_from_inventory(I)
//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
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()
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
//Mail them to nullspace
moveToNullspace()
//Size update
blob.transform = matrix()*size_multiplier
blob.size_multiplier = size_multiplier
//Message
blob.visible_message(span_infoplain(span_bold("[src.name]") + " collapses into a gooey blob!"))
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
//Duration of the to_puddle iconstate that the blob starts with
sleep(13)
blob.update_icon() //Will remove the collapse anim
//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
temporary_form = blob
//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()
//Mail them to nullspace
moveToNullspace()
//We can still speak our languages!
blob.languages = languages.Copy()
blob.name = real_name
blob.real_name = real_name
blob.voice_name = name
//Message
blob.visible_message(span_infoplain(span_bold("[src.name]") + " collapses into a gooey blob!"))
blob.update_icon(1)
//Duration of the to_puddle iconstate that the blob starts with
sleep(13)
blob.update_icon() //Will remove the collapse anim
//Flip them to the protean panel
addtimer(CALLBACK(src, PROC_REF(nano_set_panel), C), 4)
//Transfer vore organs
blob.vore_organs = vore_organs
blob.vore_selected = vore_selected
for(var/obj/belly/B as anything in vore_organs)
B.forceMove(blob)
B.owner = blob
//We can still speak our languages!
blob.languages = languages.Copy()
//Return our blob in case someone wants it
return blob
//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)
@@ -412,74 +508,126 @@ 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))
for(var/buckledmob in buckled_mobs)
riding_datum.force_dismount(buckledmob)
if(pulledby)
pulledby.stop_pulling()
stop_pulling()
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()
//Stop healing if we are
if(blob.healing)
blob.healing.expire()
//Play the animation
blob.icon_state = "from_puddle"
if(blob.mob_radio)
blob.mob_radio.forceMove(src)
blob.mob_radio = null
if(blob.myid)
blob.myid = null
//Message
blob.visible_message(span_infoplain(span_bold("[src.name]") + " reshapes into a humanoid appearance!"))
//Play the animation
blob.icon_state = "from_puddle"
//Duration of above animation
sleep(8)
//Message
blob.visible_message(span_infoplain(span_bold("[src.name]") + " reshapes into a humanoid appearance!"))
//Record where they should go
var/atom/reform_spot = blob.drop_location()
//Size update
resize(blob.size_multiplier, FALSE, TRUE, ignore_prefs = TRUE)
//Size update
resize(blob.size_multiplier, FALSE, ignore_prefs = TRUE)
//Duration of above animation
sleep(8)
//Move them back where the blob was
forceMove(reform_spot)
//Record where they should go
var/atom/reform_spot = blob.drop_location()
//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
temporary_form = null
//dir update
dir = blob.dir
//Transfer vore organs
vore_selected = blob.vore_selected
for(var/obj/belly/B as anything in blob.vore_organs)
B.forceMove(src)
B.owner = src
//Move them back where the blob was
forceMove(reform_spot)
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)
if(blob.l_hand) blob.drop_l_hand()
if(blob.r_hand) blob.drop_r_hand()
Life(1) //Fix my blindness right meow //Has to be moved up here, there exists a circumstance where blob could be deleted without vore organs moving right.
//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
temporary_form = null
//Get rid of friend blob
qdel(blob)
//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()
//Return ourselves in case someone wants it
return 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.
/mob/living/simple_mob/protean_blob/CanStumbleVore(mob/living/target)
if(target == humanform)
return FALSE
return ..()
//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
@@ -491,3 +639,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)
@@ -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
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.")
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!"))
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(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,300 @@
/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
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!"))
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)
/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"),
/*"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")*/
)
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
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."))
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
user.visible_message(span_notice("Black mist swirls around [user] as they change size."))
/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 +611,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 +653,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 +675,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
@@ -0,0 +1,609 @@
/*
proteans
*/
/obj/item/rig/protean
name = "nanosuit control cluster"
suit_type = "nanomachine"
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)
siemens_coefficient= 1
slowdown = 0
offline_slowdown = 0
seal_delay = 0
var/mob/living/myprotean
initial_modules = list(/obj/item/rig_module/protean/syphon, /obj/item/rig_module/protean/armor, /obj/item/rig_module/protean/healing)
helm_type = /obj/item/clothing/head/helmet/space/rig/protean //These are important for sprite pointers
boot_type = /obj/item/clothing/shoes/magboots/rig/protean
chest_type = /obj/item/clothing/suit/space/rig/protean
glove_type = /obj/item/clothing/gloves/gauntlets/rig/protean
protean = 1
offline_vision_restriction = 0
open = 1
cell_type = /obj/item/cell/protean
var/dead = 0
//interface_path = "RIGSuit_protean"
//ai_interface_path = "RIGSuit_protean"
var/sealed = 0
var/assimilated_rig
var/can_assimilate_rig = FALSE
/obj/item/rig/protean/relaymove(mob/user, var/direction)
if(user.stat || user.stunned)
return
forced_move(direction, user, 0)
/obj/item/rig/protean/check_suit_access(mob/living/user)
if(user == myprotean)
return 1
return ..()
/obj/item/rig/protean/digest_act(atom/movable/item_storage = null)
return 0
/obj/item/rig/protean/ex_act(severity)
return
/obj/item/rig/protean/New(var/newloc, var/mob/living/carbon/human/P)
if(P)
var/datum/species/protean/S = P.species
S.OurRig = src
if(P.back)
addtimer(CALLBACK(src, PROC_REF(AssimilateBag), P, 1, P.back), 3)
myprotean = P
else
to_chat(P, span_notice("You should have spawned with a backpack to assimilate into your RIG. Try clicking it with a backpack."))
..(newloc)
/obj/item/rig/protean/Destroy()
if(myprotean)
var/mob/living/carbon/human/P = myprotean
var/datum/species/protean/S = P?.species
S?.OurRig = null
myprotean = null
. = ..()
/obj/item/rig/proc/AssimilateBag(var/mob/living/carbon/human/P, var/spawned, var/obj/item/storage/backpack/B)
if(istype(B,/obj/item/storage/backpack))
if(spawned)
B = P.back
P.unEquip(P.back)
if(QDELETED(B)) // for mannequins or such
return
B.forceMove(src)
rig_storage = B
P.drop_item(B)
to_chat(P, span_notice("[B] has been integrated into the [src]."))
if(spawned) //This feels very dumb to have a second if but I'm lazy
P.equip_to_slot_if_possible(src, slot_back)
src.Moved()
else
to_chat(P,span_warning("Your rigsuit can only assimilate a backpack into itself. If you are seeing this message, and you do not have a rigsuit, tell a coder."))
/obj/item/rig/protean/verb/RemoveBag()
set name = "Remove Stored Bag"
set category = "Object"
if(rig_storage)
usr.put_in_hands(rig_storage)
rig_storage = null
else
to_chat(usr, "This Rig does not have a bag installed. Use a bag on it to install one.")
/obj/item/rig/protean/attack_hand(mob/user as mob)
if (src.loc == user)
if(rig_storage)
src.rig_storage.open(user)
else
..()
for(var/mob/M in range(1))
if (M.s_active == src)
src.rig_storage.close(M)
src.add_fingerprint(user)
return
/obj/item/clothing/head/helmet/space/rig/protean
name = "mass"
desc = "A helmet-shaped clump of nanomachines."
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 = '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 = '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 = 'icons/mob/head.dmi'
default_worn_icon = 'icons/mob/head.dmi'
/obj/item/clothing/gloves/gauntlets/rig/protean
name = "mass"
desc = "Glove-shaped clusters of nanomachines."
siemens_coefficient= 0
species_restricted = list(SPECIES_PROTEAN, SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJ, SPECIES_UNATHI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_PROMETHEAN, SPECIES_XENOHYBRID, SPECIES_VOX, SPECIES_TESHARI, SPECIES_VASILISSAN, SPECIES_XENOMORPH_HYBRID)
sprite_sheets = list(
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 = '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 = '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 = '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 = 'icons/mob/feet.dmi'
default_worn_icon = 'icons/mob/feet.dmi'
/obj/item/clothing/suit/space/rig/protean
name = "mass"
desc = "A body-hugging mass of nanomachines."
can_breach = 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)
allowed = list(
/obj/item/gun,
/obj/item/flashlight,
/obj/item/tank,
/obj/item/suit_cooling_unit,
/obj/item/melee/baton,
/obj/item/storage/backpack,
)
sprite_sheets = list(
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 = '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)
if(!istype(user))
return 0
if(dead)
switch(dead)
if(1)
if(W.is_screwdriver())
playsound(src, W.usesound, 50, 1)
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
to_chat(user, span_notice("You unscrew the maintenace panel on the [src]."))
dead +=1
return
if(2)
if(istype(W, /obj/item/protean_reboot))//placeholder
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
to_chat(user, span_notice("You carefully slot [W] in the [src]."))
dead +=1
qdel(W)
return
if(3)
if(istype(W, /obj/item/stack/nanopaste))
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
playsound(src, 'sound/effects/ointment.ogg', 50, 1)
to_chat(user, span_notice("You slather the interior confines of the [src] with the [W]."))
dead +=1
W?:use(1)
return
if(4)
if(istype(W, /obj/item/shockpaddles))
if(W?:can_use(user))
to_chat(user, span_notice("You hook up the [W] to the contact points in the maintenance assembly"))
if(do_after(user,50,src,exclusive = TASK_ALL_EXCLUSIVE))
playsound(src, 'sound/machines/defib_charge.ogg', 50, 0)
if(do_after(user,10,src))
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
playsound(src, 'sound/machines/defib_success.ogg', 50, 0)
new /obj/effect/gibspawner/robot(src.loc)
src.atom_say("Contact received! Reassembly nanites calibrated. Estimated time to resucitation: 1 minute 30 seconds")
addtimer(CALLBACK(src, PROC_REF(make_alive), myprotean?:humanform), 900)
return
if(istype(W,/obj/item/rig))
if(!assimilated_rig)
AssimilateRig(user,W)
if(istype(W,/obj/item/tank)) //Todo, some kind of check for suits without integrated air supplies.
if(air_supply)
to_chat(user, "\The [src] already has a tank installed.")
return
if(!user.unEquip(W))
return
air_supply = W
W.forceMove(src)
to_chat(user, "You slot [W] into [src] and tighten the connecting valve.")
return
// Check if this is a hardsuit upgrade or a modification.
else if(istype(W,/obj/item/rig_module))
if(!installed_modules)
installed_modules = list()
if(installed_modules.len)
for(var/obj/item/rig_module/installed_mod in installed_modules)
if(!installed_mod.redundant && istype(installed_mod,W))
to_chat(user, "The hardsuit already has a module of that class installed.")
return 1
var/obj/item/rig_module/mod = W
to_chat(user, "You begin installing \the [mod] into \the [src].")
if(!do_after(user,40))
return
if(!user || !W)
return
if(!user.unEquip(mod))
return
to_chat(user, "You install \the [mod] into \the [src].")
installed_modules |= mod
mod.forceMove(src)
mod.installed(src)
update_icon()
return 1
else if(W.is_wrench())
if(!air_supply)
to_chat(user, "There is no tank to remove.")
return
if(user.r_hand && user.l_hand)
air_supply.forceMove(get_turf(user))
else
user.put_in_hands(air_supply)
to_chat(user, "You detach and remove \the [air_supply].")
air_supply = null
return
else if(W.is_screwdriver())
var/list/possible_removals = list()
for(var/obj/item/rig_module/module in installed_modules)
if(module.permanent)
continue
possible_removals[module.name] = module
if(!possible_removals.len)
to_chat(user, "There are no installed modules to remove.")
return
var/removal_choice = tgui_input_list(usr, "Which module would you like to remove?", "Removal Choice", possible_removals)
if(!removal_choice)
return
var/obj/item/rig_module/removed = possible_removals[removal_choice]
to_chat(user, "You detach \the [removed] from \the [src].")
removed.forceMove(get_turf(src))
removed.removed()
installed_modules -= removed
update_icon()
return
for(var/obj/item/rig_module/module in installed_modules)
if(module.accepts_item(W,user)) //Item is handled in this proc
return
if(rig_storage)
var/obj/item/storage/backpack = rig_storage
if(backpack.can_be_inserted(W, 1))
backpack.handle_item_insertion(W)
else
if(istype(W,/obj/item/storage/backpack))
AssimilateBag(user,0,W)
..()
/obj/item/rig/protean/proc/make_alive(var/mob/living/carbon/human/H, var/partial)
if(H)
H.setToxLoss(0)
H.setOxyLoss(0)
H.setCloneLoss(0)
H.setBrainLoss(0)
H.SetParalysis(0)
H.SetStunned(0)
H.SetWeakened(0)
H.blinded = 0
H.SetBlinded(0)
H.eye_blurry = 0
H.ear_deaf = 0
H.ear_damage = 0
H.heal_overall_damage(H.getActualBruteLoss(), H.getActualFireLoss(), 1)
for(var/I in H.organs_by_name)
if(!H.organs_by_name[I] || istype(H.organs_by_name[I], /obj/item/organ/external/stump))
if(H.organs_by_name[I])
var/obj/item/organ/external/oldlimb = H.organs_by_name[I]
oldlimb.removed()
qdel(oldlimb)
var/list/organ_data = H.species.has_limbs[I]
var/limb_path = organ_data["path"]
var/obj/item/organ/external/new_eo = new limb_path(H)
new_eo.robotize(H.synthetic ? H.synthetic.company : null)
new_eo.sync_colour_to_human(H)
if(!partial)
dead_mob_list.Remove(H)
living_mob_list += H
H.tod = null
H.timeofdeath = 0
H.set_stat(CONSCIOUS)
if(istype(H.species, /datum/species/protean))
var/datum/species/protean/S
S = H.species
S.pseudodead = 0
to_chat(myprotean, span_notice("You have finished reconstituting."))
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
dead = 0
/obj/item/rig/protean/take_hit(damage, source, is_emp=0)
return //We don't do that here
/obj/item/rig/protean/emp_act(severity_class)
return //Same here
/obj/item/rig/protean/cut_suit()
return //nope
/obj/item/rig/protean/force_rest(var/mob/user)
wearer.lay_down()
to_chat(user, span_notice("\The [wearer] is now [wearer.resting ? "resting" : "getting up"]."))
/obj/item/cell/protean
name = "Protean power cell"
desc = "Something terrible must have happened if you're managing to see this."
maxcharge = 10000
charge_amount = 100
var/mob/living/carbon/human/charger
/obj/item/cell/protean/Initialize() //ChompEDIT New --> Initialize
charge = maxcharge
update_icon()
addtimer(CALLBACK(src, PROC_REF(search_for_protean)), 60)
/obj/item/cell/protean/proc/search_for_protean()
if(istype(src.loc, /obj/item/rig/protean))
var/obj/item/rig/protean/prig = src.loc
charger = prig.wearer
if(charger)
START_PROCESSING(SSobj, src)
/obj/item/cell/protean/process()
var/C = charge
if(charger)
if((world.time >= last_use + charge_delay) && charger.nutrition > 100)
give(charge_amount)
charger.nutrition -= ((1/200)*(charge - C)) //Take nutrition relative to charge. Change the 1/200 if you want to alter the nutrition to charge ratio
else
return PROCESS_KILL
/obj/item/rig/protean/equipped(mob/living/carbon/human/M)
..()
if(dead)
canremove = 1
else
canremove = 0
/obj/item/rig/protean/ai_can_move_suit(mob/user, check_user_module = 0, check_for_ai = 0)
if(check_for_ai)
return 0 //We don't do that here.
if(offline || !cell || !cell.charge || locked_down)
if(user)
to_chat(user, span_warning("Your host rig is unpowered and unresponsive."))
return 0
if(!wearer || (wearer.back != src && wearer.belt != src))
if(user)
to_chat(user, span_warning("Your host rig is not being worn."))
return 0
return 1
/obj/item/rig/protean/toggle_seals(mob/living/carbon/human/M, instant)
M = src.wearer
..()
/obj/item/rig/protean/toggle_cooling(mob/user)
user = src.wearer
..()
/obj/item/rig/protean/toggle_piece(piece, mob/living/carbon/human/H, deploy_mode, forced)
H = src.wearer
..()
/obj/item/rig/protean/get_description_interaction()
if(dead)
var/list/results = list()
switch(dead)
if(1)
results += "Use a screwdriver to start repairs."
if(2)
results += "Insert a Protean Reboot Programmer, printed from a protolathe."
if(3)
results += "Use some Nanopaste."
if(4)
results += "Use either a defib or jumper cables to start the reboot sequence."
return results
//Effectively a round about way of letting a Protean wear other rigs.
/obj/item/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))
to_chat(user, span_warning("The world is not ready for such a technological singularity."))
return
to_chat(user, span_notice("You assimilate the [R] into the [src]. Mimicking its stats and appearance."))
for(var/obj/item/piece in list(gloves,helmet,boots,chest))
piece.armor = R.armor.Copy()
piece.max_pressure_protection = R.max_pressure_protection
piece.max_heat_protection_temperature = R.max_heat_protection_temperature
//I dislike this piece of code, but not every rig has the full set of parts
if(R.gloves)
gloves.sprite_sheets = R.gloves.sprite_sheets.Copy()
gloves.sprite_sheets_obj = R.gloves.sprite_sheets.Copy()
gloves.icon = R.gloves.icon
gloves.icon_state = R.gloves.icon_state
gloves.default_worn_icon = R.gloves.default_worn_icon
if(R.helmet)
helmet.sprite_sheets = R.helmet.sprite_sheets.Copy()
helmet.sprite_sheets_obj = R.helmet.sprite_sheets.Copy()
helmet.icon = R.helmet.icon
helmet.icon_state = R.helmet.icon_state
helmet.default_worn_icon = R.helmet.default_worn_icon
if(R.boots)
boots.sprite_sheets = R.boots.sprite_sheets.Copy()
boots.sprite_sheets_obj = R.boots.sprite_sheets.Copy()
boots.icon = R.boots.icon
boots.icon_state = R.boots.icon_state
boots.default_worn_icon = R.boots.default_worn_icon
if(R.chest)
chest.sprite_sheets = R.chest.sprite_sheets.Copy()
chest.sprite_sheets_obj = R.chest.sprite_sheets.Copy()
chest.icon = R.chest.icon
chest.icon_state = R.chest.icon_state
chest.default_worn_icon = R.chest.default_worn_icon
suit_state = R.suit_state
name = R.name
icon = R.icon
icon_state = R.icon_state
user.drop_item(R)
contents += R
assimilated_rig = R
slowdown = (initial(R.slowdown) *0.5)
offline_slowdown = slowdown
/obj/item/rig/protean/verb/RemoveRig()
set name = "Remove Assimilated Rig"
set category = "Object"
if(assimilated_rig)
for(var/obj/item/piece in list(gloves,helmet,boots,chest))
piece.armor = armor.Copy()
piece.max_pressure_protection = initial(piece.max_pressure_protection)
piece.max_heat_protection_temperature = initial(piece.max_heat_protection_temperature)
piece.icon_state = src.icon_state
piece.icon = initial(piece.icon)
piece.default_worn_icon = initial(piece.default_worn_icon)
//Byond at this time does not support initial() on lists
//So we have to create a new rig, just so we can copy the lists we're after
//If someone figures out a smarter way to do this, please tell me
var/obj/item/rig/tempRig = new /obj/item/rig/protean()
gloves.sprite_sheets = tempRig.gloves.sprite_sheets.Copy()
gloves.sprite_sheets_obj = tempRig.gloves.sprite_sheets.Copy()
helmet.sprite_sheets = tempRig.helmet.sprite_sheets.Copy()
helmet.sprite_sheets_obj = tempRig.helmet.sprite_sheets.Copy()
boots.sprite_sheets = tempRig.boots.sprite_sheets.Copy()
boots.sprite_sheets_obj = tempRig.boots.sprite_sheets.Copy()
chest.sprite_sheets = tempRig.chest.sprite_sheets.Copy()
chest.sprite_sheets_obj = tempRig.chest.sprite_sheets.Copy()
slowdown = initial(slowdown)
name = tempRig.name
icon = tempRig.icon // Reset the icon back to its original
icon_state = tempRig.icon_state
suit_state = icon_state
offline_slowdown = initial(offline_slowdown)
usr.put_in_hands(assimilated_rig)
assimilated_rig = null
qdel(tempRig)
else
to_chat(usr, "[src] has not assimilated a RIG. Use one on it to assimilate.")
/obj/item/rig/protean/MouseDrop(obj/over_object as obj)
if(!canremove)
return
if (isliving(usr) || isobserver(usr))
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
return
if (!( istype(over_object, /obj/screen) ))
return ..()
if (!(src.loc == usr) || (src.loc && src.loc.loc == usr))
return
if (( usr.restrained() ) || ( usr.stat ))
return
if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src))
return
switch(over_object.name)
if("r_hand")
usr.unEquip(src)
usr.put_in_r_hand(src)
if("l_hand")
usr.unEquip(src)
usr.put_in_l_hand(src)
src.add_fingerprint(usr)
@@ -0,0 +1,128 @@
/*
It's a bit snowflake, but some rigsuit rewriting was necessary to achieved what I wanted
for protean rigsuits, and rolling these changes into the base RIGsuit code would definitely create
merge conflicts down the line.
So here it sits, snowflake code for a single item.
*/
/obj/item/rig/protean/tgui_state(mob/user)
return GLOB.tgui_always_state
/obj/item/rig/protean/tgui_data(mob/user)
var/list/data = list()
if(selected_module)
data["primarysystem"] = "[selected_module.interface_name]"
else
data["primarysystem"] = null
if(loc != user)
data["ai"] = TRUE
else
data["ai"] = FALSE
data["cooling"] = cooling_on
data["sealed"] = !sealed
data["sealing"] = sealing
data["helmet"] = (helmet ? "[helmet.name]" : "None.")
data["gauntlets"] = (gloves ? "[gloves.name]" : "None.")
data["boots"] = (boots ? "[boots.name]" : "None.")
data["chest"] = (chest ? "[chest.name]" : "None.")
data["helmetDeployed"] = (helmet && helmet.loc == loc)
data["gauntletsDeployed"] = (gloves && gloves.loc == loc)
data["bootsDeployed"] = (boots && boots.loc == loc)
data["chestDeployed"] = (chest && chest.loc == loc)
data["charge"] = cell ? round(cell.charge,1) : 0
data["maxcharge"] = cell ? cell.maxcharge : 0
data["chargestatus"] = cell ? FLOOR((cell.charge/cell.maxcharge)*50, 1) : 0
data["emagged"] = subverted
data["coverlock"] = locked
data["interfacelock"] = interface_locked
data["aicontrol"] = control_overridden
data["aioverride"] = ai_override_enabled
data["securitycheck"] = security_check_enabled
data["malf"] = malfunction_delay
var/list/module_list = list()
if(!canremove && !sealing)
var/i = 1
for(var/obj/item/rig_module/module in installed_modules)
var/list/module_data = list(
"index" = i,
"name" = "[module.interface_name]",
"desc" = "[module.interface_desc]",
"can_use" = module.usable,
"can_select" = module.selectable,
"can_toggle" = module.toggleable,
"is_active" = module.active,
"engagecost" = module.use_power_cost*10,
"activecost" = module.active_power_cost*10,
"passivecost" = module.passive_power_cost*10,
"engagestring" = module.engage_string,
"activatestring" = module.activate_string,
"deactivatestring" = module.deactivate_string,
"damage" = module.damage
)
if(module.charges && module.charges.len)
module_data["charges"] = list()
var/datum/rig_charge/selected = module.charges["[module.charge_selected]"]
module_data["realchargetype"] = module.charge_selected
module_data["chargetype"] = selected ? "[selected.display_name]" : "none"
for(var/chargetype in module.charges)
var/datum/rig_charge/charge = module.charges[chargetype]
module_data["charges"] += list(list("caption" = "[charge.display_name] ([charge.charges])", "index" = "[chargetype]"))
module_list += list(module_data)
i++
if(module_list.len)
data["modules"] = module_list
else
data["modules"] = list()
return data
/*
/obj/item/rig/protean/tgui_act(action, params)
switch(action)
if("toggle_seals")
toggle_seals(wearer)
. = TRUE
if("toggle_cooling")
toggle_cooling(wearer)
. = TRUE
if("toggle_ai_control")
to_chat(usr, span_notice("Proteans cannot be AI controlled."))
. = TRUE
if("toggle_suit_lock")
locked = !locked
. = TRUE
if("toggle_piece")
toggle_piece(params["piece"], wearer)
. = TRUE
if("interact_module")
var/module_index = text2num(params["module"])
if(module_index > 0 && module_index <= installed_modules.len)
var/obj/item/rig_module/module = installed_modules[module_index]
switch(params["module_mode"])
if("select")
selected_module = module
. = TRUE
if("engage")
module.engage()
. = TRUE
if("toggle")
if(module.active)
module.deactivate()
else
module.activate()
. = TRUE
if("select_charge_type")
module.charge_selected = params["charge_type"]
. = TRUE
*/
@@ -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,52 @@
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
virus_immune = 1
blood_volume = 0
min_age = 18
max_age = 200
brute_mod = 0.8
burn_mod = 1.5
oxy_mod = 0
item_slowdown_mod = 1.33
// male_scream_sound = null
// female_scream_sound = null
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
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
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
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
body_temperature = 290
siemens_coefficient = 1.5 //Very bad zappy times
rarity_value = 5
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
O_FACT = /obj/item/organ/internal/nano/refactory,
)
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable/nano),
@@ -85,7 +86,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 +95,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 +110,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 +149,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 +225,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,18 +238,22 @@
/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)
@@ -325,16 +395,26 @@
material_name = MAT_STEEL
/datum/modifier/protean/steel/tick()
holder.adjustBruteLoss(-1,include_robo = TRUE) //Modified by species resistances
holder.adjustFireLoss(-0.5,include_robo = TRUE) //Modified by species resistances
var/mob/living/carbon/human/H = holder
for(var/obj/item/organ/O as anything in H.internal_organs)
// Fix internal damage
if(O.damage > 0)
O.damage = max(0,O.damage-0.1)
// If not damaged, but dead, fix it
else if(O.status & ORGAN_DEAD)
O.status &= ~ORGAN_DEAD //Unset dead if we repaired it entirely
//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
@@ -357,6 +437,4 @@
. = ..()
. += validstring
. += registring
#undef DAM_SCALE_FACTOR
#undef METAL_PER_TICK
@@ -170,7 +170,7 @@
update_canmove()
weakened = 2
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"
+6
View File
@@ -28,3 +28,9 @@
S.sharer_died(gibbed)
. = ..()
/mob/living/proc/delayed_gib()
visible_message(span_danger(span_bold("[src]") + " starts convulsing violently!"), span_danger("You feel as if your body is tearing itself apart!"))
Weaken(30)
make_jittery(1000)
addtimer(CALLBACK(src, PROC_REF(gib)), rand(2 SECONDS, 10 SECONDS))
+11
View File
@@ -25,6 +25,17 @@
else
newitem.forceMove(S)
return S
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)
var/obj/item/storage/backpack = R.rig_storage
if(backpack.can_be_inserted(newitem, 1))
if(user_initiated)
backpack.handle_item_insertion(newitem)
else
newitem.forceMove(src.back)
return backpack
return 0
//Returns the thing in our active hand
+5
View File
@@ -613,6 +613,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)
+2 -44
View File
@@ -140,50 +140,8 @@
set desc = "Sets your voice style!"
set category = "OOC.Game Settings"
var/list/possible_voice_types = 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")
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
voice_sounds_list = get_talk_sound(choice)
+1 -29
View File
@@ -29,35 +29,7 @@
if(!voice_sounds_list.len || !voice_sounds_list)
if(client.prefs.voice_sound)
var/prefsound = client.prefs.voice_sound
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
voice_sounds_list = get_talk_sound(prefsound)
else
voice_sounds_list = talk_sound
//VOREStation Add End

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