From bfe8bfe263d5db2522b88eeddd3995b4eda74f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schr=C3=B6dinger?= <132720404+Schrodinger71@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:47:58 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=D0=97=D0=B0=D0=BA=D0=B8=D0=BD=D1=83=D0=BB?= =?UTF-8?q?=20=D1=82=D0=B5=D0=BB=D0=B5=D1=81=D0=BA=D0=BE=D0=BF=D0=B8=D1=87?= =?UTF-8?q?=D0=BA=D1=83=20(#111)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Описание PR **Медиа** **Проверки** - [x] PR полностью завершён и мне не нужна помощь чтобы его закончить. - [x] Я внимательно просмотрел все свои изменения и багов в них не нашёл. - [x] Я запускал локальный сервер со своими изменениями и всё протестировал. - [x] Я добавил скриншот/видео демонстрации PR в игре, **или** этот PR этого не требует. **Изменения** no cl --- .../SwitchableWeaponSystem.cs | 83 +++++++++++ .../SwitchableWeaponComponent.cs | 51 +++++++ .../Weapons/Melee/close_telescopichka.ogg | Bin 0 -> 18437 bytes .../Weapons/Melee/open_telescopichka.ogg | Bin 0 -> 13639 bytes .../Entities/Objects/Weapons/Melee/melee.ftl | 9 ++ .../Weapons/Melee/telescopic_baton.yml | 135 ++++++++++++++++++ .../Melee/telescopic_baton.rsi/meta.json | 33 +++++ .../telescopic_baton.rsi/off-inhand-left.png | Bin 0 -> 218 bytes .../telescopic_baton.rsi/off-inhand-right.png | Bin 0 -> 213 bytes .../telescopic_baton.rsi/on-inhand-left.png | Bin 0 -> 371 bytes .../telescopic_baton.rsi/on-inhand-right.png | Bin 0 -> 374 bytes .../telescopic_baton.rsi/telescope_off.png | Bin 0 -> 374 bytes .../telescopic_baton.rsi/telescope_on.png | Bin 0 -> 615 bytes .../Melee/telescopic_baton_bob.rsi/meta.json | 33 +++++ .../off-inhand-left.png | Bin 0 -> 171 bytes .../off-inhand-right.png | Bin 0 -> 173 bytes .../on-inhand-left.png | Bin 0 -> 837 bytes .../on-inhand-right.png | Bin 0 -> 939 bytes .../telescope_off.png | Bin 0 -> 236 bytes .../telescopic_baton_bob.rsi/telescope_on.png | Bin 0 -> 289 bytes .../Melee/telescopic_baton_kon.rsi/meta.json | 33 +++++ .../off-inhand-left.png | Bin 0 -> 170 bytes .../off-inhand-right.png | Bin 0 -> 172 bytes .../on-inhand-left.png | Bin 0 -> 830 bytes .../on-inhand-right.png | Bin 0 -> 934 bytes .../telescope_off.png | Bin 0 -> 222 bytes .../telescopic_baton_kon.rsi/telescope_on.png | Bin 0 -> 252 bytes 27 files changed, 377 insertions(+) create mode 100644 Content.Server/ADT/SwitchableWeapon/SwitchableWeapon/SwitchableWeaponSystem.cs create mode 100644 Content.Shared/ADT/SwitchableWeapon/SwitchableWeaponComponent.cs create mode 100644 Resources/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg create mode 100644 Resources/Audio/ADT/Entities/Objects/Weapons/Melee/open_telescopichka.ogg create mode 100644 Resources/Locale/ru-RU/ADT/Entities/Objects/Weapons/Melee/melee.ftl create mode 100644 Resources/Prototypes/ADT/Entities/Objects/Weapons/Melee/telescopic_baton.yml create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/meta.json create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-left.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/off-inhand-right.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-left.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-right.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_off.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_on.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/meta.json create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-left.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-right.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-left.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-right.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_off.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_on.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/meta.json create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-left.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-right.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-left.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-right.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_off.png create mode 100644 Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/telescope_on.png diff --git a/Content.Server/ADT/SwitchableWeapon/SwitchableWeapon/SwitchableWeaponSystem.cs b/Content.Server/ADT/SwitchableWeapon/SwitchableWeapon/SwitchableWeaponSystem.cs new file mode 100644 index 0000000000..f359681cf5 --- /dev/null +++ b/Content.Server/ADT/SwitchableWeapon/SwitchableWeapon/SwitchableWeaponSystem.cs @@ -0,0 +1,83 @@ +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Events; +using Content.Shared.Examine; +using Content.Shared.Interaction.Events; +using Content.Shared.Item; +using Content.Shared.ADT.SwitchableWeapon; +using Content.Shared.Toggleable; +using Content.Shared.Weapons.Melee.Events; +using Robust.Shared.Audio.Systems; + +namespace Content.Server.ADT.SwitchableWeapon; + +public sealed class SwitchableWeaponSystem : EntitySystem +{ + [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(Toggle); + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnStaminaHitAttempt); + SubscribeLocalEvent(OnGetMeleeDamage); + SubscribeLocalEvent(OnComponentAdded); + } + + private void OnComponentAdded(EntityUid uid, SwitchableWeaponComponent component, ComponentAdd args) + { + UpdateState(uid, component); + } + + //Non-stamina damage + private void OnGetMeleeDamage(EntityUid uid, SwitchableWeaponComponent component, ref GetMeleeDamageEvent args) + { + args.Damage = component.IsOpen ? component.DamageOpen : component.DamageFolded; + } + + private void OnStaminaHitAttempt(EntityUid uid, SwitchableWeaponComponent component, ref StaminaDamageOnHitAttemptEvent args) + { + if (!component.IsOpen) + return; + + //args.HitSoundOverride = component.BonkSound; + } + + private void OnExamined(EntityUid uid, SwitchableWeaponComponent comp, ExaminedEvent args) + { + var msg = comp.IsOpen + ? Loc.GetString("comp-switchable-examined-on") + : Loc.GetString("comp-switchable-examined-off"); + args.PushMarkup(msg); + } + + private void UpdateState(EntityUid uid, SwitchableWeaponComponent comp) + { + if (TryComp(comp.Owner, out var item)) + { + _item.SetSize(item.Owner, comp.IsOpen ? comp.SizeOpened : comp.SizeClosed, item); + _item.SetHeldPrefix(comp.Owner, comp.IsOpen ? "on" : "off", false, item); + } + + if (TryComp(comp.Owner, out var appearance)) + _appearance.SetData(comp.Owner, ToggleVisuals.Toggled, comp.IsOpen, appearance); + + // Change stamina damage according to state + if (TryComp(uid, out var stamComp)) + { + stamComp.Damage = comp.IsOpen ? comp.StaminaDamageOpen : comp.StaminaDamageFolded; + } + } + + private void Toggle(EntityUid uid, SwitchableWeaponComponent comp, UseInHandEvent args) + { + comp.IsOpen = !comp.IsOpen; + UpdateState(uid, comp); + + var soundToPlay = comp.IsOpen ? comp.OpenSound : comp.CloseSound; + _audio.PlayPvs(soundToPlay, args.User); + } +} diff --git a/Content.Shared/ADT/SwitchableWeapon/SwitchableWeaponComponent.cs b/Content.Shared/ADT/SwitchableWeapon/SwitchableWeaponComponent.cs new file mode 100644 index 0000000000..c4020bcd5a --- /dev/null +++ b/Content.Shared/ADT/SwitchableWeapon/SwitchableWeaponComponent.cs @@ -0,0 +1,51 @@ + +using Content.Shared.Damage; +using Content.Shared.Item; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Shared.ADT.SwitchableWeapon; + +[RegisterComponent] +public sealed partial class SwitchableWeaponComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite)][DataField("damageFolded")] + public DamageSpecifier DamageFolded = new(){ + DamageDict = new() + { + { "Blunt", 0.0f }, + } + }; + + [ViewVariables(VVAccess.ReadWrite)][DataField("damageOpen")] + public DamageSpecifier DamageOpen = new(){ + DamageDict = new() + { + { "Blunt", 4.0f }, + } + }; + + [ViewVariables(VVAccess.ReadWrite)][DataField("staminaDamageFolded")] + public float StaminaDamageFolded = 0; + + [ViewVariables(VVAccess.ReadWrite)][DataField("staminaDamageOpen")] + public float StaminaDamageOpen = 28; + + [ViewVariables(VVAccess.ReadWrite)][DataField("isOpen")] + public bool IsOpen = false; + + [ViewVariables(VVAccess.ReadWrite)][DataField("openSound")] + public SoundSpecifier? OpenSound; + + [ViewVariables(VVAccess.ReadWrite)][DataField("closeSound")] + public SoundSpecifier? CloseSound; + + [ViewVariables(VVAccess.ReadWrite)][DataField("bonkSound")] + public SoundSpecifier? BonkSound; + + [ViewVariables(VVAccess.ReadWrite)][DataField("sizeOpened")] + public ProtoId SizeOpened = "Normal"; + + [ViewVariables(VVAccess.ReadWrite)][DataField("sizeClosed")] + public ProtoId SizeClosed = "Normal"; +} diff --git a/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg b/Resources/Audio/ADT/Entities/Objects/Weapons/Melee/close_telescopichka.ogg new file mode 100644 index 0000000000000000000000000000000000000000..227ce64529df87f4302ef3c5e848939d65324fc6 GIT binary patch literal 18437 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�(~Dy|$vT%6X;yX{>&E{wc0x+g2I zdvTINIXo_3pgvf?HvJYKFrVqcpJFMbp?LBM`4M7&W)pPp&l_j6GnG@esgtP|sDI$s zy!joe@EUF18MAs(wb;v*wi8vFa_26mce!>Xr8%A9Bd`86U#{Ad#60^|GmDf+?{AOy zH7Ch;Y5H`V{dVi|nH@W|G|eNc&Cr0v`r4pRQyG;``bNL+ntuM^_&hVAF6`rTY5Czc ziZX+VKB?cJgE!L-MZqB3VTM7^j5FYBQgTxL4V0dqvD7hC(zmglO< zRLHmrLh^WECWq0YqIi(Q+4fm3@~$WwpnuHw_!VJQuc zK?u%OqcN-FcVlAeas;*MJ!IK0kQw*B@HSsF%wYD?4hNyudW3cM^b}`8cjwHmat~pRAaGoxg5?*yQ0|X z?cuna=4~pe=DHLm<;|xNpm5rs?R)=ho3{2Ek-_IM3iS|i&DeX)$EMIChb-{E2mQ~m zYMMA-`JkrG#V=CqeFMc|z8Uqy5Hj(CB~^r+{;D|=xs4LGcKLuBM#iDGuu*yMZ|t5g z{bMErscD4xFiQ*tt)mEvmR)cHTb)SKSBu+qR4;rYUJ^ZoI{V-;w>d;UT&W-{9R-3N z<6%(ef74dhY*yzA_XOXE7JDB~cSeP}M&fwA*{}p)CME~Ho!L1y=Xbw0XF>yIi!vNU zCzD5UpV`i_T$N0f%w%jtVOr8bZ$7j=Mchr&d;11g7;lNd;^qbPkoIelvbw~gL44a- z=H3F?AK~{~ z<@DAEk6b(TfO&<<0mzuFcbd{1=cSlzd{VXCXGy~B&$`)VNQU@J*(B_nYm*|l7U_Xv z@C!#^J?vx7uXXkiq?eMD?j`HQ2En76gYQ&HkY1ilR69j72EIZ)ka)KOY%+!L@xt%m zqbHi0q(9URe@Eu`=ThM(m%DGmMp|EYw9>DX_nw*MEv)J2%WB~325so$FG}AEy372S zFXh(y?8HlW!WjRH2~WeVn3whBlbluU66_e|>lJy34AGJo+ZnX!Hv>;v>$KS{(qS#% z&UZ6vr#s1y!4^#%9T;+={!;>*M+ zO_&n`g!9gIo(PtzUJS~{$Ueuf zRdyOoR#PVesKNuBXPA&ef-QuDhw1%LXo00NlJMv$WXNh`=JpWhbD>3C9l#%6xgjWt zS!^tkXM#gKK=~SAds$WX?xrI3itO#ri!4$}RWw<=1#FT`zCWbT8GEM(EIHo7qZN>Z z(M}(ClqZ)%I^7R1iAW}Hc+)4ScbdA45?$l!SWVQ7r>LXpjL^ejMaIJf4W9mL_a!e` zxDqQZtQ!=5ySvZQR+)2OSZ)OU{_5I-PN(R?I|b%PK-P|Fh-5FeAV4l}`zf725t17! z)c?jdSp_*a2O9{vsoo;qKC>f{%+NZ{tQ$6EmeA9Uf&@6a#CXt$OP!lUh8~F7`*BZd zPp;p53=jNn$ob> zxPfncv@cTVqHbT>1#A?}9@r6yW^{b&D_wK@;b-SpqIxX%$k_4>YpB!m^2v*s_tLZ^ zA3xQaJVpSh(r!J|gczu;4A5dI{hjg?d9V^f*6!Y@s(3}3=%sJ88lfhuVOdu;>iL)6 z;g6(#$bbEte$sQ)HQQxnunn>$7za7lVX z!_f%|hAMX?S|4hNE~x70>e{t7E7kdu?uLhZna}wAJM}jbq~Ag2`ctuQ`x1Lk+qXS) zm3)?ZuC1_3$SKs^v*qW-vf7T)l2G%7Z+}e?PmNMMGDSRfhyA=vmV#H)nSgp37#b$u z+$8b5z0(e0P_ zEZK1^;Hqz+;+E@q`zvo}Pydyuqt>u0FUY!_c1)00000Y^vK%^~0#9#`MFe>b9F4W7?0ag$~EFxZNLVJck7Kq|RHElEd>i;F(Y`s6oUv_(`Ol>;dY}IZrRTL*-9fC7vfV4@X_w}9zvz!aHhqG=ny9%M~s19ZId1FqJC&w`860002si=O|*u@nAy RwEF-6002ovPDHLkV1oPJsPq5; literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/on-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..9cea4086c4c9a93fc26e466f4e2ddd844566c946 GIT binary patch literal 374 zcmV-+0g3*JP)OTF(f7&ivw@~ZsDejE*^yeCKincVCcYBCzCh6Ab&!u#qVc> zK+-<#Z+adf00000RI*lCQL0a`Lx-#=RVC|xdt3Z{xZdt!e>j<2l|lQ%NnCID?hlXW zOJk*MR>@i&&zJstij#CUQOJr?#Yx(_mqpXdC=A5PU+P0#8vGh`h*!<9b#V!C!BtTd%*~sO>JYrT~uXsqHROlNP}ym8_MP8*5t( z0000000000y0!J-hcY>*@U}BFRPP>q2P@|k2KV4QST(26)q@|)M00kM2#oH*cd%kk zp^~+h(|`KvIR#x;|CP=tjE;cgdMYn+Em!~5SI#Mz?!ntOr!ZeXJ9z;B0Dzf!0Dg(F U6J*Eor~m)}07*qoM6N<$f^p8Hod5s; literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_off.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton.rsi/telescope_off.png new file mode 100644 index 0000000000000000000000000000000000000000..e0875d24f54fe089bdf5f796ce590168cdb563e2 GIT binary patch literal 374 zcmV-+0g3*JP)zXw%6n?Q z;AnrhjP#j{kXE}R-H(Cn>>bGA>3OEOi8AD2wI+T*SX*7e-Tec$H`Wm+uaYHpvZ$Q2 zk-7N=D5a1JaC3c$v=YGk9C*#=$6w6(w-naq0ES+x{`6D^CQl9T%Pm$aY-n zH#16FLKt;od}@Bi)YK93g^$%WflC)F#;qII$L`e?$#qP@C0 zK#iqk1^*ds;nBkfI$k{zs^HaHUClicMV%NQgO(QfKV{(8&JJdZ#XW7e9XC4z)43e2 zhZ|aEJ~o8R;<$77J{A_v<5+H*<}3360AKj{y$j?02a$f@n8nEx0Y#mdY{#W)t*$L_ zV@FUb&r!a>uz2M%8cWN#cl#zL{l+KJ$jgXXoQgB2VVWj-1iXCl9KE9j7`w6Y?#+r8 z14A=VD$fyP3{pxk#sC0PN^G|!bFijI-tBD>#I~>@j1A`}*QUXW^ z4h)2lS)7t~GsY0MnyJEpz78;pQ|Zhs!d4Uc0#gs930DS~#c2?lFR;|%K;HclKg%;E(6y#xLW{Q=WjC;S0I8lV6G002ovPDHLkV1mXk B5VrYytPe=(BGKvfLWY`=dEtJ6QS?!~mn%dh^J_SoNb zyT!4WC&b)AvJ4Cj^H2QPul+q;LNX-pkBDGcUQJrSFT+dBT_y|+TRt)dv72pNX~Xjq Oq}0>Z&t;ucLK6T0YdIwV literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/off-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..95b859847c16c6c8488b97e596a2561ea9486ea7 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|(mh=qLn`LH zy}6OM!GOp0pw5v~JSUj~c6zmnBt_rx{jhJUUNTS_!+|GO{noo5_AcFf_gK5?-Pq&p z@%vi*tyjx0tda-GGcc4)`N$vs?tOlGz|N0}?h!jb&UAcv+=E}^5(C49d(4kg%{G=k RwD}8C>FMg{vd$@?2>|hlKjHuY literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..10512d90a31f6c20f827ffcb92ae6a793bd068e4 GIT binary patch literal 837 zcmV-L1G@Z)P)VLLewHIXO5f001bFV_;x1aCC8UWfEXu$jvJ$3UYT+h=`0*U_Z~m#=y(~28qeV z1&#p$J|K2peqJgA2KaW3fe}Ps)&-e`DUTO$B^MNx0O>zKY?P8(oXo($XaHnqmzNX( z#Tn-S*&<2VVD<(OyC@{c8OS~YWb>s%*jGU8BnbNnh+PEq1d#m&q&^+YX5s*w17XX6 z*d?hIAbS~{^9w4AGSf3k6bvmbEfpM7@{>{(f-8$lQge$HJoA$Ciwg3K5=&B3fNCM` z0|P;bLQsfl05w`@lIU-O02B`p*5^QQ_%e!}L5Lwha%oW+l*!0sOqh=_V~zv^ga1+n z29`evF_T^fh6Oqd4E$3OVrqsA3*GWV{RCt{2nlVnp zKoCX05kkAgx=m@M2-yueL~cTx3-}C_P^2U`;R1A2X;P#BDU{yAh-N9kQLqAXvO5e& z|4ETjMB_g%iCydm2qArIv-TOSbt)49pKZvX&(F$q;w9X!J?CSi3w3IN2G z2ZRIwAECQ%@1Z_BNP=HXg7*!kbF*E%ZCjC?A_CUy_4a-DYZxk_zkJ)aV#@F;as;bKFXH9sh^8n!6|Fm;CfHy3cOUY3Rq;Bo`3d3m8gw%+_7+ z&tQz%_IjGT%TShO^4?H$cNv~;icpp%j4@Gp#cqO!_5y~ouRjn&askKm0*2CGKE)Bb z=;^Sv7DZ9ue)bxi%cG9P_mw9)*)gZX;spt7Eu6bZGOsI7>@H6TAtZu#pt5DQX0Lt{ P00000NkvXXu0mjf0cTZw literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/on-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..f150a01e584155cf44a5cfa94e281316363ce306 GIT binary patch literal 939 zcmV;c162HpP)VLLewHIXO5f001bFV_;x1aCC8UWfEXu$jvJ$3UYT+h=`0*U_Z~m#=y(~28qeV z1&#p$J|K2peqJgA2KaW3fe}Ps)&-e`DUTO$B^MNx0O>zKY?P8(oXo($XaHnqmzNX( z#Tn-S*&<2VVD<(OyC@{c8OS~YWb>s%*jGU8BnbNnh+PEq1d#m&q&^+YX5s*w17XX6 z*d?hIAbS~{^9w4AGSf3k6bvmbEfpM7@{>{(f-8$lQge$HJoA$Ciwg3K5=&B3fNCM` z0|P;bLQsfl05w`@lIU-O02B`p*5^QQ_%e!}L5Lwha%oW+l*!0sOqh=_V~zv^ga1+n z29`evF_T^fh6Oqd4E$3OVrqsA3E0 z%$V1QE2oqiWM+83wRZ1XEXU%!K3ut?m|(k{_R@XO06*9ek=9xO|HP(B-jChI_2Mlv zW{2y=Th=FDrvYX?cK~3_4!5hkS1@8Wo7JBw`BYWl$L@lX-!7-ltmp2~Gpz=g_1sb7 zeVq(ZN;Q71@H{479|Qe0s2ZLYUph^wlcNp7PaXiY)_Z~bhz*}N zQhGYZzBWFzr%mpDHD2jU|D-4;06zYUENdEY^pDWFBL;8_ z;6@DK7Ql@dz%76qF@ReDH(~&{0B*zpZUNkg0o($(5d*jda3cnA3*bf!;1>gHe{e$*P?tU_u=x5lUp zx65hWf==06^gGtnst1|_7egu`d25Uo_gm1ZDj{sw`)iJwH}FZ;9Bms$7*h#dvkJ5p z5SRQ(o1@2u5&9A)UsYAIIf0O529Q9lHNxFG28z*DMW-@E5Cq{<@du5M%a>;z);<6L N002ovPDHLkV1fhSk~aVV literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_off.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_off.png new file mode 100644 index 0000000000000000000000000000000000000000..a456a690e96dfddba04a181be1cec07d2ec9b614 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}%RF5iLn2y} z6C_v{Cy4Yk1sZU<9n_FuRcY}5T=L()N9>QkuklQejWz%7sq+Leo#DAs!V<{musTX2i2Ht zoYTnYE~4;z&a`R91__-^Pb`*)Zct_xY0jMc;Dc3yf=+sZLl+b0y!*Ugw#l#_=(-7X h!OEyBeN0Xa44tKE7iMtX*$#9ugQu&X%Q~loCIGH`SQY>P literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_on.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_bob.rsi/telescope_on.png new file mode 100644 index 0000000000000000000000000000000000000000..0df0ef1f98034ccefffe2dcd38b725bb93b8fa52 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}w>@1PLn2y} z6C_v{C#W=By{Ys+JiYtRakb+v*{AK#UOt*-7<*uOrY&v&+3VjU gCNtwystYrNS=sUOOI{u=KyNa5y85}Sb4q9e05^VjlK=n! literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/meta.json b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/meta.json new file mode 100644 index 0000000000..9ce465ccac --- /dev/null +++ b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/meta.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "license": "CC-BY-3.0", + "copyright": "Sprited by mixnikita", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "telescope_on" + }, + { + "name": "telescope_off" + }, + { + "name": "off-inhand-left", + "directions": 4 + }, + { + "name": "off-inhand-right", + "directions": 4 + }, + { + "name": "on-inhand-left", + "directions": 4 + }, + { + "name": "on-inhand-right", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-left.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..be086e63ecc0e65cc482c10f61eabe8b7ff5aa47 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|QaoK8Ln`LH zz3C}pPy<7RK$>Q+xU6(&%FZ67e)8QmpzW|+b??e zk;Hc8Xc$C-{Vk9+WITw-9jaE$#zf=Z_Pro|xp O7(8A5T-G@yGywoDz&jlP literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/off-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..431831404ed4a711a1a3d480219b2c67812b5710 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|(mY)pLn`LH zy}6P1fC7)JV_U+1R-=@lonEaj8`j?O{jksVxCBrc!-t}?mFebdZrr+^TXW;m-O`#L zPrZL^+5Agz)ptgaJcEO~P)VLLewHIXO5f001bFV_;x1aCC8UWfEXu$jvJ$3UYT+h=`0*U_Z~m#=y(~28qeV z1&#p$J|K2peqJgA2KaW3fe}Ps)&-e`DUTO$B^MNx0O>zKY?P8(oXo($XaHnqmzNX( z#Tn-S*&<2VVD<(OyC@{c8OS~YWb>s%*jGU8BnbNnh+PEq1d#m&q&^+YX5s*w17XX6 z*d?hIAbS~{^9w4AGSf3k6bvmbEfpM7@{>{(f-8$lQge$HJoA$Ciwg3K5=&B3fNCM` z0|P;bLQsfl05w`@lIU-O02B`p*5^QQ_%e!}L5Lwha%oW+l*!0sOqh=_V~zv^ga1+n z29`evF_T^fh6Oqd4E$3OVrqsA3&`Cr=RCt{2nz3ra zP!xv$loIZROeQX7a7;>`$v1KIO&l%wCf%&A4vtO=fh@N}n_z>M=)I?>h5v(qgPi>5 zGu{m60E7@i2qA?0k+wWa}d$V4kMYrfC2G+dOw=S>9b^o9AwsBo2UB^MH^5;4^gl z>#a|xyCiJ$+-;f$^EB-muj^VQr-*?4e&2m=pN63l`pwsME!I3BB%mL9sDys=mm;Nj zmMnfLp)AX2aXh;9>Er<1{7+YL3;@{ec9PLLf*&ro-pkfnyp2W<0A3DP@V%k;$;7R)%oRleV~kf`u|x3Qy?~)y+aK^DxPV9Y0*2CWKEw!JbUJLU#dJEw z;&^mb9D9w$uPslsvVEq*;tLYiT2!M^kb3Qjf7v`Cgb)ut0LzG5H$7`SR{#J207*qo IM6N<$f<1s-)Bpeg literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-right.png b/Resources/Textures/ADT/Objects/Weapons/Melee/telescopic_baton_kon.rsi/on-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..199b35af1e1ef9a655ab8bb45a390e8c7ca9f942 GIT binary patch literal 934 zcmV;X16lluP)VLLewHIXO5f001bFV_;x1aCC8UWfEXu$jvJ$3UYT+h=`0*U_Z~m#=y(~28qeV z1&#p$J|K2peqJgA2KaW3fe}Ps)&-e`DUTO$B^MNx0O>zKY?P8(oXo($XaHnqmzNX( z#Tn-S*&<2VVD<(OyC@{c8OS~YWb>s%*jGU8BnbNnh+PEq1d#m&q&^+YX5s*w17XX6 z*d?hIAbS~{^9w4AGSf3k6bvmbEfpM7@{>{(f-8$lQge$HJoA$Ciwg3K5=&B3fNCM` z0|P;bLQsfl05w`@lIU-O02B`p*5^QQ_%e!}L5Lwha%oW+l*!0sOqh=_V~zv^ga1+n z29`evF_T^fh6Oqd4E$3OVrqsA3h1+oRH1`4WCY1M0(jwhAp$l=!Euf>q(n@ZY0!_4DuN}wUFbL+W z{1eZfIT`;*Gk_onf*=TjAP9mW2!imtP_*HkyVxRHYglV97C+>1xpbSlR=e05@U)w*YR$0B!-?hymOJxDf-m1#lwF52S=<6?{^(&1M_0YZ?H+)9vkGAAS!0tU_vLx5lUpw|RbS zL8t63`W?O5ylcGUsct`#_WBQkYFMEsZV9s!4-gA^P8& z_wj8ml9E|B&mZvUds;JHU-*i<&H-sAgVXlqdzN=TtzgtS_*F0QhkanchyUuav8&YV z7U|^A^sGK@*fjZCVc&JeFWY2}GBPJxb}_4gtl9olgJIf-7qf1;Gcq$XGc4-LSheWQ S=iNXzGI+ZBxvXPx#wn;=mR9J=W);|iuFcb#xuXb<|;YlXx72csdQZ@&{0|XBvy+U!8?BzLSNG+{H z{(ybon&I~)d5{1a%@*Q}5oe6dt?hE-o_Q8763;Bo7^zZ1am5u^{6BHeES4xK{_|tx zndLqVIJYfc-ef-YTDv3Eaeo#70000 Date: Wed, 10 Jul 2024 01:43:15 +0300 Subject: [PATCH 2/4] Drask (#28) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Перенос драска no cl --------- Co-authored-by: Schrödinger <132720404+Schrodinger71@users.noreply.github.com> --- Content.Shared/Humanoid/NamingSystem.cs | 5 + .../Humanoid/Prototypes/SpeciesPrototype.cs | 3 + Resources/Audio/ADT/Drask/draskcough.ogg | Bin 0 -> 11493 bytes Resources/Audio/ADT/Drask/draskscream.ogg | Bin 0 -> 21043 bytes Resources/Audio/ADT/Drask/drasksneeze.ogg | Bin 0 -> 15147 bytes Resources/Audio/ADT/Drask/drasktalk.ogg | Bin 0 -> 21172 bytes Resources/Locale/en-US/species/namepreset.ftl | 3 + .../Chemistry}/metabolizer-types.ftl | 1 + .../ru-RU/ADT/Entities/Mobs/Player/drask.ftl | 2 + .../ru-RU/ADT/Entities/Mobs/Species/drask.ftl | 5 + Resources/Locale/ru-RU/ADT/Species/drask.ftl | 13 ++ .../Prototypes/ADT/Body/Organs/Drask.yml | 103 ++++++++++ Resources/Prototypes/ADT/Body/Parts/Drask.yml | 190 ++++++++++++++++++ .../Prototypes/ADT/Body/Prototypes/Drask.yml | 49 +++++ .../{ => ADT}/Chemistry/metabolizer_types.yml | 6 + .../Prototypes/ADT/Damage/ADTmodifiers.yml | 190 ++++++++++++++++++ .../ADT/Datasets/Names/name_drask.yml | 20 ++ .../Mobs/Customization/Markings/Drask.yml | 43 ++++ .../ADT/Entities/Mobs/Species/Drask.yml | 81 ++++++++ .../ADT/Entities/Mobs/player/Drask.yml | 46 +++++ .../ADT/SoundCollections/emotes.yml | 16 ++ Resources/Prototypes/ADT/Species/drask.yml | 158 +++++++++++++++ .../ADT/Voice/speech_emote_sounds.yml | 67 ++++++ .../Prototypes/ADT/Voice/speech_sounds.yml | 8 + Resources/Prototypes/Reagents/gases.yml | 6 + .../ADT/Mobs/Drask/custom.rsi/l_arm.png | Bin 0 -> 20744 bytes .../ADT/Mobs/Drask/custom.rsi/meta.json | 19 ++ .../ADT/Mobs/Drask/custom.rsi/r_arm.png | Bin 0 -> 20744 bytes .../ADT/Mobs/Drask/organs.rsi/eyes.png | Bin 0 -> 4394 bytes .../ADT/Mobs/Drask/organs.rsi/heart_on.png | Bin 0 -> 12895 bytes .../ADT/Mobs/Drask/organs.rsi/innards.png | Bin 0 -> 4691 bytes .../ADT/Mobs/Drask/organs.rsi/kidneys.png | Bin 0 -> 4405 bytes .../ADT/Mobs/Drask/organs.rsi/lungs.png | Bin 0 -> 4691 bytes .../ADT/Mobs/Drask/organs.rsi/meta.json | 33 +++ .../ADT/Mobs/Drask/parts.rsi/eyes.png | Bin 0 -> 20744 bytes .../ADT/Mobs/Drask/parts.rsi/full.png | Bin 0 -> 4691 bytes .../ADT/Mobs/Drask/parts.rsi/head_f.png | Bin 0 -> 17035 bytes .../ADT/Mobs/Drask/parts.rsi/head_m.png | Bin 0 -> 17035 bytes .../ADT/Mobs/Drask/parts.rsi/l_arm.png | Bin 0 -> 4580 bytes .../ADT/Mobs/Drask/parts.rsi/l_foot.png | Bin 0 -> 4484 bytes .../ADT/Mobs/Drask/parts.rsi/l_hand.png | Bin 0 -> 5148 bytes .../ADT/Mobs/Drask/parts.rsi/l_leg.png | Bin 0 -> 17035 bytes .../ADT/Mobs/Drask/parts.rsi/meta.json | 66 ++++++ .../ADT/Mobs/Drask/parts.rsi/r_arm.png | Bin 0 -> 4557 bytes .../ADT/Mobs/Drask/parts.rsi/r_foot.png | Bin 0 -> 4477 bytes .../ADT/Mobs/Drask/parts.rsi/r_hand.png | Bin 0 -> 5139 bytes .../ADT/Mobs/Drask/parts.rsi/r_leg.png | Bin 0 -> 17035 bytes .../ADT/Mobs/Drask/parts.rsi/torso_f.png | Bin 0 -> 5414 bytes .../ADT/Mobs/Drask/parts.rsi/torso_m.png | Bin 0 -> 5188 bytes 49 files changed, 1133 insertions(+) create mode 100644 Resources/Audio/ADT/Drask/draskcough.ogg create mode 100644 Resources/Audio/ADT/Drask/draskscream.ogg create mode 100644 Resources/Audio/ADT/Drask/drasksneeze.ogg create mode 100644 Resources/Audio/ADT/Drask/drasktalk.ogg rename Resources/Locale/ru-RU/{metabolism => ADT/Chemistry}/metabolizer-types.ftl (92%) create mode 100644 Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/drask.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/drask.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Species/drask.ftl create mode 100644 Resources/Prototypes/ADT/Body/Organs/Drask.yml create mode 100644 Resources/Prototypes/ADT/Body/Parts/Drask.yml create mode 100644 Resources/Prototypes/ADT/Body/Prototypes/Drask.yml rename Resources/Prototypes/{ => ADT}/Chemistry/metabolizer_types.yml (88%) create mode 100644 Resources/Prototypes/ADT/Damage/ADTmodifiers.yml create mode 100644 Resources/Prototypes/ADT/Datasets/Names/name_drask.yml create mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/Drask.yml create mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Species/Drask.yml create mode 100644 Resources/Prototypes/ADT/Entities/Mobs/player/Drask.yml create mode 100644 Resources/Prototypes/ADT/SoundCollections/emotes.yml create mode 100644 Resources/Prototypes/ADT/Species/drask.yml create mode 100644 Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml create mode 100644 Resources/Prototypes/ADT/Voice/speech_sounds.yml create mode 100644 Resources/Textures/ADT/Mobs/Drask/custom.rsi/l_arm.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/custom.rsi/meta.json create mode 100644 Resources/Textures/ADT/Mobs/Drask/custom.rsi/r_arm.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/organs.rsi/eyes.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/organs.rsi/heart_on.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/organs.rsi/innards.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/organs.rsi/kidneys.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/organs.rsi/lungs.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/organs.rsi/meta.json create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/eyes.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/full.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_f.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_m.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_arm.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_foot.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_hand.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_leg.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/meta.json create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_arm.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_foot.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_hand.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_leg.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_f.png create mode 100644 Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_m.png diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index 825eca17cf..a563d39639 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -35,6 +35,11 @@ public string GetName(string species, Gender? gender = null) case SpeciesNaming.FirstDashFirst: return Loc.GetString("namepreset-firstdashfirst", ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender))); + // Start ADT Tweak: Drask naming + case SpeciesNaming.FirstDashFirstDashFirst: + return Loc.GetString("namepreset-firstdashfirstdashfirst", + ("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender)), ("first3", GetFirstName(speciesProto, gender))); + // End ADT Tweak case SpeciesNaming.FirstLast: default: return Loc.GetString("namepreset-firstlast", diff --git a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs index e91785114c..1405c4b5a9 100644 --- a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs @@ -140,5 +140,8 @@ public enum SpeciesNaming : byte First, FirstLast, FirstDashFirst, + // ADT Start tweak: Drask naming + FirstDashFirstDashFirst, + // ADT End tweak TheFirstofLast, } diff --git a/Resources/Audio/ADT/Drask/draskcough.ogg b/Resources/Audio/ADT/Drask/draskcough.ogg new file mode 100644 index 0000000000000000000000000000000000000000..613f5ddb399ab7edd619a7b78171d11d1b55810f GIT binary patch literal 11493 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 ZUf>pRt8Rn9ga2H=$p2-w>D@J9%&>c& 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ℑuWw%4dz|UZwNUpeml5+oH!_ZO5zvy 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 Yhfl}=OY{Lhljw9?o6UUfb5zv-15L;HDgXcg literal 0 HcmV?d00001 diff --git a/Resources/Audio/ADT/Drask/drasktalk.ogg b/Resources/Audio/ADT/Drask/drasktalk.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8a22bf3545bff71886c0b1eb75af6cadeb1a5156 GIT binary patch literal 21172 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 B3^@P* literal 0 HcmV?d00001 diff --git a/Resources/Locale/en-US/species/namepreset.ftl b/Resources/Locale/en-US/species/namepreset.ftl index 5a42c87b78..092d0b6d62 100644 --- a/Resources/Locale/en-US/species/namepreset.ftl +++ b/Resources/Locale/en-US/species/namepreset.ftl @@ -1,4 +1,7 @@ namepreset-first = {$first} namepreset-firstlast = {$first} {$last} namepreset-firstdashfirst = {$first1}-{$first2} +# Start ADT tweak: Drask +namepreset-firstdashfirstdashfirst = { $first1 }-{ $first2 }-{ $first3 } +# End ADT tweak namepreset-thefirstoflast = The {$first} of {$last} diff --git a/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl b/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl similarity index 92% rename from Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl rename to Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl index 7a17abf365..ff10a218e1 100644 --- a/Resources/Locale/ru-RU/metabolism/metabolizer-types.ftl +++ b/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl @@ -9,3 +9,4 @@ metabolizer-type-plant = Растение metabolizer-type-dwarf = Дварф metabolizer-type-moth = Ниан metabolizer-type-arachnid = Арахнид +metabolizer-type-drask = Драск diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/drask.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/drask.ftl new file mode 100644 index 0000000000..19a7093e9f --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/drask.ftl @@ -0,0 +1,2 @@ +ent-MobDrask = { ent-BaseMobDrask } + .desc = { ent-BaseMobDrask.desc } diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/drask.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/drask.ftl new file mode 100644 index 0000000000..1d985504e9 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/drask.ftl @@ -0,0 +1,5 @@ +ent-BaseMobDrask = Урист МакДраск + .desc = { ent-BaseMobSpeciesOrganic.desc } + .suffix = Драск +ent-MobDraskDummy = { ent-BaseSpeciesDummy } + .desc = { ent-BaseSpeciesDummy.desc } diff --git a/Resources/Locale/ru-RU/ADT/Species/drask.ftl b/Resources/Locale/ru-RU/ADT/Species/drask.ftl new file mode 100644 index 0000000000..6f61062aef --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Species/drask.ftl @@ -0,0 +1,13 @@ +species-name-drask = Драск +marking-DraskArmRight = правая рука +marking-DraskArmLeft = левая рука +ent-OrganDraskEyes = глаза + .desc = Я тебя вижу! +ent-OrganDraskLungs = лёгкие + .desc = Фильтрует кислород из атмосферы, который затем поступает в кровь для использования в качестве переносчика электронов. +ent-OrganDraskHeart = сердце + .desc = Мне жаль того бессердечного ублюдка, который его потерял. +ent-OrganDraskInnards = внутренности + .desc = Мерзость. +ent-OrganDraskKidneys = почки + .desc = Выводят токсины из кровеносной системы. diff --git a/Resources/Prototypes/ADT/Body/Organs/Drask.yml b/Resources/Prototypes/ADT/Body/Organs/Drask.yml new file mode 100644 index 0000000000..53a6c3b096 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Organs/Drask.yml @@ -0,0 +1,103 @@ +- type: entity + id: OrganDraskEyes + parent: BaseHumanOrgan + suffix: "drask" + name: eyes + description: "I see you!" + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: eyes + +- type: entity + id: OrganDraskLungs + parent: BaseHumanOrgan + suffix: "drask" + name: lungs + description: "Filters oxygen from an atmosphere, which is then sent into the bloodstream to be used as an electron carrier." + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: lungs + - type: Lung + - type: Metabolizer + removeEmpty: true + solutionOnBody: false + solution: "Lung" + metabolizerTypes: [ Drask ] + groups: + - id: Gas + rateModifier: 100.0 + - type: SolutionContainerManager + solutions: + organ: + reagents: + - ReagentId: Nutriment + Quantity: 10 + Lung: + maxVol: 100.0 + canReact: false + food: + maxVol: 5 + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 5 + +- type: entity + id: OrganDraskHeart + parent: BaseHumanOrgan + suffix: "drask" + name: heart + description: "I feel bad for the heartless bastard who lost this." + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: heart_on + - type: Metabolizer + maxReagents: 2 + metabolizerTypes: [ Drask ] + groups: + - id: Medicine + - id: Poison + - id: Narcotic + +- type: entity + id: OrganDraskInnards + parent: BaseHumanOrgan + suffix: "drask" + name: innards + description: "Ew innards." + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: innards + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 50 + food: + maxVol: 5 + reagents: + - ReagentId: UncookedAnimalProteins + Quantity: 5 + - type: Stomach + - type: Metabolizer + maxReagents: 3 + metabolizerTypes: [ Drask ] + groups: + - id: Food + - id: Drink + +- type: entity + id: OrganDraskKidneys + parent: BaseHumanOrgan + suffix: "drask" + name: kidneys + components: + - type: Sprite + sprite: ADT/Mobs/Drask/organs.rsi + state: kidneys + - type: Metabolizer + maxReagents: 5 + metabolizerTypes: [ Drask ] + removeEmpty: true diff --git a/Resources/Prototypes/ADT/Body/Parts/Drask.yml b/Resources/Prototypes/ADT/Body/Parts/Drask.yml new file mode 100644 index 0000000000..bceb64a62b --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Parts/Drask.yml @@ -0,0 +1,190 @@ +# TODO: Add descriptions (many) +# TODO BODY: Part damage +- type: entity + id: PartDrask + parent: BaseItem + name: "drask body part" + abstract: true + components: + - type: Damageable + damageContainer: Biological + - type: BodyPart + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + +- type: entity + id: TorsoDrask + name: "drask torso" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "torso_m" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "torso_m" + - type: BodyPart + partType: Torso + +- type: entity + id: HeadDrask + name: "drask head" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "head_m" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "head_m" + - type: BodyPart + partType: Head + vital: true + - type: Input + context: "ghost" + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: InputMover + - type: GhostOnMove + - type: Tag + tags: + - Head + +- type: entity + id: LeftArmDrask + name: "left drask arm" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_arm" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_arm" + - type: BodyPart + partType: Arm + symmetry: Left + +- type: entity + id: RightArmDrask + name: "right drask arm" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_arm" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_arm" + - type: BodyPart + partType: Arm + symmetry: Right + +- type: entity + id: LeftHandDrask + name: "left drask hand" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_hand" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_hand" + - type: BodyPart + partType: Hand + symmetry: Left + +- type: entity + id: RightHandDrask + name: "right drask hand" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_hand" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_hand" + - type: BodyPart + partType: Hand + symmetry: Right + +- type: entity + id: LeftLegDrask + name: "left drask leg" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_leg" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_leg" + - type: BodyPart + partType: Leg + symmetry: Left + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: RightLegDrask + name: "right drask leg" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_leg" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_leg" + - type: BodyPart + partType: Leg + symmetry: Right + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: LeftFootDrask + name: "left drask foot" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_foot" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "l_foot" + - type: BodyPart + partType: Foot + symmetry: Left + +- type: entity + id: RightFootDrask + name: "right drask foot" + parent: PartDrask + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_foot" + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: "r_foot" + - type: BodyPart + partType: Foot + symmetry: Right diff --git a/Resources/Prototypes/ADT/Body/Prototypes/Drask.yml b/Resources/Prototypes/ADT/Body/Prototypes/Drask.yml new file mode 100644 index 0000000000..cdf4b04568 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Prototypes/Drask.yml @@ -0,0 +1,49 @@ +- type: body + name: "drask" + id: Drask + root: torso + slots: + head: + part: HeadDrask + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganDraskEyes + heart: OrganDraskHeart + torso: + part: TorsoDrask + organs: + lungs: OrganDraskLungs + stomach: OrganDraskInnards + liver: OrganHumanLiver + kidneys: OrganDraskKidneys + connections: + - left arm + - right arm + - left leg + - right leg + right arm: + part: RightArmDrask + connections: + - right hand + left arm: + part: LeftArmDrask + connections: + - left hand + right hand: + part: RightHandDrask + left hand: + part: LeftHandDrask + right leg: + part: RightLegDrask + connections: + - right foot + left leg: + part: LeftLegDrask + connections: + - left foot + right foot: + part: RightFootDrask + left foot: + part: LeftFootDrask diff --git a/Resources/Prototypes/Chemistry/metabolizer_types.yml b/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml similarity index 88% rename from Resources/Prototypes/Chemistry/metabolizer_types.yml rename to Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml index 3f7bf05b35..0e7706c1e5 100644 --- a/Resources/Prototypes/Chemistry/metabolizer_types.yml +++ b/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml @@ -44,3 +44,9 @@ - type: metabolizerType id: Arachnid name: metabolizer-type-arachnid + + # Start ADT tweak: Drask +- type: metabolizerType + id: Drask + name: metabolizer-type-drask + # End ADT tweak diff --git a/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml b/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml new file mode 100644 index 0000000000..3f73c916c9 --- /dev/null +++ b/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml @@ -0,0 +1,190 @@ +# - type: damageModifierSet +# id: Fur # 1) - ебучий годспид, балансим уроном. 2) - шерсть должна гореть +# coefficients: +# Blunt: 1 +# Piercing: 1.2 +# Slash: 1.2 +# Cold: 0.6 +# Heat: 1.5 +# Poison: 1 + +- type: damageModifierSet + id: Kobalt # мне даже жаль кобальдов, но жизнь такова какова она какова и больше не какова + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 1.0 + Cold: 1.5 + Heat: 0.9 + Poison: 1 + Bloodloss: 0.3 + +# - type: damageModifierSet +# id: Demon # они вообще то мутанты, но кого ебёт так? +# coefficients: +# Blunt: 1 +# Piercing: 1 +# Slash: 1.0 +# Cold: 0.8 +# Heat: 0.8 +# Poison: 0.8 +# Cellular: 1.5 + +# - type: damageModifierSet +# id: Shadowkin # пупупу +# coefficients: +# Blunt: 1.2 +# Piercing: 1.2 +# Slash: 1.2 +# Cold: 0.8 +# Heat: 0.8 +# Poison: 1 +# Cellular: 1 + +- type: damageModifierSet + id: Drask # саморезы + coefficients: + Heat: 1.5 + Asphyxiation: 2.0 + +# - type: damageModifierSet +# id: Felinid # мяу +# coefficients: +# Blunt: 1.0 +# Piercing: 1.15 +# Slash: 1.30 +# Cold: 1.5 +# Heat: 2.0 +# Poison: 1.1 + +- type: damageModifierSet + id: CyborgMetallic + coefficients: + Blunt: 0.8 + Slash: 0.7 + Piercing: 0.8 + Heat: 1.2 + Shock: 1.5 + flatReductions: + Blunt: 5 + Slash: 5 + Piercing: 5 + Heat: 5 + + +- type: damageModifierSet + id: CyborgMetallicStrong + coefficients: + Blunt: 0.6 + Slash: 0.6 + Piercing: 0.6 + Heat: 0.8 + Shock: 1.1 + flatReductions: + Blunt: 9 + Slash: 9 + Piercing: 9 + Heat: 9 + +# - type: damageModifierSet +# id: Ursus # мишк +# coefficients: +# Blunt: 1.0 + +- type: damageModifierSet + id: AshWalker # Груба кожа = умно ящериц + coefficients: + Blunt: 0.8 + +- type: damageModifierSet + id: ADTAntagDroneIPCDamageModSet + coefficients: + Blunt: 0.75 + Slash: 0.75 + Piercing: 0.55 + Heat: 0.80 + #Explosive: 0.25 + Structural: 0 + # zap + Shock: 0.5 + Cold: 0 + Caustic: 0.3 + +- type: damageModifierSet + id: ADTSecurityCybDamagModSet + coefficients: + Blunt: 0.5 + Slash: 0.4 + Piercing: 0.45 + # fire and lasers burn it good + Heat: 1.0 + # zap + Shock: 1.2 + Cold: 0 + Caustic: 0.4 + +- type: damageModifierSet + id: distorted + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 1.0 + Cold: 0.5 + Heat: 0.5 + Poison: 0.5 + Bloodloss: 1 + +- type: damageModifierSet + id: echo + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 0.4 + Cold: 0.6 + Heat: 0.6 + Poison: 1.0 + Bloodloss: 1 + +- type: damageModifierSet + id: grant + coefficients: + Blunt: 0.5 + Piercing: 0.7 + Slash: 0.5 + Cold: 0.7 + Heat: 0.7 + Poison: 0.7 + Bloodloss: 1 + +- type: damageModifierSet + id: hunter + coefficients: + Blunt: 0.45 + Piercing: 0.6 + Slash: 0.45 + Cold: 0.6 + Heat: 0.45 + Poison: 0.6 + Bloodloss: 1 + +- type: damageModifierSet + id: soldier + coefficients: + Blunt: 0.8 + Piercing: 0.8 + Slash: 0.8 + Cold: 0.8 + Heat: 0.8 + Poison: 0.8 + Bloodloss: 1 + +- type: damageModifierSet + id: wrecker + coefficients: + Blunt: 0.4 + Piercing: 0.55 + Slash: 0.4 + Cold: 0.55 + Heat: 0.65 + Poison: 0.55 + Bloodloss: 1 diff --git a/Resources/Prototypes/ADT/Datasets/Names/name_drask.yml b/Resources/Prototypes/ADT/Datasets/Names/name_drask.yml new file mode 100644 index 0000000000..e277f4313c --- /dev/null +++ b/Resources/Prototypes/ADT/Datasets/Names/name_drask.yml @@ -0,0 +1,20 @@ +- type: dataset + id: Draskfrist + values: + - Овв + - Оумн + - Мноо + - Румум + - Ваар + - Дромнн + - Руум + - Гоом + - Фмонг + - Оорм + - Гаар + - Хоорб + - Саар + - Ссооумн + - Гнии + - Вииск + - Вррм diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/Drask.yml b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/Drask.yml new file mode 100644 index 0000000000..242111d6d6 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/Drask.yml @@ -0,0 +1,43 @@ +- type: marking + id: DraskArmRight + bodyPart: RArm + markingCategory: Arms + speciesRestriction: [DraskSpecies] + sponsorOnly: false + coloring: + default: + type: + !type:CategoryColoring + category: Hair + fallbackTypes: + - !type:SkinColoring + layers: + r_arm: + type: + !type:SimpleColoring + color: "#171717" + sprites: + - sprite: ADT/Mobs/Drask/custom.rsi + state: r_arm + +- type: marking + id: DraskArmLeft + bodyPart: LArm + markingCategory: Arms + speciesRestriction: [DraskSpecies] + sponsorOnly: false + coloring: + default: + type: + !type:CategoryColoring + category: Hair + fallbackTypes: + - !type:SkinColoring + layers: + l_arm: + type: + !type:SimpleColoring + color: "#171717" + sprites: + - sprite: ADT/Mobs/Drask/custom.rsi + state: l_arm diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/Drask.yml b/Resources/Prototypes/ADT/Entities/Mobs/Species/Drask.yml new file mode 100644 index 0000000000..72556b70a2 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Species/Drask.yml @@ -0,0 +1,81 @@ +- type: entity + parent: BaseMobSpeciesOrganic + id: BaseMobDrask + name: Urist McDrask + abstract: true + components: + - type: HumanoidAppearance + species: DraskSpecies + - type: Hunger + starvationDamage: + types: + Cold: 0.05 + Bloodloss: 0.05 + - type: Icon + sprite: ADT/Mobs/Drask/parts.rsi + state: full + - type: Thirst + - type: Perishable + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatHuman + amount: 5 + - type: Body + prototype: Drask + requiredLegs: 2 + - type: MeleeWeapon + soundHit: + path: /Audio/Weapons/pierce.ogg + angle: 30 + animation: WeaponArcPunch + damage: + types: + Blunt: 10 + - type: Bloodstream + bloodReagent: Cryoxadone + - type: Temperature + heatDamageThreshold: 330 + coldDamageThreshold: 0 + currentTemperature: 273.15 + coldDamage: #per second, scales with temperature & other constants + types: + Cold : 0 + specificHeat: 42 + heatDamage: #per second, scales with temperature & other constants + types: + Heat : 0.4 + - type: ThermalRegulator + normalBodyTemperature: 273.15 + - type: DamageVisuals + damageOverlayGroups: + Brute: + sprite: Mobs/Effects/brute_damage.rsi + color: "#0091ff" + Burn: + sprite: Mobs/Effects/burn_damage.rsi + - type: Speech + speechSounds: Drask + - type: Vocal + sounds: + Male: MaleDrask + Female: FemaleDrask + Unsexed: MaleDrask + - type: Damageable + damageContainer: Biological + damageModifierSet: Drask + +- type: entity + save: false + name: Urist McDrask + parent: MobHumanDummy + id: MobDraskDummy + noSpawn: true + components: + - type: HumanoidAppearance + species: DraskSpecies + + + + + diff --git a/Resources/Prototypes/ADT/Entities/Mobs/player/Drask.yml b/Resources/Prototypes/ADT/Entities/Mobs/player/Drask.yml new file mode 100644 index 0000000000..e962cd24e1 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/player/Drask.yml @@ -0,0 +1,46 @@ +- type: entity + save: false + name: "Urisst' McDrask" + parent: BaseMobDrask + id: MobDrask + components: + - type: CombatMode + - type: InteractionPopup + successChance: 1 + interactSuccessString: hugging-success-generic + interactSuccessSound: /Audio/Effects/thudswoosh.ogg + messagePerceivedByOthers: hugging-success-generic-others + - type: MindContainer + showExamineInfo: true + - type: Input + context: "human" + - type: MobMover + - type: InputMover + - type: Alerts + - type: Eye + - type: CameraRecoil + - type: Examiner + - type: CanHostGuardian + - type: NpcFactionMember + factions: + - NanoTrasen + - type: Respirator + damage: + types: + Asphyxiation: 1.0 + damageRecovery: + types: + Asphyxiation: -1.0 +# ОТКОММЕНТИТЬ ПРИ ПЕРЕНОСЕ ЯЗЫКОВ И РАЗМЕРОВ + # - type: LanguageSpeaker + # speaks: + # - GalacticCommon + # - Drask + # understands: + # - GalacticCommon + # - Drask + # - type: SizeAttributeWhitelist # Frontier + # tall: true + # tallscale: 1.15 + # short: true + # shortscale: 1 diff --git a/Resources/Prototypes/ADT/SoundCollections/emotes.yml b/Resources/Prototypes/ADT/SoundCollections/emotes.yml new file mode 100644 index 0000000000..3f6d324548 --- /dev/null +++ b/Resources/Prototypes/ADT/SoundCollections/emotes.yml @@ -0,0 +1,16 @@ +- type: soundCollection + id: DraskCough + files: + - /Audio/ADT/Drask/draskcough.ogg +- type: soundCollection + id: DraskScream + files: + - /Audio/ADT/Drask/draskscream.ogg +- type: soundCollection + id: DraskSneeze + files: + - /Audio/ADT/Drask/drasksneeze.ogg +- type: soundCollection + id: DraskTalk + files: + - /Audio/ADT/Drask/drasktalk.ogg diff --git a/Resources/Prototypes/ADT/Species/drask.yml b/Resources/Prototypes/ADT/Species/drask.yml new file mode 100644 index 0000000000..8c75d513ae --- /dev/null +++ b/Resources/Prototypes/ADT/Species/drask.yml @@ -0,0 +1,158 @@ +- type: species + id: DraskSpecies + name: species-name-drask + roundStart: true + prototype: MobDrask + sprites: MobDraskSprites + defaultSkinTone: "#a3d4eb" + markingLimits: MobDraskMarkingLimits + dollPrototype: MobDraskDummy + skinColoration: Hues + maleFirstNames: Draskfrist + femaleFirstNames: Draskfrist + maleLastNames: Draskfrist + femaleLastNames: Draskfrist + naming: FirstDashFirstDashFirst + +- type: speciesBaseSprites + id: MobDraskSprites + sprites: + Head: MobDraskHead + Eyes: MobDraskEyes + Hair: MobHumanoidAnyMarking + HeadTop: MobHumanoidAnyMarking + HeadSide: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking + Chest: MobDraskTorso + LArm: MobDraskLArm + RArm: MobDraskRArm + LHand: MobDraskLHand + RHand: MobDraskRHand + LLeg: MobDraskLLeg + RLeg: MobDraskRLeg + LFoot: MobDraskLFoot + RFoot: MobDraskRFoot + +- type: markingPoints + id: MobDraskMarkingLimits + onlyWhitelisted: true + points: + Head: + points: 1 + required: false + Hair: + points: 1 + required: false + HeadTop: + points: 1 + required: true + HeadSide: + points: 1 + required: true + Chest: + points: 1 + required: true + Tail: + points: 1 + required: false + Snout: + points: 1 + required: false + Legs: + points: 2 + required: false + Arms: + points: 2 + required: false + defaultMarkings: [DraskArmRight,DraskArmLeft] + + +- type: humanoidBaseSprite + id: MobDraskEyes + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: eyes + +- type: humanoidBaseSprite + id: MobDraskHead + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDraskHeadMale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDraskHeadFemale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobDraskTorso + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDraskTorsoMale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDraskTorsoFemale + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobDraskLLeg + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobDraskLHand + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobDraskLArm + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobDraskLFoot + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobDraskRLeg + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobDraskRHand + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobDraskRArm + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobDraskRFoot + baseSprite: + sprite: ADT/Mobs/Drask/parts.rsi + state: r_foot diff --git a/Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml b/Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml new file mode 100644 index 0000000000..8eb673d93f --- /dev/null +++ b/Resources/Prototypes/ADT/Voice/speech_emote_sounds.yml @@ -0,0 +1,67 @@ +- type: emoteSounds + id: MaleDrask + params: + variation: 0.125 + sounds: + Scream: + collection: DraskScream + Laugh: + collection: MaleLaugh + Sneeze: + collection: DraskSneeze + Cough: + collection: DraskCough + CatMeow: + collection: CatMeows + CatHisses: + collection: CatHisses + MonkeyScreeches: + collection: MonkeyScreeches + RobotBeep: + collection: RobotBeeps + Yawn: + collection: MaleYawn + Snore: + collection: Snores + Honk: + collection: BikeHorn + Sigh: + collection: MaleSigh + Crying: + collection: MaleCry + Whistle: + collection: Whistles + +- type: emoteSounds + id: FemaleDrask + params: + variation: 0.125 + sounds: + Scream: + collection: DraskScream + Laugh: + collection: FemaleLaugh + Sneeze: + collection: DraskSneeze + Cough: + collection: DraskCough + CatMeow: + collection: CatMeows + CatHisses: + collection: CatHisses + MonkeyScreeches: + collection: MonkeyScreeches + RobotBeep: + collection: RobotBeeps + Yawn: + collection: FemaleYawn + Snore: + collection: Snores + Honk: + collection: CluwneHorn + Sigh: + collection: FemaleSigh + Crying: + collection: FemaleCry + Whistle: + collection: Whistles diff --git a/Resources/Prototypes/ADT/Voice/speech_sounds.yml b/Resources/Prototypes/ADT/Voice/speech_sounds.yml new file mode 100644 index 0000000000..224f49ef3a --- /dev/null +++ b/Resources/Prototypes/ADT/Voice/speech_sounds.yml @@ -0,0 +1,8 @@ +- type: speechSounds + id: Drask + saySound: + path: /Audio/ADT/Drask/drasktalk.ogg + askSound: + path: /Audio/ADT/Drask/drasktalk.ogg + exclaimSound: + path: /Audio/ADT/Drask/drasktalk.ogg diff --git a/Resources/Prototypes/Reagents/gases.yml b/Resources/Prototypes/Reagents/gases.yml index 9ef508feea..2087d88655 100644 --- a/Resources/Prototypes/Reagents/gases.yml +++ b/Resources/Prototypes/Reagents/gases.yml @@ -14,6 +14,12 @@ conditions: - !type:OrganType type: Human + # Start ADT tweak: Drask + - !type:Oxygenate + conditions: + - !type:OrganType + type: Drask + # End ADT tweak - !type:Oxygenate conditions: - !type:OrganType diff --git a/Resources/Textures/ADT/Mobs/Drask/custom.rsi/l_arm.png b/Resources/Textures/ADT/Mobs/Drask/custom.rsi/l_arm.png new file mode 100644 index 0000000000000000000000000000000000000000..f63177c4dbb75d42aa67281bdc83bed2d89cc2ee GIT binary patch literal 20744 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 YJQyo_dg0dozshnh=Q2mfqWjnV7Zx@yd;kCd literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/eyes.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..c976b9b9d38b24a3c7849ba5534023a95fa16eee GIT binary patch literal 4394 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 SdyZ@Yx!u#%&t;ucLK6TSPyxlq%tsQ zOst(~>v7mY=4gEI(z+0lH42Xe7FykOb(QfJ?M_&@MKr3^U}v4v9V{pw<(w9I(* zqW7YEB@QthyP#|6+^s4eTp%0&{lkZ^dPg?jIse!4*CxwmM!AU=XH4#@+*6o$*TnSP z?<0(1Q#KuWeq^#$?1Uc^UvD~`KZo0l+s1goa-q*h7?U<$I94RRdC@w7^8)OfyS#on z-Fm3=T=$&U&Qr6#Khgj4{K{07>zRE@U8+X}+Bqacrv$Wh3ar)AWE0vVU-+^A#y^Xl zDMeEcoY>gFCE~G7{ttg$dG?d#%jc-nv%IL;xTe4Gz;wP+3y~I zVe|+LKW%>CprS$Gf;Xkp%geWZ|Mq@nTD|?8`l9VRjPmKgXkkn8c6VX;4}uH!E}sk( z;VkfoEM{QPQwCwiilz2tKtc8rPhVH|=iH(K%Dmir_ICk=BuiW)N}Tg^b5rw57@Uhz z6H8K46v{J8G8EiBeFMT9`NSC*1hhR}977^F85IQXzX$3W1*0J_8UmvsFd70QJOmht z@qgXot^bkLHN|>^^`VQy)WGCne0(%k2h5yl{Qtk-L9Z@WQ+m8eRv#uY5( zBNsrRJda+uz#IWH5*F+*J~1?g17JZ9%ImR5*CEURCO`y-dMu160A;T<25|;>p+X~z p@q1zB%>N7^JPJlbU^E2i5CUTI>qGOTZfpQq<>~6@vd$@?2>`g#mqq{p literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/kidneys.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/kidneys.png new file mode 100644 index 0000000000000000000000000000000000000000..793f341da9e454a73b24ba038029c849f84e6d8e GIT binary patch literal 4405 zcmeHKeNn|p8Kl_d9)dm(}P zQ7iL^T~VwK?ZB;|wN`9()nR9+(7?(@Tidlxr?vH?8_brvO+KdMjJ-Dj3|r6H;hgn9 zl5=z4`@FyB_dd_>eV+H^)|#_3Bf}SlLl6{c%rfMFyG**mLcp(3T|EG99o2aSVh-t+ z@h;BF+8LQx#WOO-!&)K8bJbzK7U@O9Mr^z4+Iwa#d6&&Swn!YgwW|4SzcD%3))aK* zvp2r?X~==-(@*5DKhgK$D=(Z2-LdVw^5w7J-k$sSO|N;EpKR#lYCqX{KIM+Mu=A3B z#e&##M^ApR`s0B%q-CTqBQti(;k9dGZ_ZALtp4$j&iv8!UGh4=qib90M&Vk@{ae?b zi5|^7povMf&3Pe&UL5on#UAC%@_m^_jce=bH^qz&iBR$%mKH)!^!@BZ2nwoU)6&ew zw6yVLKnjhU>-AaQRg1fRxc*4Ur#n6Tr@P(5OWb!MuH~KRmX+ZNuN^yj z3yb;b`gtR7^m);cIq$S~N5J(Z@3mKKy6*K}J{NY;l``Dh*KjW+IB7=tKK56}w^Nhe zWH&Yr*KTi(`(0;mXB1Jq=O6W7?)7qw&nG@pWi?+s{O8*3ovTl6KQha@tT^US{H&f` zPu~Bm)rWYY%hF2s(m=3 z=$K>cnV|PJ?=9iVZpN0DE;@VGS@!!S{9C~_hg549IDVV?@%jYlu5G}iEA5-#S1eSQ z_1_){>Nc|p5!3_frAlAna5#w3WP^5_wf>7ESV9x%m)$6^zs6eS(e7R7@10;QlN0Uhpoir z$>Fjj7i}eS3>jk-;7KpvAc{PJAa1u?;Z`a*mkq&mIvs-I2#&)50Si@5k@Ub$Ay%UB za~K$ba@G`MRFK{t8h_FdL`o&V*@E@YQmqdaM^w7&=kVh83%w0U{!3=l9@)6dBQ`I zz{WawpBE5&5>jNX55<}kn>6D~ComA;KEXQ)J)XM{3{WN$Vc@6=DLkV=FPGLQXpUlO z!Z&0n(yF30S~yXQk+2H0s$h#w14cB)Xml1@XQj~qDx*^nNhiffRDfK;0v?NnwCXfk zHLTOBG_ZYLE0FEciMatlHf$D*{GM}3V+}}i`hU6AjUhlf zKw46&R6yYK0ND^}E`}62S02aN^>Qf$ndCV!Z2}ENlOky#MFx|=jl)%*l zs$7XG2{ZuD(X6%Vf1#!JktO*zJ&P5<`c*!Yzo&AUa{rV6(a!psNhb5P1wm5&6a=!8 zp?z@zF8>s@fppp!aDI#x?6{r%ree@gs7{TlVTwt_VUjkMdcC0tC&BlCB`= zrN+mAF;p~~(nEV^&YSaia5oq41*Y3ZLuy`uw}0Quvz{|Y?-*Tk`byIe-k%@dWkdJc zXAeFSasJtirzq;4E@A$zE_uEUD{Q^oUfQsdD%pdz-P^AWv5kiI7C}4616yrNcQY?; zIo|Wv2Qv(F4Zq-vqsYY(rPmkDfabp$49RvD*-P369={mXA2!>lFIcv-2+B&2h^sMr z3i*ROYikDkU6Jv}^Rw$;y~=-{U9&>GU{A^5H+_9$py7TP{!we&M`52JH?P$~^$|_F z*N;Bda;*5(J9F=BzSE;hzJ2q4OlsWVOP~Mq(uL-nRmYi*6D`k+@$G1YSM{gJp|)Dx Uz@gGUkS=6Q&o;ciy7ak!13?K%Y5)KL literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/organs.rsi/lungs.png b/Resources/Textures/ADT/Mobs/Drask/organs.rsi/lungs.png new file mode 100644 index 0000000000000000000000000000000000000000..512f2b74484c3d8fe70dd860a2736938e8d3e6d9 GIT binary patch literal 4691 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/full.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..33f6f187dc5b59b0466949a23e879fe203949162 GIT binary patch literal 4691 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_m.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/head_m.png new file mode 100644 index 0000000000000000000000000000000000000000..267f0540e5d493e17e5a6d51a2aa9ad34444c1e3 GIT binary patch literal 17035 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU~I{Bb`J1#c2+1T%1_J8No8Qr zm{>c}*5j~)%+dJhtwGv+X##~O0_MJ1q|~>x%XLG*Ev~gzGh%+R`btd_5qCeh^}&PV zNmmaZjSOcGcNF-;P*_?RR5DTM|8$Y4BNYXA`pdt|mA_}G-+U@$vpU;~S*c5e3k|2o zi#D&9XlM{P^kVXimFmXbkrjRGtAG5c5`P+b@A*HOX0L-O4gM;9hIcn~n0KU`>(2db zxADNKNlrC>HklV#JLPxk?f!FY=aUWd)4ANtZ2ffvx|ixr+dX3{@6?Jmi$yD>p8hV@ z)1I^4V)a$4?E91V8^l})Gm2Sm*~T($f(w^Y%9TJzQL#l^vX;#7xLkMVu>Gqa!A~Zg z3}sY4&Xg6PXj%8c{>R<5k#pu1O+Hk(;QP^S_Qx6@=v~OV@$LJ@-0gl12aF4rmj2nQ zX7Js!YVl&%zJ`Ul4<7AWe6sq$Q$B-FOT62jcrecTmn2wWzc~LC^Wp6d8E4YTpz(|ho=gyt`AEZxC zPLAQxqeoyPl9Q9kGK&)Xk@b>mKgo^;d0t;%pW*%c_Y6u(N(}ez-D40G6lAz~@gf7c zjzIPZAvVl@bamv~Pf`HDEC+cW;#oRAOI_eKoRi#`E!!3BqhEuUoh7KP>ej zdma=hK|w(z`-kW(fb0m6Ww6))(I7s(04`7B5+~#?vI2mRp(93~Rt4UO3BXa0j)uT! z2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgR)j}Zn-PUKY zwE$Ezbkv~X9RegzD}jOo+uQ&>rpb|`f?94MIRMb-2w{!_&E0`!jFpv@Nj4K^1~K&A zyLbP?)+eB=CuhErq-ipc=Ora2(d~t=82~wK_wL;^nJNca3Njn!c~F3(1CZOWr3`d+ z$b6Ef%3&H|^YtJ;D=RC;su7qvYSW;pc=VMjzkmOx$QqIY0F=*hg)lv5i$Qk5)+eC* zp4764qyPX}2D1P;JAh(_o&f-I2gpuXb_6YwfVm4KM+zXR48UeE%yQV;0c>ihEe0#> z$XOkN?iR8F06F&24IBtQIfWn0on!?7OfzV~(m;d3;0AaY;3^>D3aG%KhaFUK=BN>) zAut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O)DD4chKl1r fGrd9Q0#M0p(*n+C>p2fdgN*ZZ^>bP0l+XkK%c1^i literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_arm.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_arm.png new file mode 100644 index 0000000000000000000000000000000000000000..7b411c4d1cf1a4765b9477072110684fe6f86987 GIT binary patch literal 4580 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_hand.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/l_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..9a89e6bb8f3d4e03d8b65aadfa9f56d75a71647a GIT binary patch literal 5148 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 CGJG5W literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_foot.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..ebaf3c833b56af5cba61f31e36d8991e838ff629 GIT binary patch literal 4477 zcmeHKdr%X19$%~#M9^Lx?5Lni^aSKK+08pUgl7v_Ko?`daln7RJPX0ng( zlaBpOau7XEbsX2!?5gyp-Vy#Re z4f7>V8m7IB6@t8%c4Vw}w4nh%_C=LW&VBcM(Y}tf)(_{EM<~ih2mtgVPUb^7-2v|GEIYIii8 z4!-J&ST*g%vYrC@o<}Vik;ZwunVs|B*p(I;_}%Krv$>t$u7A8_`QIM@Vb&*0Z&}`1 zWKMJUulP8y_jqk$-fLd=$o9(Iw(Yiq@w-FMroGdsG~X#P&-HE%`Nx*T3xA2KP}F?j z{U|eW(w+@L>v`nCZO6T^C!3zGi7tb}?zsk?uA}qv&FOV^Ec5i?{1saXq|n~yX@SptoGNlACi+d zLy6DJe$bU-&wO^jc*gv^E>TS9)hBc}hkdjE5^ zGndcd6TV4#yHk9!NR0oc`&`{F{rQ>xRqYo4&aiW7Thn5aLbJ>}dMcYb18*aruCG6{ zs_&*G=w@?`{37#m_{+au_{x@m*@`_Gn<@j|niI9ibY%X6?%#%%SFe#CKfCT`PJGDX zg&i~g5Qy+$- z8T;=R@AUM!dwaWH%_@&$3taVUuTdvJg}NC~i8+R4ILX?@1jSltvDfYdB?>_?ab71u z7SKFwp>2#qE9z=FDS{bFE6P?FP=hmx&Sz3fU36w?x|u93AT^XIE;ca6ivs{V%@eTK zUg+R(uU6#4#lgEEmWW`V316TUO2xmYenkz_C9mWpBn;TRWX#Z9^;gAm|L zE6V42CoYkAJRY$}CT3kW38v9#B&bv(l_J0b;Yu7l;YA$W0s&$GLq~I@i*fP{>wpDJ z!on8wT9F9o;i35KPJ>|>-oXvB0Qiu238w@TqY}GaGTMXVlidJhFrc6H;LM<*B_^6< zi(Mq0?4}+3g3%BZIqdH&b`|>4p-2f`NZWxa2S&xl44I-g7>7Ls3T%ws>GJ|)kFn$# z>j+t6ViPpJbVdgP+=p?;SP$jyGX_=$1FmDqVj(=ePAd||$0?R%DBSm|P*Dn{0;3QT zrBsL~p-KeR&=yofNach^H3~}a;CRA8(gG9!7c&6IDpgXnT!|u5B~2i5QlUcB zGPx4mtWr!yU@C=jG{kZj1FDiJ937PaMFA*_9Mh0;OohlO(u&CCs1?zuRTcnhwWujM zN+>L}FB*!(m#{870j86&6E<4nbl7|ffp9#*sMm_5Vsu1eEF^d6dMcAH8u%LcEM$Dm1jD|zzzK371&(mjlrK(zHJ~E%35Sga z>&IZh4#}CHDFzgytrjH;ib1U=5jjl}h(@NS5sgBv(aN-dF$icKN9|T;Yf|n@`T+lUTd3Cx?6+MVf*=44)4R8^!ER(_a8aU+Z-VX78o%FJX>0 z__@j(M-L%uR=y#B_W6kG#@LIYXCs`pw1tcD10vI2%AWFdO;35qv#4xRW5OihJaBC+ zzutRSC%gRkE6oAZwp%41w4Q)ump8;-+4cUtlnQTGjmZ>n({*nruB-Sjf3{yl literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_hand.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/r_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..57140e922eca22eb53d3640127b0e799970cc1f5 GIT binary patch literal 5139 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 FCIC=DLSg^_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_f.png b/Resources/Textures/ADT/Mobs/Drask/parts.rsi/torso_f.png new file mode 100644 index 0000000000000000000000000000000000000000..75f8571969aac09228ccb83c0a93e2284caa6a72 GIT binary patch literal 5414 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 Date: Thu, 11 Jul 2024 19:40:48 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=20=D0=BC=D0=B5=D1=85=D0=B0=D0=BD=D0=B8=D0=BA=D0=B8=20=D1=8F?= =?UTF-8?q?=D0=B7=D1=8B=D0=BA=D0=BE=D0=B2,=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=D1=87=D0=B8=D0=BA=D0=BE=D0=B2=20=D1=8F=D0=B7?= =?UTF-8?q?=D1=8B=D0=BA=D0=BE=D0=B2,=20=D0=B8=D0=BC=D0=BF=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D1=80=D0=BE=D0=B2=20=D1=8F=D0=B7=D1=8B=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2.=20(#116)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Как-то так no cl --- .../ADT/Language/LanguageMenuUIController.cs | 51 + .../ADT/Language/LanguageMenuWindow.xaml | 18 + .../ADT/Language/LanguageMenuWindow.xaml.cs | 124 +++ .../ADT/Language/Systems/LanguageSystem.cs | 8 + .../Systems/TranslatorImplanterSystem.cs | 8 + .../Language/Commands/ListLanguagesCommand.cs | 39 + .../Language/Commands/SayLanguageCommand.cs | 53 + .../Commands/SelectLanguageCommand.cs | 48 + .../ADT/Language/LanguageSystem.Windows.cs | 40 + Content.Server/ADT/Language/LanguageSystem.cs | 319 ++++++ .../ADT/Language/TranslatorImplanterSystem.cs | 79 ++ .../ADT/Language/TranslatorSystem.cs | 243 +++++ Content.Server/Chat/Systems/ChatSystem.cs | 133 ++- .../Language/Components/CommonLangUnknown.cs | 14 + .../Components/LanguageSpeakerComponent.cs | 53 + .../Components/TranslatorComponent.cs | 93 ++ .../TranslatorImplanterComponent.cs | 34 + .../UniversalLanguageSpeacerComponent.cs | 11 + .../ADT/Language/LanguagePrototype.cs | 28 + .../Language/Systems/SharedLanguageSystem.cs | 73 ++ .../SharedTranslatorImplanterSystem.cs | 36 + .../Systems/SharedTranslatorSystem.cs | 34 + .../ru-RU/ADT/Actions/language-menu.ftl | 6 + .../Entities/Objects/Device/translators.ftl | 61 ++ .../ADT/Entities/Objects/Misc/implanters.ftl | 68 ++ .../Locale/ru-RU/ADT/Languages/languages.ftl | 133 +++ .../Locale/ru-RU/ADT/Research/translators.ftl | 3 + Resources/Prototypes/ADT/Actions/language.yml | 12 + .../Entities/Objects/Device/translators.yml | 386 +++++++ .../ADT/Entities/Objects/Misc/implanters.yml | 287 ++++++ .../Prototypes/ADT/Languages/languages.yml | 949 ++++++++++++++++++ .../ADT/Recipes/Lathes/translators.yml | 358 +++++++ .../Prototypes/ADT/Research/translators.yml | 59 ++ .../Prototypes/Entities/Mobs/NPCs/animals.yml | 44 + .../Prototypes/Entities/Mobs/NPCs/pets.yml | 48 + .../Entities/Mobs/NPCs/revenant.yml | 5 + .../Prototypes/Entities/Mobs/NPCs/silicon.yml | 7 + .../Prototypes/Entities/Mobs/NPCs/slimes.yml | 5 + .../Prototypes/Entities/Mobs/NPCs/xeno.yml | 5 + .../Entities/Mobs/Player/observer.yml | 1 + .../Entities/Mobs/Species/arachnid.yml | 7 + .../Prototypes/Entities/Mobs/Species/base.yml | 6 + .../Entities/Mobs/Species/diona.yml | 7 + .../Entities/Mobs/Species/dwarf.yml | 7 + .../Entities/Mobs/Species/human.yml | 7 + .../Prototypes/Entities/Mobs/Species/moth.yml | 7 + .../Entities/Mobs/Species/reptilian.yml | 9 + .../Entities/Mobs/Species/slime.yml | 7 + Resources/Prototypes/Entities/Mobs/base.yml | 5 + .../Entities/Structures/Machines/lathe.yml | 36 + .../_NF/Interface/Actions/language.png | Bin 0 -> 898 bytes .../Objects/Devices/translator.rsi/icon.png | Bin 0 -> 383 bytes .../translator.rsi/inhand-left-translator.png | Bin 0 -> 169 bytes .../Devices/translator.rsi/inhand-left.png | Bin 0 -> 333 bytes .../inhand-right-translator.png | Bin 0 -> 168 bytes .../Devices/translator.rsi/inhand-right.png | Bin 0 -> 346 bytes .../Objects/Devices/translator.rsi/meta.json | 43 + .../Devices/translator.rsi/translator.png | Bin 0 -> 306 bytes 58 files changed, 4089 insertions(+), 28 deletions(-) create mode 100644 Content.Client/ADT/Language/LanguageMenuUIController.cs create mode 100644 Content.Client/ADT/Language/LanguageMenuWindow.xaml create mode 100644 Content.Client/ADT/Language/LanguageMenuWindow.xaml.cs create mode 100644 Content.Client/ADT/Language/Systems/LanguageSystem.cs create mode 100644 Content.Client/ADT/Language/Systems/TranslatorImplanterSystem.cs create mode 100644 Content.Server/ADT/Language/Commands/ListLanguagesCommand.cs create mode 100644 Content.Server/ADT/Language/Commands/SayLanguageCommand.cs create mode 100644 Content.Server/ADT/Language/Commands/SelectLanguageCommand.cs create mode 100644 Content.Server/ADT/Language/LanguageSystem.Windows.cs create mode 100644 Content.Server/ADT/Language/LanguageSystem.cs create mode 100644 Content.Server/ADT/Language/TranslatorImplanterSystem.cs create mode 100644 Content.Server/ADT/Language/TranslatorSystem.cs create mode 100644 Content.Shared/ADT/Language/Components/CommonLangUnknown.cs create mode 100644 Content.Shared/ADT/Language/Components/LanguageSpeakerComponent.cs create mode 100644 Content.Shared/ADT/Language/Components/TranslatorComponent.cs create mode 100644 Content.Shared/ADT/Language/Components/TranslatorImplanterComponent.cs create mode 100644 Content.Shared/ADT/Language/Components/UniversalLanguageSpeacerComponent.cs create mode 100644 Content.Shared/ADT/Language/LanguagePrototype.cs create mode 100644 Content.Shared/ADT/Language/Systems/SharedLanguageSystem.cs create mode 100644 Content.Shared/ADT/Language/Systems/SharedTranslatorImplanterSystem.cs create mode 100644 Content.Shared/ADT/Language/Systems/SharedTranslatorSystem.cs create mode 100644 Resources/Locale/ru-RU/ADT/Actions/language-menu.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Entities/Objects/Device/translators.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Entities/Objects/Misc/implanters.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Languages/languages.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Research/translators.ftl create mode 100644 Resources/Prototypes/ADT/Actions/language.yml create mode 100644 Resources/Prototypes/ADT/Entities/Objects/Device/translators.yml create mode 100644 Resources/Prototypes/ADT/Entities/Objects/Misc/implanters.yml create mode 100644 Resources/Prototypes/ADT/Languages/languages.yml create mode 100644 Resources/Prototypes/ADT/Recipes/Lathes/translators.yml create mode 100644 Resources/Prototypes/ADT/Research/translators.yml create mode 100644 Resources/Textures/_NF/Interface/Actions/language.png create mode 100644 Resources/Textures/_NF/Objects/Devices/translator.rsi/icon.png create mode 100644 Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left-translator.png create mode 100644 Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left.png create mode 100644 Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right-translator.png create mode 100644 Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right.png create mode 100644 Resources/Textures/_NF/Objects/Devices/translator.rsi/meta.json create mode 100644 Resources/Textures/_NF/Objects/Devices/translator.rsi/translator.png diff --git a/Content.Client/ADT/Language/LanguageMenuUIController.cs b/Content.Client/ADT/Language/LanguageMenuUIController.cs new file mode 100644 index 0000000000..791b616bb3 --- /dev/null +++ b/Content.Client/ADT/Language/LanguageMenuUIController.cs @@ -0,0 +1,51 @@ +using Content.Client.ADT.Language; +using Content.Client.Gameplay; +using Content.Shared.Language; +using Robust.Client.UserInterface.Controllers; +using Robust.Client.UserInterface.Controls; +using static Content.Shared.Language.Systems.SharedLanguageSystem; + +namespace Content.Client.ADT.Language; + +public sealed class LanguageMenuUIController : UIController, IOnStateEntered, IOnStateExited +{ + public LanguageMenuWindow? _languageWindow; + + public override void Initialize() + { + EntityManager.EventBus.SubscribeLocalEvent(OnActionMenu); + EntityManager.EventBus.SubscribeEvent(EventSource.Network, this, OnStateUpdate); + } + + private void OnStateUpdate(LanguageMenuStateMessage ev) + { + if (_languageWindow == null) + return; + + _languageWindow.UpdateState(ev); + } + + private void OnActionMenu(EntityUid uid, LanguageSpeakerComponent component, LanguageMenuActionEvent args) + { + if (_languageWindow == null) + return; + + if (!_languageWindow.IsOpen) + { + _languageWindow.Open(); + EntityManager.EntityNetManager?.SendSystemNetworkMessage(new RequestLanguageMenuStateMessage()); + } + } + + public void OnStateEntered(GameplayState state) + { + _languageWindow = UIManager.CreateWindow(); + LayoutContainer.SetAnchorPreset(_languageWindow, LayoutContainer.LayoutPreset.Center); + } + + public void OnStateExited(GameplayState state) + { + _languageWindow?.Dispose(); + _languageWindow = null; + } +} diff --git a/Content.Client/ADT/Language/LanguageMenuWindow.xaml b/Content.Client/ADT/Language/LanguageMenuWindow.xaml new file mode 100644 index 0000000000..188b3bc3b5 --- /dev/null +++ b/Content.Client/ADT/Language/LanguageMenuWindow.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + diff --git a/Content.Client/ADT/Language/LanguageMenuWindow.xaml.cs b/Content.Client/ADT/Language/LanguageMenuWindow.xaml.cs new file mode 100644 index 0000000000..0a795aebbd --- /dev/null +++ b/Content.Client/ADT/Language/LanguageMenuWindow.xaml.cs @@ -0,0 +1,124 @@ +using Content.Client.Language.Systems; +using Content.Shared.Language; +using Content.Shared.Language.Systems; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Console; +using Robust.Shared.Utility; +using static Content.Shared.Language.Systems.SharedLanguageSystem; + +namespace Content.Client.ADT.Language; // This EXACT class must have the _NF part because of xaml linking + +[GenerateTypedNameReferences] +public sealed partial class LanguageMenuWindow : DefaultWindow +{ + [Dependency] private readonly IConsoleHost _consoleHost = default!; + private readonly LanguageSystem _language; + + private readonly List _entries = new(); + + public LanguageMenuWindow() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + _language = IoCManager.Resolve().GetEntitySystem(); + + Title = Loc.GetString("language-menu-window-title"); + } + + public void UpdateState(LanguageMenuStateMessage state) + { + var clanguage = _language.GetLanguage(state.CurrentLanguage); + CurrentLanguageLabel.Text = Loc.GetString("language-menu-current-language", ("language", clanguage?.LocalizedName ?? "")); + + OptionsList.RemoveAllChildren(); + _entries.Clear(); + + foreach (var language in state.Options) + { + AddLanguageEntry(language); + } + + // Disable the button for the currently chosen language + foreach (var entry in _entries) + { + if (entry.button != null) + entry.button.Disabled = entry.language == state.CurrentLanguage; + } + } + + private void AddLanguageEntry(string language) + { + var proto = _language.GetLanguage(language); + var state = new EntryState { language = language }; + + var container = new BoxContainer(); + container.Orientation = BoxContainer.LayoutOrientation.Vertical; + + // Create and add a header with the name and the button to select the language + { + var header = new BoxContainer(); + header.Orientation = BoxContainer.LayoutOrientation.Horizontal; + + header.Orientation = BoxContainer.LayoutOrientation.Horizontal; + header.HorizontalExpand = true; + header.SeparationOverride = 2; + + var name = new Label(); + name.Text = proto?.LocalizedName ?? ""; + name.MinWidth = 50; + name.HorizontalExpand = true; + + var button = new Button(); + button.Text = "Выбрать"; + button.OnPressed += _ => OnLanguageChosen(language); + state.button = button; + + header.AddChild(name); + header.AddChild(button); + + container.AddChild(header); + } + + // Create and add a collapsible description + { + var body = new CollapsibleBody(); + body.HorizontalExpand = true; + body.Margin = new Thickness(4f, 4f); + + var description = new RichTextLabel(); + description.SetMessage(proto?.LocalizedDescription ?? ""); + description.HorizontalExpand = true; + + body.AddChild(description); + + var collapser = new Collapsible(Loc.GetString("language-menu-description-header"), body); + collapser.Orientation = BoxContainer.LayoutOrientation.Vertical; + collapser.HorizontalExpand = true; + + container.AddChild(collapser); + } + + // Before adding, wrap the new container in a PanelContainer to give it a distinct look + var wrapper = new PanelContainer(); + wrapper.StyleClasses.Add("PdaBorderRect"); + + wrapper.AddChild(container); + OptionsList.AddChild(wrapper); + + _entries.Add(state); + } + + private void OnLanguageChosen(string id) + { + _consoleHost.ExecuteCommand("lsselectlang " + id); + } + + private struct EntryState + { + public string language; + public Button? button; + } +} diff --git a/Content.Client/ADT/Language/Systems/LanguageSystem.cs b/Content.Client/ADT/Language/Systems/LanguageSystem.cs new file mode 100644 index 0000000000..4d603a700a --- /dev/null +++ b/Content.Client/ADT/Language/Systems/LanguageSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Language.Systems; + +namespace Content.Client.Language.Systems; + +public sealed class LanguageSystem : SharedLanguageSystem +{ + +} diff --git a/Content.Client/ADT/Language/Systems/TranslatorImplanterSystem.cs b/Content.Client/ADT/Language/Systems/TranslatorImplanterSystem.cs new file mode 100644 index 0000000000..bbe28d24f5 --- /dev/null +++ b/Content.Client/ADT/Language/Systems/TranslatorImplanterSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.Language.Systems; + +namespace Content.Client.Language.Systems; + +public sealed class TranslatorImplanterSystem : SharedTranslatorImplanterSystem +{ + +} diff --git a/Content.Server/ADT/Language/Commands/ListLanguagesCommand.cs b/Content.Server/ADT/Language/Commands/ListLanguagesCommand.cs new file mode 100644 index 0000000000..eda7030b9b --- /dev/null +++ b/Content.Server/ADT/Language/Commands/ListLanguagesCommand.cs @@ -0,0 +1,39 @@ +using System.Linq; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.Enums; + +namespace Content.Server.Language.Commands; + +[AnyCommand] +public sealed class ListLanguagesCommand : IConsoleCommand +{ + public string Command => "lslangs"; + public string Description => "List languages your current entity can speak at the current moment."; + public string Help => "lslangs"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not { } player) + { + shell.WriteError("This command cannot be run from the server."); + return; + } + + if (player.Status != SessionStatus.InGame) + return; + + if (player.AttachedEntity is not { } playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } + + var languages = IoCManager.Resolve().GetEntitySystem(); + + var (spokenLangs, knownLangs) = languages.GetAllLanguages(playerEntity); + + shell.WriteLine("Spoken: " + string.Join(", ", spokenLangs)); + shell.WriteLine("Understood: " + string.Join(", ", knownLangs)); + } +} diff --git a/Content.Server/ADT/Language/Commands/SayLanguageCommand.cs b/Content.Server/ADT/Language/Commands/SayLanguageCommand.cs new file mode 100644 index 0000000000..711c2c5fbf --- /dev/null +++ b/Content.Server/ADT/Language/Commands/SayLanguageCommand.cs @@ -0,0 +1,53 @@ +using Content.Server.Chat.Systems; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.Enums; + +namespace Content.Server.Language.Commands; + +[AnyCommand] +public sealed class SayLanguageCommand : IConsoleCommand +{ + public string Command => "lsay"; + public string Description => "Send chat languages to the local channel or a specific chat channel, in a specific language."; + public string Help => "lsay "; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not { } player) + { + shell.WriteError("This command cannot be run from the server."); + return; + } + + if (player.Status != SessionStatus.InGame) + return; + + if (player.AttachedEntity is not { } playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } + + if (args.Length < 2) + return; + + var languageId = args[0]; + var message = string.Join(" ", args, startIndex: 1, count: args.Length - 1).Trim(); + + if (string.IsNullOrEmpty(message)) + return; + + var languages = IoCManager.Resolve().GetEntitySystem(); + var chats = IoCManager.Resolve().GetEntitySystem(); + + var language = languages.GetLanguage(languageId); + if (language == null || !languages.CanSpeak(playerEntity, language.ID)) + { + shell.WriteError($"Language {languageId} is invalid or you cannot speak it!"); + return; + } + + chats.TrySendInGameICMessage(playerEntity, message, InGameICChatType.Speak, ChatTransmitRange.Normal, false, shell, player, languageOverride: language); + } +} diff --git a/Content.Server/ADT/Language/Commands/SelectLanguageCommand.cs b/Content.Server/ADT/Language/Commands/SelectLanguageCommand.cs new file mode 100644 index 0000000000..72336747fa --- /dev/null +++ b/Content.Server/ADT/Language/Commands/SelectLanguageCommand.cs @@ -0,0 +1,48 @@ +using System.Linq; +using Content.Shared.Administration; +using Robust.Shared.Console; +using Robust.Shared.Enums; + +namespace Content.Server.Language.Commands; + +[AnyCommand] +public sealed class SelectLanguageCommand : IConsoleCommand +{ + public string Command => "lsselectlang"; + public string Description => "Open a menu to select a langauge to speak."; + public string Help => "lsselectlang"; + + public void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (shell.Player is not { } player) + { + shell.WriteError("This command cannot be run from the server."); + return; + } + + if (player.Status != SessionStatus.InGame) + return; + + if (player.AttachedEntity is not { } playerEntity) + { + shell.WriteError("You don't have an entity!"); + return; + } + + if (args.Length < 1) + return; + + var languageId = args[0]; + + var languages = IoCManager.Resolve().GetEntitySystem(); + + var language = languages.GetLanguage(languageId); + if (language == null || !languages.CanSpeak(playerEntity, language.ID)) + { + shell.WriteError($"Language {languageId} is invalid or you cannot speak it!"); + return; + } + + languages.SetLanguage(playerEntity, language.ID); + } +} diff --git a/Content.Server/ADT/Language/LanguageSystem.Windows.cs b/Content.Server/ADT/Language/LanguageSystem.Windows.cs new file mode 100644 index 0000000000..52b5e7cbf4 --- /dev/null +++ b/Content.Server/ADT/Language/LanguageSystem.Windows.cs @@ -0,0 +1,40 @@ +using Content.Shared.Language; +using Robust.Server.GameObjects; +using Robust.Shared.Player; + +namespace Content.Server.Language; + +public sealed partial class LanguageSystem +{ + [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + + public void InitializeWindows() + { + SubscribeNetworkEvent(OnLanguagesRequest); + SubscribeLocalEvent(OnLanguageSwitch); + } + + private void OnLanguagesRequest(RequestLanguageMenuStateMessage args, EntitySessionEventArgs session) + { + var uid = session.SenderSession.AttachedEntity; + if (uid == null) + return; + + var langs = GetLanguages(uid.Value); + if (langs == null) + return; + + var state = new LanguageMenuStateMessage(langs.CurrentLanguage, langs.SpokenLanguages); + RaiseNetworkEvent(state, uid.Value); + } + + private void OnLanguageSwitch(EntityUid uid, LanguageSpeakerComponent component, LanguagesUpdateEvent args) + { + var langs = GetLanguages(uid); + if (langs == null) + return; + + var state = new LanguageMenuStateMessage(langs.CurrentLanguage, langs.SpokenLanguages); + RaiseNetworkEvent(state, uid); + } +} diff --git a/Content.Server/ADT/Language/LanguageSystem.cs b/Content.Server/ADT/Language/LanguageSystem.cs new file mode 100644 index 0000000000..e76ce23cd3 --- /dev/null +++ b/Content.Server/ADT/Language/LanguageSystem.cs @@ -0,0 +1,319 @@ +using System.Linq; +using System.Text; +using Content.Shared.GameTicking; +using Content.Shared.Language; +using Content.Shared.Language.Systems; +using Robust.Shared.Random; +using Robust.Shared.Player; +using Robust.Server.GameObjects; +using UniversalLanguageSpeakerComponent = Content.Shared.Language.Components.UniversalLanguageSpeakerComponent; + +namespace Content.Server.Language; + +public sealed partial class LanguageSystem : SharedLanguageSystem +{ + /// + /// A random number added to each pseudo-random number's seed. Changes every round. + /// + public int RandomRoundSeed { get; private set; } + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInitLanguageSpeaker); + SubscribeAllEvent(it => RandomRoundSeed = _random.Next()); + SubscribeLocalEvent(OnUnknow); + + InitializeWindows(); + } + + private void OnInitLanguageSpeaker(EntityUid uid, LanguageSpeakerComponent component, ComponentInit args) + { + if (string.IsNullOrEmpty(component.CurrentLanguage)) + { + component.CurrentLanguage = component.SpokenLanguages.FirstOrDefault(UniversalPrototype); + } + } + + private void OnUnknow(EntityUid uid, UnknowLanguageComponent unknow, MapInitEvent args) + { + TryComp(uid, out var component); + + if (component != null) + { + component.SpokenLanguages.Remove(unknow.LanguageToForgot); + component.UnderstoodLanguages.Remove(unknow.LanguageToForgot); + component.CurrentLanguage = component.SpokenLanguages.FirstOrDefault(UniversalPrototype); + } + else + return; + + } + + /// + /// Obfuscate speech of the given entity, or using the given language. + /// + /// The speaker whose message needs to be obfuscated. Must not be null if "language" is not set. + /// The language for obfuscation. Must not be null if "source" is null. + public string ObfuscateSpeech(EntityUid? source, string message, LanguagePrototype? language = null) + { + if (language == null) + { + if (source is not { Valid: true }) + { + throw new NullReferenceException("Either source or language must be set."); + } + language = GetLanguage(source.Value); + } + + var builder = new StringBuilder(); + if (language.ObfuscateSyllables) + { + ObfuscateSyllables(builder, message, language); + } + else + { + ObfuscatePhrases(builder, message, language); + } + + //_sawmill.Info($"Got {message}, obfuscated to {builder}. Language: {language.ID}"); + + return builder.ToString(); + } + + private void ObfuscateSyllables(StringBuilder builder, string message, LanguagePrototype language) + { + // Go through each word. Calculate its hash sum and count the number of letters. + // Replicate it with pseudo-random syllables of pseudo-random (but similar) length. Use the hash code as the seed. + // This means that identical words will be obfuscated identically. Simple words like "hello" or "yes" in different langs can be memorized. + var wordBeginIndex = 0; + var hashCode = 0; + for (var i = 0; i < message.Length; i++) + { + var ch = char.ToLower(message[i]); + // A word ends when one of the following is found: a space, a sentence end, or EOM + if (char.IsWhiteSpace(ch) || IsSentenceEnd(ch) || i == message.Length - 1) + { + var wordLength = i - wordBeginIndex; + if (wordLength > 0) + { + var newWordLength = PseudoRandomNumber(hashCode, 1, 4); + + for (var j = 0; j < newWordLength; j++) + { + var index = PseudoRandomNumber(hashCode + j, 0, language.Replacement.Count); + builder.Append(language.Replacement[index]); + } + } + + builder.Append(ch); + hashCode = 0; + wordBeginIndex = i + 1; + } + else + { + hashCode = hashCode * 31 + ch; + } + } + } + + private void ObfuscatePhrases(StringBuilder builder, string message, LanguagePrototype language) + { + // In a similar manner, each phrase is obfuscated with a random number of conjoined obfuscation phrases. + // However, the number of phrases depends on the number of characters in the original phrase. + var sentenceBeginIndex = 0; + for (var i = 0; i < message.Length; i++) + { + var ch = char.ToLower(message[i]); + if (IsSentenceEnd(ch) || i == message.Length - 1) + { + var length = i - sentenceBeginIndex; + if (length > 0) + { + var newLength = (int) Math.Clamp(Math.Cbrt(length) - 1, 1, 4); // 27+ chars for 2 phrases, 64+ for 3, 125+ for 4. + + for (var j = 0; j < newLength; j++) + { + var phrase = _random.Pick(language.Replacement); + builder.Append(phrase); + } + } + sentenceBeginIndex = i + 1; + + if (IsSentenceEnd(ch)) + builder.Append(ch).Append(" "); + } + } + } + + public bool CanUnderstand(EntityUid listener, + LanguagePrototype language, + LanguageSpeakerComponent? listenerLanguageComp = null) + { + if (language.ID == UniversalPrototype || HasComp(listener)) + return true; + + var listenerLanguages = GetLanguages(listener, listenerLanguageComp)?.UnderstoodLanguages; + + return listenerLanguages?.Contains(language.ID, StringComparer.Ordinal) ?? false; + } + + public bool CanSpeak(EntityUid speaker, string language, LanguageSpeakerComponent? speakerComp = null) + { + if (HasComp(speaker)) + return true; + + var langs = GetLanguages(speaker, speakerComp)?.UnderstoodLanguages; + return langs?.Contains(language, StringComparer.Ordinal) ?? false; + } + + // + // Returns the current language of the given entity. Assumes Universal if not specified. + // + public LanguagePrototype GetLanguage(EntityUid speaker, LanguageSpeakerComponent? languageComp = null) + { + var id = GetLanguages(speaker, languageComp)?.CurrentLanguage; + if (id == null) + return Universal; // Fallback + + _prototype.TryIndex(id, out LanguagePrototype? proto); + + return proto ?? Universal; + } + + // + // Set the CurrentLanguage of the given entity. + // + public void SetLanguage(EntityUid speaker, string language, LanguageSpeakerComponent? languageComp = null) + { + if (!CanSpeak(speaker, language)) + return; + + if (languageComp == null && !TryComp(speaker, out languageComp)) + return; + + if (languageComp.CurrentLanguage == language) + return; + + languageComp.CurrentLanguage = language; + + RaiseLocalEvent(speaker, new LanguagesUpdateEvent(), true); + } + + /// + /// Adds a new language to the lists of understood and/or spoken languages of the given component. + /// + public void AddLanguage(LanguageSpeakerComponent comp, string language, bool addSpoken = true, bool addUnderstood = true) + { + if (addSpoken && !comp.SpokenLanguages.Contains(language, StringComparer.Ordinal)) + comp.SpokenLanguages.Add(language); + + if (addUnderstood && !comp.UnderstoodLanguages.Contains(language, StringComparer.Ordinal)) + comp.UnderstoodLanguages.Add(language); + + RaiseLocalEvent(comp.Owner, new LanguagesUpdateEvent(), true); + } + + private static bool IsSentenceEnd(char ch) + { + return ch is '.' or '!' or '?'; + } + + // This event is reused because re-allocating it each time is way too costly. + private readonly DetermineEntityLanguagesEvent _determineLanguagesEvent = new(string.Empty, new(), new()); + + /// + /// Returns a pair of (spoken, understood) languages of the given entity. + /// + public (List, List) GetAllLanguages(EntityUid speaker) + { + var languages = GetLanguages(speaker); + if (languages == null) + return (new(), new()); + + // The lists need to be copied because the internal ones are re-used for performance reasons. + return (new List(languages.SpokenLanguages), new List(languages.UnderstoodLanguages)); + } + + /// + /// Dynamically resolves the current language of the entity and the list of all languages it speaks. + /// The returned event is reused and thus must not be held as a reference anywhere but inside the caller function. + /// + private DetermineEntityLanguagesEvent? GetLanguages(EntityUid speaker, LanguageSpeakerComponent? comp = null) + { + if (comp == null && !TryComp(speaker, out comp)) + return null; + + var ev = _determineLanguagesEvent; + ev.SpokenLanguages.Clear(); + ev.UnderstoodLanguages.Clear(); + + ev.CurrentLanguage = comp.CurrentLanguage; + ev.SpokenLanguages.AddRange(comp.SpokenLanguages); + ev.UnderstoodLanguages.AddRange(comp.UnderstoodLanguages); + + RaiseLocalEvent(speaker, ev, true); + + if (ev.CurrentLanguage.Length == 0) + ev.CurrentLanguage = !string.IsNullOrEmpty(comp.CurrentLanguage) ? comp.CurrentLanguage : UniversalPrototype; // Fall back to account for admemes like admins possessing a bread + return ev; + } + + /// + /// Generates a stable pseudo-random number in the range [min, max) for the given seed. Each input seed corresponds to exactly one random number. + /// + private int PseudoRandomNumber(int seed, int min, int max) + { + // This is not a uniform distribution, but it shouldn't matter: given there's 2^31 possible random numbers, + // The bias of this function should be so tiny it will never be noticed. + seed += RandomRoundSeed; + var random = ((seed * 1103515245) + 12345) & 0x7fffffff; // Source: http://cs.uccs.edu/~cs591/bufferOverflow/glibc-2.2.4/stdlib/random_r.c + return random % (max - min) + min; + } + + /// + /// Ensures the given entity has a valid language as its current language. + /// If not, sets it to the first entry of its SpokenLanguages list, or universal if it's empty. + /// + public void EnsureValidLanguage(EntityUid entity, LanguageSpeakerComponent? comp = null) + { + if (comp == null && !TryComp(entity, out comp)) + return; + + var langs = GetLanguages(entity, comp); + + if (langs != null && !langs.SpokenLanguages.Contains(comp!.CurrentLanguage, StringComparer.Ordinal)) + { + comp.CurrentLanguage = langs.SpokenLanguages.FirstOrDefault(UniversalPrototype); + } + } + + /// + /// Raised in order to determine the language an entity speaks at the current moment, + /// as well as the list of all languages the entity may speak and understand. + /// + public sealed class DetermineEntityLanguagesEvent : EntityEventArgs + { + /// + /// The default language of this entity. If empty, remain unchanged. + /// This field has no effect if the entity decides to speak in a concrete language. + /// + public string CurrentLanguage; + /// + /// The list of all languages the entity may speak. Must NOT be held as a reference! + /// + public List SpokenLanguages; + /// + /// The list of all languages the entity may understand. Must NOT be held as a reference! + /// + public List UnderstoodLanguages; + + public DetermineEntityLanguagesEvent(string currentLanguage, List spokenLanguages, List understoodLanguages) + { + CurrentLanguage = currentLanguage; + SpokenLanguages = spokenLanguages; + UnderstoodLanguages = understoodLanguages; + } + } +} diff --git a/Content.Server/ADT/Language/TranslatorImplanterSystem.cs b/Content.Server/ADT/Language/TranslatorImplanterSystem.cs new file mode 100644 index 0000000000..f24a013cc2 --- /dev/null +++ b/Content.Server/ADT/Language/TranslatorImplanterSystem.cs @@ -0,0 +1,79 @@ +using System.Linq; +using Content.Server.Administration.Logs; +using Content.Server.Popups; +using Content.Shared.Database; +using Content.Shared.Interaction; +using Content.Shared.Language; +using Content.Shared.Language.Components; +using Content.Shared.Language.Systems; +using Content.Shared.Mobs.Components; + +namespace Content.Server.Language; + +public sealed class TranslatorImplanterSystem : SharedTranslatorImplanterSystem +{ + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly LanguageSystem _language = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnImplant); + } + + private void OnImplant(EntityUid implanter, TranslatorImplanterComponent component, AfterInteractEvent args) + { + if (component.Used || !args.CanReach || args.Target is not { Valid: true } target) + return; + + if (!TryComp(target, out var speaker)) + return; + + if (component.MobsOnly && !HasComp(target)) + { + _popup.PopupEntity("translator-implanter-refuse", component.Owner); + return; + } + + var (_, understood) = _language.GetAllLanguages(target); + if (component.RequiredLanguages.Count > 0 && !component.RequiredLanguages.Any(lang => understood.Contains(lang))) + { + RefusesPopup(implanter, target); + return; + } + + var intrinsic = EnsureComp(target); + intrinsic.Enabled = true; + + foreach (var lang in component.SpokenLanguages.Where(lang => !intrinsic.SpokenLanguages.Contains(lang))) + intrinsic.SpokenLanguages.Add(lang); + + foreach (var lang in component.UnderstoodLanguages.Where(lang => !intrinsic.UnderstoodLanguages.Contains(lang))) + intrinsic.UnderstoodLanguages.Add(lang); + + component.Used = true; + SuccessPopup(implanter, target); + + _adminLogger.Add(LogType.Action, LogImpact.Medium, + $"{ToPrettyString(args.User):player} used {ToPrettyString(implanter):implanter} to give {ToPrettyString(target):target} the following languages:" + + $"\nSpoken: {string.Join(", ", component.SpokenLanguages)}; Understood: {string.Join(", ", component.UnderstoodLanguages)}"); + + OnAppearanceChange(implanter, component); + RaiseLocalEvent(target, new SharedLanguageSystem.LanguagesUpdateEvent(), true); + } + + private void RefusesPopup(EntityUid implanter, EntityUid target) + { + _popup.PopupEntity( + Loc.GetString("translator-implanter-refuse", ("implanter", implanter), ("target", target)), + implanter); + } + + private void SuccessPopup(EntityUid implanter, EntityUid target) + { + _popup.PopupEntity( + Loc.GetString("translator-implanter-success", ("implanter", implanter), ("target", target)), + implanter); + } +} diff --git a/Content.Server/ADT/Language/TranslatorSystem.cs b/Content.Server/ADT/Language/TranslatorSystem.cs new file mode 100644 index 0000000000..e19b2b29d7 --- /dev/null +++ b/Content.Server/ADT/Language/TranslatorSystem.cs @@ -0,0 +1,243 @@ +using System.Linq; +using Content.Server.Popups; +using Content.Server.PowerCell; +using Content.Shared.Hands; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; +using Content.Shared.Inventory; +using Content.Shared.Inventory.Events; +using Content.Shared.Language; +using Content.Shared.Language.Components; +using Content.Shared.Language.Systems; +using Content.Shared.PowerCell; +using static Content.Server.Language.LanguageSystem; +using HandheldTranslatorComponent = Content.Shared.Language.Components.HandheldTranslatorComponent; +using HoldsTranslatorComponent = Content.Shared.Language.Components.HoldsTranslatorComponent; +using IntrinsicTranslatorComponent = Content.Shared.Language.Components.IntrinsicTranslatorComponent; + +namespace Content.Server.Language; + +// this does not support holding multiple translators at once yet. +// that should not be an issue for now, but it better get fixed later. +public sealed class TranslatorSystem : SharedTranslatorSystem +{ + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly LanguageSystem _language = default!; + [Dependency] private readonly PowerCellSystem _powerCell = default!; + + private ISawmill _sawmill = default!; + + public override void Initialize() + { + base.Initialize(); + _sawmill = Logger.GetSawmill("translator"); + + // I wanna die. But my death won't help us discover polymorphism. + SubscribeLocalEvent(ApplyTranslation); + SubscribeLocalEvent(ApplyTranslation); + SubscribeLocalEvent(ApplyTranslation); + // TODO: make this thing draw power + // SubscribeLocalEvent(...); + + SubscribeLocalEvent(OnTranslatorToggle); + SubscribeLocalEvent(OnPowerCellSlotEmpty); + + SubscribeLocalEvent( + (uid, component, args) => TranslatorEquipped(args.User, uid, component)); + SubscribeLocalEvent( + (uid, component, args) => TranslatorUnequipped(args.User, uid, component)); + } + + private void ApplyTranslation(EntityUid uid, IntrinsicTranslatorComponent component, + DetermineEntityLanguagesEvent ev) + { + if (!component.Enabled) + return; + + if (!_powerCell.HasActivatableCharge(uid)) + return; + + var addUnderstood = true; + var addSpoken = true; + if (component.RequiredLanguages.Count > 0) + { + if (component.RequiresAllLanguages) + { + // Add langs when the wielder has all of the required languages + foreach (var language in component.RequiredLanguages) + { + if (!ev.SpokenLanguages.Contains(language, StringComparer.Ordinal)) + addSpoken = false; + + if (!ev.UnderstoodLanguages.Contains(language, StringComparer.Ordinal)) + addUnderstood = false; + } + } + else + { + // Add langs when the wielder has at least one of the required languages + addUnderstood = false; + addSpoken = false; + foreach (var language in component.RequiredLanguages) + { + if (ev.SpokenLanguages.Contains(language, StringComparer.Ordinal)) + addSpoken = true; + + if (ev.UnderstoodLanguages.Contains(language, StringComparer.Ordinal)) + addUnderstood = true; + } + } + } + + if (addSpoken) + { + foreach (var language in component.SpokenLanguages) + { + AddIfNotExists(ev.SpokenLanguages, language); + } + + if (component.CurrentSpeechLanguage != null && ev.CurrentLanguage.Length == 0) + { + ev.CurrentLanguage = component.CurrentSpeechLanguage; + } + } + + if (addUnderstood) + { + foreach (var language in component.UnderstoodLanguages) + { + AddIfNotExists(ev.UnderstoodLanguages, language); + } + } + } + + private void TranslatorEquipped(EntityUid holder, EntityUid translator, HandheldTranslatorComponent component) + { + if (!EntityManager.HasComponent(holder)) + return; + + var intrinsic = EntityManager.EnsureComponent(holder); + UpdateBoundIntrinsicComp(component, intrinsic, component.Enabled); + + UpdatedLanguages(holder); + } + + private void TranslatorUnequipped(EntityUid holder, EntityUid translator, HandheldTranslatorComponent component) + { + if (!EntityManager.TryGetComponent(holder, out var intrinsic)) + return; + + if (intrinsic.Issuer == component) + { + + intrinsic.Enabled = false; + EntityManager.RemoveComponent(holder, intrinsic); + } + + _language.EnsureValidLanguage(holder); + + UpdatedLanguages(holder); + } + + private void OnTranslatorToggle(EntityUid translator, HandheldTranslatorComponent component, ActivateInWorldEvent args) + { + if (!component.ToggleOnInteract) + return; + + var hasPower = _powerCell.HasDrawCharge(translator); + + if (Transform(args.Target).ParentUid is { Valid: true } holder && EntityManager.HasComponent(holder)) + { + // This translator is held by a language speaker and thus has an intrinsic counterpart bound to it. Make sure it's up-to-date. + var intrinsic = EntityManager.EnsureComponent(holder); + var isEnabled = !component.Enabled; + if (intrinsic.Issuer != component) + { + // The intrinsic comp wasn't owned by this handheld component, so this comp wasn't the active translator. + // Thus it needs to be turned on regardless of its previous state. + intrinsic.Issuer = component; + isEnabled = true; + } + + isEnabled &= hasPower; + UpdateBoundIntrinsicComp(component, intrinsic, isEnabled); + component.Enabled = isEnabled; + _powerCell.SetPowerCellDrawEnabled(translator, isEnabled); + + _language.EnsureValidLanguage(holder); + UpdatedLanguages(holder); + } + else + { + // This is a standalone translator (e.g. lying on the ground). Simply toggle its state. + component.Enabled = !component.Enabled && hasPower; + _powerCell.SetPowerCellDrawEnabled(translator, !component.Enabled && hasPower); + } + + OnAppearanceChange(translator, component); + + // HasPower shows a popup when there's no power, so we do not proceed in that case + if (hasPower) + { + var message = + Loc.GetString(component.Enabled ? "translator-component-turnon" : "translator-component-shutoff", ("translator", component.Owner)); + _popup.PopupEntity(message, component.Owner, args.User); + } + } + + private void OnPowerCellSlotEmpty(EntityUid translator, HandheldTranslatorComponent component, PowerCellSlotEmptyEvent args) + { + component.Enabled = false; + _powerCell.SetPowerCellDrawEnabled(translator, false); + OnAppearanceChange(translator, component); + + if (Transform(translator).ParentUid is { Valid: true } holder && EntityManager.HasComponent(holder)) + { + if (!EntityManager.TryGetComponent(holder, out var intrinsic)) + return; + + if (intrinsic.Issuer == component) + { + intrinsic.Enabled = false; + EntityManager.RemoveComponent(holder, intrinsic); + } + + _language.EnsureValidLanguage(holder); + UpdatedLanguages(holder); + } + } + + /// + /// Copies the state from the handheld [comp] to the [intrinsic] comp, using [isEnabled] as the enabled state. + /// + private void UpdateBoundIntrinsicComp(HandheldTranslatorComponent comp, HoldsTranslatorComponent intrinsic, bool isEnabled) + { + if (isEnabled) + { + intrinsic.SpokenLanguages = new List(comp.SpokenLanguages); + intrinsic.UnderstoodLanguages = new List(comp.UnderstoodLanguages); + intrinsic.CurrentSpeechLanguage = comp.CurrentSpeechLanguage; + } + else + { + intrinsic.SpokenLanguages.Clear(); + intrinsic.UnderstoodLanguages.Clear(); + intrinsic.CurrentSpeechLanguage = null; + } + + intrinsic.Enabled = isEnabled; + intrinsic.Issuer = comp; + } + + private static void AddIfNotExists(List list, string item) + { + if (list.Contains(item)) + return; + list.Add(item); + } + + private void UpdatedLanguages(EntityUid uid) + { + RaiseLocalEvent(uid, new SharedLanguageSystem.LanguagesUpdateEvent(), true); + } +} diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 38d485458b..93818d0df6 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -11,6 +11,7 @@ using Content.Server.Speech.EntitySystems; using Content.Server.Station.Components; using Content.Server.Station.Systems; +using Content.Server.Language; using Content.Shared.ActionBlocker; using Content.Shared.Administration; using Content.Shared.CCVar; @@ -26,6 +27,7 @@ using Content.Shared.Radio; using Content.Shared.Speech; using Content.Shared.Whitelist; +using Content.Shared.Language; using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; @@ -64,6 +66,7 @@ public sealed partial class ChatSystem : SharedChatSystem [Dependency] private readonly ReplacementAccentSystem _wordreplacement = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly ExamineSystemShared _examineSystem = default!; + [Dependency] private readonly LanguageSystem _language = default!; // Corvax-TTS-Start: Moved from Server to Shared // public const int VoiceRange = 10; // how far voice goes in world units @@ -177,8 +180,8 @@ public void TrySendInGameICMessage( ICommonSession? player = null, string? nameOverride = null, bool checkRadioPrefix = true, - bool ignoreActionBlocker = false - ) + bool ignoreActionBlocker = false, + LanguagePrototype? languageOverride = null) // Frontier - languages mechanic { if (HasComp(source)) { @@ -253,10 +256,10 @@ public void TrySendInGameICMessage( switch (desiredType) { case InGameICChatType.Speak: - SendEntitySpeak(source, message, range, nameOverride, hideLog, ignoreActionBlocker); + SendEntitySpeak(source, message, range, nameOverride, hideLog, ignoreActionBlocker, languageOverride: languageOverride); break; case InGameICChatType.Whisper: - SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker); + SendEntityWhisper(source, message, range, null, nameOverride, hideLog, ignoreActionBlocker, languageOverride: languageOverride); break; case InGameICChatType.Emote: SendEntityEmote(source, message, range, nameOverride, hideLog: hideLog, ignoreActionBlocker: ignoreActionBlocker); @@ -387,7 +390,8 @@ private void SendEntitySpeak( ChatTransmitRange range, string? nameOverride, bool hideLog = false, - bool ignoreActionBlocker = false + bool ignoreActionBlocker = false, + LanguagePrototype? languageOverride = null // Frontier: languages mechanic ) { if (!_actionBlocker.CanSpeak(source) && !ignoreActionBlocker) @@ -416,18 +420,30 @@ private void SendEntitySpeak( speech = proto; } + // Frontier - languages mechanic + var language = languageOverride ?? _language.GetLanguage(source); + name = FormattedMessage.EscapeText(name); + // Frontier: languages mechanic ADT Upd start + if (TryComp(source, out var lang) && lang.CurrentLanguage != "GalacticCommon" && lang.CurrentLanguage != "Universal") + name = $"{lang.LocalizedID}|{name}"; + // Frontier: languages mechanic ADT Upd end + var wrappedMessage = Loc.GetString(speech.Bold ? "chat-manager-entity-say-bold-wrap-message" : "chat-manager-entity-say-wrap-message", ("entityName", name), ("verb", Loc.GetString(_random.Pick(speech.SpeechVerbStrings))), ("fontType", speech.FontId), ("fontSize", speech.FontSize), ("message", FormattedMessage.EscapeText(message))); + + var encodedMessage = _language.ObfuscateSpeech(source, message, language); + var wrappedEncodedMessage = WrapPublicMessage(source, name, encodedMessage); - SendInVoiceRange(ChatChannel.Local, message, wrappedMessage, source, range); + // Frontier: languages mechanic + SendInVoiceRange(ChatChannel.Local, message, wrappedMessage, encodedMessage, wrappedEncodedMessage, source, range, languageOverride: language); - var ev = new EntitySpokeEvent(source, message, originalMessage, null, null); + var ev = new EntitySpokeEvent(source, message, originalMessage, encodedMessage, null, language, null); RaiseLocalEvent(source, ev, true); // To avoid logging any messages sent by entities that are not players, like vendors, cloning, etc. @@ -460,7 +476,8 @@ private void SendEntityWhisper( RadioChannelPrototype? channel, string? nameOverride, bool hideLog = false, - bool ignoreActionBlocker = false + bool ignoreActionBlocker = false, + LanguagePrototype? languageOverride = null // Frontier: languages mechanic ) { if (!_actionBlocker.CanSpeak(source) && !ignoreActionBlocker) @@ -487,16 +504,15 @@ private void SendEntityWhisper( name = nameEv.Name; } name = FormattedMessage.EscapeText(name); + + // Frontier: languages mechanic ADT Upd start + if (TryComp(source, out var lang) && lang.CurrentLanguage != "GalacticCommon" && lang.CurrentLanguage != "Universal") + name = $"{lang.LocalizedID}|{name}"; + // Frontier: languages mechanic ADT Upd end - var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", - ("entityName", name), ("message", FormattedMessage.EscapeText(message))); - - var wrappedobfuscatedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", - ("entityName", nameIdentity), ("message", FormattedMessage.EscapeText(obfuscatedMessage))); - - var wrappedUnknownMessage = Loc.GetString("chat-manager-entity-whisper-unknown-wrap-message", - ("message", FormattedMessage.EscapeText(obfuscatedMessage))); - + // Frontier - languages mechanic (+ everything in the foreach loop) + var language = languageOverride ?? _language.GetLanguage(source); + var languageEncodedMessage = _language.ObfuscateSpeech(source, message, language); foreach (var (session, data) in GetRecipients(source, WhisperMuffledRange)) { @@ -509,19 +525,42 @@ private void SendEntityWhisper( if (MessageRangeCheck(session, data, range) != MessageRangeCheckResult.Full) continue; // Won't get logged to chat, and ghosts are too far away to see the pop-up, so we just won't send it to them. + var canUnderstand = _language.CanUnderstand(listener, language); + var _message = canUnderstand ? message : languageEncodedMessage; + if (data.Range <= WhisperClearRange) - _chatManager.ChatMessageToOne(ChatChannel.Whisper, message, wrappedMessage, source, false, session.Channel); + { + var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", + ("entityName", name), ("message", FormattedMessage.EscapeText(_message))); + + _chatManager.ChatMessageToOne(ChatChannel.Whisper, _message, wrappedMessage, source, false, session.Channel); + } //If listener is too far, they only hear fragments of the message else if (_examineSystem.InRangeUnOccluded(source, listener, WhisperMuffledRange)) - _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedobfuscatedMessage, source, false, session.Channel); + { + var _obfuscatedMessage = ObfuscateMessageReadability(_message, 0.2f); + + var wrappedobfuscatedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message", + ("entityName", nameIdentity), ("message", FormattedMessage.EscapeText(_obfuscatedMessage))); + _chatManager.ChatMessageToOne(ChatChannel.Whisper, _obfuscatedMessage, wrappedobfuscatedMessage, source, false, session.Channel); + } //If listener is too far and has no line of sight, they can't identify the whisperer's identity else - _chatManager.ChatMessageToOne(ChatChannel.Whisper, obfuscatedMessage, wrappedUnknownMessage, source, false, session.Channel); + { + var _obfuscatedMessage = ObfuscateMessageReadability(_message, 0.2f); + + var wrappedUnknownMessage = Loc.GetString("chat-manager-entity-whisper-unknown-wrap-message", + ("message", FormattedMessage.EscapeText(_obfuscatedMessage))); + _chatManager.ChatMessageToOne(ChatChannel.Whisper, _obfuscatedMessage, wrappedUnknownMessage, source, false, session.Channel); + } } - _replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); + var replayWrap = Loc.GetString("chat-manager-entity-whisper-wrap-message", + ("entityName", name), + ("message", FormattedMessage.EscapeText(message))); + _replay.RecordServerMessage(new ChatMessage(ChatChannel.Whisper, message, replayWrap, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); - var ev = new EntitySpokeEvent(source, message, originalMessage, channel, obfuscatedMessage); + var ev = new EntitySpokeEvent(source, message, originalMessage, languageEncodedMessage, channel, language, obfuscatedMessage); RaiseLocalEvent(source, ev, true); if (!hideLog) if (originalMessage == message) @@ -568,7 +607,7 @@ private void SendEntityEmote( if (checkEmote) TryEmoteChatInput(source, action); - SendInVoiceRange(ChatChannel.Emotes, action, wrappedMessage, source, range, author); + SendInVoiceRange(ChatChannel.Emotes, action, wrappedMessage,encodedMessage: string.Empty, wrappedEncodedMessage: string.Empty, source, range, author); if (!hideLog) if (name != Name(source)) _adminLogger.Add(LogType.Chat, LogImpact.Low, $"Emote from {ToPrettyString(source):user} as {name}: {action}"); @@ -595,7 +634,12 @@ private void SendLOOC(EntityUid source, ICommonSession player, string message, b ("entityName", name), ("message", FormattedMessage.EscapeText(message))); - SendInVoiceRange(ChatChannel.LOOC, message, wrappedMessage, source, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, player.UserId); + SendInVoiceRange(ChatChannel.LOOC, message, wrappedMessage, + encodedMessage: string.Empty, + wrappedEncodedMessage: string.Empty, + source, hideChat ? ChatTransmitRange.HideChat : ChatTransmitRange.Normal, + player.UserId, + languageOverride: LanguageSystem.Universal); _adminLogger.Add(LogType.Chat, LogImpact.Low, $"LOOC from {player:Player}: {message}"); } @@ -676,15 +720,31 @@ private MessageRangeCheckResult MessageRangeCheck(ICommonSession session, ICChat /// /// Sends a chat message to the given players in range of the source entity. /// - private void SendInVoiceRange(ChatChannel channel, string message, string wrappedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null) + private void SendInVoiceRange(ChatChannel channel, string message, string wrappedMessage, string encodedMessage, string wrappedEncodedMessage, EntityUid source, ChatTransmitRange range, NetUserId? author = null, LanguagePrototype? languageOverride = null) { + + var language = languageOverride ?? _language.GetLanguage(source); // frontier + foreach (var (session, data) in GetRecipients(source, VoiceRange)) { var entRange = MessageRangeCheck(session, data, range); if (entRange == MessageRangeCheckResult.Disallowed) continue; var entHideChat = entRange == MessageRangeCheckResult.HideChat; - _chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.Channel, author: author); + + // Frontier - languages mechanic + if (session.AttachedEntity is not { Valid: true } playerEntity) + continue; + EntityUid listener = session.AttachedEntity.Value; + + if (channel == ChatChannel.LOOC || channel == ChatChannel.Emotes || _language.CanUnderstand(listener, language)) + { + _chatManager.ChatMessageToOne(channel, message, wrappedMessage, source, entHideChat, session.ConnectedClient, author: author); + } + else + { + _chatManager.ChatMessageToOne(channel, encodedMessage, wrappedEncodedMessage, source, entHideChat, session.ConnectedClient, author: author); + } } _replay.RecordServerMessage(new ChatMessage(channel, message, wrappedMessage, GetNetEntity(source), null, MessageRangeHideChatForReplay(range))); @@ -794,6 +854,19 @@ public string SanitizeMessageReplaceWords(string message) return msg; } + // Frontier - languages mechanic + public string WrapPublicMessage(EntityUid source, string name, string message) + { + var speech = GetSpeechVerb(source, message); + var verbName = Loc.GetString(_random.Pick(speech.SpeechVerbStrings)); + return Loc.GetString(speech.Bold ? "chat-manager-entity-say-bold-wrap-message" : "chat-manager-entity-say-wrap-message", + ("entityName", name), + ("verb", verbName), + ("fontType", speech.FontId), + ("fontSize", speech.FontSize), + ("message", FormattedMessage.EscapeText(message))); + } + /// /// Returns list of players and ranges for all players withing some range. Also returns observers with a range of -1. /// @@ -930,7 +1003,9 @@ public sealed class EntitySpokeEvent : EntityEventArgs public readonly EntityUid Source; public readonly string Message; public readonly string OriginalMessage; - public readonly string? ObfuscatedMessage; // not null if this was a whisper + public readonly string LanguageEncodedMessage; + public readonly string? ObfuscatedMessage; // not null if this was a + public readonly LanguagePrototype Language; /// /// If the entity was trying to speak into a radio, this was the channel they were trying to access. If a radio @@ -938,13 +1013,15 @@ public sealed class EntitySpokeEvent : EntityEventArgs /// public RadioChannelPrototype? Channel; - public EntitySpokeEvent(EntityUid source, string message, string originalMessage, RadioChannelPrototype? channel, string? obfuscatedMessage) + public EntitySpokeEvent(EntityUid source, string message, string originalMessage, string languageEncodedMessage, RadioChannelPrototype? channel, LanguagePrototype language, string? obfuscatedMessage) { Source = source; Message = message; OriginalMessage = originalMessage; // Corvax-TTS: Spec symbol sanitize + LanguageEncodedMessage = languageEncodedMessage; Channel = channel; ObfuscatedMessage = obfuscatedMessage; + Language = language; } } diff --git a/Content.Shared/ADT/Language/Components/CommonLangUnknown.cs b/Content.Shared/ADT/Language/Components/CommonLangUnknown.cs new file mode 100644 index 0000000000..bac1230704 --- /dev/null +++ b/Content.Shared/ADT/Language/Components/CommonLangUnknown.cs @@ -0,0 +1,14 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language; + +[RegisterComponent] +public sealed partial class UnknowLanguageComponent : Component +{ + [DataField("language")] + public string LanguageToForgot = "GalacticCommon"; +} diff --git a/Content.Shared/ADT/Language/Components/LanguageSpeakerComponent.cs b/Content.Shared/ADT/Language/Components/LanguageSpeakerComponent.cs new file mode 100644 index 0000000000..2d3953f78c --- /dev/null +++ b/Content.Shared/ADT/Language/Components/LanguageSpeakerComponent.cs @@ -0,0 +1,53 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language; + +[RegisterComponent, AutoGenerateComponentState] +public sealed partial class LanguageSpeakerComponent : Component +{ + /// + /// The current language the entity may use to speak. + /// Other listeners will hear the entity speak in this language. + /// + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] + public string CurrentLanguage = default!; + + /// + /// чтоб в чате видно было не айди, а название. + /// + public string LocalizedID => Loc.GetString("language-" + CurrentLanguage); + + + /// + /// List of languages this entity can speak. + /// + [ViewVariables] + [DataField("speaks", customTypeSerializer: typeof(PrototypeIdListSerializer), required: true)] + public List SpokenLanguages = new(); + + /// + /// List of languages this entity can understand. + /// + [ViewVariables] + [DataField("understands", customTypeSerializer: typeof(PrototypeIdListSerializer), required: true)] + public List UnderstoodLanguages = new(); + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("languageMenuAction", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string LanguageMenuAction = "ActionLanguageMenu"; + + [DataField] public EntityUid? Action; +} + +[Serializable, NetSerializable] +public enum LanguageMenuUiKey : byte +{ + Key +} + +public sealed partial class LanguageMenuActionEvent : InstantActionEvent { } diff --git a/Content.Shared/ADT/Language/Components/TranslatorComponent.cs b/Content.Shared/ADT/Language/Components/TranslatorComponent.cs new file mode 100644 index 0000000000..a5fac7d2ff --- /dev/null +++ b/Content.Shared/ADT/Language/Components/TranslatorComponent.cs @@ -0,0 +1,93 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language.Components; + +public abstract partial class BaseTranslatorComponent : Component +{ + /// + /// The language this translator changes the speaker's language to when they don't specify one. + /// If null, does not modify the default language. + /// + [DataField("default-language")] + [ViewVariables(VVAccess.ReadWrite)] + public string? CurrentSpeechLanguage = null; + + /// + /// The list of additional languages this translator allows the wielder to speak. + /// + [DataField("spoken", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [ViewVariables(VVAccess.ReadWrite)] + public List SpokenLanguages = new(); + + /// + /// The list of additional languages this translator allows the wielder to understand. + /// + [DataField("understood", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [ViewVariables(VVAccess.ReadWrite)] + public List UnderstoodLanguages = new(); + + /// + /// The languages the wielding MUST know in order for this translator to have effect. + /// The field [RequiresAllLanguages] indicates whether all of them are required, or just one. + /// + [DataField("requires", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [ViewVariables(VVAccess.ReadWrite)] + public List RequiredLanguages = new(); + + /// + /// If true, the wielder must understand all languages in [RequiredLanguages] to speak [SpokenLanguages], + /// and understand all languages in [RequiredLanguages] to understand [UnderstoodLanguages]. + /// + /// Otherwise, at least one language must be known (or the list must be empty). + /// + [DataField("requires-all")] + [ViewVariables(VVAccess.ReadWrite)] + public bool RequiresAllLanguages = false; + + [DataField("enabled")] + public bool Enabled = true; +} + +/// +/// A translator that must be held in a hand or a pocket of an entity in order ot have effect. +/// +[RegisterComponent] +public sealed partial class HandheldTranslatorComponent : BaseTranslatorComponent +{ + /// + /// Whether or not interacting with this translator + /// toggles it on or off. + /// + [DataField("toggleOnInteract")] + public bool ToggleOnInteract = true; +} + +/// +/// A translator attached to an entity that translates its speech. +/// An example is a translator implant that allows the speaker to speak another language. +/// +[RegisterComponent, Virtual] +public partial class IntrinsicTranslatorComponent : BaseTranslatorComponent +{ +} + +/// +/// Applied internally to the holder of [HandheldTranslatorComponent]. +/// Do not use directly. Use [HandheldTranslatorComponent] instead. +/// +[RegisterComponent] +public sealed partial class HoldsTranslatorComponent : IntrinsicTranslatorComponent +{ + public Component? Issuer = null; +} + +/// +/// Applied to entities who were injected with a translator implant. +/// +[RegisterComponent] +public sealed partial class ImplantedTranslatorComponent : IntrinsicTranslatorComponent +{ +} diff --git a/Content.Shared/ADT/Language/Components/TranslatorImplanterComponent.cs b/Content.Shared/ADT/Language/Components/TranslatorImplanterComponent.cs new file mode 100644 index 0000000000..28ed4cce18 --- /dev/null +++ b/Content.Shared/ADT/Language/Components/TranslatorImplanterComponent.cs @@ -0,0 +1,34 @@ +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.Language.Components; + +/// +/// An item that, when used on a mob, adds an intrinsic translator to it. +/// +[RegisterComponent] +public sealed partial class TranslatorImplanterComponent : Component +{ + [DataField("spoken", customTypeSerializer: typeof(PrototypeIdListSerializer)), ViewVariables] + public List SpokenLanguages = new(); + + [DataField("understood", customTypeSerializer: typeof(PrototypeIdListSerializer)), ViewVariables] + public List UnderstoodLanguages = new(); + + /// + /// The list of languages the mob must understand in order for this translator to have effect. + /// Knowing one language is enough. + /// + [DataField("requires", customTypeSerializer: typeof(PrototypeIdListSerializer)), ViewVariables] + public List RequiredLanguages = new(); + + /// + /// If true, only allows to use this implanter on mobs. + /// + [DataField("mobs-only")] + public bool MobsOnly = true; + + /// + /// Whether this implant has been used already. + /// + public bool Used = false; +} diff --git a/Content.Shared/ADT/Language/Components/UniversalLanguageSpeacerComponent.cs b/Content.Shared/ADT/Language/Components/UniversalLanguageSpeacerComponent.cs new file mode 100644 index 0000000000..7ef609e6ba --- /dev/null +++ b/Content.Shared/ADT/Language/Components/UniversalLanguageSpeacerComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Shared.Language.Components; + +// +// Signifies that this entity can speak and understand any language. +// Applies to such entities as ghosts. +// +[RegisterComponent] +public sealed partial class UniversalLanguageSpeakerComponent : Component +{ + +} diff --git a/Content.Shared/ADT/Language/LanguagePrototype.cs b/Content.Shared/ADT/Language/LanguagePrototype.cs new file mode 100644 index 0000000000..c160187bf6 --- /dev/null +++ b/Content.Shared/ADT/Language/LanguagePrototype.cs @@ -0,0 +1,28 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Language; + +[Prototype("language")] +public sealed class LanguagePrototype : IPrototype +{ + [IdDataField] + public string ID { get; private set; } = default!; + + // + // If true, obfuscated phrases of creatures speaking this language will have their syllables replaced with "replacement" syllables. + // Otherwise entire sentences will be replaced. + // + [DataField("obfuscateSyllables", required: true)] + public bool ObfuscateSyllables { get; private set; } = false; + + // + // Lists all syllables that are used to obfuscate a message a listener cannot understand if obfuscateSyllables is true, + // Otherwise uses all possible phrases the creature can make when trying to say anything. + // + [DataField("replacement", required: true)] + public List Replacement = new(); + + public string LocalizedName => Loc.GetString("language-" + ID + "-name"); + + public string LocalizedDescription => Loc.GetString("language-" + ID + "-description"); +} diff --git a/Content.Shared/ADT/Language/Systems/SharedLanguageSystem.cs b/Content.Shared/ADT/Language/Systems/SharedLanguageSystem.cs new file mode 100644 index 0000000000..54c33fc185 --- /dev/null +++ b/Content.Shared/ADT/Language/Systems/SharedLanguageSystem.cs @@ -0,0 +1,73 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Serialization; + +namespace Content.Shared.Language.Systems; + +public abstract class SharedLanguageSystem : EntitySystem +{ + [ValidatePrototypeId] + public static readonly string GalacticCommonPrototype = "GalacticCommon"; + [ValidatePrototypeId] + public static readonly string UniversalPrototype = "Universal"; + public static LanguagePrototype GalacticCommon { get; private set; } = default!; + public static LanguagePrototype Universal { get; private set; } = default!; + + [Dependency] private readonly SharedActionsSystem _action = default!; + [Dependency] protected readonly IPrototypeManager _prototype = default!; + [Dependency] protected readonly IRobustRandom _random = default!; + protected ISawmill _sawmill = default!; + + public override void Initialize() + { + GalacticCommon = _prototype.Index("GalacticCommon"); + Universal = _prototype.Index("Universal"); + _sawmill = Logger.GetSawmill("language"); + + SubscribeLocalEvent(OnInit); + } + + public LanguagePrototype? GetLanguage(string id) + { + _prototype.TryIndex(id, out var proto); + return proto; + } + + private void OnInit(EntityUid uid, LanguageSpeakerComponent component, MapInitEvent args) + { + _action.AddAction(uid, ref component.Action, component.LanguageMenuAction, uid); + } + + /// + /// Raised on an entity when its list of languages changes. + /// + public sealed class LanguagesUpdateEvent : EntityEventArgs + { + } + + /// + /// Sent when a client wants to update its language menu. + /// + [Serializable, NetSerializable] + public sealed class RequestLanguageMenuStateMessage : EntityEventArgs + { + } + + /// + /// Sent by the server when the client needs to update its language menu, + /// or directly after [RequestLanguageMenuStateMessage]. + /// + [Serializable, NetSerializable] + public sealed class LanguageMenuStateMessage : EntityEventArgs + { + public string CurrentLanguage; + public List Options; + + public LanguageMenuStateMessage(string currentLanguage, List options) + { + CurrentLanguage = currentLanguage; + Options = options; + } + } +} diff --git a/Content.Shared/ADT/Language/Systems/SharedTranslatorImplanterSystem.cs b/Content.Shared/ADT/Language/Systems/SharedTranslatorImplanterSystem.cs new file mode 100644 index 0000000000..5a602d03c5 --- /dev/null +++ b/Content.Shared/ADT/Language/Systems/SharedTranslatorImplanterSystem.cs @@ -0,0 +1,36 @@ +using Content.Shared.Examine; +using Content.Shared.Implants.Components; +using Content.Shared.Language.Components; +using Robust.Shared.Serialization; + +namespace Content.Shared.Language.Systems; + +public abstract class SharedTranslatorImplanterSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + } + + private void OnExamined(EntityUid uid, TranslatorImplanterComponent component, ExaminedEvent args) + { + if (!args.IsInDetailsRange) + return; + + var text = !component.Used + ? Loc.GetString("translator-implanter-ready") + : Loc.GetString("translator-implanter-used"); + + args.PushText(text); + } + + protected void OnAppearanceChange(EntityUid implanter, TranslatorImplanterComponent component) + { + var used = component.Used; + _appearance.SetData(implanter, ImplanterVisuals.Full, !used); + } +} diff --git a/Content.Shared/ADT/Language/Systems/SharedTranslatorSystem.cs b/Content.Shared/ADT/Language/Systems/SharedTranslatorSystem.cs new file mode 100644 index 0000000000..540744139d --- /dev/null +++ b/Content.Shared/ADT/Language/Systems/SharedTranslatorSystem.cs @@ -0,0 +1,34 @@ +using Content.Shared.Examine; +using Content.Shared.Language.Components; +using Content.Shared.Toggleable; + +namespace Content.Shared.Language.Systems; + +public abstract class SharedTranslatorSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + } + + private void OnExamined(EntityUid uid, HandheldTranslatorComponent component, ExaminedEvent args) + { + var state = Loc.GetString(component.Enabled + ? "translator-enabled" + : "translator-disabled"); + + args.PushMarkup(state); + } + + protected void OnAppearanceChange(EntityUid translator, HandheldTranslatorComponent? comp = null) + { + if (comp == null && !TryComp(translator, out comp)) + return; + + _appearance.SetData(translator, ToggleVisuals.Toggled, comp.Enabled); + } +} diff --git a/Resources/Locale/ru-RU/ADT/Actions/language-menu.ftl b/Resources/Locale/ru-RU/ADT/Actions/language-menu.ftl new file mode 100644 index 0000000000..56833276de --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Actions/language-menu.ftl @@ -0,0 +1,6 @@ +language-menu-window-title = Выбор языка +language-menu-current-language = Выбранный язык: {$language} +language-menu-description-header = Описание +choose-lang-button = Выбрать +language-menu-action = Меню языков +language-menu-action-desc = Открыть меню выбора языка. diff --git a/Resources/Locale/ru-RU/ADT/Entities/Objects/Device/translators.ftl b/Resources/Locale/ru-RU/ADT/Entities/Objects/Device/translators.ftl new file mode 100644 index 0000000000..5ae89edec3 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Objects/Device/translators.ftl @@ -0,0 +1,61 @@ +translator-component-shutoff = {$translator} выключается. +translator-component-turnon = The {$translator} включается. +translator-enabled = Оно включено. +translator-disabled = Оно выключено. + +ent-TranslatorUnpowered = переводчик + .desc = Переводит речь. + +ent-Translator = переводчик + .desc = Переводит речь. + +ent-VulpTranslator = переводчик вульпканинов + .desc = Используется вульпканинами, для понимания Общегалактического языка в случае его незнания. + +ent-CanilunztTranslator = переводчик Каннилунц + .desc = Используется для взаимного перевода Общегалактического языка и языка Каннилунц. + +ent-BubblishTranslator = переводчик Пузырчатого языка + .desc = Используется для взаимного перевода Общегалактического и Пузырчатого языков. + +ent-NekomimeticTranslator = переводчик некоязыка + .desc = Используется для взаимного перевода Общегалактического и неко-языков. + +ent-DraconicTranslator = переводчик Синта'унати + .desc = Используется для взаимного перевода Общегалактического языка и Синта'унати. + +ent-SolCommonTranslator = переводчик Солнечного языка + .desc = Используется для взаимного перевода Общегалактического и Солнечного языков. + +ent-RootSpeakTranslator = переводчик Песни Корней + .desc = Используется для взаимного перевода Общегалактического языка и Песни Корней. + +ent-MofficTranslator = переводчик Паучьего языка + .desc = Используется для взаимного перевода Общегалактического и Паучьего языков. + +ent-XenoTranslator = переводчик языка ксено + .desc = Используется для общения с наименее агрессивными ксеноморфами. + +ent-AnimalTranslator = переводчик для животных + .desc = Используется для общения с животными. + +ent-DraskTranslator = переводчик языка Орлуум + .desc = Используется для взаимного перевода Общегалактического языка и языка Орлуум. + +ent-SikTajTranslator = переводчик Сик'тайр + .desc = Используется для взаимного перевода Общегалактического языка и Сик'тайр. + +ent-CintaTajTranslator = переводчик Синта’Тайр + .desc = Используется для взаимного перевода Общегалактического языка и Синта’тайр. + +ent-ArkaneTranslator = переводчик языка Каукиттен + .desc = Используется для взаимного перевода Общегалактического языка и Каукиттен. + +ent-ShadowkinTranslator = переводчик языка Миар + .desc = Используется для взаимного перевода Общегалактического языка и Миар. + +ent-NianTranslator = переводчик Ткачьего языка + .desc = Используется для взаимного перевода Общегалактического и Ткачьего языков. + +ent-FireTranslator = переводчик Огненного языка + .desc = Используется для взаимного перевода Общегалактического и Огненного языков. diff --git a/Resources/Locale/ru-RU/ADT/Entities/Objects/Misc/implanters.ftl b/Resources/Locale/ru-RU/ADT/Entities/Objects/Misc/implanters.ftl new file mode 100644 index 0000000000..ae8e374fb5 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Objects/Misc/implanters.ftl @@ -0,0 +1,68 @@ +translator-implanter-refuse = {$implanter} не возымел эффекта для {$target}. +translator-implanter-success = {$implanter} успешно имплантирован в {$target}. +translator-implanter-ready = Имплантер готов к использованию. +translator-implanter-used = Имплантер пуст. + +ent-BasicGalaticCommonTranslatorImplanter = базовый языковой имплант Общегалактического языка + .desc = Имплант, позволяющий понимать Общегалактический язык. + +ent-AdvancedGalaticCommonTranslatorImplanter = полноценный языковой имплант Общегалактического языка + .desc = Имплант, позволяющий понимать и общаться на Общегалактическом языке. + +ent-BubblishTranslatorImplanter = полноценный языковой имплант Пузырчатого языка + .desc = Имплант, позволяющий понимать и общаться на Пузырчатом языке. + +ent-NekomimeticTranslatorImplanter = полноценный языковой имплант некоязыка + .desc = Имплант, позволяющий понимать и общаться на некоязыке. + +ent-DraconicTranslatorImplanter = полноценный языковой имплант Синта'унати + .desc = Имплант, позволяющий понимать и общаться на Синта'унати. + +ent-CanilunztTranslatorImplanter = полноценный языковой имплант Канилунц + .desc = Имплант, позволяющий понимать и общаться на языке Канилунц. + +ent-SolCommonTranslatorImplanter = полноценный языковой имплант Солнечного языка + .desc = Имплант, позволяющий понимать и общаться на Солнечном языке. + +ent-RootSpeakTranslatorImplanter = базовый языковой имплант Песни корней + .desc = Имплант, позволяющий понимать Песнь корней. + +ent-MofficTranslatorImplanter = полноценный языковой имплант Паучьего языка + .desc = Имплант, позволяющий понимать и общаться на Паучьем языке. + +ent-CodeSpeakImplanter = полноценный языковой имплант Кодового языка + .desc = Имплант, позволяющий понимать и общаться на Кодовом языке. + +ent-SikTajTranslatorImplanter = полноценный языковой имплант языка Сик'тайр + .desc = Имплант, позволяющий понимать и общаться на Сик'тайре. + +ent-CintaTajTranslatorImplanter = полноценный языковой имплант языка Синта’Тайр + .desc = Имплант, позволяющий понимать и общаться на Синта’тайре. + +ent-NianTranslatorImplanter = полноценный языковой имплант Ткачьего языка + .desc = Имплант, позволяющий понимать и общаться на Ткачьем языке. + +ent-FireTranslatorImplanter = базовый языковой имплант Огненного языка + .desc = Имплант, позволяющий понимать Огненный язык. + +ent-DraskTranslatorImplanter = полноценный языковой имплант Орлуум + .desc = Имплант, позволяющий понимать и общаться на языке Орлуум. + +ent-UrsTranslatorImplanter = полноценный языковой имплант Рыкрур + .desc = Имплант, позволяющий понимать и общаться на языке Рыкрур. + +ent-ArkaneTranslatorImplanter = полноценный языковой имплант Каукиттен + .desc = Имплант, позволяющий понимать и общаться на языке Каукиттен. + +ent-ShadowkinTranslatorImplanter = полноценный языковой имплант Миар + .desc = Имплант, позволяющий понимать и общаться на языке Миар. + +ent-BorgTranslatorImplanter = полноценный языковой имплант двоичного кода + .desc = Имплант, позволяющий понимать и общаться на двоичном коде. + +ent-SyndUniversalTranslatorImplanter = универсальный языковой имплант + .desc = Имплант, позволяющий (только) понимать все расовые языки. + +ent-DevTranslatorImplanter = имплант языка разработчика + .desc = Опять чинить апстрим? + .suffix = АДМЕМЫ diff --git a/Resources/Locale/ru-RU/ADT/Languages/languages.ftl b/Resources/Locale/ru-RU/ADT/Languages/languages.ftl new file mode 100644 index 0000000000..f1cdbe6c92 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Languages/languages.ftl @@ -0,0 +1,133 @@ +language-Universal-name = Универсальный +language-Universal-description = Что ты такое? +language-GalacticCommon-name = Общегалактический +language-GalacticCommon-description = Обычно используется для межвидового общения и официальных целей. +language-Bubblish-name = Пузырчатый +language-Bubblish-description = Язык слаймолюдов. Это смесь булькающих звуков и хлюпов. Человеку очень трудно говорить без механической помощи. +language-RootSpeak-name = Песнь корней +language-RootSpeak-description = Странный шелестящий язык, на котором говорят дионы. +language-CodeSpeak-name = Кодовый язык +language-CodeSpeak-description = Оперативники синдиката могут использовать серию кодовых слов для передачи сложной информации, в то время как для любого слушателя они звучат как случайные понятия и напитки. +language-Nekomimetic-name = Некоязык +language-Nekomimetic-description = Для стороннего наблюдателя этот язык представляет собой непонятную смесь ломаного японского. Для фелинидов он каким-то образом понятен. +language-Draconic-name = Синта'унати +language-Draconic-description = Общий язык унатхов с преобладающими шипящими звуками. +language-Canilunzt-name = Канилунц +language-Canilunzt-description = Гортанный язык, на котором говорят и используют обитатели системы Ваззенда, состоящий из рычания, лая, тявканья и интенсивного использования движений ушей и хвоста, вулпканины говорят на этом языке с легкостью. + +language-SikTaj-name = Сик'тайр +language-SikTaj-description = Язык, на котором говорят и используют обитатели системы Адомай. Таяры говорят на этом языке с легкостью. + +language-Nian-name = Ткачий +language-Nian-description = Язык, состоящий из жужжащих звуков, на котором говорят и используют нианы. + +language-Fire-name = Огненный +language-Fire-description = Звуки огня, что каким-то образом складываются в осмысленную речь. + +language-SolCommon-name = Солнечный язык +language-SolCommon-description = Общий язык, на котором говорят обитатели солнечной системы. +language-Cat-name = Кошачий +language-Cat-description = Примитивные звуки, издаваемые кошками. Каким-то образом они передают смысл! + +language-Dog-name = Собачий +language-Dog-description = Лающие и рычащие звуки, используемые для передачи примитивных значений. + +language-Mothroach-name = Молиный +language-Mothroach-description = Милые пищащие звуки, из которых иногда складываются осмысленные фразы. + +language-Xeno-name = Ксено +language-Xeno-description = Давно забытый язык ксеноморфов. + +language-RobotTalk-name = Троичный +language-RobotTalk-description = Это не язык сам по себе, но он используется роботами и КПБ для обмена данными. + +language-Monkey-name = Обезьяний +language-Monkey-description = Набор звуков и жестов, издаваемых приматами с целью общения. + +language-Bee-name = Пчелиный +language-Bee-description = Странный язык, основанный на движениях, которые пчелы используют для общения. + +language-Mouse-name = Мышиный +language-Mouse-description = Милые пищащие звуки, которые мыши используют, чтобы выпрашивать еду. + +# These ones are half-assed because these creatures are almost never played as. +language-Chicken-name = Animal chicken +language-Chicken-description = A collection of sounds made by chickens. + +language-Duck-name = Animal duck +language-Duck-description = A collection of sounds made by ducks. + +language-Cow-name = Animal cow +language-Cow-description = A collection of sounds made by cows. + +language-Sheep-name = Animal sheep +language-Sheep-description = A collection of sounds made by sheep. + +language-Kangaroo-name = Animal kangaroo +language-Kangaroo-description = A collection of sounds made by kangaroos. + +language-Pig-name = Animal pig +language-Pig-description = A collection of sounds made by pigs. + +language-Moffic-name = Паучий +language-Moffic-description = Древний язык, на котором говорят арахниды. + +language-Drask-name = Орлуум +language-Drask-description = Монотонный, вибрирующий язык драсков. Он чем-то напоминает китовую песню. + +language-BorgTalk-name = Двоичный +language-BorgTalk-description = Нули и единицы, передающие массивные и не очень данные. + +language-Urs-name = Рыкрур +language-Urs-description = Басистый и рычащий язык, на котором говорят урсы. + +language-Arkane-name = Каукиттен +language-Arkane-description = Протяжный, чем-то напоминающий Солнечный язык, на котором говорят арканы. + +language-Shadowkin-name = Миар +language-Shadowkin-description = Загадочный язык, на котором говорят сумеречники. + +language-Dwarf-name = Шахтёрский +language-Dwarf-description = Rock and stone! + +language-Dev-name = Разработческий +language-Dev-description = Больше звучит как ругань покрытая кодом, чем язык. + +language-CintaTaj-name = Синта’Тайр +language-CintaTaj-description = Язык, разработанный таярами и унатхами для общения между двумя расами, представляет собой смесь шипений и слов. + +language-GalacticCommon = Общ. +language-Bubblish = Пузырчатый +language-RootSpeak = Песнь корней +language-CodeSpeak = Кодовый +language-Nekomimetic = Неко +language-Draconic = Синта'унати +language-Canilunzt = Канилунц +language-SikTaj = Сик'тайр +language-Nian = Ткачий +language-Fire = Огненный +language-SolCommon = Солнечный +language-Cat = Кошачий +language-Dog = Собачий +language-Mothroach = Молиный +language-Xeno = Ксено +language-RobotTalk = Троичный +language-Monkey = Обезьяний +language-Bee = Пчелиный +language-Mouse = Мышиный +language-Drask = Орлуум +# These ones are half-assed because these creatures are almost never played as. +language-Chicken = Animal chicken +language-Duck = Animal duck +language-Cow = Animal cow +language-Sheep = Animal sheep +language-Kangaroo = Animal kangaroo +language-Pig = Animal pig +language-Moffic = Паучий +language-BorgTalk = Двоичный +language-Urs = Рыкрур +language-Arkane = Каукиттен +language-Shadowkin = Миар +language-Dev = Разраб +language-Dwarf = Шахт +language-CintaTaj = Синта’тайр diff --git a/Resources/Locale/ru-RU/ADT/Research/translators.ftl b/Resources/Locale/ru-RU/ADT/Research/translators.ftl new file mode 100644 index 0000000000..13ef329422 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Research/translators.ftl @@ -0,0 +1,3 @@ +research-technology-basic-translation = Технология базовых переводчиков + +research-technology-advanced-translation = Технология продвинутых переводчиков diff --git a/Resources/Prototypes/ADT/Actions/language.yml b/Resources/Prototypes/ADT/Actions/language.yml new file mode 100644 index 0000000000..222a73c9ba --- /dev/null +++ b/Resources/Prototypes/ADT/Actions/language.yml @@ -0,0 +1,12 @@ +- type: entity + id: ActionLanguageMenu + name: language-menu-action + description: language-menu-action-desc + noSpawn: true + components: + - type: InstantAction + checkCanInteract: false + icon: _NF/Interface/Actions/language.png + event: !type:LanguageMenuActionEvent + useDelay: 2 + priority: -97 diff --git a/Resources/Prototypes/ADT/Entities/Objects/Device/translators.yml b/Resources/Prototypes/ADT/Entities/Objects/Device/translators.yml new file mode 100644 index 0000000000..97280e5348 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Objects/Device/translators.yml @@ -0,0 +1,386 @@ +- type: entity + id: TranslatorUnpowered + parent: [ BaseItem ] + name: Translator + description: "Translates speech." + components: + - type: Item + sprite: _NF/Objects/Devices/translator.rsi + inhandVisuals: + left: + - state: inhand-left + right: + - state: inhand-right + - type: Sprite + sprite: _NF/Objects/Devices/translator.rsi + state: icon + layers: + - state: icon + - state: translator + shader: unshaded + visible: false + map: [ "enum.ToggleVisuals.Layer", "enum.PowerDeviceVisualLayers.Powered" ] + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: { visible: true } + False: { visible: false } + - type: HandheldTranslator + enabled: false + - type: ToggleableLightVisuals + spriteLayer: translator + inhandVisuals: + left: + - state: inhand-left-translator + shader: unshaded + right: + - state: inhand-right-translator + shader: unshaded + +- type: entity + id: Translator + parent: [ TranslatorUnpowered, PowerCellSlotMediumItem ] + suffix: Powered + components: + - type: PowerCellDraw + drawRate: 1 + +- type: entity + id: TranslatorEmtpy + parent: [ Translator ] + suffix: Empty + components: + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + +- type: entity + id: VulpTranslator + parent: [ Translator ] + name: Vulpkanin translator + description: "Used only by Vulpkanin to understand and speak with Galatic Common speakers." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + understood: + - GalacticCommon + requires: + - Canilunzt + requires-all: false + - type: PowerCellDraw + drawRate: 0.1 + - type: StaticPrice + price: 35 + +- type: entity + id: CanilunztTranslator + parent: [ TranslatorEmtpy ] + name: Canilunzt translator + description: "Translates speech between Canilunzt and Galactic Common. Commonly used by Vulpkanin to communicate with galactic common speakers" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Canilunzt + understood: + - GalacticCommon + - Canilunzt + requires: + - GalacticCommon + - Canilunzt + requires-all: false + +- type: entity + id: BubblishTranslator + parent: [ TranslatorEmtpy ] + name: Bubblish translator + description: "Translates speech between Bubblish and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Bubblish + understood: + - GalacticCommon + - Bubblish + requires: + - GalacticCommon + - Bubblish + requires-all: false + +- type: entity + id: NekomimeticTranslator + parent: [ TranslatorEmtpy ] + name: Nekomimetic translator + description: "Translates speech between Nekomimetic and Galactic Common. Why would you want that?" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Nekomimetic + understood: + - GalacticCommon + - Nekomimetic + requires: + - GalacticCommon + - Nekomimetic + requires-all: false + +- type: entity + id: DraconicTranslator + parent: [ TranslatorEmtpy ] + name: Draconic translator + description: "Translates speech between Draconic and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Draconic + understood: + - GalacticCommon + - Draconic + requires: + - GalacticCommon + - Draconic + requires-all: false + +- type: entity + id: SolCommonTranslator + parent: [ TranslatorEmtpy ] + name: Sol Common translator + description: "Translates speech between Sol Common and Galactic Common. Like a true Earthman!" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - SolCommon + understood: + - GalacticCommon + - SolCommon + requires: + - GalacticCommon + - SolCommon + requires-all: false + +- type: entity + id: RootSpeakTranslator + parent: [ TranslatorEmtpy ] + name: RootSpeak translator + description: "Translates speech between RootSpeak and Galactic Common. Like a true plant?" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - RootSpeak + understood: + - GalacticCommon + - RootSpeak + requires: + - GalacticCommon + - RootSpeak + requires-all: false + +- type: entity + id: MofficTranslator + parent: [ TranslatorEmtpy ] + name: Moffic translator + description: "Translates speech between Moffic and Galactic Common. Like a true moth... or bug?" + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Moffic + understood: + - GalacticCommon + - Moffic + requires: + - GalacticCommon + - Moffic + requires-all: false + +- type: entity + id: XenoTranslator + parent: [ TranslatorEmtpy ] + name: Xeno translator + description: "Translates speech between Xeno and Galactic Common. Not sure if that will help." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Xeno + understood: + - GalacticCommon + - Xeno + requires: + - GalacticCommon + +- type: entity + id: AnimalTranslator + parent: [ TranslatorEmtpy ] + name: Animal translator + description: "Translates all the cutes nosies that animals make into a more understandable form!" + components: + - type: HandheldTranslator + understood: + - Cat + - Dog + - Mothroach + - Monkey + - Bee + - Mouse + - Chicken + - Duck + - Cow + - Sheep + - Kangaroo + - Pig + requires: + - GalacticCommon + requires-all: false + +- type: entity + id: DraskTranslator + parent: [ TranslatorEmtpy ] + name: Orluum translator + description: "Translates speech between Orluum and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Drask + understood: + - GalacticCommon + - Drask + requires: + - GalacticCommon + - Drask + requires-all: false + + +- type: entity + id: ShadowkinTranslator + parent: [ TranslatorEmtpy ] + name: Shadowkin translator + description: "Translates speech between Shadowkin lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Shadowkin + understood: + - GalacticCommon + - Shadowkin + requires: + - GalacticCommon + - Shadowkin + requires-all: false + +- type: entity + id: ArkaneTranslator + parent: [ TranslatorEmtpy ] + name: Arkane translator + description: "Translates speech between Arkane lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Arkane + understood: + - GalacticCommon + - Arkane + requires: + - GalacticCommon + - Arkane + requires-all: false + +- type: entity + id: NianTranslator + parent: [ TranslatorEmtpy ] + name: Nian translator + description: "Translates speech between Nian lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Nian + understood: + - GalacticCommon + - Nian + requires: + - GalacticCommon + - Nian + requires-all: false + +- type: entity + id: FireTranslator + parent: [ TranslatorEmtpy ] + name: Fire translator + description: "Translates speech between Shadowkin lang and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - Fire + understood: + - GalacticCommon + - Fire + requires: + - GalacticCommon + - Fire + requires-all: false + +- type: entity + id: SikTajTranslator + parent: [ TranslatorEmtpy ] + name: SikTaj translator + description: "Translates speech between SikTaj and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - SikTaj + understood: + - GalacticCommon + - SikTaj + requires: + - GalacticCommon + - SikTaj + requires-all: false + +- type: entity + id: CintaTajTranslator + parent: [ TranslatorEmtpy ] + name: CintaTajTaj translator + description: "Translates speech between CintaTaj and Galactic Common." + components: + - type: HandheldTranslator + default-language: GalacticCommon + spoken: + - GalacticCommon + - CintaTaj + understood: + - GalacticCommon + - CintaTaj + requires: + - GalacticCommon + - CintaTaj + requires-all: false diff --git a/Resources/Prototypes/ADT/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/ADT/Entities/Objects/Misc/implanters.yml new file mode 100644 index 0000000000..3ebd7c9036 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Objects/Misc/implanters.yml @@ -0,0 +1,287 @@ +- type: entity + id: BaseTranslatorImplanter + parent: [ BaseItem ] + name: Basic translator implant + description: "Translates speech." + abstract: true + components: + - type: Sprite + sprite: Objects/Specific/Medical/implanter.rsi + state: implanter0 + layers: + - state: implanter1 + map: [ "implantFull" ] + visible: true + - state: implanter0 + map: [ "implantBroken" ] + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ImplanterVisuals.Full: + implantFull: + True: {visible: true} + False: {visible: false} + implantBroken: + True: {visible: false} + False: {visible: true} + +- type: entity + id: BasicGalaticCommonTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Basic Galatic Common translator implant + description: "An implant giving the ability to understand Galatic Common." + components: + - type: TranslatorImplanter + understood: + - GalacticCommon + +- type: entity + id: AdvancedGalaticCommonTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Advanced Galatic Common translator implant + description: "An implant giving the ability to understand and speak Galatic Common." + components: + - type: TranslatorImplanter + spoken: + - GalacticCommon + understood: + - GalacticCommon + +- type: entity + id: BubblishTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Bubblish translator implant + description: "An implant giving the ability to understand and speak Bubblish." + components: + - type: TranslatorImplanter + spoken: + - Bubblish + understood: + - Bubblish + +- type: entity + id: NekomimeticTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Nekomimetic translator implant + description: "An implant giving the ability to understand and speak Nekomimetic, Nya~!" + components: + - type: TranslatorImplanter + spoken: + - Nekomimetic + understood: + - Nekomimetic + +- type: entity + id: DraconicTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Draconic translator implant + description: "An implant giving the ability to understand and speak Draconic." + components: + - type: TranslatorImplanter + spoken: + - Draconic + understood: + - Draconic + +- type: entity + id: CanilunztTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Canilunzt translator implant + description: "An implant giving the ability to understand and speak Canilunzt, Yeeps!" + components: + - type: TranslatorImplanter + spoken: + - Canilunzt + understood: + - Canilunzt + +- type: entity + id: SolCommonTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: SolCommon translator implant + description: "An implant giving the ability to understand and speak SolCommon, raaagh!" + components: + - type: TranslatorImplanter + spoken: + - SolCommon + understood: + - SolCommon + +- type: entity + id: RootSpeakTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: RootSpeak translator implant + description: "An implant giving the ability to understand and speak RootSpeak." + components: + - type: TranslatorImplanter + understood: + - RootSpeak + +- type: entity + id: MofficTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Moffic translator implant + description: "An implant giving the ability to understand and speak Moffic." + components: + - type: TranslatorImplanter + spoken: + - Moffic + understood: + - Moffic + +- type: entity + id: CodeSpeakImplanter + parent: [ BaseTranslatorImplanter ] + name: CodeSpeak Implanter + description: "\"CodeSpeak(tm) - Secure your communication with metaphors so elaborate, they seem randomly generated!\"" + components: + - type: TranslatorImplanter + spoken: + - CodeSpeak + understood: + - CodeSpeak + - type: StaticPrice + price: 150 + +- type: entity + id: SikTajTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: SikTaj translator implant + description: "An implant giving the ability to understand and speak SikTaj." + components: + - type: TranslatorImplanter + spoken: + - SikTaj + understood: + - SikTaj + +- type: entity + id: NianTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Nian translator implant + description: "An implant giving the ability to understand and speak Nian." + components: + - type: TranslatorImplanter + spoken: + - Nian + understood: + - Nian + +- type: entity + id: FireTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Nian translator implant + description: "An implant giving the ability to understand and speak Nian." + components: + - type: TranslatorImplanter + understood: + - Fire + +- type: entity + id: DraskTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Orluum translator implant + description: "An implant giving the ability to understand and speak Orluum." + components: + - type: TranslatorImplanter + spoken: + - Drask + understood: + - Drask + +- type: entity + id: UrsTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Urs translator implant + description: "An implant giving the ability to understand and speak Ursus language." + components: + - type: TranslatorImplanter + spoken: + - Urs + understood: + - Urs + +- type: entity + id: ArkaneTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Arkane translator implant + description: "An implant giving the ability to understand and speak Arcane language." + components: + - type: TranslatorImplanter + spoken: + - Arkane + understood: + - Arkane + +- type: entity + id: ShadowkinTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Shadowkin translator implant + description: "An implant giving the ability to understand and speak Shadowkin language." + components: + - type: TranslatorImplanter + spoken: + - Shadowkin + understood: + - Shadowkin + +- type: entity + id: BorgTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Borg translator implant + description: "An implant giving the ability to understand and speak Binary." + components: + - type: TranslatorImplanter + spoken: + - BorgTalk + understood: + - BorgTalk + +- type: entity + id: CintaTajTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: CintaTaj translator implant + description: "An implant giving the ability to understand and speak CintaTaj." + components: + - type: TranslatorImplanter + spoken: + - CintaTaj + understood: + - CintaTaj + + +- type: entity + id: SyndUniversalTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: universal translator implant + description: "An implant giving the ability to understand any racial language." + components: + - type: TranslatorImplanter + understood: + - RobotTalk + - Shadowkin + - Arkane + - Urs + - Drask + - Fire + - Nian + - SikTaj + - Moffic + - RootSpeak + - SolCommon + - Canilunzt + - Draconic + - Bubblish + - Nekomimetic + +- type: entity + id: DevTranslatorImplanter + parent: [ BaseTranslatorImplanter ] + name: Dev translator implant + description: "e" + components: + - type: TranslatorImplanter + spoken: + - Dev + understood: + - Dev diff --git a/Resources/Prototypes/ADT/Languages/languages.yml b/Resources/Prototypes/ADT/Languages/languages.yml new file mode 100644 index 0000000000..10dde690b5 --- /dev/null +++ b/Resources/Prototypes/ADT/Languages/languages.yml @@ -0,0 +1,949 @@ +# The universal language, assumed if the entity has a UniversalLanguageSpeakerComponent. +# Do not use otherwise. Try to use the respective component instead of this language. +- type: language + id: Universal + obfuscateSyllables: false + replacement: + - "*incomprehensible*" + +# The common galactic tongue. +- type: language + id: GalacticCommon + obfuscateSyllables: true + replacement: + - Бла + - Бла + - Бла + - динг-донг + - динг + - донг + - жиббер-жаббер + - жуббр + - бле + - зиппти + - зуп + - виббл + - воббл + - виггл + - яда + - мех + - нех + - нах + - вах + +# Spoken by slimes. +- type: language + id: Bubblish + obfuscateSyllables: true + replacement: + - блоб + - плоп + - поп + - боп + - буп + - блюп + - бульп + - блеб + +# Spoken by moths. +- type: language + id: Moffic + obfuscateSyllables: true + replacement: + - år + - i + - går + - sek + - mo + - ff + - ok + - gj + - ø + - gå + - la + - le + - lit + - ygg + - van + - dår + - næ + - møt + - idd + - hvo + - ja + - på + - han + - så + - ån + - det + - att + - nå + - gö + - bra + - int + - tyc + - om + - när + - två + - må + - dag + - sjä + - vii + - vuo + - eil + - tun + - käyt + - teh + - vä + - hei + - huo + - suo + - ää + - ten + - ja + - heu + - stu + - uhr + - kön + - we + - hön + + # Spoken by dionas. +- type: language + id: RootSpeak + obfuscateSyllables: true + replacement: + - хс + - зт + - кр + - ст + - ш + - шш + +# Syndicate operatives can use a series of codewords to convey complex information. +- type: language + id: CodeSpeak + obfuscateSyllables: true + replacement: + - Белый русский + - Представитель станции + - Шериф + - Депутат + - Хранилище + - Фронтир + - Станция + - Безопасность + - Кофе + - Кола + - Вода + - Инженерный + - Капитан + - Вызываю друга + - Атмос + - Робототехника + - Медицинский + - ИИ + - Человек + - Вульпканин + - Унатх + - Ниан + - Чай + - Стул + - Кресло + - Корабль + - Шаттл + - Оружие + - Пушки + - Лазер + - Карп + - Космический Карп + - Ксено + - Ксеноморф + - Биоугроза + - Деньги + - Космос + - Опасность + - Обезьяна + - Пун-пун + - Внутри + - Бежит + - Убивает + - Убить + - Спасти + - Жизнь + - Дракон + - Ниндзя + - Секрет + +# A mess of broken Japanese, spoken by Felinds and Oni +- type: language + id: Nekomimetic + obfuscateSyllables: true + replacement: + - неко + - нян + - мими + - ми + - мофу + - фува + - кьяя + - кавай + - пока + - муня + - пуни + - мунью + - уфуфу + - ича + - доки + - кьюн + - кусу + - ня + - няя + - десу + - кис + - ама + - чуу + - бака + - хево + - буп + - гато + - кит + - сюн + - йори + - соу + - бака + - чан + - сан + - кун + - махо + - йатта + - сукки + - усаги + - домо + - ори + - ува + - заазаа + - шику + - пуру + - ира + - хето + - етто + +# Spoken by the Lizard race. +- type: language + id: Draconic + obfuscateSyllables: true + replacement: + - za + - az + - ze + - ez + - zi + - iz + - zo + - oz + - zu + - uz + - zs + - sz + - ha + - ah + - he + - eh + - hi + - ih + - ho + - oh + - hu + - uh + - hs + - sh + - la + - al + - le + - el + - li + - il + - lo + - ol + - lu + - ul + - ls + - sl + - ka + - ak + - ke + - ek + - ki + - ik + - ko + - ok + - ku + - uk + - ks + - sk + - sa + - as + - se + - es + - si + - is + - so + - os + - su + - us + - ss + - ss + - ra + - ar + - re + - er + - ri + - ir + - ro + - or + - ru + - ur + - rs + - sr + - a + - a + - e + - e + - i + - i + - o + - o + - u + - u + - s + - s + +# Spoken by the Vulpkanin race. +- type: language + id: Canilunzt + obfuscateSyllables: true + replacement: + - rur + - ya + - cen + - rawr + - bar + - kuk + - tek + - qat + - uk + - wu + - vuh + - tah + - tch + - schz + - auch + - ist + - ein + - entch + - zwichs + - tut + - mir + - wo + - bis + - es + - vor + - nic + - gro + - lll + - enem + - zandt + - tzch + - noch + - hel + - ischt + - far + - wa + - baram + - iereng + - tech + - lach + - sam + - mak + - lich + - gen + - or + - ag + - eck + - gec + - stag + - onn + - bin + - ket + - jarl + - vulf + - einech + - cresthz + - azunein + - ghzth + +# Spoken by the Tajaran race. +- type: language + id: SikTaj + obfuscateSyllables: true + replacement: + - rae + - ye + - cen + - prr + - mer + - kuk + - tek + - qar + - ud + - wu + - wuh + - "taj'" + - tch + - ser + - "'aerch" + - it + - ei + - endr + - zeihs + - tet + - mir + - wo + - bis + - es + - voj + - jic + - fro + - rrr + - ener + - zajet + - th + - nort + - hel + - ist + - far + - wa + - bara + - ierg + - tech + - lach + - sam + - mak + - "'lirch" + - get + - or + - "jag'" + - eck + - gec + - stag + - "'onn" + - bin + - ket + - "jart'" + - vul + - einech + - cres + - "'eirr" + - ghh + +# Spoken by the Nian race. +- type: language + id: Nian + obfuscateSyllables: true + replacement: + - жз + - эзз + - ззе + - ржез + - зшусж + - жсса + - жж + - жжс + - еж + - шшз + - ззуш + - жашшз + - ззис + - ссж + - ужжс + - сз + - жш + - эшзз + - жесш + - шжш + - жуж + - ж + - ш + - з + - ззз + - зсе + - фжж + - зсжу + +# Spoken by the Novakid race. +- type: language + id: Fire + obfuscateSyllables: true + replacement: + - шш + - вшш + - шжшш + - сшшшс + - шсжсс + - ссш + - сс + - жжс + - жшж + + +# The common language of the Sol system. +- type: language + id: SolCommon + obfuscateSyllables: true + replacement: + - тао + - ши + - тзу + - йи + - ком + - би + - ис + - я + - оп + - ви + - эд + - лек + - мо + - кле + - те + - дис + - ее + +# Languages spoken by various critters. +- type: language + id: Cat + obfuscateSyllables: true + replacement: + - мурр + - мяу + - мурр + - мрау + +- type: language + id: Dog + obfuscateSyllables: true + replacement: + - вуф + - гав + - гаф + - рафф + - гарр + +- type: language + id: Mothroach + obfuscateSyllables: false + replacement: + - Бзз + - Чрик + - Скуик + - Пип + - Ииии + - Иип + +- type: language + id: Xeno + obfuscateSyllables: true + replacement: + - ссс + - сСс + - ССС +# IPC +- type: language + id: RobotTalk + obfuscateSyllables: true + replacement: + - "0" + - "1" + - "2" +# Borgs +- type: language + id: BorgTalk + obfuscateSyllables: true + replacement: + - "0" + - "1" + +- type: language + id: Monkey + obfuscateSyllables: true + replacement: + - аг + - ааг + - аааг + - ааааг + - аааааг + +- type: language + id: Bee + obfuscateSyllables: false + replacement: + - Бз + - Бзз + - Бззз + - Бзззз + - Бззззз + +- type: language + id: Mouse + obfuscateSyllables: false + replacement: + - Скуик + - Пип + - Чуу + - Ииии + - Пип + +- type: language + id: Chicken + obfuscateSyllables: false + replacement: + - Coo + - Coot + - Cooot + +- type: language + id: Duck + obfuscateSyllables: false + replacement: + - Quack + +- type: language + id: Cow + obfuscateSyllables: false + replacement: + - Moo + - Mooo + +- type: language + id: Sheep + obfuscateSyllables: false + replacement: + - Ba + - Baa + - Baaa + +- type: language + id: Kangaroo + obfuscateSyllables: false + replacement: + - Shreak + - Chuu + +- type: language + id: Pig + obfuscateSyllables: false + replacement: + - Oink + +# Spoken by the Drask race. +- type: language + id: Drask + obfuscateSyllables: true + replacement: + - овв + - оумн + - мноо + - румум + - ваар + - дромнн + - руум + - гоом + - фмонг + - оорм + - гаар + - хоорб + - саар + - ссооумн + - гнии + - вииск + - вррм + +# Spoken by the Ursus race. +- type: language + id: Urs + obfuscateSyllables: true + replacement: + - раа + - ишш + - тзуур + - арр + - кромм + - би + - инн + - рр + - оот + - вирр + - эк + - лерр + - мои + - крр + - тее + - ррс + - аа + - ир + - ррэк + - ер + - маа + - ке + - етт + +# Spoken by the Arkane race. +- type: language + id: Arkane + obfuscateSyllables: true + replacement: + - рииа + - инн + - тлаа + - айр + - коо + - бии + - иинта + - реаа + - онт + - виер + - энк + - лааир + - оии + - кееа + - теу + - риина + - ин + +# Spoken by the Shadowkin race. +- type: language + id: Shadowkin + obfuscateSyllables: true + replacement: + - mia + - ar + - ren + - naar + - mae + - tre + - ien + - trr + - ou + - rin + - nae + - ena + - oi + - kerr + - que + - uoh + - een + +# Spoken by the Dwarf race. +- type: language + id: Dwarf + obfuscateSyllables: true + replacement: + - арр + - рок + - стн + - шахт + - руд + - трэ + - кирк + - диг + - йи + - мыэ + - молл + - бур + - пив + - стн + - дрг + - эйе + +# Spoken by the Dwarf race. +- type: language + id: CintaTaj + obfuscateSyllables: true + replacement: + - za + - az + - ze + - ez + - zi + - iz + - zo + - oz + - zu + - uz + - zs + - sz + - ha + - ah + - he + - eh + - hi + - ih + - ho + - oh + - hu + - uh + - hs + - sh + - la + - al + - le + - el + - li + - il + - lo + - ol + - lu + - ul + - ls + - sl + - ka + - ak + - ke + - ek + - ki + - ik + - ko + - ok + - ku + - uk + - ks + - sk + - sa + - as + - se + - es + - si + - is + - so + - os + - su + - us + - ss + - ss + - ra + - ar + - re + - er + - ri + - ir + - ro + - or + - ru + - ur + - rs + - sr + - a + - a + - e + - e + - i + - i + - o + - o + - u + - u + - s + - s + - rae + - ye + - cen + - prr + - mer + - kuk + - tek + - qar + - ud + - wu + - wuh + - "taj'" + - tch + - ser + - "'aerch" + - it + - ei + - endr + - zeihs + - tet + - mir + - wo + - bis + - es + - voj + - jic + - fro + - rrr + - ener + - zajet + - th + - nort + - hel + - ist + - far + - wa + - bara + - ierg + - tech + - lach + - sam + - mak + - "'lirch" + - get + - or + - "jag'" + - eck + - gec + - stag + - "'onn" + - bin + - ket + - "jart'" + - vul + - einech + - cres + - "'eirr" + - ghh + +# Here goes admeme languages. +- type: language + id: Dev + obfuscateSyllables: true + replacement: + - су + - ка + - офф + - ямл + - бл + - пид + - рас + - о + - виз + - код + - с# + - мета + - билд + - сук + - гни + - эмис + - баг + - да + - бля + - гит + - мердж + - пулл + - ПР + - огг + - пнг + - робст + - релз + - дебаг diff --git a/Resources/Prototypes/ADT/Recipes/Lathes/translators.yml b/Resources/Prototypes/ADT/Recipes/Lathes/translators.yml new file mode 100644 index 0000000000..233acfe64d --- /dev/null +++ b/Resources/Prototypes/ADT/Recipes/Lathes/translators.yml @@ -0,0 +1,358 @@ +# Translators +- type: latheRecipe + id: CanilunztTranslator + result: CanilunztTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: BubblishTranslator + result: BubblishTranslator + completetime: 2 + materials: + Steel: 500 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: NekomimeticTranslator + result: NekomimeticTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: DraconicTranslator + result: DraconicTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: SolCommonTranslator + result: SolCommonTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: RootSpeakTranslator + result: RootSpeakTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: MofficTranslator + result: MofficTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: BasicGalaticCommonTranslatorImplanter + result: BasicGalaticCommonTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: XenoTranslator + result: XenoTranslator + completetime: 2 + materials: + Steel: 200 + Plastic: 50 + Gold: 50 + Plasma: 50 + Silver: 50 + +- type: latheRecipe + id: AdvancedGalaticCommonTranslatorImplanter + result: AdvancedGalaticCommonTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: BubblishTranslatorImplanter + result: BubblishTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: NekomimeticTranslatorImplanter + result: NekomimeticTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: DraconicTranslatorImplanter + result: DraconicTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: CanilunztTranslatorImplanter + result: CanilunztTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: SolCommonTranslatorImplanter + result: SolCommonTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: RootSpeakTranslatorImplanter + result: RootSpeakTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: MofficTranslatorImplanter + result: MofficTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: AnimalTranslator + result: AnimalTranslator + completetime: 2 + materials: + Steel: 200 + Plastic: 50 + Gold: 50 + Plasma: 50 + Silver: 5 + +- type: latheRecipe + id: SikTajTranslatorImplanter + result: SikTajTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: NianTranslatorImplanter + result: NianTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: FireTranslatorImplanter + result: FireTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: DraskTranslator + result: DraskTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: DraskTranslatorImplanter + result: DraskTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: UrsTranslatorImplanter + result: UrsTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: ArkaneTranslatorImplanter + result: ArkaneTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: ShadowkinTranslatorImplanter + result: ShadowkinTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +- type: latheRecipe + id: CintaTajTranslatorImplanter + result: CintaTajTranslatorImplanter + completetime: 2 + materials: + Steel: 500 + Glass: 500 + Plastic: 100 + Gold: 50 + Silver: 50 + +#- type: latheRecipe +# id: UrsTranslator +# result: UrsTranslator +# completetime: 2 +# materials: +# Steel: 500 +# Glass: 100 +# Plastic: 50 +# Gold: 50 + +- type: latheRecipe + id: ArkaneTranslator + result: ArkaneTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: ShadowkinTranslator + result: ShadowkinTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: NianTranslator + result: NianTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: FireTranslator + result: FireTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: SikTajTranslator + result: SikTajTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 + +- type: latheRecipe + id: CintaTajTranslator + result: CintaTajTranslator + completetime: 2 + materials: + Steel: 500 + Glass: 100 + Plastic: 50 + Gold: 50 diff --git a/Resources/Prototypes/ADT/Research/translators.yml b/Resources/Prototypes/ADT/Research/translators.yml new file mode 100644 index 0000000000..a687d06a53 --- /dev/null +++ b/Resources/Prototypes/ADT/Research/translators.yml @@ -0,0 +1,59 @@ +# Tier 2 - entrypoint to translators +- type: technology + id: BasicTranslation + name: research-technology-basic-translation + icon: + sprite: _NF/Objects/Devices/translator.rsi + state: icon + discipline: CivilianServices + tier: 2 + cost: 10000 + recipeUnlocks: + - CanilunztTranslator + - BubblishTranslator + - NekomimeticTranslator + - DraconicTranslator + - SolCommonTranslator + - RootSpeakTranslator + - BasicGalaticCommonTranslatorImplanter + - MofficTranslator + - DraskTranslator +# - UrsTranslator # Закомменчено до раундстарт урсов + - ArkaneTranslator + - ShadowkinTranslator + - NianTranslator + - FireTranslator + - SikTajTranslator + - CintaTajTranslator + + +# Frontier - languages mechanic +- type: technology + id: AdvancedTranslation + name: research-technology-advanced-translation + icon: + sprite: _NF/Objects/Devices/translator.rsi + state: icon + discipline: CivilianServices + tier: 3 + cost: 15000 + recipeUnlocks: + - XenoTranslator + - AdvancedGalaticCommonTranslatorImplanter + - BubblishTranslatorImplanter + - NekomimeticTranslatorImplanter + - DraconicTranslatorImplanter + - CanilunztTranslatorImplanter + - SolCommonTranslatorImplanter + - RootSpeakTranslatorImplanter + - AnimalTranslator + - MofficTranslatorImplanter + - DraskTranslatorImplanter + - SikTajTranslatorImplanter + - NianTranslatorImplanter + - FireTranslatorImplanter + - DraskTranslatorImplanter +# - UrsTranslatorImplanter # Закомменчено до раундстарт урсов + - ArkaneTranslatorImplanter + - ShadowkinTranslatorImplanter + - CintaTajTranslatorImplanter diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index a79fbfbf24..baf7d7ade0 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -62,6 +62,11 @@ - type: Tag tags: - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - Mouse - type: entity name: bee @@ -1046,6 +1051,11 @@ - type: HTN rootTask: task: SimpleHostileCompound + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - Monkey - type: entity name: kangaroo @@ -1282,6 +1292,11 @@ Burn: 3 clumsySound: path: /Audio/Animals/monkey_scream.ogg + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - Monkey - type: entity name: monkey @@ -1312,6 +1327,12 @@ - type: GhostTakeoverAvailable - type: Loadout prototypes: [SyndicateOperativeGearMonkey] + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - GalacticCommon + - Monkey - type: entity id: MobMonkeySyndicateAgent @@ -1471,6 +1492,9 @@ - Syndicate - type: Loadout prototypes: [SyndicateOperativeGearMonkey] + - type: LanguageSpeaker # Frontier + understands: + - GalacticCommon - type: entity id: MobKoboldSyndicateAgent @@ -1655,6 +1679,11 @@ - type: FireVisuals sprite: Mobs/Effects/onfire.rsi normalState: Mouse_burning + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - Mouse - type: entity parent: MobMouse @@ -2613,6 +2642,11 @@ - type: Tag tags: - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - Dog - type: entity name: corrupted corgi @@ -2766,6 +2800,11 @@ - type: Tag tags: - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - Cat - type: entity name: calico cat @@ -3161,6 +3200,11 @@ - type: FireVisuals sprite: Mobs/Effects/onfire.rsi normalState: Mouse_burning + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - Mouse - type: entity name: pig diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 4436ebc612..fe265c7cb6 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -36,6 +36,12 @@ - VimPilot - type: StealTarget stealGroup: AnimalIan + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - GalacticCommon + - Dog - type: entity name: Old Ian @@ -121,6 +127,12 @@ tags: - CannotSuicide - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - GalacticCommon + - Cat - type: entity name: Exception @@ -139,6 +151,12 @@ tags: - CannotSuicide - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - GalacticCommon + - Cat - type: entity name: Floppa @@ -164,6 +182,12 @@ tags: - CannotSuicide - VimPilot + - type: LanguageSpeaker # Frontier + speaks: + - Cat + understands: + - GalacticCommon + - Cat - type: entity name: Bandito @@ -295,6 +319,12 @@ - VimPilot - type: StealTarget stealGroup: AnimalMcGriff + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - GalacticCommon + - Dog - type: entity name: Paperwork @@ -388,6 +418,12 @@ - VimPilot - type: StealTarget stealGroup: AnimalWalter + - type: LanguageSpeaker # Frontier + speaks: + - Dog + understands: + - GalacticCommon + - Dog - type: entity name: Morty @@ -577,6 +613,12 @@ - Hamster - VimPilot - ChefPilot + - type: LanguageSpeaker # Frontier + speaks: + - Mouse + understands: + - GalacticCommon + - Mouse - type: entity name: Shiva @@ -781,6 +823,12 @@ attributes: proper: true gender: male + - type: LanguageSpeaker # Frontier + speaks: + - Monkey + understands: + - GalacticCommon + - Monkey - type: entity name: Tropico diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml index d63afd4fa4..eefaedb47f 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml @@ -97,3 +97,8 @@ - RevenantTheme - type: Speech speechVerb: Ghost + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + understands: + - GalacticCommon diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index 1686b723b5..28758fb95b 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -109,6 +109,13 @@ - type: StepTriggerImmune - type: NoSlip - type: Insulated + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - BorgTalk + understands: + - GalacticCommon + - BorgTalk - type: entity parent: MobSiliconBase diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml index c50ad70ea2..d4970d88de 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml @@ -112,6 +112,11 @@ speechSounds: Slime - type: TypingIndicator proto: slime + - type: LanguageSpeaker # Frontier + speaks: + - Bubblish + understands: + - Bubblish - type: entity name: basic slime diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 9fb0be02ae..3cf6fc69f5 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -119,6 +119,11 @@ molsPerSecondPerUnitMass: 0.0005 - type: Speech speechVerb: LargeMob + - type: LanguageSpeaker # Frontier + speaks: + - Xeno + understands: + - Xeno - type: entity name: Praetorian diff --git a/Resources/Prototypes/Entities/Mobs/Player/observer.yml b/Resources/Prototypes/Entities/Mobs/Player/observer.yml index 85be42cc02..0f826936a5 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/observer.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/observer.yml @@ -48,6 +48,7 @@ - type: Tag tags: - BypassInteractionRangeChecks + - type: UniversalLanguageSpeaker # Frontier / Ghosts should understand any language. - type: entity id: ActionGhostBoo diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml index 8b3c66d5dd..e1ec78b419 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml @@ -122,6 +122,13 @@ sprite: "Effects/creampie.rsi" state: "creampie_arachnid" visible: false + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Moffic + understands: + - GalacticCommon + - Moffic - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index d956f1871d..ee19b937ce 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -221,6 +221,12 @@ - CanPilot - FootstepSound - DoorBumpOpener + # Frontier - languages mechanic + - type: LanguageSpeaker + speaks: + - GalacticCommon + understands: + - GalacticCommon - type: entity save: false diff --git a/Resources/Prototypes/Entities/Mobs/Species/diona.yml b/Resources/Prototypes/Entities/Mobs/Species/diona.yml index ba1a2cbf76..98341e8d12 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/diona.yml @@ -102,6 +102,13 @@ actionPrototype: DionaGibAction allowedStates: - Dead + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - RootSpeak + understands: + - GalacticCommon + - RootSpeak - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml b/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml index 5a54b56c48..d332914399 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/dwarf.yml @@ -56,6 +56,13 @@ hideLayersOnEquip: - Hair - Snout + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Dwarf + understands: + - GalacticCommon + - Dwarf - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 6716d3902b..1152f654da 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -20,6 +20,13 @@ hideLayersOnEquip: - Hair - Snout + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - SolCommon + understands: + - GalacticCommon + - SolCommon - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml index f6fde849ef..a2730b6d7e 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml @@ -118,6 +118,13 @@ sprite: "Effects/creampie.rsi" state: "creampie_moth" visible: false + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Nian + understands: + - GalacticCommon + - Nian - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml index ad543620cf..4d09690201 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml @@ -62,6 +62,15 @@ types: Heat : 1.5 #per second, scales with temperature & other constants - type: Wagging + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + - Draconic + - CintaTaj + understands: + - GalacticCommon + - Draconic + - CintaTaj - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index caa3690e5d..7c76d34222 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -110,6 +110,13 @@ types: Asphyxiation: -1.0 maxSaturation: 15 + - type: LanguageSpeaker + speaks: + - GalacticCommon + - Bubblish + understands: + - GalacticCommon + - Bubblish - type: entity parent: MobHumanDummy diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index d973c5c607..c3b4bbbb82 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -46,6 +46,11 @@ - type: TTS # Corvax-TTS - type: RequireProjectileTarget active: False + - type: LanguageSpeaker # Frontier + speaks: + - GalacticCommon + understands: + - GalacticCommon # Used for mobs that have health and can take damage. - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 8021d39028..28f5796c71 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -333,6 +333,42 @@ - FauxTileAstroSnow - OreBagOfHolding - DeviceQuantumSpinInverter + # vv Frontier - languages mechanic vv + - CanilunztTranslator + - BubblishTranslator + - NekomimeticTranslator + - DraconicTranslator + - SolCommonTranslator + - RootSpeakTranslator + - XenoTranslator + - DraskTranslator + - BasicGalaticCommonTranslatorImplanter + - AdvancedGalaticCommonTranslatorImplanter + - BubblishTranslatorImplanter + - NekomimeticTranslatorImplanter + - DraconicTranslatorImplanter + - CanilunztTranslatorImplanter + - SolCommonTranslatorImplanter + - RootSpeakTranslatorImplanter + - AnimalTranslator + - MofficTranslatorImplanter + - MofficTranslator + - SikTajTranslatorImplanter + - NianTranslatorImplanter + - FireTranslatorImplanter + - DraskTranslatorImplanter +# - UrsTranslatorImplanter # Закомменчено до раундстарт урсов + - ArkaneTranslatorImplanter + - ShadowkinTranslatorImplanter + - CintaTajTranslatorImplanter +# - UrsTranslator # Закомменчено до раундстарт урсов + - ArkaneTranslator + - ShadowkinTranslator + - NianTranslator + - FireTranslator + - SikTajTranslator + - CintaTajTranslator + # ^^ Frontier - languages mechanic ^^ - type: EmagLatheRecipes emagDynamicRecipes: - BoxBeanbag diff --git a/Resources/Textures/_NF/Interface/Actions/language.png b/Resources/Textures/_NF/Interface/Actions/language.png new file mode 100644 index 0000000000000000000000000000000000000000..51962871ac7350a9e35354181cb7d38e22a36493 GIT binary patch literal 898 zcmV-|1AY97P)EX>4Tx04R}tkv&MmP!xqvQ>9WWf_4yb$WWc^q9Tr^6^me@v=v%)FnQ@8G-*gu zTpR`0f`dPcRRW2pGX{Ix?vG-5YKH| zI_G`jFsn!k@j3C7K@Ac=a$R=$jdR&yfoFz|TqZ#rCKk&*EcY<07%K5BaYRuy$`|r3 zE1b7DtF;E}^vPcsDrzfPu2YR8i6x|vh6ouAR8fP4DD4_4CNgv$_wbK7{xrE{a#g{| zv4A>MNRA);4}Q2NufB<|6)#N?kat9cF(j`N3BtMl{010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=L`xAEEO;=`rZHl02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00BTrL_t(o!|heQt%NWPc1|bJQByJrEWiLXnScQ@Lk7qM znIxN#22mp#s$69ha{1vsj(d7iJ_!L%?C-N<3_wOk#vg;EHf-Bwt`HPO5#@NMi065} zlp)3m2_Ye;tHdsh($t+mlw zo4)U(_pa*DFXm-RS1^cM}F#GfI@r-iL=i+M0{F6N}MYqRO(v< z;PCn_d2|kZs>yBzj@DS8r0~46!!t56{smrL<^A&IBr!q&000hUSV?A0O#mtY000O8 Y00000007cclK=n!07*qoM6N<$f>hCV-2eap literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/icon.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..92c3c4ab24904415efb0680558cd00cf12bbec46 GIT binary patch literal 383 zcmV-_0f7FAP)pGF-b&0R9J=WmNARMKoEtWhtc2`TO1zb8bxdlgY<52D^8tLT26#9? zgBuV%BpUHiQV#YW;=h`2k90Q0fN&j#VL8001CF8|(Eq=5s1N zlTxDFeP`vf@&FMb2!hf@L=YmpJ%CSn2RQY`Ljbs9n-D0>Ms(eTcLC`42LQ_L&hrDd z+w}GTx_FW#rWUd~aw(-LzF4eSo6reB`#|5h#Q}#;00413F=wSRs~k=M zv)R;mU^x7^A3*W8;h6_)#rA-9xl&ol12$rJAWiq?97V-G=yYD$<7W+U3E?WQe?;67 dtW^sDegRU8bFKABW~l%G002ovPDHLkV1hSUp|b!0 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left-translator.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-left-translator.png new file mode 100644 index 0000000000000000000000000000000000000000..84add80f419bf8a9db769ca326c852b43230c391 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sDEfH31!Z9ZwBpq;0SV@O5Z+gpyj3<^BV2Y!_|onn-$(0QY` zvf-^tk=9Q&7b}g=7KVl%RjljZS(?D%c<=X_ z>ilUtsr?l%HZ^q=`d4227+`drzo^8v?=}WFO-GBRS@29ix z*-gZg@4oi0Tz>he%KbeIldA6X{#deZ`^|?1`@|EAj%B6#uS@;cZTIg<7tpK*`$FbS W&aBmvl2h)2jP`W(b6Mw<&;$UCbBU|~ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right-translator.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right-translator.png new file mode 100644 index 0000000000000000000000000000000000000000..76a1db299de63a48de8d07be86235a589e162fd5 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sDEfH31!Z9ZwBpslBiV@O5Z+gpab3Tp%H zd=h8HKcEVRg4OR*wq5(h3}OSp1L?Uzopr03|mp A$^ZZW literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right.png b/Resources/Textures/_NF/Objects/Devices/translator.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..f6c8e44768e7df5fa629564c11a42ff5d70915d7 GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|O(E zr;B4q#hkad?D?7uM2>%)f2`5Mx{9HVuSaId@h1v$3z`$l3=J{5%@WA_XaS^MP9vckLST zoG)|y^)((p$Loi)eH;pdMb=JH>HK6f-$kg$bMMw|LXS6_mtQQsxby6poyRYDpN?bf zI~w(RvrhHP$!~oeZhqax^UuDZU;oW^5wL|IVshwv#UCMzrEBb3Bv>Cz=b50SYigY`d3J;C9(T1JzBeAenzG~slV79$u3K{)1n;XW zx-`z`efwJ&sF~s1qou#k8eQi}{`76$pBnY}?MrIDtlw^0zf0B9VE^Yo>+eeMXpi4? zuYF_nO1-5|mp^^};LoPwx=mMNvVCuT-FfBi=V1A71rGln|13X$KIXrj)3jZ7r`bUU zgFyq|=UW~7wxyNa+&L#I%JSR1dKb&@oX_9S=RYyShyU-7z0aB33{N(GW~@9{bD&NB wLd>n&TYD~jvz?>;`$gTKo1Ym$rZoJ2ByNy4?F`2vV|5VU)78&qol`;+0DoAAHvj+t literal 0 HcmV?d00001 From 6c67b8e4f1ab518a154d5257dc00a22e0b185a77 Mon Sep 17 00:00:00 2001 From: nixsilvam404 <125667541+nixsilvam404@users.noreply.github.com> Date: Sat, 13 Jul 2024 09:46:50 +0300 Subject: [PATCH 4/4] Demon (#126) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Описание PR перенос Аркан --- .../Locale/en-US/ADT/Body/Parts/demon.ftl | 22 ++ .../en-US/ADT/Entities/Mobs/Species/demon.ftl | 4 + .../Locale/ru-RU/ADT/Body/Organs/demon.ftl | 2 + .../Locale/ru-RU/ADT/Body/Organs/drask.ftl | 10 + .../Locale/ru-RU/ADT/Body/Parts/demon.ftl | 22 ++ .../Locale/ru-RU/ADT/Body/Parts/drask.ftl | 2 + .../ru-RU/ADT/Chemistry/metabolizer-types.ftl | 8 + .../ru-RU/ADT/Entities/Mobs/Player/demon.ftl | 2 + .../ru-RU/ADT/Entities/Mobs/Species/demon.ftl | 5 + Resources/Locale/ru-RU/ADT/Species/demon.ftl | 1 + Resources/Locale/ru-RU/ADT/Species/drask.ftl | 12 -- Resources/Locale/ru-RU/ADT/Species/kobolt.ftl | 1 + .../Prototypes/ADT/Body/Organs/demon.yml | 21 ++ Resources/Prototypes/ADT/Body/Organs/fill.txt | 1 - Resources/Prototypes/ADT/Body/Parts/demon.yml | 193 ++++++++++++++++++ Resources/Prototypes/ADT/Body/Parts/fill.txt | 1 - .../Prototypes/ADT/Body/Prototypes/demon.yml | 49 +++++ .../ADT/Chemistry/metabolizer_types.yml | 36 +++- .../Prototypes/ADT/Damage/ADTmodifiers.yml | 86 ++++---- .../Mobs/Customization/Markings/demon.yml | 133 ++++++++++++ .../Mobs/Customization/Markings/fill.txt | 1 - .../ADT/Entities/Mobs/Player/demon.yml | 50 +++++ .../ADT/Entities/Mobs/Player/fill.txt | 1 - .../ADT/Entities/Mobs/Species/demon.yml | 66 ++++++ .../ADT/Entities/Mobs/Species/fill.txt | 1 - Resources/Prototypes/ADT/Species/demon.yml | 157 ++++++++++++++ .../ADT/Mobs/Demon/custom.rsi/cow_ears.png | Bin 0 -> 180 bytes .../ADT/Mobs/Demon/custom.rsi/cow_horns.png | Bin 0 -> 200 bytes .../ADT/Mobs/Demon/custom.rsi/cow_spots.png | Bin 0 -> 502 bytes .../Demon/custom.rsi/deer_antlers_horns.png | Bin 0 -> 229 bytes .../ADT/Mobs/Demon/custom.rsi/demon_ears.png | Bin 0 -> 172 bytes .../ADT/Mobs/Demon/custom.rsi/demon_tail.png | Bin 0 -> 265 bytes .../ADT/Mobs/Demon/custom.rsi/goatee.png | Bin 0 -> 162 bytes .../Mobs/Demon/custom.rsi/guards_stripes.png | Bin 0 -> 342 bytes .../Mobs/Demon/custom.rsi/lines_emperos.png | Bin 0 -> 346 bytes .../ADT/Mobs/Demon/custom.rsi/long.png | Bin 0 -> 461 bytes .../ADT/Mobs/Demon/custom.rsi/meta.json | 71 +++++++ .../ADT/Mobs/Demon/custom.rsi/queen_lines.png | Bin 0 -> 264 bytes .../ADT/Mobs/Demon/custom.rsi/small_horns.png | Bin 0 -> 163 bytes .../ADT/Mobs/Demon/custom.rsi/tree_lines.png | Bin 0 -> 497 bytes .../Mobs/Demon/custom.rsi/trinity_spots.png | Bin 0 -> 287 bytes .../Textures/ADT/Mobs/Demon/custom.rsi/up.png | Bin 0 -> 396 bytes .../ADT/Mobs/Demon/parts.rsi/full_f.png | Bin 0 -> 939 bytes .../ADT/Mobs/Demon/parts.rsi/full_m.png | Bin 0 -> 946 bytes .../ADT/Mobs/Demon/parts.rsi/full_t.png | Bin 0 -> 915 bytes .../ADT/Mobs/Demon/parts.rsi/head_f.png | Bin 0 -> 708 bytes .../ADT/Mobs/Demon/parts.rsi/head_m.png | Bin 0 -> 713 bytes .../ADT/Mobs/Demon/parts.rsi/head_t.png | Bin 0 -> 708 bytes .../ADT/Mobs/Demon/parts.rsi/l_arm.png | Bin 0 -> 369 bytes .../ADT/Mobs/Demon/parts.rsi/l_foot.png | Bin 0 -> 342 bytes .../ADT/Mobs/Demon/parts.rsi/l_hand.png | Bin 0 -> 317 bytes .../ADT/Mobs/Demon/parts.rsi/l_leg.png | Bin 0 -> 424 bytes .../ADT/Mobs/Demon/parts.rsi/meta.json | 80 ++++++++ .../ADT/Mobs/Demon/parts.rsi/r_arm.png | Bin 0 -> 365 bytes .../ADT/Mobs/Demon/parts.rsi/r_foot.png | Bin 0 -> 335 bytes .../ADT/Mobs/Demon/parts.rsi/r_hand.png | Bin 0 -> 318 bytes .../ADT/Mobs/Demon/parts.rsi/r_leg.png | Bin 0 -> 412 bytes .../ADT/Mobs/Demon/parts.rsi/tail.png | Bin 0 -> 496 bytes .../ADT/Mobs/Demon/parts.rsi/torso_f.png | Bin 0 -> 1224 bytes .../ADT/Mobs/Demon/parts.rsi/torso_m.png | Bin 0 -> 1160 bytes .../ADT/Mobs/Demon/parts.rsi/torso_t.png | Bin 0 -> 1252 bytes 61 files changed, 975 insertions(+), 63 deletions(-) create mode 100644 Resources/Locale/en-US/ADT/Body/Parts/demon.ftl create mode 100644 Resources/Locale/en-US/ADT/Entities/Mobs/Species/demon.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Body/Organs/demon.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Body/Organs/drask.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Body/Parts/demon.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Body/Parts/drask.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/demon.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/demon.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Species/demon.ftl create mode 100644 Resources/Locale/ru-RU/ADT/Species/kobolt.ftl create mode 100644 Resources/Prototypes/ADT/Body/Organs/demon.yml delete mode 100644 Resources/Prototypes/ADT/Body/Organs/fill.txt create mode 100644 Resources/Prototypes/ADT/Body/Parts/demon.yml delete mode 100644 Resources/Prototypes/ADT/Body/Parts/fill.txt create mode 100644 Resources/Prototypes/ADT/Body/Prototypes/demon.yml create mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/demon.yml delete mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/fill.txt create mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml delete mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Player/fill.txt create mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Species/demon.yml delete mode 100644 Resources/Prototypes/ADT/Entities/Mobs/Species/fill.txt create mode 100644 Resources/Prototypes/ADT/Species/demon.yml create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_ears.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_horns.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_spots.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/deer_antlers_horns.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_ears.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_tail.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/goatee.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/guards_stripes.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/lines_emperos.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/long.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/meta.json create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/queen_lines.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/small_horns.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/tree_lines.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/trinity_spots.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/custom.rsi/up.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_f.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_m.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_t.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_f.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_m.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_t.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_arm.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_foot.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_hand.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_leg.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/meta.json create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_arm.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_foot.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_hand.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_leg.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/tail.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_f.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_m.png create mode 100644 Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_t.png diff --git a/Resources/Locale/en-US/ADT/Body/Parts/demon.ftl b/Resources/Locale/en-US/ADT/Body/Parts/demon.ftl new file mode 100644 index 0000000000..48a7c98fb8 --- /dev/null +++ b/Resources/Locale/en-US/ADT/Body/Parts/demon.ftl @@ -0,0 +1,22 @@ +ent-PartDemon = demon body part + .desc = { ent-BaseItem.desc } +ent-TorsoDemon = demon torso + .desc = { ent-PartDemon.desc } +ent-HeadDemon = demon head + .desc = { ent-PartDemon.desc } +ent-LeftArmDemon = left demon arm + .desc = { ent-PartDemon.desc } +ent-RightArmDemon = right demon arm + .desc = { ent-PartDemon.desc } +ent-LeftHandDemon = left demon hand + .desc = { ent-PartDemon.desc } +ent-RightHandDemon = right demon hand + .desc = { ent-PartDemon.desc } +ent-LeftLegDemon = left demon leg + .desc = { ent-PartDemon.desc } +ent-RightLegDemon = right demon leg + .desc = { ent-PartDemon.desc } +ent-LeftFootDemon = left demon foot + .desc = { ent-PartDemon.desc } +ent-RightFootDemon = right demon foot + .desc = { ent-PartDemon.desc } diff --git a/Resources/Locale/en-US/ADT/Entities/Mobs/Species/demon.ftl b/Resources/Locale/en-US/ADT/Entities/Mobs/Species/demon.ftl new file mode 100644 index 0000000000..d07b87e90b --- /dev/null +++ b/Resources/Locale/en-US/ADT/Entities/Mobs/Species/demon.ftl @@ -0,0 +1,4 @@ +ent-BaseMobDemon = Urisst' Mzhand Demon + .desc = { ent-BaseMobSpecies.desc } +ent-MobDemonDummy = Urist McHands + .desc = A dummy reptilian meant to be used in character setup. diff --git a/Resources/Locale/ru-RU/ADT/Body/Organs/demon.ftl b/Resources/Locale/ru-RU/ADT/Body/Organs/demon.ftl new file mode 100644 index 0000000000..a216c9d900 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Organs/demon.ftl @@ -0,0 +1,2 @@ +ent-OrganDemonStomach = { ent-OrganAnimalStomach } + .desc = { ent-OrganAnimalStomach.desc } diff --git a/Resources/Locale/ru-RU/ADT/Body/Organs/drask.ftl b/Resources/Locale/ru-RU/ADT/Body/Organs/drask.ftl new file mode 100644 index 0000000000..63dfb61b32 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Organs/drask.ftl @@ -0,0 +1,10 @@ +ent-OrganDraskEyes = глаза + .desc = Я тебя вижу! +ent-OrganDraskLungs = лёгкие + .desc = Фильтрует кислород из атмосферы, который затем поступает в кровь для использования в качестве переносчика электронов. +ent-OrganDraskHeart = сердце + .desc = Мне жаль того бессердечного ублюдка, который его потерял. +ent-OrganDraskInnards = внутренности + .desc = Мерзость. +ent-OrganDraskKidneys = почки + .desc = Выводят токсины из кровеносной системы. diff --git a/Resources/Locale/ru-RU/ADT/Body/Parts/demon.ftl b/Resources/Locale/ru-RU/ADT/Body/Parts/demon.ftl new file mode 100644 index 0000000000..d3d5b5e8ae --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Parts/demon.ftl @@ -0,0 +1,22 @@ +ent-PartDemon = часть тела арканы + .desc = { ent-BaseItem.desc } +ent-TorsoDemon = торс арканы + .desc = { ent-PartDemon.desc } +ent-HeadDemon = голова арканы + .desc = { ent-PartDemon.desc } +ent-LeftArmDemon = левая рука арканы + .desc = { ent-PartDemon.desc } +ent-RightArmDemon = правая рука арканы + .desc = { ent-PartDemon.desc } +ent-LeftHandDemon = левая кисть арканы + .desc = { ent-PartDemon.desc } +ent-RightHandDemon = правая кисть арканы + .desc = { ent-PartDemon.desc } +ent-LeftLegDemon = левая нога арканы + .desc = { ent-PartDemon.desc } +ent-RightLegDemon = правая нога арканы + .desc = { ent-PartDemon.desc } +ent-LeftFootDemon = левая стопа арканы + .desc = { ent-PartDemon.desc } +ent-RightFootDemon = правая стопа арканы + .desc = { ent-PartDemon.desc } diff --git a/Resources/Locale/ru-RU/ADT/Body/Parts/drask.ftl b/Resources/Locale/ru-RU/ADT/Body/Parts/drask.ftl new file mode 100644 index 0000000000..5dd856b7d7 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Body/Parts/drask.ftl @@ -0,0 +1,2 @@ +marking-DraskArmRight = правая рука +marking-DraskArmLeft = левая рука diff --git a/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl b/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl index ff10a218e1..c7d9b2badd 100644 --- a/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl +++ b/Resources/Locale/ru-RU/ADT/Chemistry/metabolizer-types.ftl @@ -10,3 +10,11 @@ metabolizer-type-dwarf = Дварф metabolizer-type-moth = Ниан metabolizer-type-arachnid = Арахнид metabolizer-type-drask = Драск +metabolizer-type-demon = Аркана +metabolizer-type-novakid = Новакид +metabolizer-type-shark = Акула +metabolizer-type-vulpkanin = Вульпканин +metabolizer-type-tajaran = Таяран +metabolizer-type-reptilian = Унатх +metabolizer-type-ursus = Урс +metabolizer-type-felinid = Фелинид diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/demon.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/demon.ftl new file mode 100644 index 0000000000..c9f0b371ae --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Player/demon.ftl @@ -0,0 +1,2 @@ +ent-MobDemon = { ent-BaseMobDemon } + .desc = { ent-BaseMobDemon.desc } diff --git a/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/demon.ftl b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/demon.ftl new file mode 100644 index 0000000000..ae5d1f883b --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Entities/Mobs/Species/demon.ftl @@ -0,0 +1,5 @@ +ent-BaseMobDemon = Урист МакАркана + .desc = { ent-BaseMobSpeciesOrganic.desc } + .suffix = Аркана +ent-MobDemonDummy = { ent-BaseSpeciesDummy } + .desc = { ent-BaseSpeciesDummy.desc } diff --git a/Resources/Locale/ru-RU/ADT/Species/demon.ftl b/Resources/Locale/ru-RU/ADT/Species/demon.ftl new file mode 100644 index 0000000000..903d09dfbd --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Species/demon.ftl @@ -0,0 +1 @@ +species-name-demon = Аркана diff --git a/Resources/Locale/ru-RU/ADT/Species/drask.ftl b/Resources/Locale/ru-RU/ADT/Species/drask.ftl index 6f61062aef..5cdbc67a20 100644 --- a/Resources/Locale/ru-RU/ADT/Species/drask.ftl +++ b/Resources/Locale/ru-RU/ADT/Species/drask.ftl @@ -1,13 +1 @@ species-name-drask = Драск -marking-DraskArmRight = правая рука -marking-DraskArmLeft = левая рука -ent-OrganDraskEyes = глаза - .desc = Я тебя вижу! -ent-OrganDraskLungs = лёгкие - .desc = Фильтрует кислород из атмосферы, который затем поступает в кровь для использования в качестве переносчика электронов. -ent-OrganDraskHeart = сердце - .desc = Мне жаль того бессердечного ублюдка, который его потерял. -ent-OrganDraskInnards = внутренности - .desc = Мерзость. -ent-OrganDraskKidneys = почки - .desc = Выводят токсины из кровеносной системы. diff --git a/Resources/Locale/ru-RU/ADT/Species/kobolt.ftl b/Resources/Locale/ru-RU/ADT/Species/kobolt.ftl new file mode 100644 index 0000000000..c3a413cdb8 --- /dev/null +++ b/Resources/Locale/ru-RU/ADT/Species/kobolt.ftl @@ -0,0 +1 @@ +species-name-kobolt = Кобольд diff --git a/Resources/Prototypes/ADT/Body/Organs/demon.yml b/Resources/Prototypes/ADT/Body/Organs/demon.yml new file mode 100644 index 0000000000..544df0ff96 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Organs/demon.yml @@ -0,0 +1,21 @@ +- type: entity + id: OrganDemonStomach + parent: OrganAnimalStomach + noSpawn: true + components: + - type: SolutionContainerManager + solutions: + stomach: + maxVol: 50 + +- type: entity + id: OrganDemonHeart + parent: OrganAnimalHeart + components: + - type: Metabolizer + maxReagents: 2 + metabolizerTypes: [ Demon ] + groups: + - id: Medicine + - id: Poison + - id: Narcotic diff --git a/Resources/Prototypes/ADT/Body/Organs/fill.txt b/Resources/Prototypes/ADT/Body/Organs/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Body/Organs/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Body/Parts/demon.yml b/Resources/Prototypes/ADT/Body/Parts/demon.yml new file mode 100644 index 0000000000..ddc0a23bd8 --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Parts/demon.yml @@ -0,0 +1,193 @@ +# TODO: Add descriptions (many) +# TODO BODY: Part damage +- type: entity + id: PartDemon + parent: BaseItem + name: "demon body part" + abstract: true + components: + - type: Damageable + damageContainer: Biological + - type: BodyPart + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + - type: Tag + tags: + - Trash + +- type: entity + id: TorsoDemon + name: "demon torso" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "torso_m" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "torso_m" + - type: BodyPart + partType: Torso + +- type: entity + id: HeadDemon + name: "demon head" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "head_m" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "head_m" + - type: BodyPart + partType: Head + vital: true + - type: Input + context: "ghost" + - type: MovementSpeedModifier + baseWalkSpeed: 0 + baseSprintSpeed: 0 + - type: InputMover + - type: GhostOnMove + - type: Tag + tags: + - Head + +- type: entity + id: LeftArmDemon + name: "left demon arm" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_arm" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_arm" + - type: BodyPart + partType: Arm + symmetry: Left + +- type: entity + id: RightArmDemon + name: "right demon arm" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_arm" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_arm" + - type: BodyPart + partType: Arm + symmetry: Right + +- type: entity + id: LeftHandDemon + name: "left demon hand" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_hand" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_hand" + - type: BodyPart + partType: Hand + symmetry: Left + +- type: entity + id: RightHandDemon + name: "right demon hand" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_hand" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_hand" + - type: BodyPart + partType: Hand + symmetry: Right + +- type: entity + id: LeftLegDemon + name: "left demon leg" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_leg" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_leg" + - type: BodyPart + partType: Leg + symmetry: Left + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: RightLegDemon + name: "right demon leg" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_leg" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_leg" + - type: BodyPart + partType: Leg + symmetry: Right + - type: MovementBodyPart + walkSpeed : 2.5 + sprintSpeed : 4.5 + +- type: entity + id: LeftFootDemon + name: "left demon foot" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_foot" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "l_foot" + - type: BodyPart + partType: Foot + symmetry: Left + +- type: entity + id: RightFootDemon + name: "right demon foot" + parent: PartDemon + components: + - type: Sprite + netsync: false + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_foot" + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: "r_foot" + - type: BodyPart + partType: Foot + symmetry: Right diff --git a/Resources/Prototypes/ADT/Body/Parts/fill.txt b/Resources/Prototypes/ADT/Body/Parts/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Body/Parts/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Body/Prototypes/demon.yml b/Resources/Prototypes/ADT/Body/Prototypes/demon.yml new file mode 100644 index 0000000000..ab2d8e2bdb --- /dev/null +++ b/Resources/Prototypes/ADT/Body/Prototypes/demon.yml @@ -0,0 +1,49 @@ +- type: body + name: "demon" + id: Demon + root: torso + slots: + head: + part: HeadDemon + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganHumanEyes + torso: + part: TorsoDemon + organs: + heart: OrganDemonHeart + lungs: OrganHumanLungs + stomach: OrganDemonStomach + liver: OrganAnimalLiver + kidneys: OrganHumanKidneys + connections: + - left arm + - right arm + - left leg + - right leg + right arm: + part: RightArmDemon + connections: + - right hand + left arm: + part: LeftArmDemon + connections: + - left hand + right hand: + part: RightHandDemon + left hand: + part: LeftHandDemon + right leg: + part: RightLegDemon + connections: + - right foot + left leg: + part: LeftLegDemon + connections: + - left foot + right foot: + part: RightFootDemon + left foot: + part: LeftFootDemon diff --git a/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml b/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml index 0e7706c1e5..a492dde8d0 100644 --- a/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml +++ b/Resources/Prototypes/ADT/Chemistry/metabolizer_types.yml @@ -1,4 +1,4 @@ -# If your species wants to metabolize stuff differently, +# If your species wants to metabolize stuff differently, # you'll likely have to tag its metabolizers with something other than Human. - type: metabolizerType @@ -45,8 +45,38 @@ id: Arachnid name: metabolizer-type-arachnid - # Start ADT tweak: Drask +- type: metabolizerType + id: Novakid + name: metabolizer-type-novakid + +- type: metabolizerType + id: Demon + name: metabolizer-type-demon + +- type: metabolizerType + id: Shark + name: metabolizer-type-shark + +- type: metabolizerType + id: Vulpkanin + name: metabolizer-type-vulpkanin + +- type: metabolizerType + id: Tajaran + name: metabolizer-type-tajaran + +- type: metabolizerType + id: Reptilian + name: metabolizer-type-reptilian + +- type: metabolizerType + id: Ursus + name: metabolizer-type-ursus + - type: metabolizerType id: Drask name: metabolizer-type-drask - # End ADT tweak + +- type: metabolizerType + id: Felinid + name: metabolizer-type-felinid diff --git a/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml b/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml index 3f73c916c9..17be8eafaa 100644 --- a/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml +++ b/Resources/Prototypes/ADT/Damage/ADTmodifiers.yml @@ -1,12 +1,12 @@ -# - type: damageModifierSet -# id: Fur # 1) - ебучий годспид, балансим уроном. 2) - шерсть должна гореть -# coefficients: -# Blunt: 1 -# Piercing: 1.2 -# Slash: 1.2 -# Cold: 0.6 -# Heat: 1.5 -# Poison: 1 +- type: damageModifierSet + id: Fur # 1) - ебучий годспид, балансим уроном. 2) - шерсть должна гореть + coefficients: + Blunt: 1 + Piercing: 1.2 + Slash: 1.2 + Cold: 0.6 + Heat: 1.5 + Poison: 1 - type: damageModifierSet id: Kobalt # мне даже жаль кобальдов, но жизнь такова какова она какова и больше не какова @@ -19,27 +19,27 @@ Poison: 1 Bloodloss: 0.3 -# - type: damageModifierSet -# id: Demon # они вообще то мутанты, но кого ебёт так? -# coefficients: -# Blunt: 1 -# Piercing: 1 -# Slash: 1.0 -# Cold: 0.8 -# Heat: 0.8 -# Poison: 0.8 -# Cellular: 1.5 - -# - type: damageModifierSet -# id: Shadowkin # пупупу -# coefficients: -# Blunt: 1.2 -# Piercing: 1.2 -# Slash: 1.2 -# Cold: 0.8 -# Heat: 0.8 -# Poison: 1 -# Cellular: 1 +- type: damageModifierSet + id: Demon # они вообще то мутанты, но кого ебёт так? + coefficients: + Blunt: 1 + Piercing: 1 + Slash: 1.0 + Cold: 0.8 + Heat: 0.8 + Poison: 0.8 + Cellular: 1.5 + +- type: damageModifierSet + id: Shadowkin # пупупу + coefficients: + Blunt: 1.2 + Piercing: 1.2 + Slash: 1.2 + Cold: 0.8 + Heat: 0.8 + Poison: 1 + Cellular: 1 - type: damageModifierSet id: Drask # саморезы @@ -47,15 +47,15 @@ Heat: 1.5 Asphyxiation: 2.0 -# - type: damageModifierSet -# id: Felinid # мяу -# coefficients: -# Blunt: 1.0 -# Piercing: 1.15 -# Slash: 1.30 -# Cold: 1.5 -# Heat: 2.0 -# Poison: 1.1 +- type: damageModifierSet + id: Felinid # мяу + coefficients: + Blunt: 1.0 + Piercing: 1.15 + Slash: 1.30 + Cold: 1.5 + Heat: 2.0 + Poison: 1.1 - type: damageModifierSet id: CyborgMetallic @@ -86,10 +86,10 @@ Piercing: 9 Heat: 9 -# - type: damageModifierSet -# id: Ursus # мишк -# coefficients: -# Blunt: 1.0 +- type: damageModifierSet + id: Ursus # мишк + coefficients: + Blunt: 1.0 - type: damageModifierSet id: AshWalker # Груба кожа = умно ящериц diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/demon.yml b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/demon.yml new file mode 100644 index 0000000000..bb197ca124 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/demon.yml @@ -0,0 +1,133 @@ +- type: marking + id: DemomTail1 + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: demon_tail + +- type: marking + id: DemomTailLong + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: long + +- type: marking + id: DemomTailUp + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: up + +- type: marking + id: DemonCowEars + bodyPart: HeadSide + markingCategory: HeadSide + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: cow_ears + +- type: marking + id: DemonEars + bodyPart: HeadSide + markingCategory: HeadSide + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: demon_ears + +- type: marking + id: DemonCowHorns + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: cow_horns + +- type: marking + id: DemonHornsDeer + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: deer_antlers_horns + +- type: marking + id: DemonHornsSmall + bodyPart: HeadTop + markingCategory: HeadTop + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: small_horns + +- type: marking + id: DemonChestCowSpots + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: cow_spots + +- type: marking + id: DemonChestGuard + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: guards_stripes + +- type: marking + id: DemonChestLinesEmperos + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: lines_emperos + +- type: marking + id: DemonChestQueenLines + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: queen_lines + +- type: marking + id: DemonChestTreeLines + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: tree_lines + +- type: marking + id: DemonChestTrinitySpots + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [DemonSpecies] + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: trinity_spots + +- type: marking + id: DemonGoatee + bodyPart: FacialHair + markingCategory: FacialHair + sprites: + - sprite: ADT/Mobs/Demon/custom.rsi + state: goatee diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/fill.txt b/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Entities/Mobs/Customization/Markings/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml b/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml new file mode 100644 index 0000000000..04c38254a1 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Player/demon.yml @@ -0,0 +1,50 @@ +- type: entity + save: false + name: Urisst' Mzhand Demon + parent: BaseMobDemon + id: MobDemon + components: + - type: CombatMode + - type: InteractionPopup + successChance: 1 + interactSuccessString: hugging-success-generic + interactSuccessSound: /Audio/Effects/thudswoosh.ogg + messagePerceivedByOthers: hugging-success-generic-others + - type: MindContainer + showExamineInfo: true + - type: Input + context: "human" + - type: MobMover + - type: InputMover + - type: Alerts + - type: Eye + - type: CameraRecoil + - type: Examiner + - type: CanHostGuardian + + # ОТКОММЕНТИТЬ ПРИ ПЕРЕНОСЕ ЯЗЫКОВ И РАЗМЕРОВ + # - type: LanguageSpeaker + # speaks: + # - GalacticCommon + # - Arkane + # understands: + # - GalacticCommon + # - Arkane + + - type: NpcFactionMember + factions: + - NanoTrasen + - type: Respirator + damage: + types: + Asphyxiation: 1.0 + damageRecovery: + types: + Asphyxiation: -1.0 + # - type: SizeAttributeWhitelist # Frontier + # tall: true + # tallscale: 1.1 + # short: true + # shortscale: 0.9 + +#Weh diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Player/fill.txt b/Resources/Prototypes/ADT/Entities/Mobs/Player/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Entities/Mobs/Player/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/demon.yml b/Resources/Prototypes/ADT/Entities/Mobs/Species/demon.yml new file mode 100644 index 0000000000..6f99d51300 --- /dev/null +++ b/Resources/Prototypes/ADT/Entities/Mobs/Species/demon.yml @@ -0,0 +1,66 @@ +- type: entity + save: false + name: Urisst' Mzhand Demon + parent: BaseMobSpeciesOrganic + id: BaseMobDemon + abstract: true + components: + - type: HumanoidAppearance + species: DemonSpecies + - type: Hunger + - type: Thirst + - type: Icon + sprite: ADT/Mobs/Demon/parts.rsi + state: full_m + - type: Sprite + netsync: false + noRot: true + drawdepth: Mobs + - type: Body + prototype: Demon + requiredLegs: 2 + - type: Speech + speechSounds: Lizard + - type: Vocal + sounds: + Male: MaleHuman + Female: FemaleHuman + Unsexed: FemaleHuman + - type: Damageable + damageContainer: Biological + damageModifierSet: Demon + - type: MeleeWeapon + # hidden: true + soundHit: + path: /Audio/Weapons/pierce.ogg + angle: 30 + animation: WeaponArcPunch + damage: + types: + Piercing: 5 + - type: Temperature + heatDamageThreshold: 400 + coldDamageThreshold: 193 #starting temperature damage treshold + currentTemperature: 310.15 + specificHeat: 46 + coldDamage: + types: + Cold : 0.1 #per second, scales with temperature & other constants + heatDamage: + types: + Heat : 0.3 #per second, scales with temperature & other constants + - type: MovementSpeedModifier + baseWalkSpeed : 2.5 + baseSprintSpeed : 4.5 + - type: Perishable + +- type: entity + save: false + name: Urist McHands + parent: MobHumanDummy + id: MobDemonDummy + noSpawn: true + description: A dummy reptilian meant to be used in character setup. + components: + - type: HumanoidAppearance + species: DemonSpecies diff --git a/Resources/Prototypes/ADT/Entities/Mobs/Species/fill.txt b/Resources/Prototypes/ADT/Entities/Mobs/Species/fill.txt deleted file mode 100644 index b4954caf47..0000000000 --- a/Resources/Prototypes/ADT/Entities/Mobs/Species/fill.txt +++ /dev/null @@ -1 +0,0 @@ -# Данный файл существует по причине того что Githab плохо дружит с пустыми папками, при работе с этой папкой этот файл можно спокойно удалить \ No newline at end of file diff --git a/Resources/Prototypes/ADT/Species/demon.yml b/Resources/Prototypes/ADT/Species/demon.yml new file mode 100644 index 0000000000..82bbe62c59 --- /dev/null +++ b/Resources/Prototypes/ADT/Species/demon.yml @@ -0,0 +1,157 @@ +- type: species + id: DemonSpecies + name: species-name-demon + roundStart: true + prototype: MobDemon + sprites: MobDemonSprites + defaultSkinTone: "#34a223" + markingLimits: MobDemonMarkingLimits + dollPrototype: MobDemonDummy + skinColoration: Hues + maleFirstNames: names_first_male + femaleFirstNames: names_first_female + maleLastNames: names_last_male + femaleLastNames: names_last_female + naming: firstlast + +- type: speciesBaseSprites + id: MobDemonSprites + sprites: + Head: MobDemonHead + Hair: MobHumanoidAnyMarking + FacialHair: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking + Chest: MobDemonTorso + HeadTop: MobHumanoidAnyMarking + HeadSide: MobHumanoidAnyMarking + Tail: MobDemonTail + Eyes: MobHumanoidEyes + LArm: MobDemonLArm + RArm: MobDemonRArm + LHand: MobDemonLHand + RHand: MobDemonRHand + LLeg: MobDemonLLeg + RLeg: MobDemonRLeg + LFoot: MobDemonLFoot + RFoot: MobDemonRFoot + +- type: markingPoints + id: MobDemonMarkingLimits + points: + Hair: + points: 1 + required: false + FacialHair: + points: 1 + required: false + HeadTop: + points: 1 + required: false + HeadSide: + points: 1 + required: false + Chest: + points: 1 + required: false + Tail: + points: 1 + required: false + Snout: + points: 1 + required: false + Legs: + points: 2 + required: false + Arms: + points: 2 + required: false + +- type: humanoidBaseSprite + id: MobDemonHead + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDemonHeadMale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobDemonHeadFemale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobDemonTorso + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDemonTorsoMale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobDemonTorsoFemale + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobDemonLLeg + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobDemonLHand + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobDemonLArm + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobDemonLFoot + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobDemonRLeg + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobDemonRHand + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobDemonRArm + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobDemonRFoot + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: r_foot + +- type: humanoidBaseSprite + id: MobDemonTail + baseSprite: + sprite: ADT/Mobs/Demon/parts.rsi + state: tail diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_ears.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_ears.png new file mode 100644 index 0000000000000000000000000000000000000000..6c7c43592a0770a644a6adfa0fb34935ccab0156 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%sP%zEY z#WAE}&f8lXc^eD_m=Cxl{jb%y*`_;>O=^}(ivmmeR@G{TX4ICEzHyZ?s&w|&~N z`+nP*GbP`%{!Lo_Sy^e(DmCNzZ70sGT(x%p{~7y>_<)82!GZN}-?6_r5%G#$#xmQ! o{)*s^Gc*4-bX=EZg~&g+AS>aVVt7I>bt6c?)78&qol`;+0F0+gw*UYD literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_spots.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/cow_spots.png new file mode 100644 index 0000000000000000000000000000000000000000..f6e3dbc945291a8bf953f3c5791ff0e49e66e526 GIT binary patch literal 502 zcmVLh&;D*0IK`kMu5VWLC6Z6C~zAADPgYSt|MUk`-7Fz?;hFC zbASKy{rYS2ajZJ0KTSx9y>8T(ymBj_VOo8ElF$0edE4ihKR;*tuGa7Jm(ss!!S3Zi zYe3*%?3~@(pM4GgGU5C^xn0km7pDEsiGPq&DgW?FY(sg>Uik!hMu*?y} Jvd$@?2>`ifH)sF= literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_tail.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/demon_tail.png new file mode 100644 index 0000000000000000000000000000000000000000..53bb821fa88e98f910a8fdabb41bc76d5804231b GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%sP;j@W zi(^Q|oVT|O`I-%QS`!anGW71YaLt==`8nGhCdO{}X*-y+LRT_6F5TAfFTYp$>CMH; zOhA2L(9pT`;=jLb`C8NXcCV{$TfZu6W0}5AZ`hRSSM%rU=FEDQ`{~~ASo4RI8{b-8 z5ObH2fN2EM_LJ_;kCs|1A98D(Xy{adLyF(u7`hdo^NhV-wAvv&*5z0ux`V7@6vC?EVFL!^3zHQP1y=E)zj6_Wt~$(699(oVQ>Hd literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/goatee.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/goatee.png new file mode 100644 index 0000000000000000000000000000000000000000..98a511a24abbd16cd13ca6bbc01b916e36f44634 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%sP%y;P z#WAE}&fA*@c@G$HFdta)dp(!-4&g6?nz>7!yC5Pz`yPk!CzY}sP$iB=Z#Qw{j2rg zj7Wqd^+!dl%&GN<9%h{xwf=HkU&P!8+|zKbjmblQ_P&{TPX;`DK+h^*qJQ_0o@~#W znBDky;#-P|D&!&ss33w@{iF^TH!%(JCLx0zUP66 s9rOVJ0J5{fr*XN570v~$-~o2$3Edg$GZsIu+yDRo07*qoM6N<$f|3)MMF0Q* literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/long.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/long.png new file mode 100644 index 0000000000000000000000000000000000000000..af7875e2fb59e72edaea043df3fccb085298f6a1 GIT binary patch literal 461 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%s0|R5d zr;B4q#hkadc27F2z{7gsw4YZ{P_pJ-ai_Hn;KFBmZLIDM1Bx^Y6|}@zRVwB)-;j zpWmLk|95WGv#yx@{T{#d&ZQid&ky%yhRa9Si7meCKQK-h6-MsvpLV# z!-Y@(z@_s1?Ct+`*+Z{NEIuaTe!e|8kblGeU@wLS0j40Y9Wi?Cb*HO!-p2j4IkqD9 zIwQlL?+gvU|MsnW{a~;BT%qa3Vcs`d1Q`B^K8j>?ak(Ek$8>&T?U%J2%ijNfxP9OI z!rgc6_HA@Q2J;t9U70>V;<8xub&FjxbENLXx$Rr@`LV|NYi8FCKV4><8Wi9q*>vlm zdwJcSS)!?{l36NBI##TTYPh?+`@{vwApaY2OY0|>73)+AUYsHngTe~DWM4f*Hq6( literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/meta.json b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/meta.json new file mode 100644 index 0000000000..5c76f5ca41 --- /dev/null +++ b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/meta.json @@ -0,0 +1,71 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by discord:lunalita", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "cow_ears", + "directions": 4 + }, + { + "name": "demon_ears", + "directions": 4 + }, + { + "name": "goatee", + "directions": 4 + }, + { + "name": "cow_horns", + "directions": 4 + }, + { + "name": "cow_spots", + "directions": 4 + }, + { + "name": "deer_antlers_horns", + "directions": 4 + }, + { + "name": "guards_stripes", + "directions": 4 + }, + { + "name": "lines_emperos", + "directions": 4 + }, + { + "name": "queen_lines", + "directions": 4 + }, + { + "name": "small_horns", + "directions": 4 + }, + { + "name": "tree_lines", + "directions": 4 + }, + { + "name": "trinity_spots", + "directions": 4 + }, + { + "name": "demon_tail", + "directions": 4 + }, + { + "name": "long", + "directions": 4 + }, + { + "name": "up", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/queen_lines.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/queen_lines.png new file mode 100644 index 0000000000000000000000000000000000000000..0e30ea261a405a186ef20a97f9287f6d0dbbe631 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%sP;i&0 zi(^Q|oVT|Q@--_6xCR>h{U5(I>sQKw!MqauKzvnRsA=+&r;owZJsW=D|_|oW`!;PFCGhP?RY1z zv4*kodc#e(e}5|(7(Tq*B|9&x`cL%6m28Ya2QW;Sd1?83pJ~ad6HKPu+gEt__Ve4{6{{jsfm%Rd z$Cdf!za~eY@0@gI&O5untxI<+8~;^-$Q{@xUR|T3eQpcOQILSAtDnm{r-UW|4Qw_i literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/custom.rsi/tree_lines.png b/Resources/Textures/ADT/Mobs/Demon/custom.rsi/tree_lines.png new file mode 100644 index 0000000000000000000000000000000000000000..4a555c4d1137d85931a243c935adf426caa372b3 GIT binary patch literal 497 zcmVlvr(yWw3 zBB6nZ2wQ^&e{2D4RBeFk45+oL zK#fXo0<{#GKVM)lexx5|I3AUtSJ`R$a0o}AvtSp=v+pI2P@~@ zyR~Oi&D+N>{yJ+e-EwsO^Q-fY)iUkL-u`uZn#9|huocVe-0EjbB~^ZG|5tUp@nn#` z>CU`Q2WwC10=JzklghzH3-}z;$+@TNnXlh-)K>iji_4ia`LUd7&)N?kUw8Z1-PNBp{%_eD(K}mkg19}8 zvvKwQWsD!sn9PlFS@ORB^WN-@u_E%-+m1eReRWTB)vB~-fz2m&a#j|9x_UEYV)Use z+h@%D{`dEv-S7MV|LO*L8w@t|hxv76|A|_+{z6N1@g9i@4RhLgrtOk+Kd&2gDtE2e z#HoTaEnI6`Q|o79{w0BmLAJ#W1XFyopAh#PjSM;lVw>VBI5gg*hEAu%aSe!tK5_V(QP zbL)Vz+W^$-bqp2I`fvfj&2SXyTOTekR6xC6kN7pu;UPNyT|N~I!&LLoAjPN&&BI}Yc+ft{W)*mo&b# z5wQ|Y(Z zjLmVFfSF8&NxLiQ@3RZlf`tISmf>z9xHos*YViZ`*FQxmE6d%4zX3M>`)3I0RI300 N002ovPDHLkV1m4mYbcK{oU-`a0~y-e=M0a zP8VmtiMhLzJkKt#Ir{Ngs#s)&wNf3CY`vhDia3rLkH^xkHP!-I>)c$|l{k(u$JZ1}MK%ljg#97? zj?3)n4whw6EEZGM!pc&w*Cpr;B#I(w*BTN#5h{wi%5^92^`h zjlZ-HD6a=VtJT6%8m%?m_a7H*y6-=twZ>AKR;#t(_aK0Fts#X{F?q9o$0g&36iUSf zyF#f*#t-RtT;Q)v6iP)_sfT+3)DxSmW7BH2s8*|)K}OT>xMUq0tu@!z*J!QDIyU`| z%OInvR;!s-t3}qaQBUk;``-_+wY7CyS3X2*O%MbC1VMn-nyvETZQDEi*8-SMrvOwc z72dvlwUEx8ot=gGM&7=BC6!8L!9O*?Y&HYHdw0h37u7^RpU(-ykju+U!Z2h$pC@b2 zUsUnloh|sM2H5yAVSY8CP%0(`1~B?`j%k|g@9$%pCZkX1$y&eTQYaOfUrpHfGI zmePrSV`Jl+KKIGWKP0f&1$U3jG=HtLdt3%UMDFd9{|dm@;`=^7{ql3h_x-dX)(0>Q z12dX(b>3dkU!AuxqbY`AJT8D`S!5j>=kK)Nh;v*f>)2S9^|%0W95Wh??pzylzq@F1gat^LvM@&oXDw+ldC*839v1b>(B Uo2DpT8~^|S07*qoM6N<$f{dKM@&Et; literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_t.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/full_t.png new file mode 100644 index 0000000000000000000000000000000000000000..3c71c7d8c3f8f246ff1aea5f06043ca18faf1353 GIT binary patch literal 915 zcmV;E18n?>P)BMvO)x-LHku=DoNGAc{JbAvz6|Nf4>gXe`}35A?CH?X_A%b&mCOOY_eU>F7w5k*nN8xfIV7*r(Q zTGoMsPL~|Vp)d>)$1!wW2LR~0jyR4Hh9Mlsp+Tpci%70@GYo^mFofWIN3BsurM8V= zGR0(QVE$wSk|d#CuNTrnW@ws5{@5bM7!5jIVvLbLwn)>oLQ7DXgyT58J!JA+=^Avp zgxV9xvW%;%D{kN0+k@-6z{ElG_-HjtFz9s2A6rC3#2BOLbjllJjEIQ*v6WkdnP8eG z#c|9hVvKPT$$esvz@#R4V^E_SZ4CZDVI=XKDPUbs#p! z0DykK4=G+?bp8nda6NNV*U|YWNbv&wem~{+AOeF43|L#3*yHz))X22UJvbdyQFCvC6gSUo*)PU9G;#)fA{`JuxBbC zcW`ik__4e+1NRcBR;#yczyI+P)oK+{6afIDD8k|C34Gtja5!A*e-rmEK{83J)xw82 zZ&T?^#CTJbAKtvBR;!irFHB%Qp928Qk3GD2)lT&VL4fIW%Jq@p#j7^VkG+(CVFHi7 zxm;kAp#k7WTCIyqh@yz??QMvn2ad3;ow3=K?%2Aao5B}tM1 z0Lp$7=Rbva{_Z`L{U!iFlB8Qc%Lpvp5#0>3SSKmU4N@;t9-i2MY~x(^4jis9uoCeTn10}xBwMJfj_pW`c%zS3o;Q%%CJ>h p-0J%}8sQm$%h3n`pi;gs;UCG_>q~Cg@gD#H002ovPDHLkV1ityr6~Xa literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_f.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/head_f.png new file mode 100644 index 0000000000000000000000000000000000000000..1285b693dcc7ecae9d05b7abfdf20d2f09647afe GIT binary patch literal 708 zcmV;#0z3VQP)u=#YbBkNE>8Po z?rvwt>iZR5zk91S*1wK#>YOyY9OM1bhwRun`>ZpJHgk6y2L}h)@g**c3+}ou5fR

kUg<(iaDM%@iBuUn!lu$|`48z>upYg{GpN(rlG!`RuvNPK~@vjwYW zLrS^Qi%;XH@0C(Zua7@pDIo-fVVE@`L?QeCVSLZ?D2gKTJg@Nhj4{R-V~jDz7-Nhv z#u#JIl6ETTaW?kb*;lkaeJmt3C5}(%)zO=!KHIhnt53*M)G2X%LKmm~!qQV0r+pH~ zCrfiEDm{9 zRxM0M?oyvsvoVWrR+^))x0|I|d;_ayFZEAGF3hT>HD>MwXfzrn-}hlwEkx1%Q!p=Y zAP54jN#qd(0p{h6?CwWV1hZC%dz6hYPg;0000Yg zY!=5dy2hLL@09xb*ZI22Nmr984i7#Q$M)%Gm2Q;jjZN(A>=efnOsWg_JdcQo=JR>c zh=@GTqbl=nZ*PnCH~HFQKRE6W=;q>*(lkYuWf%^J0D$3eh%C#HrYUYNE@|8!tYsp` z{Q-qxNK#4&A&_NR(S#6?QX&k)()p#<&A2}x`Qq;O%j55O-h7ESavDPoY$X`5{Qm#Bce1EMh%c3w0i)L9?CF}owzVG`K$1(Z7UwJ-bj4{R-V~jDz z7-Nhv#@K&Jxs>#<8vE_^E4rUPR#KX>ddKwo;O)w5ySuxU?N2C5)C*Scm_{dOm6fMP zCud~!j#tJ|Re2tcCYfVyzE5NV45actrpg`K?1njAJA&GV45a0Z8>x)Vn~0c)Thz} z=ptqZd))rN>9Gh)p8t%qA0@l_BH?@2m$~=x7)4eZ}8WK vi2M1CMnh==7-Nhv#u#IaF~%5U>`D0vu=#YbBkNE>8Po z?rvwt>iZR5zk91S*1wK#>YOyY9OM1bhwRun`>ZpJHgk6y2L}h)@g**c3+}ou5fR

kUg<(iaDM%@iBuUn!lu$|`48z>upYg{GpN(rlG!`RuvNPK~@vjwYW zLrS^Qi%;XH@0C(Zua7@pDIo-fVVE@`L?QeCVSLZ?D2gKTJg@Nhj4{R-V~jDz7-Nhv z#u#JIl6ETTaW?kb*;lkaeJmt3C5}(%)zO=!KHIhnt53*M)G2X%LKmm~!qQV0r+pH~ zCrfiEDm{9 zRxM0M?oyvsvoVWrR+^))x0|I|d;_ayFZEAGF3hT>HD>MwXfzrn-}hlwEkx1%Q!p=Y zAP54jN#qd(0p{h6?CwWV1hZC%dz6hYPg;00001J%PqDoQphLTwT(ZeMfb9@wud)y&4L~GS2P1omzS>lH=g2Rj*tb zZ@<0f#1TIIL&-~r5^2v%MLTmO*Gj+s8gJ4j|A$Rm`u6+p)$0!4@| z;m_4lq8}bDp7)xcmyNmCZE&YrxbF(eePg_QNo!s+1{ApFpCk_6^ zvh(McSjeb&UN*^`wM?|I{{HFXYl6B|R<6>rd_JZ9V%+^ZX(#_IVs2SGU8Q&S`K^}! z&#Zf|I(M_>>UWatFsm3C{!Lt#sne36sp_p6dA-#9Emuiw`7K$e4a+ja-q%MMKUovh z6S!1lYEa1at)C3;J>jU7SiA1^<#!T~`}Z9Y|H`cQ_E+5dN!tv)e%X1%$v(829?P13 db*1u#W8$%G(;mD`sN4p!%G1@)Wt~$(698AUkGcQ= literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_hand.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..ff61ecd0cff443c01869d6af091b9333e64061db GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%sQ1HE{ zi(^Q|oVT|&dL3~PX??hO$JB)BdQW(_MSZ&%{6w%xIzsUG$xU4obSDX@_%vPjT5G1I zcJaXft>S5XhfBVD08Idb1MJV|Y|YJ%y&fs0{_T3@KIL9v?XE+wc9}iDGkvChdt2>& z?@9CC$!)op=hkJh_G{VV>3;$*rT)cz|GQPwK;D3W59d=N)9zJ&zIXnfxzh|K^Q=IQF^vd$@? F2>{HTh@}7k literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_leg.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/l_leg.png new file mode 100644 index 0000000000000000000000000000000000000000..2125370c5b07083b1bcc33f2e2a8c631fb78eda8 GIT binary patch literal 424 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%s0|R4} zr;B4q#hkad46~aZMA$#n7pW^vOv!x4QMN&Tq4WMy?ziR{3!ItP@!eFK*1)cq9=a}= z`DWGm8)BdS`L$^)C~7@p##+JS8#OvQ+&=#L zqVxM_C&D!^+|6e9u3mLYGI`F{YfmfR)$MM#IX`#nHOb_d(9lOU7wa6Zmo6{9y{%)B z$1Hs@SHWA`WdF#0Y&ufDV{2H6uI-c{u4}h8$Eh4)2HMXMaNTs0%FoH6Gk2{!Uo}yH zH^FT7+;iPWon-7>u9u3R6su=+3D5caaouw-_)*>?#*i1 z|JKibB&XLtGfM?%D1&8ATJh_kyfRJI;&Z97*DTXDm*$BCT;JL%uxaXpIhzHV-hTfb z##M1rc1PTLRnL=eH$AyqwC#58v_11Ti7R;CtL{~My!-y!G_&m&Q*_?fuDdF?c$F5n z;*G4WyH+zipCjAvzIxTFt>5pT;@u(1!wOL5<(FF`^rqi`zDY;=Z23M0&sSfoxD;3Dcwa5OoAFJP zOMgTe~DWM4f DHWHjf literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_foot.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..92cc25101de575eb36e7bcd46da933d14d30d6f6 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%s0|O(Y zr;B4q#hkadHf9|*5OI5GUpReQg8srUfA1gPy>MPr+YKX@PB)LnB5RYcL0&88mRQ|q zzN7qZl{O>LKq#oYUOIQKpZaOb=yNyc6qoh)6`xD$nHIEZ%B0fR^2z58-(u{~k9>YN zGBnh4(yLuzQtH)J_wvK`ztifSocnsN-t=xS&EoH3Vfqg&c&a9TvErGuWN&D;d);Gx zzey&!_nsg7c#9ck6$8Va;M?1t?cFZ1_^8C%_rG`FVg0k@{qLP`_io>oEBg@i@iz@|m{+haTnsJo=q6zMQdLK&4hsMOXHl`}RHJKNtc7 VXY6>s_U3<(9iFa!F6*2UngHl;jClY6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_hand.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..74b5130e82e224c3256149948e9f8fdc8eb95a52 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%sQ1FAN zi(^Q|oVT|&dL3~PIQB7c&nc_e6VfrIcNQ-{q0AzDLh;*d0oRD`6iy+tgF9bY*`%cYW4ck*!tb&Up`k%TDnnr{jNXK630Kff4wOF z;YYynzCEYP_O5B3T)lVV*RQ#k@723So9_SC3JQt;S0&j^@?4!S?VbxV(9_k=Wt~$( F69DGshe-ec literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_leg.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/r_leg.png new file mode 100644 index 0000000000000000000000000000000000000000..020edfde734415a24a6a1077f921a0755fdb5c39 GIT binary patch literal 412 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%s0|TR< zr;B4q#hkad46_e8NF4jof;(9g`4o6}-D=`MT`=tM6?*W5nRF zFV1zoX&>*L^UrS_agMteXQ*HF#;w^yzlxC|;WfX?y5=A+rSEH(Wgdy@bV-SOB9Yx& z@S^_unbn#gJYmY>%@eaZSckT0G5Cv7w5EX7~B8{SuEtW7rNzZ|vr{rMk9G`yDndrj`){P|7n98=eaFJ5bV?~IVrFX0Fs tv4hwBAH7-qvP9~Nz;FA8j(H!!#vJYD@<);T3K0RS$uth)dJ literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/tail.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/tail.png new file mode 100644 index 0000000000000000000000000000000000000000..cd8f833d5d3a99bdac7af0e38c158736eadfe7d0 GIT binary patch literal 496 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9Gmi6G3l!hU%s0|R4+ zr;B4q#hkadHug0cNU(qSA1fnM(f*iGM(@eIBjF{_EoFELUpxuvoV;nK#fC3!-oj2y zxgQS)z5g%Gd+NWoJnLm97by6$zvc+vhn`J3ybMn&`4}|1lwMZNTQtQeG<4<-%SDeA z9^?x+_5Gj1m+=0y#FU_CC04Ap?llYz7R?FW_w%-YR6lgVY>LJGE5+-U9Ny!#|H0Wb zkvDJ65OenX4-pGHze1JX5>((As?!|Ce1)E?BW5e1B=?+Kb!XCb-`^ z@BD0yt8bp&sZA!|&il{5RwenK5$+qkvfXzdg~z3zp5gRyTE(>~UE7Zsz5o9EN!Rw8 zP1e_0H|b3F6mIk{Ti-e{T)*5~;Ov}7xesPnPLoy2*IasAK}FkI!G$YUVVm!}!rU`I z3u0;x>aF7yZvGv=ET=zm(eEnOo}3v4>z0;(|Fd+{H@Qha#VaqJZTg-gvIrPae5nzh cX}-P;T0k}j5QD&_;K?A$)78&qol`;+0QQUCDF6Tf literal 0 HcmV?d00001 diff --git a/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_f.png b/Resources/Textures/ADT/Mobs/Demon/parts.rsi/torso_f.png new file mode 100644 index 0000000000000000000000000000000000000000..c7c0027dafb0598e837c5645204314710b277db1 GIT binary patch literal 1224 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 O0000