From 369e1bdcc589d12d90426f2702610c438167bf43 Mon Sep 17 00:00:00 2001 From: Seris02 Date: Thu, 9 Feb 2023 11:53:23 +0800 Subject: [PATCH] adds the ability to turn into other people for proteans, and gives protean blobs their robot emotes back --- .../code/modules/client/preferences.dm | 1 + .../mob/living/carbon/human/human_helpers.dm | 138 ++++++++++++++++++ .../species/station/protean/protean_blob.dm | 5 + .../species/station/protean/protean_powers.dm | 79 +++++++++- .../station/protean/protean_species.dm | 1 + .../mob/species/protean/protean_powers.dmi | Bin 2407 -> 2578 bytes vorestation.dme | 1 + 7 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 modular_chomp/code/modules/mob/living/carbon/human/human_helpers.dm diff --git a/modular_chomp/code/modules/client/preferences.dm b/modular_chomp/code/modules/client/preferences.dm index 6c9af02123..63ca5acd26 100644 --- a/modular_chomp/code/modules/client/preferences.dm +++ b/modular_chomp/code/modules/client/preferences.dm @@ -186,6 +186,7 @@ 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"] diff --git a/modular_chomp/code/modules/mob/living/carbon/human/human_helpers.dm b/modular_chomp/code/modules/mob/living/carbon/human/human_helpers.dm new file mode 100644 index 0000000000..6f950f1762 --- /dev/null +++ b/modular_chomp/code/modules/mob/living/carbon/human/human_helpers.dm @@ -0,0 +1,138 @@ +/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 + for(var/name in BP_ALL) + 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 - Synthetic" + O.robotize(dsi_company) + + for(var/N in character.organs_by_name) + var/obj/item/organ/external/O = organs_by_name[N] + var/obj/item/organ/external/I = character.organs_by_name[N] + O.markings = I.markings.Copy() + + markings_len = character.markings_len + + descriptors = character.descriptors?.Copy() + + if (copy_flavour) + flavor_texts = character.flavor_texts?.Copy() + + weight = character.weight + weight_gain = character.weight_gain + weight_loss = character.weight_loss + fuzzy = character.fuzzy + offset_override = character.offset_override //CHOMPEdit + voice_freq = character.voice_freq + character.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() diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm index 8fef3aaa20..c26d3ca134 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_blob.dm @@ -180,6 +180,11 @@ /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/Stat() ..() if(humanform) diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm index 77a0cdbc2b..513979c618 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm @@ -130,12 +130,81 @@ to_chat(caller, "You begin to reassemble. You will need to remain still.") caller.visible_message("[caller] rapidly contorts and shifts!", "You begin to reassemble.") if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE)) - if(client.prefs) //Make sure we didn't d/c + if(caller.client.prefs) //Make sure we didn't d/c var/obj/item/weapon/rig/protean/Rig = species?:OurRig - caller.client.prefs.vanity_copy_to(caller, FALSE, flavour, oocnotes, TRUE) + 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("[caller] adopts a new form!", "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" + set hidden = 1 + var/mob/living/caller = src + if(temporary_form) + caller = temporary_form + + var/grabbing_but_not_enough + var/mob/living/carbon/human/victim = null + for(var/obj/item/weapon/grab/G in caller) + if(G.state < GRAB_AGGRESSIVE) + grabbing_but_not_enough = TRUE + return + else + victim = G.affecting + if (!victim) + if (grabbing_but_not_enough) + to_chat(caller, "You need a better grip to do that!") + else + to_chat(caller, "You need to be aggressively grabbing someone before you can copy their form.") + return + if (!istype(victim)) + to_chat(caller, "You can only perform this on human mobs!") + return + if (!victim.client) + to_chat(caller, "The person you try this on must have a client!") + return + + + to_chat(caller, "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, "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/weapon/grab/G in caller) + if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE) + checking = TRUE + if (!checking) + to_chat(caller, "You lost your grip on [victim]!") + return + + to_chat(caller, "You begin to reassemble into [victim]. You will need to remain still.") + caller.visible_message("[caller] rapidly contorts and shifts!", "You begin to reassemble into [victim].") + if(do_after(caller, 40,exclusive = TASK_ALL_EXCLUSIVE)) + checking = FALSE + for(var/obj/item/weapon/grab/G in caller) + if(G.affecting == victim && G.state >= GRAB_AGGRESSIVE) + checking = TRUE + if (!checking) + to_chat(caller, "You lost your grip on [victim]!") + return + if(caller.client) //Make sure we didn't d/c + var/obj/item/weapon/rig/protean/Rig = species?:OurRig + transform_into_other_human(victim, FALSE, flavour, TRUE) + species?:OurRig = Rig //Get a reference to our Rig and put it back after reassembling + caller.visible_message("[caller] adopts the form of [victim]!", "You have reassembled into [victim].") + //// // Storing metal //// @@ -491,4 +560,10 @@ 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 diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm index e94b767e84..55667c2f42 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_species.dm @@ -95,6 +95,7 @@ /mob/living/carbon/human/proc/nano_metalnom, /mob/living/carbon/human/proc/nano_blobform, /mob/living/carbon/human/proc/nano_rig_transform, + /mob/living/carbon/human/proc/nano_copy_body, /mob/living/carbon/human/proc/appearance_switch, /mob/living/carbon/human/proc/nano_latch, /mob/living/proc/set_size, diff --git a/modular_chomp/icons/mob/species/protean/protean_powers.dmi b/modular_chomp/icons/mob/species/protean/protean_powers.dmi index 3120d9d0ce1f0dde8723f8d0c5ed8fc85fa52543..efcd821a813507c566afa4be18c7e80062d41f98 100644 GIT binary patch delta 2003 zcmV;^2Q2vK5|R{fFDZ*Bkpc$|&VO$viB5C!0Ma*Ck)(!XstMJX=o6-qSG3?v;%ri!<3 zu*I$<-Mt4NkAca>wY*ieDDD*>wGV(#aS`X;p0f!QnOIIo&WwiM(5D2Fq+`q)i%rIv z0)HQ3J#f}}>GU^S#9>K4j%wcGE3)7=H&^5|Nt;w7+LzNw=AloTFafnDeZ2ffwK&X= z4!zrwxhU&m`N$i$*>b?(qGv?_00x~&L_t(&f$f?5d(%`H$8(yHw%dSCsoU5~EYe!3U0~8eTzWqzSC+Qe% z&Phv4ANgVLL-Q08zMu1c-*et}dl_al?rtE23af82nF>ijCYEChNI)z*h8x4O1tTDq z!%;W@gLu&A3t9x8FQh&~JTk+pPzbz-AOoX)#O0G9GI3C4&_^7Vz*{UCb}{{=s(veBYcwpCkWga0i)rb(``~Xv#YACZ+?D z`eXvalCVp)G9n59Zd<VE{N##E}YtT|p*`MJprCBgl;k(ALj#Ma4y=BoOQ##9BDD zjMy)-ikSvL+VV@(48RDKo&|IXWPipb#$`m*eqrWl04oOxl#DIG3Ou3Zfc^Lst2fMu zdY)(&VSDh}NFCr~O%b-;49 z*N>=^c9MlR)5~ZK&=9IF;&m0i1%P8pEn^bE=Fx1iMbt8CVWu6_>;Rk!FnU?{J#NOhsdvthWeb^?DH$5AwVr)o@E>jdW;)C&Q@A_pS9F>{{)l00QwJAnX_ikaZa2&Z$9NQmn&Dm_zLHYEL?I`=Sr}a*JR_8 zYeBWk?RMt?SXj9z3zuB3T7MucuFC=OaQ%|ZF1e}~)Vf?Q_fkOIDd3U%hKw$`s%y0( zyWLBv1kvO5h=hOlIUmjB64oDnPbG*BzsK(&5E`A2C0%M-*1UZAMd+*-}$BL7#waD};@j0zHFgozH15ZCkzl`Hqekw(n@3wev*+ zz}B|aMh7sW-{bK3Mg5JJ>UU`_?cVe9-hG{2n_t^?e;1S{tfLQvkJE zAJPEsx}`)wyVvXYdi6DCJcsKwm)Fzvw^!VGS-&x^wqylP3S}837Ab5&Jf<7a?J5O_|wSVWmu0zL;cb{Ij<^6G~ z&tO8bRZ#VrfLKHXFdAC zM74wr9_p-Mgkwo}hmSck4Pzfis5c z(wvzeZ~0{Zr+=R{%&7WYB0uN8^G}1}0GB4!Py1p~)9f#&eKq%-NO>%$&rCJIr75S@ z9xf~Yy6l@%=cdZJ>d+&^3Zc;a^QLc2=j}=X^haYf?uodk=L;9Y7cOMf&ttw2{_gwU zUPD488p&h6(04HwkHvd08R#bxiAc`#g|;7JafsgDAAf0xNTR>Le;^vkalX)YIj%*l zw~zQh6zfA=iAHkK9|6Q;SAQY`2Ktk6B|=X@y6s8>#4leB8v+ank|5o>>Igp%1Fl{F zrO^m5FhC{9vLZ>6A`?GqepRa+zwulA=I;c+FkxVzAKp<3il7K&eddo?{N@eVN7t_R z5dkO)>VH50`DlUykc6?KAQ#KTuM>TLLJBu7#;*Ou#vIbgLZq`Pq`|f9}XK{e}pz)0D?%<2hCvcpJ34buiZX~BNc%-6or!< z!7uuJL6&3%Uc`H#>cf(-_8`3V`3BPfEQ&;+9e+iP<_n-ND&!JieP43X_CenuGnh)q zZoV)iNZ`^C8Q}AU!%2Y82iJ5!7V`zHkN*$|+M<&LyDvQQms^A^<_klLESwi)g$%%p zP6F)VurEztWn`K!;0jB)&KWYmg@(5zfZ==rK>#F%!Ln`qTqfFN#p=9oG*aoU=Z$g(CvUB-T8OGO!Ec!I8!7= l7!u$ri#h!KM42!A2ag>PR)jk|bN~PV00>D%PDHLkV1k)o!%+YL delta 1830 zcmV+>2if?N6z39&}1udlDMv9VTGR<5qD#l^+O#>P=m zQLU}5TwGkVw6v380y%$#P|RHb0004WQchCV=- z0C=2*&`k=$Fc1acb#jW(?!~{Y8)=a)>>W}wHUo)MlCj0x8>-Y*&F($;cnnjjbA4%A zRb3l7LWoEYbyCO8R*DG?+f)vFDJ)=b`BNfmh7^m=QCCP|FvNdUcT(Jg_VCS)XqeNF zlX{Y_85bY{!9KuU$|HDA zzX+fA=Fu1EzYOjmuV}TY2!&>>6E`s%kkzLX5SD~4C1pem0G#x(Ey4hBph%z<0=t4d zJ|8I~%Ol8*2_Wm|g`(mjS`rAl2k}0^DkJubuHt0@5LteSl>r!mhGqd%0(o(XaTyVF zUU&r-z%PG50wv>1u!2Y#Ibc8D#nuTgV(urFMc5v^wi3|x!)~><><|Jt@3UqRNU(Q{ z$Y?@5iFuwE2Zp^4K5O+k`UFbFs18_e&H8)lv`+GgUUnIC0|>&>MWU_3cLA_XnPtoZ z_yUG4wuo6q5?|cmQQZc7%nMF4G@;qIzT*Jw>-Z~ zO4Wbj8bwjUD*!Q4z$10_d0kSfYDkg8;T24R8i__!%Fkn=NAtOa_4}VQ32IP_Xh900 zA@o?*rN)&_t5!X}va$M!CkK0^EVlFm0gJGV3W#f3uqdc$aod?hXf<(Z&D!Rto?f@U zWo_d#8+1wnf!5XlJB7A372bKOZEchcRuX@gR&U(2dCS&qo0_**mrb%K5ZD0`V5Y#% z;Mve~#HF3_6WNC5;|cLdk~PSqm8h^E?4yi~WBxU_Ho%Lfj2bZ&cP z=b9-K?EsFm9AW~Xha&K>pIA~km$-E3aC_&GBOP7chhD7=&;UDf0-_O3(;`v(iQs>p zYT{DM;nzBjzJ9QMb4z_?=^#K2nL`8+u3bR|v_+#@G-|Ig7dci(Tzcbpd&h~Brw$x% ze)IGoz_8ksi=WYoB4_M1=H5EHfwy|X$L91N(rH%eIv03lMWQuI0f z-G#)ZmhSgDkDff$b#CMK_a_X#1`~g>qk^f=#nmDzfJ^ekrF|c4?dt3}aDIPF{ple9 z&YGn#t!tMt^&x|{2o=!pQq#r@Th4!Ye%J0*b1FU>dI=uamOOiy#^Yz=3;=Oyc~kSc z3*GzI@7p_T+9dl$cv{yo3Y<4Am*&s;c>5=ZKK-nIcID?f{krhTUk&;LT$+DcH}i|7 zjq|>o`PG7pD&sOoubEbWOViJ8I94|K>#}doUYub#)nP}Hmy^jwmptEkE=i^f`eQK` zW05Z|r!HT1Q$O|H_dPu>5_+$sGwDpvRk!q8e@JH_dU}3z3DJ5jLn7VN>nvxYf!q0#GfEzb|X>bTI3{%&2)1bc8{AyJ>bL+Rv?cbdOIKz}p znXb?Mk0e3e!{G#B=!OXo>N!x2VM$nf0-k@yVtoz(ps$+r z5@7vUcF|H_tdHw+LbxOA;L;sBAQnrdvVd3&jt&4=AAeB@WYJlI6ieOvW<&tfkT1!G zNeAFXX8}?w6?34^;R@@x&Q!pFMN1el@-9M90998FL#KT1IPa|K zZj)Kf?`(Gwb%gu^)E8>hWkVP2x4H0|3;DRyy3M7_vTCTZtm~tGXPw;UGUOywI4MJ~ z+HZ3e2*9_w@Fp`&Jg*^%(Y|>PmV-ff*1@y`hCcfLV*)Q{rf$l2WH=h?=>7flAL;9@ U+_