ccks5a3wf5m}oYyfFvx&gRiRQ#1@(VOgO~v
zFjHYRk*-zTMn?&c*cKyRiO{Onj^L9jMvI
z1cii#$5$TQf}^has$Aa=3#UQig$f$JXKuQxiyyxYM7>IEYul-@65z2B
zAp)1*LYV+4>c#0Kg1LVr+-h_b!Bs*>%K+Z+Pp)RLg-W-VcKV4${jqZVeT8J@v{KK3
zO0UeW-t%x|e8)skwK7iXXZQ};py2HI?fi!^E}A`&miAb1JNTF0s3&vn-S#qB+x-0e74f4;
zVit*#!?&K8gC%5T(FbgXe{~@~UbycdYXZEJ`TXOR6&d2-m0tn<^K+Caq_b(TU&iOW
z*^&E!K;_ZEZvX8+a+IV6^~+Wh>2x{fCRghBRFxW}dmJ*HAJIR`W?cWIAoewO8~=_g
z9E8kaQw&w`?E-z%QVj)yNKBdO{XbWab0?+Cn+_E!k8i}QsXkQgT^|KhG-oc7tC8e~
zoZsT$;1?$B_#8!N@A}ic5KUb^RO~yw)fCGb)VF@I)Ryj?oj5R2l&!DZpE_V#lN?~H
z4m%yQi+B6cE1^n~KYxjZP9>R|CGPTUW+V$GZ)bYRyM;doqJ%UPNxq52VMBEaJ!vZZ
zm+J>9bsY
zaTlhS&3Q4(_QvldTK=W@t0fId?zorITY38egK;nt9N(l9MN*J~9~WfaO*#V`E5~7s
zR&cPq*|{r1O%rlYUsf_Ky69?fL9@BzD@7kmlcCwp5j$I_AfOfSs$<&=cJ@H-gWP@-
z@y{qx!_lO2n=zsB>LG6S6deM~({Y=e08OrZi`3fHn!^`52}wn6rX|!HKHqt}on_?5
z2oMS3in1&T6Xi1P8jm4w{^eoJFVC&+CthEDD2^OC0`~9PmM~~Pt5;b>uia+IxSfs1
z{RYHVa8j{KI#t|OyyQA1wg~%Ge9j9GVKC3k!;8i`ck;3;W-Pu+4BmD})A1k9N>gdu
z%BqqL;2aC0Wpr^^*2=SsH>Z(9NPxQkX&dQcI-|}SNJWmcqJf<_#NiWSttA&fb6G_$
z-|!tHsbEvMsBK*{Qkbu*j;S*pB4g|+Dd|Sz(NOZ`&!fw3s$!ntaMkO{pQmCvvnVVK
z_<}SP#_`Hz+GVZA>{S>uh2$`O5Meb!DUp&&Y8i+2_p{~Y`9tuT!X@zpR$=%Dk`XA*YEZ@!>L
zUT|u|S8)wNG!*mgF?0<;!5m2S=0Li1llQm{!H$NL8kH&AGd=21POEw>yB%%L4~#Ml
zwaH(-kfW+l`5=*;%-s1_NlRbz6SsGG%_^A)PE&n)iHYgdd{0zbSypvzvMG=Vp^?69
z7js5KpuVawm(DCUa2O0_O?rbNjanLwXim^%h{7O&l}I(+pY_8Y&yv&gKu^tsCP;jw
zV(ELFx4ynE>=+qIn%#R>Ol*be6$mY6y$cbao&sjHpd4Rbc6*#~=}>P~GS)ScaNxG`
zA{x^$Tr8nc+@QJtRY5mNU$T5mZKjp=-Oy?^?|kX!Yo2_UexJ;
zBbP^$
ziw98y+uy|{SNjn~ZrGiHv9`0zr|Fcsz7(k3z~1_!cf9E@y$WTX^k#!*9w)|PBw(dj
zo!-#>)S`|XpHq?ZvK$^V|7LFCLNRZooZZ};nK+tF%OA|$
zl-o~+Zowdy2Abo&Qlx)cBu-Qc;o8YN`AofcEnGSi=3AsFB||B1xOpkY?oTtX|LQ-S
zwX0s^gQnnA6fLU!8{~l<*M!ziI?QjoTuyM=Ioz{(XbJDc3ICsy`42n6fWsdKBmC?i
z(G+Xc@3lBLb?=WXkE_WQxf=X!|Ehc%uW9t?*vqqV+Aoec>zpc3VYTJ-x-RwJ)`uEZ
zrz*$W1RIbIh9E*IZi3W-_5-Z?-vtRHd(#yTl{~Suz#F7eJfxc)u+kmOSK+l@kUj#I
ze}AQe12lP*XI_T_OLMEMm=P-Fg++p)t(TR~t2?CzS*Z#c$CBpx&92XnpOCKbK%34g;%Osb@R1bK!Fp0kDg*aXy#s2r`*17@`96l5-~wGjwD2IiC|fNiBZK0`xarL>=us6hjUc-5+?
z;a)%1Z6RmN^_Oe*59N{wzj+O0Ym8}&1ir~3uFv8d8OOv~(Tv;i!g8faUQyFuHEE$z
z8WGI(d~hdpS3o-8cj?}7MlkikA3&N%0m@x)n2AZztF`m&pp!|75o|VaO=iy=0s{e^81z
z0P1_x{SqoPofj9w(obwfyEtshR_hm(IzL0q!9Y6mi=cMHx|Ta4i;HFMm2a#r>*E=N
zhY~?vyyD8FGsc+turVHE-7c!Dp)en-4;IiTmM9+GYBxR}P11}Ts(Ae9H3l-K@f`&i
z0AQNkufAa9y96Q!M8dRznep6vY|7+6|~PztoLF$-QEg9Fa>XFIjGD-hCvg6}fd_3PJ9YBYa<
zNIXMUc~RZje(bh{snlTt_c!&BlA03Nggo8qh22tMW%h#EI>k>#+%JdUI}iay;HYw`
zycUfi_P`<-jao0Z$zZ1oVXXlyG7zP@_^Myoa7f5sCx+ITt33<52P^fuP9k2)f0vx>
z#v+3Z>!Y0fn;rZ5S_PS?zH6h|D(WmdkkVUuIL&lAzgURJ8V24~gxO(vuKR-}+464A
zP5!Hn#QSu$@iA%A*JZT?46EbK`-fT%^*r>h8~*~n+q0~{v$4X8P~$jMvMlQR_wP|*
z5YzO!bZLLYZN!1N5d7xA4A1d?QNB7CU@bMNQZJ;-<9Q0^0xx?E^82%}#J&I6*VX`$
z4szl1mcA4Noto^kW6tB-sKS^P8Lk31dHy~1ZqMUIz1_}<-P%*pocz|ad^pCol@QYa
zR?wK2^Ch3|W;H0mgI9a2qmvduy
zc4Aus(}fRDu+J#G*$u&m1JubrpLku?-&6%9j>4c}HiAYC>@FShkA-R)
zw*2@p3K}qm6R}mk0*NR{Wr3qu0sm8*!Xu;icdpsrCri!>#`F)~3Bq~BU=CFa03=)r
z=(97Bxd(r#oL59-Ne!JbiOnF?2qqi~m$VXTyXW%`_x2&-vi)RQDXs=u1P$TMAX=z|uF?XCloc6my-cX$M5*1^JP$AvRn}
z*!4W@#OM5&%0Q`B`T904SP*;=+1_h3)-PUz|L;zxsrPo}6Ro2ITzQnBjGK@*J}|)l
zTe^rUc6XCJcA!5#J&qpFEYAXOM*udzQ^P%q3M#f=V%o)-vIjJh8@|67+V46S`yul0i^?eY^#);FM9W`6^~Z6$0V8=7(r
zV8Xudc?1wsWwf4G`BlSz@@HQXL??GSgZMx~iApzEj>QT5#M^%psVr#>@jioCZJq=8
z+QgvW3F52LPoB6g-_+L$+7?VG%_N~U#0CiFzEdeR&@}YjV5v)D1DFtL(+65~CC>Rz
zrZ~0cDuagSKj7Mybv@RbkFwR}w5icl!XQy+vZ6Jfj(KHa=sR_-E{O+s_V>OBJLh`S
zttU#Uyc(GXV)55wrTt2a4oib~0sY4u?DCP&`pi8LGI{|AhcI`>$Q2m%F3n`#hzh_Q()2IRBP0!&E^Pq@DelvKbF5m^DC#ku2Z9NEv3
zNWvuUDiH)nWq>~Ia|EXD)`y>z8Sy6`ih7iZubS39;DM3s(>@5WwLKn+x2`AvpzCOQih0QoqjyplhXs@4fZk_g<&?;)rX^ed8qin(&(?e44Fs
zS2%I0fl5}6Q}MDRi!=f57cKp+{AEI(s55NA^W$+
z!ZwnN^N-Q4x=g?Uc*mN^Wm`D9DiFl6)HQ%cp>8Hc@QYmSqkBFImWDdfEOZk5B>8~<
z*0KI;61dejf%lK>QMQF)<4Tj8_|36lZx8_;@QNchrG0W9z!5wTr8xNb*>sE)JM0d5
zE8Q2!Sy_L@3`Rtp$LH+A!?$V%uod}~OszrqG*)~I$h3DhKOfZHE*}0_B*}?M$mxC)
zm(A+Vl)_@mS0E(b+w<@AUHTDe=jzStVt)qh&$V91w~_+UR-!vD!09v=B8qQ{y-JBw
zTqw}ys!P+bC4Z@+$yeZZxjOyRN(bI&iUfb!$DlI#sT_p;s7l_)kyrJCvH*
zuv*x$-U>L3lX865$39$w@UkR|Pf@F2zu)|6G3jV%&eri|5TG4O6~J4zYVX6ilc-v8
zz~t66H7Sx<+U1{*xWfMWef!S8-A6q)m8ltts+=(B^&L`gy|A3)9IP1q=_w2X9?%NV
zVcJn+yeOad4{{rhtkDR%ocWzhQ4U7LG+M@i1=BD0+4LoY~I-wxJv<8rem
zJ;(EB{*?Ck&6&0kL<`uk0Goz25%Va>{p*>YtDc%jLpYJQr
zqGfl1fp6P=Y)O)TYrNs!oo@w=0
z)~2AO6c{bd7w6^e+uDVQEMLj0_x;voI>9+QYeB!CxHI0q^hu>+S>A_>rGeundcOuLG
za)PSt@7sHi=9c&->R#fNV6cmq5@1vJwD<9*#E7eUWoNCEc<15C=e+a|tR~|BMqFj#xGu?;4e!Nkko7o2x9td`
zJ6n>}It_rQzIHs@=A~a_BaEnLc?nk#dSN;X^(IbO<&`CtcyDby_9GBC9VAmYx@zOIoxT4
z+toC|AyMNsWil98B?-vaK+E#
zM(92?odL;|NQwl(Z?lK5+k`T@!ErQJVm)HRxQ$uBQ>FI_y(+o@!}gAjv%uY&fs@7}
zg6UMU(VNoi?0r^DNCuHKuKdQ`1Dy0eJgZYVrlb%n^5c+_uNS%5V@XQbLQg~bU**hx
z2cJF5AJ^m}H0pVNU(Wj|vBLF$-6@fm*eUM@&BB{@2{U%wA9>ybks=Hy;pQR-9PzI{
z#uy@dVT9y#WpG!vP?qyw(6ex$?a3dsjc5#UUmy|q_ARv*Y`32MW3FuH@%E)ag}XHY
z8l`RV6%@@=-WW)}(W>zf)FMQ#;l4!n#njb167l)Y_!5-5-pAVqOuYeR0_%i6U|QeT
zl7w@*1BW&rE^Xe&OwX^GybyMA>zW|AuwR3T8wF0H^{{&OuM$oT435|*ua|zQ_Ov|u
zaakfBx`4z-P7QSZMBN>?FMYcV1GP;bY~n+2VwU>L?lrEV11_8sas1gp+j|zth;d&j
zZ^_ZE9#+8MBN{LdK;msi{qray`yPJPUnMqJmDtS7`cvf6OrBdx3M0}FpL6S0&7V4p
z1YJDTy-uDD>TxH?_g>d~>o*t@7M5Ni#@`zI-SocJ`p&DDUaaqM7n^JrhIH8&8>bjV
zR#JTPhHmkAxwK}R%iA61af5S0#>t<%3KDf7y4X{!3pY;#(}HcCshF2ABh32$Z`hdq
zC01vVV$o|&Ns3{OfuQj+>yZ)=DWB?;tG~6Yo(MQ$4u_xJpBFSX^fI`(X
zHc|Y)Q_iR3(Opv0;mSY?(^ncTSm3QRDC16dG4JBRJpqa&S&c8%RJi&Nz*ReE3zH6p
zu*!-Yx#XHQnf9x?4>Vm$M{2bU$n$iCHT5=c1-4R_dwa<8av}z8ED(!|J0?hw{t_L=8>|_
z@}6GF&5x4*>Bar&o+LVevy0SQP5JMUKrE#U1h9ie3KC}BEj;4{Y<2hC-KLN9_^*5f
zSPWq%Se`3nl^C;W`+V!feb@;%m*;f2L|OY2eQ;^%@v)Bc*sLvXGA&q`;tx8%S{6rG
z>sgwEZqLE_&%XJMVOXQ6Jw2-V;ZkRcN9mS2R)b
z5N2B3H{64`(FKA*pjbTz+B-ew?t2yF7MjVAc_%+K8n!8VfW!%*-sg-YLz7#H>)gEW
ziHLlgH)_t?1+?OVr^s`%qS*hwDK&YRFD^Tf&x(w&Pj)tz@GO?sqMI};Dyjd?55CXP
zd|H*ALKsmcaJFTjDlEqt_Yi)V>QSm+kAJ%Pfa>hov%I4NVplBaC*JESGv?N6DnQ{t
zsOM+?Fl{78<lh@@K6I|bBejV;LOBW|#zZkkVto;dfjTYJ4z
zqJm@*8l;UJJ*ng*KyMf1n0|}KGlzT4&Lv!q>Argj%QxP@apbl0_}Sr%HKQEH|VEy}CM9IpCe6x(IdD
z{%!;42gYzZj8lb?`!vM!N!yBvPoyyRA_{7QI!9m+31NyA+k2{V4FpfX`}Bi=$AsqnU>D7e5@4W%vxxtZURo9E&mqW)CB*qLmq~vHn!Ej%1d?#vh_6QI7a?)J+>*C
zX!o`669X*1MbWUn9EXwb&H@&F!Y?uj!wHMMJ+QqtV-;A@#MREypSjM268Jn13<`MS^eVmi$I3jTqZkXH0
zbep%1zK_M5b?h4tfuVF{^4j|@3_gYG=3WaetmJUm`OlSCJZ_zMlK1fsev%VT{`*~u
z>qkt@f9l{<*UQF5+@wf&+_}o|dy<#$J%qK&g>f4&^<$e=8Lg;*
zW_6qajTfJ^e+BR5w<{xb+}amyg3v1C+^sOF81W%xFS8K3TnslJhzL%{0&7qnG
zv!HSGIuAQ)Z;Hs1arTvZ$^Zzs>!L;_7gLs2IVU{EU}BxIbCxJf{a4&P7+fUH!7h09
zUL^d&?rdKxtq2VX+1H}jN%?EQSLA)NnJ|X)a6WDR4$VFPX!_jc9Chn5v`zP0ga|4#O7HH0fSIv9=^(<sO=>HqG8q(Rqyx8C?0Blg2yh-RNd3OqcI1u$Nzge1*CLx&5df1^DjC
zzlAr!ao;q3OqdH5#z54zokwff$ld(m#RuJHKOqyYym}$ZvIikmlb;w6MYjbaw5#?b
zGPGtxV&KToPPzSbU@a7ov6O|leS?vK!7v!_Mp`_lzuOE2JR^!iWLgXlUp};SbS(bY
z%dv4e*IYRWgK!MzT12WG=UW)zeU5fZM_gf+aThg~P>Io>w}~&;An|oK^K&wF2>jh}
zP#XRjElt}$FxmHD{u`0gYs|hVHdS#_C3t~>n3#AB>;+wGwGRM^G119lBgylgO_hp*
z$J(a{l9U8S!S8Y0tJK=_GaBWainjAMb2LS9RK1>kf9lO}Ru-=F{`>=ma~6a%c(|iA
ziGnxE_+;O|DeU|^cF
zT2>^?asbd7?VV=eB3055@r>3`<!=jKI6QwVo#s~lS|
z;L$Nx?L3|YT^QO+sjjQg@!t#B8Sa%jEf3?1-=7I+ScC=#hYBuCMxGDcyyc-oqlk?h
zgdJ|G`;}n0z!~+IS0PlfKcrWhMGQoFdVjnQt;esSO=jC7rM%uh{fd35>4L&UAq|!%
zLyO7e=Wy6}9!!uODK=Ne!r4ECV%oN9*qGQjR4GWw+<)Lt=3;)-JF`%EEY||-4$!8~
zP_1xoZAxv>=wb=^&gSLP>67L)Q`N}R8Md^vpldXIB)gi~hVl&_RaLZyyw#q#O?EqY
zO~^GXvViU$wyIqJoP0O4{DRoUa|O$AGsWT^nDGUWNQYIo
z(&hkrZutu{IOHP$riXCBMB@Wq-#uCWh=d+~wruWyyM&=LG
zY}$apHx7|JKyL4f@DJH%S}8j=kBEC%ZygQf=`o%DJe7IX;j=@MpTXK-S;#rMz%OP1
z*~Qs?IXI*tB$%9NA&f5WN
zFg!c>
z3Dto+VkK0SrX4X^wlUAtYdp&H{J3Ah?L6lHMwi>ZR4wBorDVq+(8gQ^3PJM^t9s?H
zo5w-V+dKY4ZAKiV%igC@%C3M!o%2W}!9X8-`3umH9*v#TcKz0J>PLtDDEGoC>ULer
zzNu4sCpPDL5x=DR7~a|UnhO}SkJGA<@fQZsZ3bQxzFENcdd(*tM;89jN4hFv!$)IlIIQynG;pU`@8sp!!
z7c6-s`Rt+%mR5s
zPdx}#@9s-Qp3)-5Mx#p)wT2k?ByB*Q{QI73RdafIe6g;tbdr``1NmxkGv^cjFHQon
z{ZeG(#*Ounm*W5zw%p2z6DJz(hXGUrU|DFjpsJcPeXm)t>?UklZDOk$DqVC4Ur*f+
ze?NY$wQa&KYbo{9P__z~`hN<=
zoeacd+an(23)P_4-}XNZZl(~cLEF?Dq005)Kw6e9TNZ~`eHd`X2!%m_Md=V;k#`mn
zEyx}}e!MShtge~eXxGBkZ3|et@LGoHkkB9DpludnZF(I-ERY<9*Qj(w;g#+$C=>!L
zN`>%>qKI2!J7M$ans{1@xC?Up^Ei-p`}jc8R1-^p1(HE{MOhGFQ5uBTbgBDa+@+Kj
zw(i&{#im`rv;mnW(r%u`ZUbx50hb!NY71X~y%#iX*1moF{QR4PgM)7F+_??gXWqPd
zRo`Sl$Kr7g^!_2dqAUooC?dx!)691$3{uJgYXIf0000000000005eB&i#L2
WvO+itSyX5M0000fields.isKilling = true;
+ PlayerControl_RpcMurderPlayer(*Game::pLocalPlayer, target.get_PlayerControl().value_or(nullptr), true, NULL);
}
\ No newline at end of file
diff --git a/rpc/RpcRepairSystem.cpp b/rpc/RpcRepairSystem.cpp
index 260fd0e2..89b7876d 100644
--- a/rpc/RpcRepairSystem.cpp
+++ b/rpc/RpcRepairSystem.cpp
@@ -16,5 +16,5 @@ RpcRepairSystem::RpcRepairSystem(SystemTypes__Enum selectedSystem, uint32_t amou
void RpcRepairSystem::Process()
{
- ShipStatus_RpcRepairSystem(*Game::pShipStatus, this->selectedSystem, this->amount, NULL);
+ ShipStatus_RpcUpdateSystem(*Game::pShipStatus, this->selectedSystem, this->amount, NULL);
}
\ No newline at end of file
diff --git a/used_types.txt b/used_types.txt
index 8414744d..fa6bd65b 100644
--- a/used_types.txt
+++ b/used_types.txt
@@ -60,7 +60,7 @@ EOSManager
FullAccount
SpawnFlags__Enum
InnerNetObject
-PlainDoor__Array
+OpenableDoor__Array
PlayerVoteArea
PlayerVoteArea__Array
SystemTypes__Enum
@@ -68,7 +68,6 @@ PlainShipRoom
PlainShipRoom__Array
ShipStatus_MapType__Enum
ShipStatus
-StringNames__Enum
SwitchSystem
ISystemType
Dictionary_2_TKey_TValue_Entry_SystemTypes_ISystemType_
@@ -221,3 +220,8 @@ UpdateState__Enum
AbstractChatInputField__Fields
FreeChatInputField__Fields
FreeChatInputField
+MurderResultFlags__Enum
+FungleShipStatus
+OpenableDoor
+MushroomWallDoor
+MushroomDoorSabotageMinigame
diff --git a/user/state.hpp b/user/state.hpp
index 395ffd0c..355b7f1d 100644
--- a/user/state.hpp
+++ b/user/state.hpp
@@ -181,7 +181,8 @@ class Settings {
Ship = 0,
Hq = 1,
Pb = 2,
- Airship = 3
+ Airship = 3,
+ Fungle = 4,
} mapType = MapType::Ship;
bool AutoOpenDoors = false;
diff --git a/user/utility.cpp b/user/utility.cpp
index f92f732c..5290f0c8 100644
--- a/user/utility.cpp
+++ b/user/utility.cpp
@@ -7,6 +7,8 @@
#include "profiler.h"
#include
+using namespace std::string_view_literals;
+
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
int randi(int lo, int hi) {
@@ -122,8 +124,7 @@ Vector2 GetTrueAdjustedPosition(PlayerControl* playerControl)
#pragma region PlayerSelection
PlayerSelection::PlayerSelection() noexcept
{
- this->clientId = Game::NoClientId;
- this->playerId = Game::NoPlayerId;
+ this->reset();
}
PlayerSelection::PlayerSelection(const PlayerControl* playerControl) {
@@ -132,7 +133,7 @@ PlayerSelection::PlayerSelection(const PlayerControl* playerControl) {
this->playerId = playerControl->fields.PlayerId;
}
else {
- new (this)PlayerSelection();
+ this->reset();
}
}
@@ -140,6 +141,10 @@ PlayerSelection::PlayerSelection(GameData_PlayerInfo* playerData) {
new (this)PlayerSelection(app::GameData_PlayerInfo_get_Object(playerData, nullptr));
}
+PlayerSelection::PlayerSelection(const PlayerSelection::Result& result) {
+ new (this)PlayerSelection(result.has_value() ? result.get_PlayerControl() : nullptr);
+}
+
PlayerSelection::Result PlayerSelection::validate() {
auto playerControl = this->get_PlayerControl();
if (playerControl) {
@@ -148,17 +153,27 @@ PlayerSelection::Result PlayerSelection::validate() {
return { (*playerControl), playerData };
}
}
- this->clientId = Game::NoClientId;
- this->playerId = Game::NoPlayerId;
+ this->reset();
return {};
}
bool PlayerSelection::equals(const PlayerSelection& selectedPlayer) const
{
+ if (this == &selectedPlayer) return true;
if (!this->has_value() || !selectedPlayer.has_value()) return false;
return std::tie(clientId, playerId) == std::tie(selectedPlayer.clientId, selectedPlayer.playerId);
}
+bool PlayerSelection::equals(const PlayerSelection::Result& selectedPlayer) const {
+ if (!this->has_value() || !selectedPlayer.has_value()) return false;
+ if (clientId == Game::HostInherit) {
+ return playerId == selectedPlayer.get_PlayerControl()->fields.PlayerId;
+ }
+ return std::tie(clientId, playerId) ==
+ std::tie(selectedPlayer.get_PlayerControl()->fields._.OwnerId,
+ selectedPlayer.get_PlayerControl()->fields.PlayerId);
+}
+
std::optional PlayerSelection::get_PlayerControl() const {
if (!this->has_value())
return std::nullopt;
@@ -202,27 +217,6 @@ std::optional PlayerSelection::get_PlayerData() const
}
return std::nullopt;
}
-
-Game::PlayerId PlayerSelection::get_PlayerId() const noexcept {
-#if 0//_DEBUG
- LOG_ASSERT(this->has_value());
-#endif
- return this->playerId;
-}
-
-Game::ClientId PlayerSelection::get_ClientId() const noexcept {
-#if 0//_DEBUG
- LOG_ASSERT(this->has_value());
-#endif
- return this->clientId;
-}
-
-bool PlayerSelection::is_LocalPlayer() const noexcept {
-#if 0//_DEBUG
- LOG_ASSERT(this->has_value());
-#endif
- return this->clientId == (*Game::pAmongUsClient)->fields._.ClientId;
-}
#pragma endregion
ImVec4 AmongUsColorToImVec4(const Color& color) {
@@ -288,8 +282,8 @@ PlayerControl* GetPlayerControlById(Game::PlayerId id) {
return NULL;
}
-PlainDoor* GetPlainDoorByRoom(SystemTypes__Enum room) {
- for (auto door : il2cpp::Array((*Game::pShipStatus)->fields.AllDoors))
+OpenableDoor* GetOpenableDoorByRoom(SystemTypes__Enum room) {
+ for (auto door : GetAllOpenableDoors())
{
if (door->fields.Room == room)
{
@@ -300,7 +294,7 @@ PlainDoor* GetPlainDoorByRoom(SystemTypes__Enum room) {
return nullptr;
}
-il2cpp::Array GetAllPlainDoors() {
+il2cpp::Array GetAllOpenableDoors() {
return (*Game::pShipStatus)->fields.AllDoors;
}
@@ -337,14 +331,16 @@ std::vector GetNormalPlayerTasks(PlayerControl* player) {
return normalPlayerTasks;
}
-SabotageTask* GetSabotageTask(PlayerControl* player) {
+Object_1* GetSabotageTask(PlayerControl* player) {
static std::string sabotageTaskType = translate_type_name("SabotageTask");
auto playerTasks = GetPlayerTasks(player);
for (auto playerTask : playerTasks)
- if (sabotageTaskType == playerTask->klass->_0.name || sabotageTaskType == playerTask->klass->_0.parent->name)
- return (SabotageTask*)playerTask;
+ if (sabotageTaskType == playerTask->klass->_0.name
+ || sabotageTaskType == playerTask->klass->_0.parent->name
+ || "MushroomMixupSabotageTask"sv == playerTask->klass->_0.name)
+ return (Object_1*)playerTask;
return NULL;
}
@@ -375,22 +371,18 @@ void RepairSabotage(PlayerControl* player) {
}
}
}
-
- if (hqHudOverrideTaskType == sabotageTask->klass->_0.name) {
+ else if (hqHudOverrideTaskType == sabotageTask->klass->_0.name) {
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Comms, 16));
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Comms, 17));
}
-
- if (hudOverrideTaskType == sabotageTask->klass->_0.name) {
+ else if (hudOverrideTaskType == sabotageTask->klass->_0.name) {
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Comms, 0));
}
-
- if (noOxyTaskType == sabotageTask->klass->_0.name) {
+ else if (noOxyTaskType == sabotageTask->klass->_0.name) {
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::LifeSupp, 64));
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::LifeSupp, 65));
}
-
- if (reactorTaskType == sabotageTask->klass->_0.name) {
+ else if (reactorTaskType == sabotageTask->klass->_0.name) {
if (State.mapType == Settings::MapType::Ship || State.mapType == Settings::MapType::Hq) {
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Reactor, 64));
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Reactor, 65));
@@ -405,6 +397,12 @@ void RepairSabotage(PlayerControl* player) {
State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Reactor, 17));
}
}
+ else if ("MushroomMixupSabotageTask"sv == sabotageTask->klass->_0.name) {
+ //State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::MushroomMixupSabotage, 0));
+ }
+ else {
+ STREAM_ERROR("Unknown Task:" << sabotageTask->klass->_0.name);
+ }
}
void CompleteTask(NormalPlayerTask* playerTask) {
@@ -421,7 +419,12 @@ const char* TranslateTaskTypes(TaskTypes__Enum taskType) {
"Buy Beverage", "Process Data", "Run Diagnostics", "Water Plants", "Monitor Oxygen", "Store Artifacts", "Fill Canisters", "Activate Weather Nodes", "Insert Keys",
"Reset Seismic Stabilizers", "Scan Boarding Pass", "Open Waterways", "Replace Water Jug", "Repair Drill", "Align Telecopse", "Record Temperature", "Reboot Wifi",
"Polish Ruby", "Reset Breakers", "Decontaminate", "Make Burger", "Unlock Safe", "Sort Records", "Put Away Pistols", "Fix Shower", "Clean Toilet", "Dress Mannequin",
- "Pick Up Towels", "Rewind Tapes", "Start Fans", "Develop Photos", "Get Biggol Sword", "Put Away Rifles", "Stop Charles", "Vent Cleaning"};
+ "Pick Up Towels", "Rewind Tapes", "Start Fans", "Develop Photos", "Get Biggol Sword", "Put Away Rifles", "Stop Charles", "Vent Cleaning", "None",
+ // 2023.10.24 added
+ "Build Sandcastle", "Catch Fish","Collect Shells", "Lift Weights", "Roast Marshmallow", "Throw Frisbee", "Collect Samples", "Collect Vegetables",
+ "Hoist Supplies", "Mine Ores", "Polish Gem", "Replace Parts", "Help Critter", "Crank Generator", "Fix Antenna", "Find Signal", "Mushroom Mixup Sabotage",
+ "Extract Fuel", "Monitor Mushroom", "Play Video Game",
+ };
return TASK_TRANSLATIONS.at(static_cast(taskType));
}
@@ -430,7 +433,10 @@ const char* TranslateSystemTypes(SystemTypes__Enum systemType) {
"MedBay", "Security", "Weapons", "Lower Engine", "Communications", "Ship Tasks", "Doors", "Sabotage", "Decontamination", "Launchpad", "Locker Room", "Laboratory",
"Balcony", "Office", "Greenhouse", "Dropship", "Decontamination", "Outside", "Specimen Room", "Boiler Room", "Vault Room", "Cockpit", "Armory", "Kitchen", "Viewing Deck",
"Hall Of Portraits", "Cargo Bay", "Ventilation", "Showers", "Engine Room", "The Brig", "Meeting Room", "Records Room", "Lounge Room", "Gap Room", "Main Hall", "Medical",
- "Decontamination" };
+ "Decontamination",
+ // 2023.10.24 added
+ "Zipline", "Mining Pit", "Fishing Dock", "Rec Room", "Lookout", "Beach", "Highlands", "Jungle", "Sleeping Quarters", "Mushroom Mixup Sabotage", "Heli Sabotage",
+ };
return SYSTEM_TRANSLATIONS.at(static_cast(systemType));
}
@@ -594,10 +600,10 @@ std::string GetGitBranch()
return "unavailable";
}
-void ImpersonateName(PlayerSelection& _player)
+void ImpersonateName(__maybenull GameData_PlayerInfo* data)
{
- auto player = _player.validate(); if (!player.has_value()) return;
- app::GameData_PlayerOutfit* outfit = GetPlayerOutfit(player.get_PlayerData());
+ if (!data) return;
+ app::GameData_PlayerOutfit* outfit = GetPlayerOutfit(data);
if (!(IsInGame() || IsInLobby() || outfit)) return;
const auto& playerName = convert_from_string(GameData_PlayerOutfit_get_PlayerName(outfit, nullptr));
if (playerName.length() < 10) {
@@ -704,6 +710,7 @@ Color GetRoleColor(RoleBehaviour* roleBehaviour) {
switch (roleBehaviour->fields.Role) {
default:
case RoleTypes__Enum::Crewmate:
+ case RoleTypes__Enum::CrewmateGhost:
c = Palette__TypeInfo->static_fields->White;
break;
case RoleTypes__Enum::Engineer:
@@ -713,6 +720,7 @@ Color GetRoleColor(RoleBehaviour* roleBehaviour) {
break;
case RoleTypes__Enum::Impostor:
case RoleTypes__Enum::Shapeshifter:
+ case RoleTypes__Enum::ImpostorGhost:
c = Palette__TypeInfo->static_fields->ImpostorRed;
break;
}
@@ -730,12 +738,14 @@ std::string GetRoleName(RoleBehaviour* roleBehaviour, bool abbreviated /* = fals
case RoleTypes__Enum::GuardianAngel:
return (abbreviated ? "GA" : "GuardianAngel");
case RoleTypes__Enum::Impostor:
+ case RoleTypes__Enum::ImpostorGhost:
return (abbreviated ? "Imp" : "Impostor");
case RoleTypes__Enum::Scientist:
return (abbreviated ? "Sci" : "Scientist");
case RoleTypes__Enum::Shapeshifter:
return (abbreviated ? "SH" : "Shapeshifter");
case RoleTypes__Enum::Crewmate:
+ case RoleTypes__Enum::CrewmateGhost:
return (abbreviated ? "Crew" : "Crewmate");
default:
return (abbreviated ? "Unk" : "Unknown");
@@ -838,7 +848,10 @@ std::string GetPlayerName() {
LOG_ASSERT(field != nullptr);
auto customization = il2cpp_field_get_value_object(field, player);
LOG_ASSERT(customization != nullptr);
- return convert_from_string(app::PlayerCustomizationData_get_Name(customization, nullptr));
+ static FieldInfo* field2 = il2cpp_class_get_field_from_name(customization->Il2CppClass.klass, "name");
+ auto name = il2cpp_field_get_value_object(field2, customization);
+ LOG_ASSERT(name != nullptr);
+ return convert_from_string(reinterpret_cast(name));
}
void SetPlayerName(std::string_view name) {
diff --git a/user/utility.h b/user/utility.h
index 1db25061..33a8929f 100644
--- a/user/utility.h
+++ b/user/utility.h
@@ -84,13 +84,14 @@ class PlayerSelection {
#endif
return _playerData->fields.Disconnected;
}
- constexpr bool equals(_Maybenull_ const PlayerControl* playerControl) const {
- return _playerControl == playerControl;
+ constexpr bool equals(const Result& _Right) const noexcept {
+ if (!this->has_value() || !_Right.has_value()) return false;
+ return _playerControl == _Right._playerControl;
}
- constexpr bool equals(_Maybenull_ const GameData_PlayerInfo* playerData) const {
- return _playerData == playerData;
+ constexpr bool has_value() const noexcept {
+ return _has_value;
}
- constexpr bool has_value() const {
+ constexpr operator bool() const noexcept {
return _has_value;
}
private:
@@ -116,13 +117,24 @@ class PlayerSelection {
PlayerSelection() noexcept;
explicit PlayerSelection(const PlayerControl* playerControl);
explicit PlayerSelection(GameData_PlayerInfo* playerData);
+ PlayerSelection(const PlayerSelection::Result& result);
PlayerSelection::Result validate();
bool equals(const PlayerSelection& selectedPlayer) const;
- Game::PlayerId get_PlayerId() const noexcept;
- Game::ClientId get_ClientId() const noexcept;
- bool is_LocalPlayer() const noexcept;
+ bool equals(const PlayerSelection::Result& selectedPlayer) const;
+ Game::PlayerId get_PlayerId() const noexcept {
+ return this->playerId;
+ }
+ Game::ClientId get_ClientId() const noexcept {
+ return this->clientId;
+ }
+
+ constexpr void reset() noexcept {
+ this->clientId = Game::NoClientId;
+ this->playerId = Game::NoPlayerId;
+ }
+
bool has_value() const noexcept {
return (this->clientId != Game::NoClientId || this->playerId != Game::NoPlayerId);
}
@@ -147,14 +159,15 @@ GameData_PlayerInfo* GetPlayerData(PlayerControl* player);
Vector2 GetTrueAdjustedPosition(PlayerControl* player);
GameData_PlayerInfo* GetPlayerDataById(Game::PlayerId id);
PlayerControl* GetPlayerControlById(Game::PlayerId id);
-PlainDoor* GetPlainDoorByRoom(SystemTypes__Enum room);
-il2cpp::Array GetAllPlainDoors();
+// MushroomWallDoor or PlainDoor
+OpenableDoor* GetOpenableDoorByRoom(SystemTypes__Enum room);
+il2cpp::Array GetAllOpenableDoors();
il2cpp::List GetAllPlayerControl();
il2cpp::List GetAllPlayerData();
il2cpp::Array GetAllDeadBodies();
il2cpp::List GetPlayerTasks(PlayerControl* player);
std::vector GetNormalPlayerTasks(PlayerControl* player);
-SabotageTask* GetSabotageTask(PlayerControl* player);
+Object_1* GetSabotageTask(PlayerControl* player);
void RepairSabotage(PlayerControl* player);
void CompleteTask(NormalPlayerTask* playerTask);
const char* TranslateTaskTypes(TaskTypes__Enum taskType);
@@ -180,7 +193,7 @@ std::string ToString(__maybenull PlayerControl* player);
std::string ToString(__maybenull GameData_PlayerInfo* data);
std::string GetGitCommit();
std::string GetGitBranch();
-void ImpersonateName(PlayerSelection& player);
+void ImpersonateName(__maybenull GameData_PlayerInfo* data);
Game::ColorId GetRandomColorId();
void SaveOriginalAppearance();
void ResetOriginalAppearance();
|