From 2be6c073399b738b311e60bbeca79fe75a55988c Mon Sep 17 00:00:00 2001 From: m4xxx1m Date: Thu, 4 May 2023 23:57:23 +0400 Subject: [PATCH] rewrote using GameState and PlayerState, but end turn still doesn't work --- Content/BP_MyGameMode.uasset | Bin 18906 -> 19122 bytes Content/BP_MyGameState.uasset | Bin 0 -> 18290 bytes Content/BP_MyPlayerState.uasset | Bin 0 -> 18342 bytes Content/BattleField/BP_BattleUI.uasset | Bin 134342 -> 149622 bytes Content/BattleField/BattleFieldMap.umap | Bin 639646 -> 639646 bytes .../ManageSquadPlayerController.cpp | 8 +- Source/TurnBasedTutorial/MyGameMode.cpp | 100 +++---- Source/TurnBasedTutorial/MyGameMode.h | 32 +-- Source/TurnBasedTutorial/MyGameState.cpp | 137 ++++------ Source/TurnBasedTutorial/MyGameState.h | 51 ++-- .../TurnBasedTutorial/MyPlayerController.cpp | 248 ++++++++++-------- Source/TurnBasedTutorial/MyPlayerController.h | 52 ++-- Source/TurnBasedTutorial/MyPlayerStart.cpp | 5 +- Source/TurnBasedTutorial/MyPlayerStart.h | 9 +- Source/TurnBasedTutorial/MyPlayerState.cpp | 149 +++++++++++ Source/TurnBasedTutorial/MyPlayerState.h | 63 +++++ Source/TurnBasedTutorial/Trooper.h | 4 - 17 files changed, 543 insertions(+), 315 deletions(-) create mode 100644 Content/BP_MyGameState.uasset create mode 100644 Content/BP_MyPlayerState.uasset create mode 100644 Source/TurnBasedTutorial/MyPlayerState.cpp create mode 100644 Source/TurnBasedTutorial/MyPlayerState.h diff --git a/Content/BP_MyGameMode.uasset b/Content/BP_MyGameMode.uasset index d432830cc35fdb2c9d7da503cd34e5417e10e93c..f1ac113486aa28dca38467e9d7ac25b14d2d5cf4 100644 GIT binary patch delta 4795 zcmcgwYfzMB6n?*T5haKf7M5M^5_kb4FCYkV*_EqtDK!mEL|hXuy9yYg&a4(=O*5s= zYyRkBS^lV@Oxr&; zu=b`3F#wN*C-2jgFEXAx(e~QD58GdMoQgfL)OG2JqwCvFpWV~`!oizwB0d2glxh~~ z!X(n3vB`ENO*Sa=Gp~b$Q_a9Ki~tNY$|}z&sd88;&IGlhxS?x@yV%*@*)oW$75!cP zZgKK-r$t^?Y8_+D_U&DR?p}@k*6ZKA<4-l!nd~z_!uY+NF5x`q>5yy9i_(*sYuF6@ zk((`_`wy8*rX;aK*Y>WyKH=Qx`OJSlc9$u|fY(?Z2Xn9ci{idieADPeR+_KDsWNHZ zL31!>6fjwnV15Kl_9U1e0s&tjCkPZv@A))e1wr6tb+AFAf^XXC9_AnqM88MzoFjqj%%1JQa z0cNWZ+WGlp(`gfLMnQ!U1g$4JPNpa@Q^I0Ezfq7mENDC?CJM~dC@^Xg767p4Bi9C|%%)bHH>x4%Twpkpg_nf*CVn}YV z6v~UGW_do*Dl06O)Vai&5A!gsYs%$`jv+NDIo1D>Jv=oovzz7N;Ce zig#d~u;5V=N+=?Wn<_#em>USmrP%JSLP)`%h67yqso z(U77=h049j@eZ^F%aS2`39_(R?y_#RV?Khwz%6+GhUXu6aLZ5fnpK+irpf~;3#L8= zmt1v;|GkuaQ^K)d1A!?Z4S!DhM{Nmac`-A~za`^ToVwUID?h=9iQpZ*6-(|CU8Hm! z&0I|av&Tln<-trg9qA!E@#v4yj=O2*n(#4NJvAzGMnH}OVzloG0%p+rDw+l669y0m z*HxwVDq3kSWrLn22kat-+K(8;#5Dvel_wI@?28G?+&p^sA{Xjtnk*+Tj}e>EE&tcb(Fifj`r@kOPipDbWM>y}_QsgK0Oz$X#YPV?A=A5%iW zCl9*_KJe7hsJiHr#g_GaMkISQX7~&;0=bi6IN08MX|p17)LcT|Oj%Zz@6&feJ*W+n zkRl^)Nc;h`W%^d;j3o?GFp=tr#p-nT!2ZC-NKC9%S9c^XR`I+@Oe}BiCp+bpvI6}a z+ahiG3${E=OwMZ-!FH>8jjaT4szd^ZMy`Q4hQQ$_A+*T7QEt)ALF#Rp#1){MgrP#> z9hH7etov&SE>Y1a5@^|oG8!@?yu(4tjF<6g--h+Loh%(|- z(99yrwRdps65?<axo^fT;d1qxZz`AIjFhS*JCwgMQS#cXF#s!E9u(a?B!VbMdcDm*z zrNIgZej)Vt?skhNdE7PRC{l?AGIlfUJ4Lc`Sz2KT8{sGdKBv^7iz|?>xOomYMYjl>&LP-kHQZP|(Vr?rl0`W`heLn;XiN zh4R&g6ot2b)v!SQqhOMw?Tf)vbV^%ekuR653T+xjpBdM)Xa~1qy%pkBIXe;){}9O| zW-rb8@GqJV8Vl`@(>v$XxP~ONnk>F%LWFc!zQK(KZYD5aXWUEKU^Rw#$KgjNj!A*@ T?$dyw?H|P$b-(}Q+~fZOz5Y&W delta 4490 zcmchaTWpj?6oBX7E?8O$yX|%_6f6b0wuOR)(tDxZrI)qZ7NHbHTY(mOquff2#biYk zZ!wmPz7RFSi!lbnx(^Z~Bqa64CwRd`o=gk~sH6q~qgcjBk8eXA!Z37n)eQNL**1h$4`~D_0Jc=58c$cLc~2nXwWXr6k;C=!-|jG_U+rTP5#mwefaGjYFPs7RSe(Ym?$l$pen~#gr>r zbT-XQr}`I|oki_7s;$h=z$~;dxNZ5Ffb2}N z#i6?p5gJlefI6vAucZ~nisc1YD0m0ZF%!OkP)x+HsC~6m9(NbWn=ZfXce}hn8pad0 zpW3I&014&(X3~V0M>&bn!5FnOXzGWe%SCq^F6Eb2yb1ubTO1)84} z#a%}^bwUq_eoQISZbb7@U}@48e2|i zKGYnla3dO(hco9cK;2#Nu`#%sRp~{fc>$gYJWnjXs!PQor6KsM#aNFCJxu7fh&-9u z=SDC80vrqabxSVuN@qAz2>DskLiw%NGrI*kCyV1_-dsmo1XL%1S^PH^Um8erX6qgN zKa&JoM61{-`oY64aY)WD@RbgM#81)?j*5Napr{m^6the8iRYmehOYjSC@yWX~9EC}Gd4}qCs%ig(z{H0Ts8VkgV$3kS zSZp(KoAxP@5WIt!Wmuw2D+kcnIyG)5{{dnaF1CRD(6!RIx}I{W!#6@1_4z3-VTazP z0QB>0ToO|}xRs#Q@{-FRSVJgFmr}nMrE;(|S&o)u1-4r#Uim>;R>-m zG;Ok&LB4M>^6Yp4Dc8hel{P4QSY9s6Z8m0_FB+s5ro1A4hYYU44iuci#h3&Gct<`< zf_C{)xhIHM6BagZL=EqX6kR6znw=FLBw#yulVP!jP80AOTa{9(S;bnt507LCN#;>)*8zVWsA89F zBuSsFsp<(lNj+YvaUkS{sywYt-l(e7w#p;bo)oQ+&^8EyXBMut1D>^&@~!GE+8!OL zG$DSNt&3L%{)>2avMs8oj^`#Kco&WRx(I?|^GDspGbjiI{0dK%|M;9#kg z@BDWu&p-S)<)=(lFx^Y8<10IK;83^NAO{;? z+>FNt@69}`7*GDB0{lHbsQ@+LRXd$M^;;5M@E{GvaA%2ZuX_jnT)tM9tu@QJ4f)z$ zSyX>aTO!ZahtgN+w8A&{?(7$glr)3^8Ez=|F@o23sC#$sVC%s47Yy!p!|GY+_0#fJ zQ0VY?*@NMLsGIU3`qhwnr7N$nX5Q)dbmt{{?C7;8o~X4@Bz7JT?OW49f* diff --git a/Content/BP_MyGameState.uasset b/Content/BP_MyGameState.uasset new file mode 100644 index 0000000000000000000000000000000000000000..459f88510304039187f0ca8d5176b97fa84339a2 GIT binary patch literal 18290 zcmeHP3w%`7nLmR85y67;5>X~R<&k$t0AFM>GYOACAPE&H4U?HW$;f18n7NY}MAipd zAGEHmb-P-%qOPu3#rmlIY3tI}{`zp$)mE+eYS&^x?H0At3Yh)==brE0JCm8oU}Asn zZ};RkbMF1lch2|z&N+9^&7RBW-1@iP-rkMJ2{B@bkYyNszn=WV>{;GB-s*Z`^eqQo zn>TF?!Oq_E)#}6bZx8$PcJauz&2wfJ5Nzsin!o##l{4@09$$FF^OrsBn@g~_%U{_& zYUR~aez@(q`*topS~Y@T=jlhDyTrY__RX=^e=FfUeZmZaz2C9>?ftGBK05K$vYj=L zdyCH`*aH@b^OI+ck7K?`>dR^QX>k#|*ZgrE& z%;wr?Tx(g`c7f*C#b1{co%JW#r|g| zz74lxnk|vI<_miQVqU>N4Tlfb_z6=KJvVJFnbf#j?rYP+;_eCY))N2uct8{jcIYcM=aU>UmC%@qHTCgc2db5v!)3efDW+U9PqJ{5>l)5+~Z2jJIn|o3!w1EtnA3 zeg7+G!Qo8}im?kTMoqLs>a>U!Cwm5J!@fj9%)U8R1m?{ib;(dbJa_!0mQ(G}B@tbV zM||Oygtjsg?h#kM^}SUvnc1zWC!uSdYqWR*QeLW`FgIn?=AM`)MvnRBn{aAZG#WPb zG`e8-H766WZDp4hkB0)9HyQCuRgM1mAJ;>JX}Qxx6mLzYF#(Tt}Z8tm(UKp@~{9Jsa>im(TZNR2zTn|Os#n>@t zJPV&NRHk=dc>QqP85R`3JoSm&z^6&gKr8$7;}!^Jf}6F@SQwG?>wBmE6a%=mpf4HL z#ihN`bK$M(zO}WFXs^6>(&g|P6T=>uKfCFXI9ypZ%AkQ~iidx{ugliZFWLLEAM({)fN zdAjav()`g#AR&I*e9>`~0fjr1AkllIlDB+&p9|7^0!DZjL?7M&F4cXLzeDTvwJs|c zkL~%+C}ccOAVlu!j{1`bm?e>5R6O1~`moUlO-3$g^ywYq*_zuf0T-T#k3uG3WUf6k zR=f^Nc))o|%ax1wemFT(%c4cZvK&G@xa-qj8$%{LO|M<`@-2%Yn5Tr0jK@_1{T#NWMare&O?ZP~xU8woR)&oZ-!MTFrs81JTdv19Kk>kak zN$&97Zyd!q92;`yC^A1*C7WY{tHq(K{{luN;1UGm?cIOosi= z%YM}*dm#tZHh$89UiB1{DoR3>?Zz+rrTTc3djO@B09z9%`Xm}gFs&HOX#V_Pl%Cc40#?(ZqPd0w74X? zW6DF1f`9>P^pTErv2FjwXCssiprx2?kN)U9_-%ux``kX=C*Ho~;cvmq8lr(@SfhE> zr-!;U=}fVy*ZLrhJ=l78{5}L?plphG*$2ay0ucgoR@gYb^+ON>Oe*(3?Cb;G`Z)>X>3= zB#!L-W&;AO(dXafYu7}g?y7O8TldSOek4Z{Ga7*uiI|UE@?^c|D(FjfGSzd-ygN0B zW~kN3Y!hF(AeFoA7nfXlG4lG)bmx9sl)TKuno{%xo&^Ck9$!I037a*61D{Mv44zNxmU6)cFd7hiZAzMTZJ7>otWa zQIjDf2|b>abCIzy5o71BcFKOypl(Y#|8V=>+aY$79yeX$tUdAR5>*aif=k7BkHCGJ zwF|8Xd1{gVLzrIg&}iy>@P$i|08%CT!SafSVAE!rI-5f=@yLPWe}ds#Csc{Xhr=sz4w`eI1pMcdhsY}?WDFVrL ztR1$NV3}5nX$!*E+C|xv+FDx7cA-mU4P&OjBG_KQ6bhy;lt0swwaB;>t5lr{r#259 zcRx7)O|+KefwQ_FoIlYxP#{V+o`HivK*@!J7(~g1GtWTDiSyMwaC~{-`1`?mpX6HB z56*jp)0&2ZB#FX(G0t=Y)JLus1xH1@N?FqNW5;2C$%TX1M9GE2Jm$hdNbMjH*8GA7`ECD?~HIC2~ca^e&6iZ-s*>LQOS8y&TS zH%FMJuF9ycQrBx1n9X@zWRmBQO&0JnUyX#gdQe^O_#EhjZFIh`uFqMhF7m80$@8gA z9{6J|eIOU)nWy~Vz~@8EnwPJCORM6=wR$ws?ThyXR7PH9(9ptm5I&=Hag%F zc@Q=1gY^Z9!)w&}erKZd7aJWcMtm5TKA^LYJ}9FGfzC%ZI?$V+K1}B#5TWwnAkcx2 zK@PYuu8}`M4=w;WXyO_$d=3&{sE5%9IhlDv4H#-WoNmp6HY{gRvrWv#EEk}a`cwu> zx71C(c#d{FxgOMv>C=TCdF-W5x2YKdR5Fa)mvG+)GZNC+ytdIp>*IJQJs!it+I+TS z?Ggwo@PKLw7RcC*YXP|r4AK@Nfku%sxZFi$;0d6#&FFaqG6|-(&B|+mIZK+uzD+5j zA?1c;7C+?c^BAz$wzZoju$5k+wtv_}8oQli9tKuik?dTp#lj&!JsJt9)jxL6FjA>} z#%c=d))MluC!U+3U|Vc8+8&&s5w0!S@`iow2|0t8l`p8QuBxb#ZA%i^)XGP6h=k^N zQj=lr4Y}lQ_eRPw$C2~m?@sE0x=el>Fnph2-cM9lb>aeg60M1)^j#}DMVAPQ%_1S8 zNwGq-5xh-w5HvwOMyg(`=q^ThfF=nyDD-|?hp4^-hs>=*`*8HxtUXGN;~@@o;vZhIS=u{B962Zf8@kBW&bqR!V0fh? zgQq#fXf@hO@+?c%7P^a(R^Vlu31hgznoT+a7eO(HAjd1HMd`Ci%;R8eO-gNzZHF-z z99ctbk;QGxMTO)M<7BefM$^g;O1#EMmOTr_R#8XM7$v&qs2t1>`$9cg=mPQ-2Q30PFBqO38p|O#%2*o?+DjSU zc5G``UX83$oLFl)3&JDk)*!bw65mOZ4Bv$$bCCGP9NI?rnDb9nd=8Xz&ZeNyPNR1b zog_UHfu68lchJ_%&`5TSNeaWjqb;t3uTC2zE_vQDwCPq_=pbt+$dXnL$<{tu@xj{7 zoQZgz#i}Y*+q|Y8sJ6NPQu0<8@s1Tb_|FDEW03U+x=qs3*xg|5ACNX?{bp;Ql9&EC z3W78n1!-i5aH@Xn5C5CjvMgN-#dtu3NwUJcw8E<|7pF+=ra-~Oz*mDl&_yAa5ct8Hc<`kcwK@12=v zYt@x)?~M5ob54@tsEho8_fc43@?O?KXZZ}z&kuW+!p?19UIAnq6V|r#aAsbk^8B8< z&q>$0mt=;-$XT=V8kc>xmb}_c{_Y}QuaKT!MXOd9!Q9jWpLbIXR1&0;{N77mkKKw# z?Mo_&7FIv_%dH)r7cC3g*OetSqJ5sT*3NU)=mYguUS+~M5t_e^=Lpam{55y$JjFw9 z33*kWDhX_kd>*9yj;9(}%M}fhOuS>k?9fbh!Y5ri>lsUKtm3?6goJum_s(%l` zoXB`AZJEhWe-X)iW{XIxoh2KLc*&++JY|GOr0T2Ev~i`%3%ZEYY{t>fQdgR}0&8T$ zvnowZPl66RLz}hApn)2Q5l^XiGe36q+&)&uS*nwJMbBjKsqAds{!fVAJRmY1F5a0;wx$6 zvhs}Il6kNU^#%pwb48{xg}CHN)=4_o(^RLdT(hg>IE4E58~d8*Ts2JICK~yj_ddSuo`3QD;M6~kz2@7mc#M_db3s)bP*0JM_}s!+$Z_&MY7QWXZjX`Fd6Nsp=Gj88)T+gv`OcIiIt1 zVy)`Mq&fQ2P2r$rno%lL%|n!_ds@>N1v3;%-yv|+38imKgVA7mAWxjM;ifY=9ifCX zLa!k>sSc>OjGVqmz}X!Nhp9z(wrNg!M}yv9DjwmE``Vq+V9*&0MG{Uu>TFAf!U1Pc zy(C9(a_Bw9bOgsJtloZO{|5JyrE9Oge&zPEarYk_b=gr?7>41QXBb@{c(Y*V$cs*` zzxv({C*D)t`t?jO2*t%bd+fmBNEG|X286z0M7EU)?B~K98hD6*dk#qN3qFIB-#ohS z(3MMXnl$miyG842GQm1*9Zdp`Y6Z>6JKC}~*oL!TnnMHFAMbysSXrkSWLdJu%1VXl zQneY2&lBMPcp#0Ry#JolUaqOz(RuJsE3TXWudGd|3X>5ECWWThfj4?eDi=R6^Vy=? zhrf0t6YMhv5*t#|%H!*poDqC>H{JH(wDW@XcU>{})@%Rc#d|ZszKDSYK9kAyBQ_j- z*8O;4!#83-|MZkhusJrRN#%?sfP9bDsa|9qAz#N7js*(SZe?5N{u2X2r?j|KE_YCK zIVPK&rFsQb?NxO>kCtB7DZsH!reW2Kg+1m;X4dUb{rIJ4F7VuX$3w5(v3AtuJP^j^ z~md$FDBk~womoZy_}w7<9KG>!((bJDAUPI`mduVD#5Z)|o)oPK_}Js}qlfv7V| zSaB!4N|}rm%b^z2VnTD`0fIA0|NOuiia2ZO-yGp2NC3Y?%vJm#08;o+FF-C; z?RW!E9z)g=@^H2{PBgls@l7T2-zF5}h@eptz_h(dIRJ@{K^jRL>9@_`f}ShkrDS?b zc56eFR3R^&2B0~b^moWhbEjb1XR+#zZHLjPA=)JmzLS~4Vfx1m(TH=k771wd?<(4z zEqaL7V|31YYjfNeNd$40Uj8csEUCUg?7&$wIx4bb#s&b_&;*v+rB4RK>kX4-lb~ZSMwy{%8IUs7roYOHNabBzlioxBZRdXgX`%0c literal 0 HcmV?d00001 diff --git a/Content/BP_MyPlayerState.uasset b/Content/BP_MyPlayerState.uasset new file mode 100644 index 0000000000000000000000000000000000000000..6e5c02fadf6bf3cfa23abf7ae007c64b14f63819 GIT binary patch literal 18342 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%0A2toz#T;soX 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 L?Rz$GJ`w}~kWpI5 diff --git a/Source/TurnBasedTutorial/ManageSquadPlayerController.cpp b/Source/TurnBasedTutorial/ManageSquadPlayerController.cpp index 5c324df..72d4c77 100644 --- a/Source/TurnBasedTutorial/ManageSquadPlayerController.cpp +++ b/Source/TurnBasedTutorial/ManageSquadPlayerController.cpp @@ -25,8 +25,8 @@ void AManageSquadPlayerController::OnLeftMouseClick() { UE_LOG(LogTemp, Warning, TEXT("Got hit result")); // auto const NewlySelectedLocation = HitResult.Location; - AManageSquadTrooper *NewlySelectedTrooper = dynamic_cast - ( + AManageSquadTrooper *NewlySelectedTrooper = Cast + ( HitResult.GetActor()); if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper-> @@ -46,11 +46,11 @@ void AManageSquadPlayerController::OnLeftMouseClick() { if (SelectedTrooper) { UE_LOG(LogTemp, Warning, TEXT("Trooper replacement")); SelectedTrooper->ChangeSkeletalMesh(NewlySelectedTrooper); - dynamic_cast( + Cast( GetWorld()->GetGameState())->ChangeSquad( SelectedTrooper->GetIndex(), NewlySelectedTrooper->GetIndex() - ); + ); } break; case ETrooperType::TROOPER_IN_SQUAD: diff --git a/Source/TurnBasedTutorial/MyGameMode.cpp b/Source/TurnBasedTutorial/MyGameMode.cpp index dfb44fd..dd2aed5 100644 --- a/Source/TurnBasedTutorial/MyGameMode.cpp +++ b/Source/TurnBasedTutorial/MyGameMode.cpp @@ -4,12 +4,15 @@ #include "Kismet/GameplayStatics.h" #include "MyPawn.h" #include "MyGameState.h" +#include "MyPlayerController.h" +#include "MyPlayerState.h" AMyGameMode::AMyGameMode() : Super() { UE_LOG(LogTemp, Warning, TEXT("GameMode Constructor")); GameStateClass = AMyGameState::StaticClass(); PlayerControllerClass = AMyPlayerController::StaticClass(); + PlayerStateClass = AMyPlayerState::StaticClass(); DefaultPawnClass = AMyPawn::StaticClass(); } @@ -17,6 +20,10 @@ void AMyGameMode::BeginPlay() { Super::BeginPlay(); } +auto AMyGameMode::GetMyGameState() const { + return GetGameState(); +} + void AMyGameMode::InitializeBattleField() const { UE_LOG(LogTemp, Warning, TEXT("InitializeBattleField")); @@ -46,11 +53,11 @@ void AMyGameMode::InitializeBattleField() const { LoadedBpAssets[i % 2], SpawnLocationAndRotation); // AActor *Spawned = GetWorld()->SpawnActorDeferred( // ATrooper::StaticClass(), SpawnLocationAndRotation); - dynamic_cast(Spawned)->Initialize( + Cast(Spawned)->Initialize( 0, Location, TrooperCount++); Spawned->FinishSpawning(SpawnLocationAndRotation); Spawned->SetActorLocation(Location); - Troopers.Add(dynamic_cast(Spawned)); + GetMyGameState()->AddTrooper(Cast(Spawned)); Location += {0.f, 500.f, 0.0f}; } Location = {-2000.0f, -1000.0f, 0.0f}; @@ -62,11 +69,11 @@ void AMyGameMode::InitializeBattleField() const { LoadedBpAssets[i % 2], SpawnLocationAndRotation); // AActor *Spawned = GetWorld()->SpawnActorDeferred( // ATrooper::StaticClass(), SpawnLocationAndRotation); - dynamic_cast(Spawned)->Initialize( + Cast(Spawned)->Initialize( 1, Location, TrooperCount++); Spawned->FinishSpawning(SpawnLocationAndRotation); Spawned->SetActorLocation(Location); - Troopers.Add(dynamic_cast(Spawned)); + GetMyGameState()->AddTrooper(Cast(Spawned)); Location += {0.f, 500.f, 0.0f}; } } @@ -120,7 +127,7 @@ void AMyGameMode::PostLogin(APlayerController *NewPlayer) { const auto CurrentNumberOfPlayers = GetNumPlayers(); // 0-indexation - dynamic_cast(NewPlayer)->SetPlayerIndex( + Cast(NewPlayer)->SetPlayerIndex( CurrentNumberOfPlayers - 1); UE_LOG(LogTemp, Warning, TEXT("%d"), CurrentNumberOfPlayers); if (CurrentNumberOfPlayers == 2) { @@ -141,48 +148,49 @@ void AMyGameMode::StartGame() { InitializeBattleField(); // PlayerNotInTurn()->SetEnemySelection(Troopers); // PlayerInTurn()->SetEnemySelection(Troopers); - // PlayerControllers[0]->SetEnemySelection(Troopers); - // PlayerControllers[1]->SetEnemySelection(Troopers); - PlayerInTurn()->StartTurn(); -} - - -AMyPlayerController *AMyGameMode::PlayerInTurn() const { - return GetMyPlayerController(CurrentPlayerTurn); -} - -AMyPlayerController *AMyGameMode::PlayerNotInTurn() const { - // uint8 PlayerControllerIndexNotInTurn; - // if (CurrentPlayerTurn == 0) { - // PlayerControllerIndexNotInTurn = 1; - // } else { - // PlayerControllerIndexNotInTurn = 0; - // } - // return GetMyPlayerController(PlayerControllerIndexNotInTurn); - return GetMyPlayerController(!CurrentPlayerTurn); + + // PlayerInTurn()->StartTurn(); + GetMyGameState()->StartGame(); } -void AMyGameMode::CycleTurns() { - if (!this) - return; - // PlayerInTurn()->EndTurn(); - for (const auto Trooper : Troopers) { - if (Trooper != nullptr) { - Trooper->ResetActionPoints(); - } - } - CurrentPlayerTurn = !CurrentPlayerTurn; - // if (CurrentPlayerTurn == 0) { - // CurrentPlayerTurn = 1; - // } else { - // CurrentPlayerTurn = 0; - // } - PlayerInTurn()->StartTurn(); -} +// AMyPlayerController *AMyGameMode::PlayerInTurn() const { +// return GetMyPlayerController(CurrentPlayerTurn); +// } + +// AMyPlayerController *AMyGameMode::PlayerNotInTurn() const { +// // uint8 PlayerControllerIndexNotInTurn; +// // if (CurrentPlayerTurn == 0) { +// // PlayerControllerIndexNotInTurn = 1; +// // } else { +// // PlayerControllerIndexNotInTurn = 0; +// // } +// // return GetMyPlayerController(PlayerControllerIndexNotInTurn); +// return GetMyPlayerController(!CurrentPlayerTurn); +// } + +// void AMyGameMode::CycleTurns() { +// if (!this) +// return; +// // PlayerInTurn()->EndTurn(); +// for (const auto Trooper : Troopers) { +// if (Trooper != nullptr) { +// Trooper->ResetActionPoints(); +// } +// } +// CurrentPlayerTurn = !CurrentPlayerTurn; +// // if (CurrentPlayerTurn == 0) { +// // CurrentPlayerTurn = 1; +// // } else { +// // CurrentPlayerTurn = 0; +// // } +// PlayerInTurn()->StartTurn(); +// } + + +// AMyPlayerController *AMyGameMode::GetMyPlayerController( +// uint8 const PlayerIndex) const { +// return Cast( +// UGameplayStatics::GetPlayerController(GetWorld(), PlayerIndex)); +// } -AMyPlayerController *AMyGameMode::GetMyPlayerController( - uint8 const PlayerIndex) const { - return dynamic_cast( - UGameplayStatics::GetPlayerController(GetWorld(), PlayerIndex)); -} diff --git a/Source/TurnBasedTutorial/MyGameMode.h b/Source/TurnBasedTutorial/MyGameMode.h index e7f19ab..3d7e2d3 100644 --- a/Source/TurnBasedTutorial/MyGameMode.h +++ b/Source/TurnBasedTutorial/MyGameMode.h @@ -4,7 +4,7 @@ #include "CoreMinimal.h" #include "EngineUtils.h" -#include "MyPlayerController.h" +// #include "MyPlayerController.h" #include "MyPlayerStart.h" #include "GameFramework/GameMode.h" #include "MyGameMode.generated.h" @@ -23,9 +23,9 @@ public: virtual void BeginPlay() override; - - UFUNCTION(BlueprintCallable) - void CycleTurns(); + // + // UFUNCTION(BlueprintCallable) + // void CycleTurns(); private: void InitializeSpawnPointsIfNeeded(AController *Player); @@ -34,22 +34,24 @@ private: UPROPERTY() TMap SpawnPoints{}; - - UPROPERTY() - mutable TArray Troopers; + + // UPROPERTY() + // mutable TArray Troopers; UFUNCTION(BlueprintCallable) void StartGame(); - UFUNCTION(BlueprintPure) - AMyPlayerController *PlayerInTurn() const; + // UFUNCTION(BlueprintPure) + // AMyPlayerController *PlayerInTurn() const; + // + // UFUNCTION(BlueprintPure) + // AMyPlayerController *PlayerNotInTurn() const; - UFUNCTION(BlueprintPure) - AMyPlayerController *PlayerNotInTurn() const; + // UPROPERTY() + // uint8 CurrentPlayerTurn{0}; - UPROPERTY() - uint8 CurrentPlayerTurn{0}; + // UFUNCTION() + // AMyPlayerController *GetMyPlayerController(uint8 const PlayerIndex) const; - UFUNCTION() - AMyPlayerController *GetMyPlayerController(uint8 const PlayerIndex) const; + auto GetMyGameState() const; }; diff --git a/Source/TurnBasedTutorial/MyGameState.cpp b/Source/TurnBasedTutorial/MyGameState.cpp index b1538d3..1b84b68 100644 --- a/Source/TurnBasedTutorial/MyGameState.cpp +++ b/Source/TurnBasedTutorial/MyGameState.cpp @@ -2,86 +2,65 @@ #include "MyGameState.h" -// #include "MyPlayerController.h" -// #include "Trooper.h" -// #include "Kismet/GameplayStatics.h" +#include "MyPlayerState.h" +#include "Trooper.h" +#include "Net/UnrealNetwork.h" -// void AMyGameState::InitializeBattleField() const { -// UE_LOG(LogTemp, Warning, TEXT("InitializeBattleField")); -// FVector Location(2000.0f, -1000.0f, 0.0f); -// FRotator Rotation(0.0f, 180.0f, 0.0f); -// -// uint8 TrooperCount = 0; -// -// TArray bpPaths{ -// TEXT( -// "Blueprint'/Game/Troopers/TrooperSkeletonMelee.TrooperSkeletonMelee_C'" -// ), -// TEXT("Blueprint'/Game/Troopers/TrooperWizard.TrooperWizard_C'") -// }; -// TArray LoadedBpAssets; -// for (int i = 0; i < bpPaths.Num(); ++i) { -// TSoftClassPtr ActorBpClass = TSoftClassPtr( -// FSoftObjectPath(bpPaths[i]) -// ); -// LoadedBpAssets.Push(ActorBpClass.LoadSynchronous()); -// } -// -// for (int i = 0; i < 5; ++i) { -// FTransform SpawnLocationAndRotation(Rotation); -// SpawnLocationAndRotation.SetLocation(Location); -// AActor *Spawned = GetWorld()->SpawnActorDeferred( -// LoadedBpAssets[i % 2], SpawnLocationAndRotation); -// // AActor *Spawned = GetWorld()->SpawnActorDeferred( -// // ATrooper::StaticClass(), SpawnLocationAndRotation); -// dynamic_cast(Spawned)->Initialize( -// 0, Location, TrooperCount++); -// Spawned->FinishSpawning(SpawnLocationAndRotation); -// Spawned->SetActorLocation(Location); -// Location += {0.f, 500.f, 0.0f}; -// } -// Location = {-2000.0f, -1000.0f, 0.0f}; -// Rotation = {0.0f, 0.0f, 0.0f}; -// for (int i = 0; i < 5; ++i) { -// FTransform SpawnLocationAndRotation(Rotation); -// SpawnLocationAndRotation.SetLocation(Location); -// AActor *Spawned = GetWorld()->SpawnActorDeferred( -// LoadedBpAssets[i % 2], SpawnLocationAndRotation); -// // AActor *Spawned = GetWorld()->SpawnActorDeferred( -// // ATrooper::StaticClass(), SpawnLocationAndRotation); -// dynamic_cast(Spawned)->Initialize( -// 1, Location, TrooperCount++); -// Spawned->FinishSpawning(SpawnLocationAndRotation); -// Spawned->SetActorLocation(Location); -// Location += {0.f, 500.f, 0.0f}; -// } -// } +auto AMyGameState::GetMyPlayerState(uint8 PlayerIndex) const { + return Cast(PlayerArray[PlayerIndex]); +} -// AMyPlayerController *AMyGameState::GetMyPlayerController( -// uint8 const PlayerIndex) const { -// return dynamic_cast( -// UGameplayStatics::GetPlayerController(GetWorld(), PlayerIndex)); -// } -// -// void AMyGameState::StartGame() { -// // InitializeBattleField(); -// PlayerInTurn()->StartTurn(); -// } -// -// void AMyGameState::CycleTurns() { -// PlayerInTurn()->EndTurn(); -// if (CurrentPlayerTurn == 0) { -// CurrentPlayerTurn = 1; -// } else { -// CurrentPlayerTurn = 0; +void AMyGameState::BeginPlay() { + Super::BeginPlay(); +} + +void AMyGameState::AddTrooper(ATrooper *Trooper) { + Troopers.Add(Trooper); +} + +void AMyGameState::StartGame() const { + // PlayerNotInTurn()->SetEnemySelection(Troopers); + // PlayerInTurn()->SetEnemySelection(Troopers); + PlayerInTurn()->StartTurn(); +} + +void AMyGameState::CycleTurns_Implementation(uint8 CurrentPlayerIndex) { + if (CurrentPlayerTurn == CurrentPlayerIndex) { + PlayerInTurn()->EndTurn(); + for (const auto Trooper : Troopers) { + if (Trooper != nullptr) { + Trooper->ResetActionPoints(); + } + } + CurrentPlayerTurn = !CurrentPlayerTurn; + PlayerInTurn()->StartTurn(); + } +} + +// void AMyGameState::CycleTurns(uint8 CurrentPlayerIndex) { +// if (CurrentPlayerTurn == CurrentPlayerIndex) { +// PlayerInTurn()->EndTurn(); +// for (const auto Trooper : Troopers) { +// if (Trooper != nullptr) { +// Trooper->ResetActionPoints(); +// } +// } +// CurrentPlayerTurn = !CurrentPlayerTurn; +// PlayerInTurn()->StartTurn(); // } -// PlayerInTurn()->StartTurn(); -// } -// -// AMyPlayerController *AMyGameState::PlayerInTurn() const { -// return GetMyPlayerController(CurrentPlayerTurn); -// } -// -// AMyPlayerController *AMyGameState::PlayerNotInTurn() const { -// return GetMyPlayerController(CurrentPlayerTurn == 0 ? 1 : 0); // } + +AMyPlayerState *AMyGameState::PlayerInTurn() const { + return GetMyPlayerState(CurrentPlayerTurn); +} + +AMyPlayerState *AMyGameState::PlayerNotInTurn() const { + return GetMyPlayerState(!CurrentPlayerTurn); +} + +void AMyGameState::GetLifetimeReplicatedProps( + TArray &OutLifetimeProps) const { + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + DOREPLIFETIME(AMyGameState, Troopers); + DOREPLIFETIME(AMyGameState, CurrentPlayerTurn); +} diff --git a/Source/TurnBasedTutorial/MyGameState.h b/Source/TurnBasedTutorial/MyGameState.h index d9220da..dafd47a 100644 --- a/Source/TurnBasedTutorial/MyGameState.h +++ b/Source/TurnBasedTutorial/MyGameState.h @@ -3,6 +3,7 @@ #pragma once #include "CoreMinimal.h" +#include "MyPlayerState.h" #include "GameFramework/GameState.h" #include "MyGameState.generated.h" @@ -12,26 +13,32 @@ UCLASS() class TURNBASEDTUTORIAL_API AMyGameState : public AGameState { GENERATED_BODY() -// public: -// UFUNCTION(BlueprintCallable) -// void CycleTurns(); -// -// UFUNCTION(BlueprintCallable) -// void StartGame(); -// -// private: -// // void InitializeBattleField() const; -// -// UFUNCTION() -// AMyPlayerController *GetMyPlayerController(uint8 const PlayerIndex) const; -// -// -// UFUNCTION(BlueprintPure) -// AMyPlayerController *PlayerInTurn() const; -// -// UFUNCTION(BlueprintPure) -// AMyPlayerController *PlayerNotInTurn() const; -// -// UPROPERTY() -// uint8 CurrentPlayerTurn{0}; + +public: + virtual void BeginPlay() override; + + UFUNCTION() + void AddTrooper(ATrooper *Trooper); + + UFUNCTION() + void StartGame() const; + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CycleTurns(uint8 CurrentPlayerIndex); + + UFUNCTION(BlueprintPure) + AMyPlayerState *PlayerInTurn() const; + + UFUNCTION(BlueprintPure) + AMyPlayerState *PlayerNotInTurn() const; + + auto GetMyPlayerState(uint8 PlayerIndex) const; + +private: + UPROPERTY(Replicated) + TArray Troopers; + + UPROPERTY(Replicated) + uint8 CurrentPlayerTurn{0}; + }; diff --git a/Source/TurnBasedTutorial/MyPlayerController.cpp b/Source/TurnBasedTutorial/MyPlayerController.cpp index c1ef308..e89f66b 100644 --- a/Source/TurnBasedTutorial/MyPlayerController.cpp +++ b/Source/TurnBasedTutorial/MyPlayerController.cpp @@ -3,10 +3,12 @@ #include "MyPlayerController.h" #include "Kismet/GameplayStatics.h" #include "MyGameMode.h" +#include "MyGameState.h" +#include "MyPlayerState.h" #include "Net/UnrealNetwork.h" AMyPlayerController::AMyPlayerController() - : Super(), bIsMyTurn(false), SelectedTrooper(nullptr) { + : Super()/*, bIsMyTurn(false), SelectedTrooper(nullptr)*/ { UE_LOG(LogTemp, Warning, TEXT("Player controller created")); SetShowMouseCursor(true); } @@ -17,58 +19,72 @@ void AMyPlayerController::SetupInputComponent() { &AMyPlayerController::OnLeftMouseClick); } -void AMyPlayerController::SetMyTurn(bool bMyTurn) { - bIsMyTurn = bMyTurn; - if (bIsMyTurn) { - GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, - FString::Printf( - TEXT("CURRENT TURN: %d"), - PlayerIndex)); - } - // OnMyTurnChanged.ExecuteIfBound(bIsMyTurn); +// void AMyPlayerController::SetMyTurn(bool bMyTurn) { +// bIsMyTurn = bMyTurn; +// if (bIsMyTurn) { +// GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, +// FString::Printf( +// TEXT("CURRENT TURN: %d"), +// PlayerIndex)); +// } +// OnMyTurnChanged.ExecuteIfBound(bIsMyTurn); +// } + +// void AMyPlayerController::StartTurn_Implementation() { +// SetMyTurn(true); +// UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex); +// } + +auto AMyPlayerController::GetMyGameState() const { + return Cast(UGameplayStatics::GetGameState(GetWorld())); } -void AMyPlayerController::StartTurn_Implementation() { - SetMyTurn(true); - UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex); +auto AMyPlayerController::GetMyPlayerState() const { + return GetPlayerState(); } + auto AMyPlayerController::GetMyGameMode() const { - return dynamic_cast( + return Cast( UGameplayStatics::GetGameMode(GetWorld())); } -void AMyPlayerController::EndTurn_Implementation() { - if (bIsMyTurn) { - UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"), PlayerIndex); - SetMyTurn(false); - if (SelectedTrooper) { - SelectedTrooper->SetSelection(false); - SelectedTrooper = nullptr; - } - UE_LOG(LogTemp, Warning, TEXT("Not your turn, %d"), PlayerIndex); - AMyGameMode *gameMode = GetMyGameMode(); - gameMode->CycleTurns(); - } -} + +// void AMyPlayerController::EndTurn_Implementation() { +// GetMyPlayerState()->EndTurn(); +// } + + +// if (bIsMyTurn) { +// UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"), PlayerIndex); +// SetMyTurn(false); +// if (SelectedTrooper) { +// SelectedTrooper->SetSelection(false); +// SelectedTrooper = nullptr; +// } +// UE_LOG(LogTemp, Warning, TEXT("Not your turn, %d"), PlayerIndex); +// AMyGameMode *gameMode = GetMyGameMode(); +// gameMode->CycleTurns(); +// } +// } // AMyGameState *AMyPlayerController::GetMyGameState() const { // return dynamic_cast( // GetWorld()->GetGameState()); // } -void AMyPlayerController::MoveTrooper_Implementation( - ATrooper *Trooper, - FVector Location) { - if (Trooper->CheckMoveCorrectness(Location)) { - Trooper->MoveTrooper(Location); - // GetMyGameMode()->CycleTurns(); - } else { - GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, - FString::Printf( - TEXT("Out of move radius!"))); - } -} +// void AMyPlayerController::MoveTrooper_Implementation( +// ATrooper *Trooper, +// FVector Location) { +// if (Trooper->CheckMoveCorrectness(Location)) { +// Trooper->MoveTrooper(Location); +// // GetMyGameMode()->CycleTurns(); +// } else { +// GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, +// FString::Printf( +// TEXT("Out of move radius!"))); +// } +// } // void AMyPlayerController::AttackTrooper_Implementation( // ATrooper *Attacker, @@ -90,32 +106,38 @@ void AMyPlayerController::MoveTrooper_Implementation( // } -void AMyPlayerController::Attack_Implementation(ATrooper *Attacker, - FVector Location, - int ActionIndex) { - if (Attacker && CurrentAction >= 1 && CurrentAction <= 2 && - Attacker->CheckAttackCorrectness(Location, CurrentAction)) { - Attacker->Attack(CurrentAction); - } else { - UE_LOG(LogTemp, Warning, - TEXT("Out of radius or not enough Action Points")); - } -} +// void AMyPlayerController::Attack_Implementation(ATrooper *Attacker, +// FVector Location, +// int ActionIndex) { +// if (Attacker && CurrentAction >= 1 && CurrentAction <= 2 && +// Attacker->CheckAttackCorrectness(Location, CurrentAction)) { +// Attacker->Attack(CurrentAction); +// } else { +// UE_LOG(LogTemp, Warning, +// TEXT("Out of radius or not enough Action Points")); +// } +// } void AMyPlayerController::SetPlayerIndex(uint8 NewPlayerIndex) { PlayerIndex = NewPlayerIndex; + + GetMyPlayerState()->SetPlayerIndex(NewPlayerIndex); + // GetMyPlayerState()->PlayerIndex = NewPlayerIndex; } float AMyPlayerController::SetCurrentActionAndReturnRadius(int action) { - CurrentAction = action; - UE_LOG(LogTemp, Warning, TEXT("SetCurrentAction: %d on Player Controller " - "with index %d"), CurrentAction, PlayerIndex); - if (SelectedTrooper) { - return SelectedTrooper->GetActionRadius(CurrentAction); - } - return 0.0f; + return GetMyPlayerState()->SetCurrentActionAndReturnRadius(action); + + // CurrentAction = action; + // UE_LOG(LogTemp, Warning, TEXT("SetCurrentAction: %d on Player Controller " + // "with index %d"), CurrentAction, PlayerIndex); + // if (SelectedTrooper) { + // return SelectedTrooper->GetActionRadius(CurrentAction); + // } + // return 0.0f; } + void AMyPlayerController::SetEnemySelection_Implementation( const TArray &Troopers) const { for (const auto Trooper : Troopers) { @@ -149,18 +171,19 @@ void AMyPlayerController::SetEnemySelection_Implementation( void AMyPlayerController::GetLifetimeReplicatedProps( TArray &OutLifetimeProps) const { + Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AMyPlayerController, PlayerIndex); - DOREPLIFETIME(AMyPlayerController, CurrentAction); - DOREPLIFETIME(AMyPlayerController, bIsMyTurn); - DOREPLIFETIME(AMyPlayerController, SelectedTrooper); + // DOREPLIFETIME(AMyPlayerController, CurrentAction); + // DOREPLIFETIME(AMyPlayerController, bIsMyTurn); + // DOREPLIFETIME(AMyPlayerController, SelectedTrooper); } void AMyPlayerController::OnLeftMouseClick() { - if (!bIsMyTurn) { + if (!GetMyPlayerState()->IsMyTurn()) { return; } UE_LOG(LogTemp, Warning, TEXT("Mouse clicked")); - UE_LOG(LogTemp, Warning, TEXT("Current action: %d"), CurrentAction); + // UE_LOG(LogTemp, Warning, TEXT("Current action: %d"), CurrentAction); FHitResult HitResult; bool const IsHitResult = GetHitResultUnderCursorForObjects( TArray>{ObjectTypeQuery1}, false, @@ -171,56 +194,57 @@ void AMyPlayerController::OnLeftMouseClick() { if (!IsHitResult) return; UE_LOG(LogTemp, Warning, TEXT("Got hit result")); - auto const NewlySelectedLocation = HitResult.Location; - ATrooper *NewlySelectedTrooper = dynamic_cast( - HitResult.GetActor()); - - // skip re-selection - if (SelectedTrooper == NewlySelectedTrooper) { - UE_LOG(LogTemp, Warning, TEXT("Skip reselection")); - return; - } - - if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper-> - IsValidLowLevel() || NewlySelectedTrooper->GetPlayerIndex() != - PlayerIndex) { - // we selected something that is not a trooper (or trooper in shitty state...) - // probably we should move to it if we can... - - // UE_LOG(LogTemp, Warning, TEXT("Not a trooper")); - - // if initial trooper is valid... - if (SelectedTrooper != nullptr && SelectedTrooper->IsValidLowLevel()) { - switch (CurrentAction) { - case 0: - UE_LOG(LogTemp, Warning, TEXT("Do move")); - // move this mf - MoveTrooper(SelectedTrooper, NewlySelectedLocation); - // and reset the selection.... - SelectedTrooper->SetSelection(false); - SelectedTrooper = nullptr; - break; - default: - // ATTACK! ATTACK! - UE_LOG(LogTemp, Warning, TEXT("Do attack")); - Attack(SelectedTrooper, NewlySelectedLocation, - CurrentAction); - SelectedTrooper->SetSelection(false); - SelectedTrooper = nullptr; - break; - } - } - } else if (NewlySelectedTrooper != nullptr && NewlySelectedTrooper-> - IsValidLowLevel() && NewlySelectedTrooper->GetPlayerIndex() == - PlayerIndex) { - UE_LOG(LogTemp, Warning, TEXT("Do reselect")); - // our move, selection - if (SelectedTrooper) { - SelectedTrooper->SetSelection(false); - } - SelectedTrooper = NewlySelectedTrooper; - SelectedTrooper->SetSelection(true); - } + GetMyPlayerState()->OnPlayerAction(HitResult); + // auto const NewlySelectedLocation = HitResult.Location; + // ATrooper *NewlySelectedTrooper = Cast( + // HitResult.GetActor()); + // + // // skip re-selection + // if (SelectedTrooper == NewlySelectedTrooper) { + // UE_LOG(LogTemp, Warning, TEXT("Skip reselection")); + // return; + // } + // + // if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper-> + // IsValidLowLevel() || NewlySelectedTrooper->GetPlayerIndex() != + // PlayerIndex) { + // // we selected something that is not a trooper (or trooper in shitty state...) + // // probably we should move to it if we can... + // + // // UE_LOG(LogTemp, Warning, TEXT("Not a trooper")); + // + // // if initial trooper is valid... + // if (SelectedTrooper != nullptr && SelectedTrooper->IsValidLowLevel()) { + // switch (CurrentAction) { + // case 0: + // UE_LOG(LogTemp, Warning, TEXT("Do move")); + // // move this mf + // MoveTrooper(SelectedTrooper, NewlySelectedLocation); + // // and reset the selection.... + // SelectedTrooper->SetSelection(false); + // SelectedTrooper = nullptr; + // break; + // default: + // // ATTACK! ATTACK! + // UE_LOG(LogTemp, Warning, TEXT("Do attack")); + // Attack(SelectedTrooper, NewlySelectedLocation, + // CurrentAction); + // SelectedTrooper->SetSelection(false); + // SelectedTrooper = nullptr; + // break; + // } + // } + // } else if (NewlySelectedTrooper != nullptr && NewlySelectedTrooper-> + // IsValidLowLevel() && NewlySelectedTrooper->GetPlayerIndex() == + // PlayerIndex) { + // UE_LOG(LogTemp, Warning, TEXT("Do reselect")); + // // our move, selection + // if (SelectedTrooper) { + // SelectedTrooper->SetSelection(false); + // } + // SelectedTrooper = NewlySelectedTrooper; + // SelectedTrooper->SetSelection(true); + // } // // if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper-> diff --git a/Source/TurnBasedTutorial/MyPlayerController.h b/Source/TurnBasedTutorial/MyPlayerController.h index 6b56c55..f04607c 100644 --- a/Source/TurnBasedTutorial/MyPlayerController.h +++ b/Source/TurnBasedTutorial/MyPlayerController.h @@ -2,7 +2,6 @@ #pragma once #include "CoreMinimal.h" -// #include "MyGameState.h" #include "Trooper.h" #include "GameFramework/PlayerController.h" #include "MyPlayerController.generated.h" @@ -15,25 +14,25 @@ class TURNBASEDTUTORIAL_API AMyPlayerController : public APlayerController { public: // FOnMyTurnChangedDelegate OnMyTurnChanged; - + virtual void SetupInputComponent() override; AMyPlayerController(); - UFUNCTION(Client, Reliable) - void StartTurn(); - - UFUNCTION(Client, Reliable, BlueprintCallable) - void EndTurn(); - - UFUNCTION(Server, Reliable) - void MoveTrooper(ATrooper *Trooper, FVector Location); + // UFUNCTION(Client, Reliable) + // void StartTurn(); + // UFUNCTION(Client, Reliable, BlueprintCallable) + // void EndTurn(); + // // UFUNCTION(Server, Reliable) - // void AttackTrooper(ATrooper *Attacker, ATrooper *Victim); - - UFUNCTION(Server, Reliable) - void Attack(ATrooper *Attacker, FVector Location, int ActionIndex); + // void MoveTrooper(ATrooper *Trooper, FVector Location); + // + // // // UFUNCTION(Server, Reliable) + // // // void AttackTrooper(ATrooper *Attacker, ATrooper *Victim); + // + // UFUNCTION(Server, Reliable) + // void Attack(ATrooper *Attacker, FVector Location, int ActionIndex); UFUNCTION() void SetPlayerIndex(uint8 NewPlayerIndex); @@ -45,23 +44,26 @@ public: void SetEnemySelection(const TArray &Troopers) const; private: - UPROPERTY(Replicated) - bool bIsMyTurn; - - UPROPERTY(Replicated) - int CurrentAction = 0; - + // UPROPERTY(Replicated) + // bool bIsMyTurn; + // + // UPROPERTY(Replicated) + // int CurrentAction = 0; + // UPROPERTY(Replicated) uint8 PlayerIndex; + // + // UPROPERTY(Replicated) + // ATrooper *SelectedTrooper; - UPROPERTY(Replicated) - ATrooper *SelectedTrooper; - + UFUNCTION() void OnLeftMouseClick(); - void SetMyTurn(bool bMyTurn); + // void SetMyTurn(bool bMyTurn); auto GetMyGameMode() const; - // AMyGameState *GetMyGameState() const; + auto GetMyGameState() const; + + auto GetMyPlayerState() const; }; diff --git a/Source/TurnBasedTutorial/MyPlayerStart.cpp b/Source/TurnBasedTutorial/MyPlayerStart.cpp index e963a5a..fd44adc 100644 --- a/Source/TurnBasedTutorial/MyPlayerStart.cpp +++ b/Source/TurnBasedTutorial/MyPlayerStart.cpp @@ -3,7 +3,6 @@ #include "MyPlayerStart.h" -uint8 AMyPlayerStart::GetPlayerIndex() const -{ - return PlayerIndex; +uint8 AMyPlayerStart::GetPlayerIndex() const { + return PlayerIndex; } diff --git a/Source/TurnBasedTutorial/MyPlayerStart.h b/Source/TurnBasedTutorial/MyPlayerStart.h index 297594a..c28a149 100644 --- a/Source/TurnBasedTutorial/MyPlayerStart.h +++ b/Source/TurnBasedTutorial/MyPlayerStart.h @@ -10,15 +10,14 @@ * */ UCLASS() -class TURNBASEDTUTORIAL_API AMyPlayerStart : public APlayerStart -{ - GENERATED_BODY() -public: +class TURNBASEDTUTORIAL_API AMyPlayerStart : public APlayerStart { + GENERATED_BODY() +public: uint8 GetPlayerIndex() const; protected: private: UPROPERTY(EditAnywhere, Category="Spawn Info") - uint8 PlayerIndex=0; + uint8 PlayerIndex = 0; }; diff --git a/Source/TurnBasedTutorial/MyPlayerState.cpp b/Source/TurnBasedTutorial/MyPlayerState.cpp new file mode 100644 index 0000000..cb29a24 --- /dev/null +++ b/Source/TurnBasedTutorial/MyPlayerState.cpp @@ -0,0 +1,149 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "MyPlayerState.h" + +#include "MyGameState.h" +#include "Trooper.h" +#include "Net/UnrealNetwork.h" + +AMyPlayerState::AMyPlayerState() + : Super(), bIsMyTurn(false), SelectedTrooper(nullptr) { +} + +void AMyPlayerState::BeginPlay() { + Super::BeginPlay(); +} + +void AMyPlayerState::SetPlayerIndex(uint8 NewPlayerIndex) { + PlayerIndex = NewPlayerIndex; +} + +bool AMyPlayerState::IsMyTurn() const { + return bIsMyTurn; +} + +void AMyPlayerState::SetMyTurn(bool bMyTurn) { + bIsMyTurn = bMyTurn; + if (bIsMyTurn) { + GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, + FString::Printf( + TEXT("CURRENT TURN: %d"), + PlayerIndex)); + } +} + +void AMyPlayerState::StartTurn_Implementation() { + SetMyTurn(true); + UE_LOG(LogTemp, Warning, TEXT("Your turn, %d"), PlayerIndex); +} + +void AMyPlayerState::EndTurn_Implementation() { + if (bIsMyTurn) { + UE_LOG(LogTemp, Warning, TEXT("End Turn from player %d"), PlayerIndex); + SetMyTurn(false); + if (SelectedTrooper) { + SelectedTrooper->SetSelection(false); + SelectedTrooper = nullptr; + } + UE_LOG(LogTemp, Warning, TEXT("Not your turn, %d"), PlayerIndex); + // AMyGameMode *gameMode = GetMyGameMode(); + // gameMode->CycleTurns(); + // Cast(GetWorld()->GetGameState())->CycleTurns(); + } +} + +void AMyPlayerState::MoveTrooper_Implementation( + ATrooper *Trooper, + FVector Location) { + if (Trooper->CheckMoveCorrectness(Location)) { + Trooper->MoveTrooper(Location); + // GetMyGameMode()->CycleTurns(); + } else { + GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Red, + FString::Printf( + TEXT("Out of move radius!"))); + } +} + +void AMyPlayerState::Attack_Implementation(ATrooper *Attacker, + FVector Location, + int ActionIndex) { + if (Attacker && CurrentAction >= 1 && CurrentAction <= 2 && + Attacker->CheckAttackCorrectness(Location, CurrentAction)) { + Attacker->Attack(CurrentAction); + } else { + UE_LOG(LogTemp, Warning, + TEXT("Out of radius or not enough Action Points")); + } +} + +void AMyPlayerState::OnPlayerAction(const FHitResult &HitResult) { + auto const NewlySelectedLocation = HitResult.Location; + ATrooper *NewlySelectedTrooper = Cast( + HitResult.GetActor()); + + // skip re-selection + if (SelectedTrooper == NewlySelectedTrooper) { + UE_LOG(LogTemp, Warning, TEXT("Skip reselection")); + return; + } + + if (NewlySelectedTrooper == nullptr || !NewlySelectedTrooper-> + IsValidLowLevel() || NewlySelectedTrooper->GetPlayerIndex() != + PlayerIndex) { + if (SelectedTrooper != nullptr && SelectedTrooper->IsValidLowLevel()) { + switch (CurrentAction) { + case 0: + UE_LOG(LogTemp, Warning, TEXT("Do move")); + // move this mf + MoveTrooper(SelectedTrooper, NewlySelectedLocation); + // and reset the selection.... + SelectedTrooper->SetSelection(false); + SelectedTrooper = nullptr; + break; + default: + // ATTACK! ATTACK! + UE_LOG(LogTemp, Warning, TEXT("Do attack")); + Attack(SelectedTrooper, NewlySelectedLocation, + CurrentAction); + SelectedTrooper->SetSelection(false); + SelectedTrooper = nullptr; + break; + } + } + } else if (NewlySelectedTrooper != nullptr && NewlySelectedTrooper-> + IsValidLowLevel() && NewlySelectedTrooper->GetPlayerIndex() == + PlayerIndex) { + UE_LOG(LogTemp, Warning, TEXT("Do reselect")); + // our move, selection + if (SelectedTrooper) { + SelectedTrooper->SetSelection(false); + } + SelectedTrooper = NewlySelectedTrooper; + SelectedTrooper->SetSelection(true); + } +} + +float AMyPlayerState::SetCurrentActionAndReturnRadius(int Action) { + CurrentAction = Action; + UE_LOG(LogTemp, Warning, TEXT("SetCurrentAction: %d on Player Controller " + "with index %d"), CurrentAction, PlayerIndex); + if (SelectedTrooper) { + return SelectedTrooper->GetActionRadius(CurrentAction); + } + return 0.0f; +} + +uint8 AMyPlayerState::GetPlayerIndex() { + return PlayerIndex; +} + +void AMyPlayerState::GetLifetimeReplicatedProps( + TArray &OutLifetimeProps) const { + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + DOREPLIFETIME(AMyPlayerState, PlayerIndex); + DOREPLIFETIME(AMyPlayerState, CurrentAction); + DOREPLIFETIME(AMyPlayerState, bIsMyTurn); + DOREPLIFETIME(AMyPlayerState, SelectedTrooper); +} diff --git a/Source/TurnBasedTutorial/MyPlayerState.h b/Source/TurnBasedTutorial/MyPlayerState.h new file mode 100644 index 0000000..cd08241 --- /dev/null +++ b/Source/TurnBasedTutorial/MyPlayerState.h @@ -0,0 +1,63 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/PlayerState.h" +#include "MyPlayerState.generated.h" + +/** + * + */ +UCLASS() +class TURNBASEDTUTORIAL_API AMyPlayerState : public APlayerState { + GENERATED_BODY() +public: + AMyPlayerState(); + + virtual void BeginPlay() override; + + UFUNCTION(Client, Reliable) + void StartTurn(); + + UFUNCTION(Client, Reliable, BlueprintCallable) + void EndTurn(); + + UFUNCTION(Server, Reliable) + void MoveTrooper(ATrooper *Trooper, FVector Location); + + UFUNCTION(Server, Reliable) + void Attack(ATrooper *Attacker, FVector Location, int ActionIndex); + + UFUNCTION() + bool IsMyTurn() const; + + UFUNCTION() + void OnPlayerAction(const FHitResult &HitResult); + + UFUNCTION(BlueprintCallable) + float SetCurrentActionAndReturnRadius(int Action); + + UFUNCTION(BlueprintCallable) + uint8 GetPlayerIndex(); + + UFUNCTION() + void SetPlayerIndex(uint8 NewPlayerIndex); + +private: + UPROPERTY(Replicated) + uint8 PlayerIndex; + + UFUNCTION() + void SetMyTurn(bool bMyTurn); + + UPROPERTY(Replicated) + bool bIsMyTurn; + + UPROPERTY(Replicated) + int CurrentAction = 0; + + + UPROPERTY(Replicated) + ATrooper *SelectedTrooper; +}; diff --git a/Source/TurnBasedTutorial/Trooper.h b/Source/TurnBasedTutorial/Trooper.h index 8446480..5adb591 100644 --- a/Source/TurnBasedTutorial/Trooper.h +++ b/Source/TurnBasedTutorial/Trooper.h @@ -75,10 +75,6 @@ protected: UPROPERTY(EditAnywhere) UAbility *SpecialAbility; - const float MoveRadius = 1500.f; - - float AttackRadius = 1000.f; - UPROPERTY(EditAnywhere) float Speed = 300.0f;