From 6582a1972a15d5fa75ed17a520479305e8a7382e Mon Sep 17 00:00:00 2001 From: "wagic.the.homebrew@gmail.com" Date: Sat, 4 Apr 2009 12:52:36 +0000 Subject: [PATCH] Erwan - Added Momir Basic mode :) --- projects/mtg/Makefile | 2 +- .../mtg/bin/Res/graphics/momir_unlocked.png | Bin 0 -> 19583 bytes projects/mtg/bin/Res/player/momir.txt | 5 + projects/mtg/include/AIMomirPlayer.h | 17 ++ projects/mtg/include/AIPlayer.h | 3 +- projects/mtg/include/ActionLayer.h | 2 + projects/mtg/include/GameApp.h | 4 + projects/mtg/include/GameOptions.h | 1 + projects/mtg/include/GameStateDuel.h | 2 + projects/mtg/include/GameStateMenu.h | 2 + projects/mtg/include/MTGAbility.h | 4 + projects/mtg/include/MTGGameZones.h | 1 + projects/mtg/include/MTGRules.h | 70 ++----- projects/mtg/include/ManaCost.h | 2 +- projects/mtg/src/AIMomirPlayer.cpp | 192 ++++++++++++++++++ projects/mtg/src/AIPlayer.cpp | 40 ++-- projects/mtg/src/ActionLayer.cpp | 10 + projects/mtg/src/GameApp.cpp | 4 +- projects/mtg/src/GameObserver.cpp | 4 + projects/mtg/src/GameStateDuel.cpp | 82 ++++++-- projects/mtg/src/GameStateMenu.cpp | 75 ++++--- projects/mtg/src/MTGGameZones.cpp | 5 +- projects/mtg/src/MTGRules.cpp | 75 ++++++- projects/mtg/template.vcproj | 8 + 24 files changed, 479 insertions(+), 131 deletions(-) create mode 100644 projects/mtg/bin/Res/graphics/momir_unlocked.png create mode 100644 projects/mtg/bin/Res/player/momir.txt create mode 100644 projects/mtg/include/AIMomirPlayer.h create mode 100644 projects/mtg/src/AIMomirPlayer.cpp diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index 5f60bff1c..4d0d84091 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -1,4 +1,4 @@ -OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/ConstraintResolver.o objs/Counters.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TexturesCache.o objs/Token.o objs/utils.o objs/WEvent.o +OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/ConstraintResolver.o objs/Counters.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TexturesCache.o objs/Token.o objs/utils.o objs/WEvent.o DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS)) RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) diff --git a/projects/mtg/bin/Res/graphics/momir_unlocked.png b/projects/mtg/bin/Res/graphics/momir_unlocked.png new file mode 100644 index 0000000000000000000000000000000000000000..9f66dc718bd35d6927843240d4c524f53668bbf8 GIT binary patch literal 19583 zcmcG#Lv$|Q4=!BWKDBMzw(a(u+IVZ*wr%&+w(-_>Pi^b|{^RdkcXkImdnZ{LJd>Sd zJxQdpq7)(=E*uC52%?O%xGD$;Xu^MQa~P=qWX04Uz<(Eng@}R(2uNc*{HF=ze>$wA zw2li12vght4ygR3MDKq_Xjd5p3FvhQ2zYvszh zyD}NIu7+&?j%BRY7a``38cqR49C>^9fD*QOScb)mL z8tX}^Gd6FkN+_aB1UY3n-6DDwf@41+QLFTj*2Nuv8q|U1zsO_pbtoau(lsIf2+=>OK4(#wr5exI! ztIIM|Im;sSm2#`N_Rve*TaJ=Xd{rT=7bclUhVB1}7OvTSol84~m$OhfAtHq13|%nH z=^ls8$+?Bi>G+ki2D!fVKH}L8Zl?z63-8i#8m2m$U1mkC?Cm=9TraSOy6yevs-#P9 z5|M4Er6zIw^x^^!1qY{nad-D8Cq8}-Jm;m4DAG%Z;OCAg;tRU4u+Zf0?v4SSO0gRa z9o+@`?guVTAjAdT0P1}H4rcyvG>=Z_W*EaVtA05{5slXp64XX&Sd(hs=by| z?9<#m&DGwdTbWy1j4~V^4?F!;)TNRzE&XF?bUm=4RndBj@htzpKEhv{} zh}O_X{kehrzL}4t$i=y5PKfT_6#}GHZ_~ZSQS%H|6`mTj_&&)T)V<-rPE= zLSY5QsTRyfPetC>mvf|4eDJdB6keWOw% z6-!Mm7ds=(LY}8yrj zTdm9dCt}AzlwEV{SI@&!L!SyVG}gypp~SbNWg}=>3Nqb7XJ4!91Dgkn0dV9+7fvFZHrW$WqH&8QZ8<09W#r%FMAE@bv#U~9 z)iN|4WhB)fDcE5JiF+rGUyC|?C+|-;x_i)@Cm#bRJl_o!+8QY*fFykj>K9%IqyLmJwau)5DRkigf1K$w_&I(WbH(jIQ z)LrUpk;3@02TcGjx20_i4h^3Jy^EMCk^(rNPXVeB73x)01NZYcBc^v_u&}U9j*#*= z(mi~h&~lrc8tmuh&1ENEUGH~ik~|6D6`9j|oZ7wn9!BY8@!Y+vpR-q2G>$fUV2{(t z|8V2HwrJ2ZzbcN7j`-Bd3@7_baXZ9t$vxJ0IwNx4kA=ND|M z?_$*3^zzWb!Pi5Dv(S*>XT($E_zIP^r3@Y=Px$9ULR6+|X!P_Z80NmrW z+#?@?{XUV2Gys&xR84#$b81B~=13H|6&OOnH$g04ANgmuEch7` z5n4WayE~XM+uF^~`DHhSC8gICser9lygY%bM?Mx$9zGNv6$1+%ogiU<5sRRAWdjNx zOYEeuE0uhJXW(sVbb*g!j}SNW0G)8Y->oT?(Koj7XMJsEtn4YTimp^Qj-?W3rf`X( ztgNi>%hs*2f5ztKn3AN!#w<-PToaDg5FE{VlC-4 z>N}el5$tQCgR*hx7R{Xj_kB!OPNp#;CwE|4x+QG(#NcnX+?$e=ihnZNEaUfpjsm>2qT0;e;mKMTyV-nV$kk6fDF zd>cUzL^Pytz_fyPr`508^sGPk)suzr4J*8_;yO)4>deL^jC>;p(BF41c`!i$fdEaxaQnMqobp}aS;*i$M!pg zB~l!nulm(Y3E$dAl%AK0LP(`P03f~%vY)%Vo2!vxj(JL#XE>Qa6$;hw-@ic@DZ_ik z&Whnb!lc7?5u~<*(=vaN#5hc^4i5SdWpIsPTQ~a*C{5hqu#-{3tiT@70)5`I;pU-O z72-QRpMndIyorDzp`lm8VwiioLzdL|nkORuKP}=WYEqSOY3UV(#G2|CaCpI4RQa6i zAZls|30w184!^4NbFs30HM5Q9(0 zptr7KAV;H)VJ#k+Y2(NO^GBQh-8#_FC$uJ>iI2z9xM5}pJ3&3;k1H$xuH!HaMFf*V zNuUU*k5t>1v`T#2CpplbG?bO+6P7oxeY8U6LXZJ7z#j6i1yy2e7pj{sMZFB-lze?G z5Swa_>>amt2VFu&TRj-?flxaN1E^ok6`k)$SEK=dYs zWlZX27Xw-Yzg#&ePrQAx3X%m^sz+8uzfw^S%0YT`*)Pwd+upUYGoQSC;oJwwE(_>0 z<(~%}m-efso5-Ck)bh|yPAd%GX!yrEWwFtTXD0J2!gD-~#v|?mD?r|Q6K%_zJJAwR z>gW^u)(q(!taC{57nXG;s_f-dx?M+hJiqIS0MLU|SAp|_2E6~;72qD0oTLu}tG9leJB2Pr zJ8?VGD(+bjXg-FR4T$<~qV5yR_ zC!kb~3ZlJrBfp}$O-r{8RiMY@<<@$mTpxbj#p!OBV&lPr!v>s)%1j#DRm!2)>*?2g zR`IIk^))IY5&$t0&_|dE=y$t(>Qf(9q0fhj(Y+AiMgBTe8$OR%v}suz)-og;dM4lW zk1R8gs}GgwT2m`O+UA}j%gG&;#Q9f7H`E9D^GehC%)H#cJ}NYLt$McWUt3fZolDUS z7v9WsHbqDiRj@eeF}x{m{KBTr$wndP{Dq7jla#B|Xe}MB8mvMkPgDWc5s`dYeB?iL zhx<|)AJj&!&J>2y10&vjH*^m6rYQI>Ks)TRl`qIBo6t+Epemdq)VHPq1Y-v?6K#My zh@p)@QV$ZLv-Xb{G#k!F!z-zvlUL4KqRC}r&+a{g3mD5z3_OxEFqK~X6L!a%6^)^U z7Slaf#d`dpsX<-n6orp42}@=gPHaaEkC`G&2w~~58;jAXZ$O{%=v57c#4f%4T#z(% zoF^kAGwkcC&7WlY*(2Gi_5N6!eGJ_mYWx&|Oj#ug>(DI~5f7sAx&?~uLbfhhDV~Fc zgCm?V4EEubSgB8bz5H)fk2}eZbs3YW|E<8a=*X|&-J;mey``jX6^n=>lELJljbKX#I^8GxF3sYMF#KVy5{MSmny07%ABgMV z`6uPl$~^`xVuMVcX)6hb-rK>wG@jkPM9}rPhX(yYAv$%M`c3pepuKGXd1YF8r305K z;;DQp%3P_O3jRPord)O1#W4^r?LBAhxm2yI=i&!NeAzEs&M&4;Q6Eo1UNduWp?Ujr)u>+UPgjZ2RvK>aWW#=aLopwp8 zJt+ew#HTLS3rpjQP`oyRuvn<*YiPj6W$oaYrfcnlcSw4IZV8;K#(Q&UK^Hc^NtTk2MJ5m9JV61gB&RU;zp+N&H1{ z$hYGnLMh~{(b!Pjrs?dd&}b~aEYvI5**<jp3kz>`MW<>&B>m;(qZz%V7(}B>->(EQ~*PeFqBn?}I z^uaN^5~@Ez1-`|`RR->5t&tjSa4H2Wb=3avo@gkfm#DuCM%-p{p$Aq}UV<}G<`qL#!fDgGaBb3Um1Y+yX$ab0o!fsrxn&k^6_1pw8*b@FG!p_OjGea{JJE z6JAB$tw@a!m4_-!9|xVNV+*t9YXP&Qqk}UufYnMbW{0iRz3Eoai(cfEoyN8C>kR)$j^2^vY$K%({&(e_W`SSZxWr>X#7dp`8=wDvX|nqgA7MW7k76bAF2PnOv~$ z(jo25=JYCg@oKqL`fG15kN|}5#7b(quz$Tx{G2jIhh1XPD3NsQm{D;kRZwV94dB@b zr+ZJ11W%T#->p}!0m|qj<##i-MMD}d#<2157!FvbrW#yF31}X0tdTfmHvUuQIHqr_ z;Lbw83mL7+fi#j+_D~n}oPnW`P#e_jL1N-p4witI} zyHhdqd+^d`X0i5Xt)v?&oZY{-MZLSYI_PvyWjSG%pvSkYDL)gzqnk$HSxrn)AU2J6^A|>j zawm8uaBfeV+EsnL2CsZ&g;rANAB$~xa^V{G8c}(yqkr=EB#_~qUklt#u2g$Xk1jVb z8)G%sP949eN!#;9wfP z`n;25+MxkC&!J}E>aRwm=!5W6?ct-ze|)?AGw#6ZRaA>y9$PUa3?v?I14jvCnCpc~i^a=V3!tRo9qqM-$zSOL zg}2+!%EDrua!(t1l22pVC)6&AtrwhIH!NFkV+#p#ySAL%Efb5QVfclA0dYR(N&9kE9XP-$uE=SBlY6<(+c_Xi$-sF&Xyk=h=t0DMfy)c^I zeySK`^p%RJF9)CPz!b7;hgnQOIpmLM^}i-QI8W3$t%*(J@OwCXt=&-gtSLuXwx0!E zo$+(DZ>g~p*)-93tSpyTP8Uh0Y-VfIgc7BCj2(Q&6At5!uG7eLe9M%zn(n{TSQq;- zLj7;V9=&XPbRS@hZts`;tA))fcH7#88}L#-`vbJ0ayN1B>U9MiO7nsoquy~bT<(uY z#7bX_{CCBvBdXd-OrcTa`=G7khtV;PJ5MwVq|)%{qD?9=-?H_yAgKVacH|cr_qAXM z@OlBh7=PnGO*ki{cU95{H}(_QBQ-RrFT{mDZqB`*bE|38ghG0iA$@krpqHvci5*2~ z7Q!e{PQI1*7hO{vj<&tHtfD-e=Mb3@c>DEgy{!LQ1K!cJzgRul5*jTmT?oPIaRwM9Qd>%)P! z@oas1`nLD;L8ZX!`}YIB@d&aE;#aK8jQu}%zn%`ZsH#&>O~SFh7m5Q8>Pqf*5d4yh;~o z2Q}KnUo2#N2N_>nv*U~PHRI2Ah51B=H9L=U^^cBjrHjYCrB527b7pen3{$e6h`eXm z{bO~mb1OVgo zn0LJ436FWPl}p{NsaE7`>~n{021(^jt;Vy|n@3#PT`~-}X^-ZDLnaZFP`(`cX#CHX zQaLTs^Qyg~0*s)cM#j9-iPXb%nsR2u*|K>P>(|lrMXnG zd3v8x6QD@ z*!jqUw@qlikv@G|_ZGbn^s3vM;fxJ;o$u2N;c|4$9xNw(c(=6S=b&wi#>E>_MyFWt z4z*p;z~PV^&=UZRIjo`cP*t|RZ3p2l=$EMru(+V$M8A_QXFdNg?4#p3ffZYXt{RIE zt4{QFWJ1excyd$r^lcWsTUhW+%EPuv@wI#N!DF$RHP5?N?!kYa(d_?A%abzd^x#6q zJ(Wf(rW1f(MyY`Sq>3WuNb%n-c+9bM!pz;fD_4<`9GLPkX9qfoF7FT1=2Nd}uq0w9 zpB z6$IWA8$}@8U5sgmj&7=ifGR}Y>8bNjG|`giKS+K^KCi&i8o5t_{ z>wb7WugD-7*{FzWRj!f$MxY>OyHOOGAZL*VvA*-j=0&`BBFrqzA>g0O&kUzv|9vN! z>ySeD^C9^ec2#wAL!XXxPHDf3C91#7x~~8_xA`ZzT$kiPJ`*45cZW)X5Y0dO+1Jz%QgT#AsKMI2NEUJ?-Z3$tJe#Z_w*Px=zI7D6T0t#XJI zkvShVU^aq%7T&;5!xxM`M2l0{b@B0FC{-k%E;~x^8cHZ(c~2CAbSP9f|CVtV8_RpA z*7*Z%8TQtFqW}4ADv!Q!a~iqsZ>UbhCauA8e)%>SYD0UY{`g8)yHCDnJNL+&IcogU z>UJn}Oz+WqtHkunALtmraAYFf^ICeK68J{CzA1$@%pXLWx!|*N&UP?Jnj&&Dud6w? zEx!L?z)T`@OZH#roxhriJmSC@g(G~QpvuTVmZc&Z!+qVAAM`ZUMS;GHlX~^YEQwGr ze)(5syHKp5Hu7>({y>0K6FcwswvbAZRO^VEInF`g({L=de=cMH?aQ6(Wj7nMyL2?E-A;SMHLaSq25p`+Km?5OmtI| z_;iyU3SC8_W;KqM`;hF(eF+nfyeB{mK~Ivfi(T;OtQ}cM-FaNC!wSsg^|l@s;;HtQ zY&tD>1mXEaCBV-kbFvD7Ta0oDJ%EyV3~I;xM|arE@v06gUE*~Eh$vtIviUVQ*E1d4 zg&VT;gVJnWp=4w{T`4-j;HwA*lVz>W0jyVv^vaxwWwln`X9CLiLE^#o2fRXOs{9>t zsl%kH#l?3t80-fkU;3bIpgoN;$-4#l48VR_I+g(OQVjDYFFIDiG|+SMQq|M;1pdfn zT0Wn!1|qurlFcPo2#CVFsYi3)C_i=S5mbug5XIUMZlc7!(c7VtI2SZzXS-H(%Gw$A zreIS=>FJdPx0yPo9&xtA2dPS?@@X)me0k-%64ln5bgCld(Vr6l*%TLkKh#Hecz7H6 zH0LG>hqoI91%Me{An8KQ9qiSIBPhb&UvYX8*a9B`O6XZ9>!ZJl;^&xD)d_N`yjOH+ zbv1FvoV1^i!U()D6&PYL3*n+J{yso@*~SL?ZhU{anU?ddf@^F=PzU30zZ?@|yAV9y zisr4Z6}7-rFvf(2V#+9|q5qAucX0dbexCMDyrx|)MLN~$r)QP3x_135$if0w!q){z zAb|d5ZYK2QRk`;BFd!vY)G(X2?Z*0R0MAxd z?CaNo4y;NUv&N!`pMeL(--Nac{GJPyodEYj`ccf4C#%m10k&givcP=tMGWyf!Qn&S z`v7I?moESfY~fyZDq*cz@xO>n0&Ku~Gl6HpOqSQWWk^=_AMU=Z?^O zy6W;MF65P;q5EEj-3LpF1MYAc!g3(Q(fU}CYs-H;@lg5d*{6sEbV|e6 zVxzEW0?~7>X=q~hck885!K3auW+!K(59*Dws6yRm#o)y=9f8n1-N=My z0~{T08{sgyZBmLU_@-b-1*v^{H&jis1}v!`&R6WS0Mrd8sAU@mnuna1_F!x!P(#S;K zc%@603Am@Eo63*Ofpm&{TNpW0ls0UM7n9BWBqEA)L{+}LgaGYtE!h+%)_CFwB?tOrLxZ$ao&s_&Q%_+Q{)vE#3sHQS`_|?AM#s_9<(KWKl?#R@rv@#) z(=o5%;lu5}d;|_ytNj{8meWqN?Uayri}$AUpb}*K z|7rxx1VP=+TR^Hl|E=gDHN_ z4`7jzX6}N}A9{>UPTC)RTMel;??>nGXc?c+dUx@<(FsGInP^YqJ)1N#!LWTDOfLI+ z}t#0v@sb89i?IldV9CbQM)AIMp~8?fJr3uKdUF{4E#d zFu&i4j~hxCNA>WeRBKCpt+KZh@!PZ&`Io&47YcWcCv;Iy2euVQd;)gq^266whXrka z_*+hVt+FCoX^cv2YjON3G=)~e#uF!=y5(L`7z=ScmA_-KHsz8eh=!I^i1u`7a|~($ zXZ!c3ZdKcq2X52YaVycM;Wqq&KVyHE5^t6YABkPg$&}8|=u>;`84|jYlw({v)!0?% zHq(h1!m2P}r-zrD*yip3O1lqQF?_nEA4IaHf=>VwXlC`2%7coyA;%#NZyq5Qtz`Iz zGD~UK*wv02iriOrPI8#AiRy@usjy?9FXN-de!=LSQ&c(%d_sHh!fNP8B5_vrT>@PP z30gc2#w7YF1ggfEvp&F)-uibrD?d8rAUWZ|Q`FCi+zWuirW6>GU#4uCSaVa>qR43= zBd>s{LtL<~h%Va1?&s{s@<_3%HGP&5=dd!>u=v&f9YYu zuX&(Mu^X<7;)g$|pXZYKyA~9?r#;jRmY36R8h;yYa}$3xlD|wnq+@vw2Du`qhiS?E zm(*^6u*gM@jis*II08F`>k!C@x2uLTZfn&Y&P5`sw(5RwnufY^@Fjh8k?5c5_)K8E ztJwDWD$l-cpNrK5QJZy+83H;>;wMt=$V_88xb?6`ae0ZT5Xb8z%4q~hg;1r-0R#tB zFBxhW>$|$Bu&Fw|nxm?mI%ru&!1=i^p)21_z0I>jB0Kw zZ#@V~KY)1KLXT`cSxeC6hlE2T5f8Uu6welx0RFNrqkMsei~B;Jq>d27ZNsv5&t?fH zi*0rjhN=YuEW@;$j5Olzd~}-jc)SSc%T48{_Bmy@l^=~lA z`B+e3O-%}u6+>eC<4H%SJOuKp^xmz{wVXL_zFl?Rt+8KO_zSb=x6$NCFyt&@jkY4~lvWVV>zqA_Y`MJ}Kd%VZaXW>^`0ye*5A%xpG;nEVco-aW;RWsvqcwKsqJ;3#x+omZ>aDsNDrWSyT8GTbXk#m z>pE8h8(-vWi>>{kVarvt?-|igG@Pu8s!0wGul@nKO0I}`P(Kv zE8F3d1_$KAxHf47e9v;6W@44$u10Nmnrf@u=yJ-G$^Z%Er&&41EEA?Lz^Cx`EzG%| zOYrqpx|)7QzWy6QE9rD7Hd1MyXG1P8d|-q_HeCBCgG zj9DNLudh@!j#KZu0Eyfab!+R%@*9{!qRfMjv(H zsewqV1UvEL8aQz5E_1p{SE9&;VPAhd7t$kL@Laj4UOX>}|8ZgeX5tZ&1c~clfY=-B zGF)grBB9y8Yp0&2nYIg{Ss67OK*sn9%Xs}5psU8_$Q{+hV@?R;_GKodP6d#ItqYz@y}_ktyM4K@HE+969kg_L7e)6 zXaokM)n6_1lQ{)=G>kgY`}S~FfaR49%^(ikxQd+|;ET*;N>UKUGx~C3y)~MZxz<-VQJ9)kqAL9;z`O+G6i@y^;z-3+vd_T-M;sZ@w2M$2 zeQRN!XsgFyg3Csu6FRTjQj=?WawGwX5F32^U45ThF5b0u zgmUMjr44_E?7{i#+78jNqtHvMl{#;p?va`Nc}V2fW9QjHYKhQ%8pl8T4|B45=$^Ls zL`^zEfQS!vg z1t0kIr`y#TYiJ|CDQH7o^3A2y+Q2ArhjOTjMGyPM`%2Y}@I3urCZE-_ynm^~`hF`^ zV$6T79?xo-=V&;hX`Se`D(Ch4mRn~^3tgWgdTx9VdaMT)x^9KZssQ6RTW;ri{BC`c zf10Nq<6wcU%V^u%u~|KilYKNV^{NxO`3ZDEdPQo}X^KAgHDoNMOsTZFCB4-+eE1`94C|T`-a%$aQM#3mGbE1RFrTQtg zlzK_;Ad736?(*HksD zG-(Tlw}Wh{Q<}Yg{Pn3FoyEfvA>K0h?VUr>hA6g}516?3?f^5vm*7^R8$P}^*<{Ig zaKiF|cyCjKJk?v<9%q(9t)A9C+fl-bA7u)++()UZ1($w0=wbeNl|(N;qZ*>QGtfxP zNWz2-8O~K64=LH!r%tT1 z-`QLq$}@@V>D@y0Q&sPU+%cCv=n{*@QY#)4^tt366JO3DbNgLcpUPQbP;ZrtC6Npk zw?S!A(}z2?;*f&Tt4UAsx-xeW^9YvG~q7`ZTNT_}d`jE} z7uK>B_kQi5k*T^1bElh~F~Ig|X*T_e86Vu|#$cic<$zvez8$hsK4LAPRuHq_sh1RNt5(1Pu#dG+3R1MuFCMKxe zDIe+H{Upk(bzm>k;wsSOE)!!9vlD{AJj@Ajxtef&HQ0kG-E#w!%oCce6l(3gu zla7@EgnBs~wyV$yVzvHaZaP;Z|O5~A|`!3EkgbXlRg6f z%v5K|;FqWKTvcL8p)KQfZZo<)6I2}FgjQ8zW6$?@Rf@h(SKz*ws32%15WYu~$TPjj zMsp+(tdKHS@gGwD;*mKcF`RMrgkR(#{C5yd+JtlsnA)v;kCLy^I1ZyL*9$hWY9zI7 zK(eRXW1{+MBm#_co<_}5;`09>Uwe1-FzW^J{h?rH>EGP`PE|9MeDdc~d5rfyx*j4s>IHr}fvM$&xJuFYI4re0?v~57W=T({KmG^C#DaW&Q#+=~Soo}F>bqqLG z$u2))4fN{&OSrMzirK@R3Jg7aUl40Xay7=Acy z=1gU~qXS&qu;J#Im@s_Vh1A;pcvznybq)lJCp#X5Gu(ryItB7=L`-A4o)zrKc4Qu3 z=qFJHd6}g^OB-il;jN_1kmjxqX$k)xMj}vmd=tFz3TPLei&bu)?ck~U#pI`xaL6}s ztPp$DCVMd|AYc%qV~RC+i8g_Y#q>k&F)m+(+x%vX=NjPSAeHtPhq4NsI}Gvi@bC$d zvd2hhx>X*nCJ_NeLEEz_k`jairJ|dC89J{Cc*;H%AN(F=CVnVp6g$`(pJ!9+zH#qD zTS0;u%3%Y39s4)&iImR4<3otRFPXa0Hgcs?Y0?divP*qAAiVClq^) z>fS4`e>NFiewwbslEymJpmem*)YE@@vWVqy5Z3nh(5(?kotG*)k$nZUnJSL3ZNA^8 zAkE8;!b=NIaU(2vcw&e@#4E%e&l1@Rb^~8ZK%1Msdb6^K=kP1`-d*FU@D~Pw9QW1h zCUJNd^qzY6Z%^3RbbIE(_*BVPjR!P=hO}Fau+h#G!Vz2D2(TrPF1nt1W(o%;A@Qd; z5c@LLFaWod8z%dB%!wemqnJ`2D^ciraJimMS_*^RmSQdSmUQ6qzxT5u`lgM}KGE16 zmLP)meDmXbu!RAuJN;^2GLDco3Ie6gVYAD~m+>|hzpZNze+Rtn_b4#GtKIRiHbah` zxaa3{x>#8j-nBjSbd0k;ZoYw^t?of)ZB79k4GPxu1EF8sd^VvEdng(AtYh_{ioRxcTx|q{4$J*O$GI{sniY70v6Uaw7RgC=g){v&UY%&e#fDOGq z7P^>CR(LM!Bne?J>eWBs|5B(4J1^nul{h!57*ERJC%rE)giG>vbl0b5j+4ly;6o@Y zPmjRfo`eo3&u3YW;kP`F`#)v6n6LE7JNX{SdbWA*A)iL|(oY|vp>W%zyMNj}%b2Ef zYC3C^d9@4@KRtdsc}6V2sO%54v#2|mwMoOKI%}rm87uXGDssLJtWNnBR?BxX3T;fW zyH`Lz_-GbiBKsdff&HQ`dwv&@?Ma|Ef_GP$NPY}xaoje0sY zX9f<@J|_!v2SxaIVrVqB#SPA35nzL1NwnXU0+;Qax-A#|m_S&`k9l3sEISg!v9n|7 z%%6}L+=iEQp*3-=?(OUA6Zd+)#0SAY8?GX0rvd3@qjNGAb@uIB3TxT~zHM%#9aFBD zqf_M5@%IwDbshNvgK6UP)g<@R?`=5$BMM1(0lQc;9Y#-65z}45(tjt%3f7!OE1%Lw zKbh2V4Kkl-27W&+)Ji~zA!6TQD)vaHw6Y3gz{?rQ*rxaB;?bB150{lG z*FoIN&Dk?BU`@(T>72h!`8nWmtoli}UqG<--*1atcnukSF~gEo+#=4cAaB|6An;9Q z27wd+x%AalAiPmLjL}YW4GgMmA6U8f<_-;zIMny;IGyOjdf6&*!0)38J=S9`{94$$ zy$A{KpyjZ9%p1?pwfent%GQ93rvK-mnrG01yW)(EfWlD}ez!iEhaQO_#s={Fld z91O#C%1;+}Xygcq;RTl48PgU0A9=WcM;?_IChrH*6BYCLOUT+jtfHP%BM2J?_U|Ff zv!WJ-r4PT1=9d8l7~aBWE)rU#c>cb)PBeD!)`*Sp01k%hE)LGEg1P1VgN##QLNKY1 zNz%T(U(m{Y!l?zWv3Y@&xRGBkwG{hdzwKLU`gVv@g;A~%sevZiOEc)(ru~Rrdq5RU zliX7d()UJj_j8S$p?{k}=j({>n^TVR@viH5TEAA7-&(xtl3|SW(Ra7V`mVs2Me6o| zXVUCPyWEdgHkcxP%1{&7z+~*P>T(Q(y_f=AAKSv7hrJS(J#G$*3IYXe5qx_Vd|Bgo z{J~0{IGA|JY%5!dmix;1@;EJz=CYA>$=@DcAjlfgyx~DKog4vfLFyc5`c%AK4hc_q*l#?6kCV(GCC9|O!40CZ zR^Pd_AG$V2dB=-sE-)ALO|Jmr7YeOZg%jH&hbIqn7YP_!LS#m`ozA1>aA&Sya-> zd~4;w4XdQ!3bfYiSxN*UGW~fa&Wq7Pu40k>FH8eu#>siRm8Tv87dD9er0+E$CFIt# zDhE;@$jUTN>U0@8RPX*?kZ#CF(j7As0Yhk|VM0tSe8(YHAz4aDu(S9kjG5X=jFI)s ziKK1d;Tz}cRegF(KS>Te74!9SjzoSSF9&0xYB; z2SKfKKA8OBfjL;y1biG>r%S@kE@j*wD&gnHhpAP3FPhZeeK(r5L0_GSj`OGZxCOlu zVi>m7Z|hHgdoq3oX581O`)-tTN1OHE_o+!ttAG~Ra`*cwvjcjCHdzI)uEmeTi!`&p z@Mze0`ss?eH5-_e&profeFU-it~qeWz01U%b6LY^5_2M(RYSF!$=boaL@-8g{iq|4 z75%ek_nbP4ecd*cgZsXfJmz!UN<}EkwaHOl-z<~FzdqKHGc{)v46%D&IA`HaOHJJiO#iPEiiJ%WwXi#zxt+2i9JzHV<2) z7xeWoZ`fRhvEHGZgRMVX6R;hA7}OAz3-XCN!U6sx}(kTr|_q@3pZE<2bS|;k?>;M4&2*PLn?!HXaj&yjIIO`sECKduZU) zhZcDpcf>F+sPjKeol%OUxVmxas&n~?{`qNB*wAVpv=!PUZ=S8Kw!8nZNR!6qJms6^ z!aXE|mr&rABFuy_sXyN@PQ9NMdmz( zRh;Fe^0&guKlk7wI+oU>NfmszcH!B7w{qRJP=+w@Vd!{mlTB*N*`%_CVPkbjgw`;i z>-MKZ?FkIY=EKNN^Lj^*%5^d%?d0L!%R4|R*iJv{2$R680S;Hkk+6l!jUMZn(p zuR})469?+SK4g|&%AYR1QDtDfxq+A+y4)Db>oT!1<-Is>Lx}F@9na|UQnSGy(jPt_ zNw#>6*B|Yeqk0PM8;CLJ*pu+NTL+NQ$djMGRx&T~qPNLU`+mGTeQ8EF^)JSHXu>$f z0k3prHzvF|-pdBk=|xhz#H!jh{DYg9CjYGwh`!+Kx#a5;0M(cD%CTaXwr*H|Js4_0>w3R@`maE*w z>*w8A*mUPg{fj5K)Ia^E(J-s^eT{Tow@q> z&ZL?c0UINWtPnfi5RUggVTlzm^d|kA;4G+(CfcG1Bf{KE4}IC0BR7>6_z!HRTqOIv zscqArF>88ZKG}H$;9i#{b;wr{waaCq=L4@vljwF@c|^SzqaLV-zA@#@XjYRajDM(( zGt_-wbEKVIwV%s&CHIdafAhD}rGMJAs_fsqwEB;8+YERhkg2$!$xj>vt<9b@v>)se zQteuJs+*3kG*OexMV`CyN;dVMalAmQgld|S|K(45p2L|SwS<-gGUS~&hpA%!8q&c5 zWKMMk`_Gw>!xM&o{JUGXj2Vvez$H_GO?FBSN=y-B^JDq`>AUP*J_(ccNf+;-I__E6 z^0{XA^PaMvnKRNr(EDZVhoU%~Kkw(E^Ksks?g?@`9NCuIJ0x=j7QMj}}`&#ISbD~gu{;%{rPeQ=RVNBS$5}-A+ zD|N|iQF%&r+lFn0H!8OD;HysHx(&^u0F@di|JkNlZt^RnQU@QkcXW3|o#3?MZ+HEd zm>h!m#wVF1iDdLfQcU>J5@3E8FkQDxsj{nhzp&`S|E+{YD!xH%A~^bEaV_Lk_&=N` zgrfZn8OeU+sz_E`CdwZboUUpRKb%iF^uyBI<}pBoeDZarWu?AmR#=x!h7mU;H^v56 zgg{gY5Gm@~Q4;&E;o@;{GCQ?3(>!u<*R~Mau1E!Rn`-P7&q35yNSbVjqB7FtgqmxZ z!v-&p{Tq_5kBwyob+R;NC52h=r3ck6eyjtDqzp>xZ;C27IpXRm7Iht{2Y68g*y4s7 zVk>Z75-6<5XrI;LwkvshGYrY1UgAI$$we+ib-v9?&R)P*@D;f#H9-WNi?9s(F7O%I z#y{($Vxo?J5u22akzwr|x5D*ox-EUtQfog}*CXc4O^|$TUW!WTa zWw}12yi^3K4h@d;ZnEOjB6ZRCb*B?1))^rPpALVsaP}M$)jPBlBqOARCBDndC zu~Z0v7xf$TK%}%dmK$y?=Ju>;)!feNcZV_8ER4%`1PfAetYQ9V{GFb6k*qHn!vfkz z%JT0VS+S*LHfFTQ8uUZT7_28EnvJ6)7G;CiIB732xRa)T?iw4h92;2DlQHERvTRf0 zE;_?Irm$=~?)d)$U?Kt{_3vkG28Ds6;YEhj;Es9hNxd#!HnlGS7F}QMAmo|`gfU~)w4UNXvCS{R14YC za6r$lgutU&GA~fW;7?4ratzG`x{HpG>aQB_vgwlURxOEnE3*n2;l<8JtO3BxNeh8{@@^4T8;WfCb*~~$ zghZ=&RF70^zQ?|H&@!WG-u%K6U-bS*-zDYS4<3Styb|7ljC+xF6SLI)Pe9U|@UfX; zR^TSb%)ZgVl~@KT!A|sd%ptVzkx@2XvTL$9MR(5_Ecqh!D4U0#KC4atOZK4$8#lu2SvnT+O;GREYMv4mwgi$vrQIc`}_g^(t~ zHWW)u=1>lE$}4?+um9)w^Yi7o@9TQ*`?;^@dVZyOQ<%bH6{va;;iQ*NsrzE)NAkkj zky-j`yxICY?CfR`<<`d#whSfwWhwdR;;Q3JbOZFG2=v-0=3a}D%^pDwRL2wNSo>03 z09`hI`=fdqda$U(`Q6^i!}zu1Zyjq6Z^gVjpTsSO{zGKU%>5|83cHTx0r%;R`uDEk z_gAXIfd-{gQ|K8vlvs&yjaO+6fJebHNW+>a_@GH7LeS8$L~PaZ%q1uyF^Cm`Ut=N^ zNRrE#VH3zY!8Y*X(HvOdgf9%aoYSnH0Orcf0(KsvH*?jA@;#O(3Z6O<_W|>Toun$P zUphvUxnOc2UHaVH72`5D84lgy7Q>Zy(eh;+YCf{&CGR2L`NKT26+O?)>d5Zy-z%|5w{KQ{i;msv(ma6CDu*<2BM;@~smHGv?kmhA zI>eAniv$`n_fHqd3D9S?u~qAWjI-4=DVql%rqT~ypMAYU<|00Pr0Hn%X2kK z=IEwBXB=eiaA0v~06VQr$T$`F0r#w1;Ca%mWCbYDo?>@ouKhO9>-kgB#d()9UL}rL zvDIvZ+pRE$Q9k^f?_(l}kBod@-6D3o3ZyL>Tm$TJQFvYtPuwHU3#$rdpSFC&8Fb~( zKOidImH@bTbEYz>KeuUv+VV{#yKWXB$T37puJsX_L;5u8y3XJ#$kSpbR1%$2v<`X|Nx>(kw!Pa6 z=~&q0%cBJE>t~Qgnf5GwM~Vw|jLas^XwjQ9YEuK`Ll-nR9)Sce>+D?o7qAL3af)=< zn}mm6V{f*xwaIm!r^H&Y#fS3S3sSgw&=5Ln>lOULmjF$MVDz27li9dM*2p*F7ZK2X_;-NBNP(j*A@9V|V4#Ej)s7q4#qPUi+_R{K-m4m(r}d;c;=6q7 zH&!7e*js4SZvKTU=J9y@5>2`r$j>U&>KVURpE`psCmN59MCdKr4)xCgFJZ(Hq~ zN$P9Ti>?9f$j^ZhJ!ihLBGn#Ap}rU?(IR~+KZLdy8u9!Zy2w$Tu%P0SXwwTO;qOBA zkAJdq*9~~nI~EL&*hN|vv@G@jGfm$1NSM`a)*2)-Ud`lNKQ%h5v+wvalbqOjeXh7c zwgrB@vY&0`DzWIc4sJnU*8}HX=^vXy{qm6czM)-SBJq-nA{b4r8wQxa(5w?=-6 z{TP#%c=D&{BoyR*lrpDDfrSmu96ak@>tmq!DY!K4Qtmyr<|F^qspY3!#cyGGjtwFE|S2bth2>q`AvjUGGS<&*mE_}#;F=lL@G-iP91fxWWH7y8s>)Ps{s1G5(jXo(ECRsR^-Um&bpXUC3I|{f0+R)6}e?+^4lSv;udRJSKOg zPOHEGtMb}*`8}z8Nh!zUvPHHXK<}hy_BNrD#iAMpL|aU=`g|DAvozj>;Rt zkYz^YE*~XbG_MPLBuD&SJf1mtbGoLx_|4QHC2G)!9zz|jd?l;iKR2-g@N)0psj{04 zrI@&6=t_N)0`(+L6{C|d;}5Y?0j53$HoLMp2|@fMs{nb{GjU9~CnkKt#Pe_xC8*sr zH;(hw4hvV~jg1U-_(rec7&UpyQ(%Ja3E% zJ9rb9v(rZILszZ{_uSeU>@Hp@d(2kX@nguo@&i*X&YcJOOjg>@^@3rorIboH%yG_b zoQVK4C4Rn}=RV0J1WP(#jj*$sHR=F+0(G2Rk$mK4FP{6Qr4Y>)({!)kaNoaR)TTek zGt_c=w*_l^zMVxnSBdsii? zim~4o_rC_L{hun; kzxR*--__s3AnrB~4v~yRnZhsa$Y6Wytj<|hntR0l7hM_`wg3PC literal 0 HcmV?d00001 diff --git a/projects/mtg/bin/Res/player/momir.txt b/projects/mtg/bin/Res/player/momir.txt new file mode 100644 index 000000000..3b0c041f0 --- /dev/null +++ b/projects/mtg/bin/Res/player/momir.txt @@ -0,0 +1,5 @@ +Swamp *12 +Island *12 +Plains *12 +Mountain *12 +Forest *12 \ No newline at end of file diff --git a/projects/mtg/include/AIMomirPlayer.h b/projects/mtg/include/AIMomirPlayer.h new file mode 100644 index 000000000..67acd1815 --- /dev/null +++ b/projects/mtg/include/AIMomirPlayer.h @@ -0,0 +1,17 @@ +#ifndef _AIMOMIRPLAYER_H_ +#define _AIMOMIRPLAYER_H_ + +#include "AIPlayer.h" + + +class AIMomirPlayer:public AIPlayerBaka{ +public: + AIMomirPlayer(MTGPlayerCards * _deck, char * file, char * avatarFile); + int getEfficiency(AIAction * action); + int momir(); + int computeActions(); + static MTGAbility * momirAbility; + static MTGAbility * getMomirAbility(); +}; + +#endif \ No newline at end of file diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index 436b8048a..c93689fc8 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -71,6 +71,7 @@ class AIPlayer: public Player{ int selectAbility(); int createAbilityTargets(MTGAbility * a, MTGCardInstance * c, map * ranking); int useAbility(); + virtual int getEfficiency(AIAction * action); }; @@ -84,7 +85,7 @@ class AIPlayerBaka: public AIPlayer{ AIPlayerBaka(MTGPlayerCards * _deck, char * deckFile, char * avatarFile); virtual int Act(float dt); void initTimer(); - int computeActions(); + virtual int computeActions(); }; class AIPlayerFactory{ diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index 3a24f5214..0ff6fab21 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -10,6 +10,7 @@ #include "GuiLayers.h" #include "ActionElement.h" #include "SimpleMenu.h" +#include "MTGAbility.h" class GuiLayer; class Targetable; @@ -36,6 +37,7 @@ class ActionLayer: public GuiLayer, public JGuiListener{ void ButtonPressed(int controllerid, int controlid); void doReactTo(int menuIndex); TargetChooser * getCurrentTargetChooser(); + MTGAbility * getAbility(int type); }; diff --git a/projects/mtg/include/GameApp.h b/projects/mtg/include/GameApp.h index 3eccd69da..5f3f1d110 100644 --- a/projects/mtg/include/GameApp.h +++ b/projects/mtg/include/GameApp.h @@ -41,6 +41,9 @@ #define PLAYER_TYPE_TESTSUITE 2 +#define GAME_TYPE_CLASSIC 0 +#define GAME_TYPE_MOMIR 1 + class MTGAllCards; class TexturesCache; @@ -63,6 +66,7 @@ class GameApp: public JApp public: int players[2]; MTGAllCards * collection; + int gameType; TexturesCache * cache; GameApp(); diff --git a/projects/mtg/include/GameOptions.h b/projects/mtg/include/GameOptions.h index 745042bc5..f76c34824 100644 --- a/projects/mtg/include/GameOptions.h +++ b/projects/mtg/include/GameOptions.h @@ -9,6 +9,7 @@ using std::string; #define OPTIONS_MUSICVOLUME "musicVolume" #define OPTIONS_SFXVOLUME "sfxVolume" #define OPTIONS_DIFFICULTY_MODE_UNLOCKED "prx_handler" //huhu +#define OPTIONS_MOMIR_MODE_UNLOCKED "prx_rimom" //haha #define OPTIONS_DIFFICULTY "difficulty" // WALDORF - added diff --git a/projects/mtg/include/GameStateDuel.h b/projects/mtg/include/GameStateDuel.h index cc14b0b21..1c34d4be5 100644 --- a/projects/mtg/include/GameStateDuel.h +++ b/projects/mtg/include/GameStateDuel.h @@ -33,7 +33,9 @@ class GameStateDuel: public GameState, public JGuiListener JQuad * unlockedQuad; JTexture * unlockedTex; int isDifficultyUnlocked(); + int isMomirUnlocked(); void loadPlayer(int playerId, int decknb = 0, int isAI = 0); + void loadPlayerMomir(int playerId, int isAI); public: GameStateDuel(GameApp* parent); virtual ~GameStateDuel(); diff --git a/projects/mtg/include/GameStateMenu.h b/projects/mtg/include/GameStateMenu.h index a488a3756..ff0d9147d 100644 --- a/projects/mtg/include/GameStateMenu.h +++ b/projects/mtg/include/GameStateMenu.h @@ -11,6 +11,8 @@ class GameStateMenu: public GameState, public JGuiListener private: JGuiController* mGuiController; SimpleMenu* subMenuController; + SimpleMenu* gameTypeMenu; + int hasChosenGameType; JQuad * mIcons[10]; JTexture * mIconsTexture; JTexture * bgTexture; diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index 6e1987218..852aa04ba 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -60,12 +60,16 @@ class MTGAbility: public ActionElement{ virtual int resolve(){return 0;}; /*Poor man's casting */ + /* Todo replace that crap with dynamic casting */ enum { UNKNOWN = 0, MANA_PRODUCER = 1, MTG_ATTACK_RULE = 2, DAMAGER = 3, STANDARD_REGENERATE = 4, + PUT_INTO_PLAY = 5, + MOMIR = 6, + MTG_BLOCK_RULE = 7, }; }; diff --git a/projects/mtg/include/MTGGameZones.h b/projects/mtg/include/MTGGameZones.h index 1fa83811b..e57bc494b 100644 --- a/projects/mtg/include/MTGGameZones.h +++ b/projects/mtg/include/MTGGameZones.h @@ -85,6 +85,7 @@ class MTGPlayerCards { MTGInPlay * inPlay; MTGStack * stack; MTGRemovedFromGame * removedFromGame; + MTGGameZone * garbage; MTGAllCards * collection; diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 3b782e519..10a18bab7 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -81,62 +81,6 @@ OutputDebugString("Receive5\n"); }; -/* -class MTGPersistRule:public ListMaintainerAbility{ - public: - MTGPersistRule(int _id):ListMaintainerAbility(_id){}; - - virtual void Update(float dt){ - map::iterator it; - - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCardInstance * card = ((*it).first); - Player * p = card->controller(); - if (p->game->graveyard->hasCard(card)){ - p->game->putInZone(card, p->game->graveyard, p->game->hand); - Spell * spell = NEW Spell(card); - p->game->putInZone(card, p->game->hand, p->game->stack); - spell->resolve(); - delete spell; - card->counters->addCounter(-1,-1); - } - } - - // Dirtiest Code Ever, we remove the counters here - - for (int i = 0; i < 2; i++){ - Player * p = game->players[i]; - MTGGameZone * zones[] = {p->game->graveyard, p->game->hand, p->game->library, p->game->removedFromGame}; - for (int j = 0; j < 5; j++){ - MTGGameZone * zone = zones[j]; - for (int k=0; k < zone->nb_cards; k++){ - zone->cards[k]->counters->init(); - } - } - } - - - ListMaintainerAbility::Update(dt); - } - - int canBeInList(MTGCardInstance * card){ - if (card->basicAbilities[Constants::PERSIST] && !card->counters->hasCounter(-1,-1) ){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("yay, persist !\n"); -#endif - return 1; - } - return 0; - } - - int added(MTGCardInstance * card){return 1;} - - int removed(MTGCardInstance * card){return 0;} - - int testDestroy(){return 0;} -}; - -*/ /* * Rule 420.5e (Legend Rule) @@ -176,4 +120,18 @@ class MTGLegendRule:public ListMaintainerAbility{ int testDestroy(){return 0;} }; + +class MTGMomirRule:public MTGAbility{ +public: + int alreadyplayed; + MTGAllCards * collection; + MTGCardInstance * genRandomCreature(int convertedCost); + int testDestroy(); + void Update(float dt); + MTGMomirRule(int _id, MTGAllCards * _collection); + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); + int reactToClick(MTGCardInstance * card); + const char * getMenuText(){return "Momir";} +}; + #endif diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index ac3d6759f..5846bee92 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -22,7 +22,7 @@ class ManaCost{ static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL); void init(); void x(); - ManaCost(int _cost[], int nb_elems); + ManaCost(int _cost[], int nb_elems = 1); ManaCost(); ~ManaCost(); ManaCost(ManaCost * _manaCost); diff --git a/projects/mtg/src/AIMomirPlayer.cpp b/projects/mtg/src/AIMomirPlayer.cpp new file mode 100644 index 000000000..883f3d220 --- /dev/null +++ b/projects/mtg/src/AIMomirPlayer.cpp @@ -0,0 +1,192 @@ +#include "../include/config.h" +#include "../include/AIMomirPlayer.h" +#include "../include/CardDescriptor.h" +#include "../include/DamageResolverLayer.h" +#include "../include/DamagerDamaged.h" +#include "../include/AIStats.h" +#include "../include/AllAbilities.h" + + +MTGAbility * AIMomirPlayer::momirAbility = NULL; + +AIMomirPlayer::AIMomirPlayer(MTGPlayerCards * _deck, char * file, char * avatarFile): AIPlayerBaka(_deck,file, avatarFile){ +// TODO count min and max number of mana (should probably be part of the gameobserver so that human players don't make mistakes) + momirAbility = NULL; +} + +int AIMomirPlayer::getEfficiency(AIAction * action){ + + +int efficiency = AIPlayerBaka::getEfficiency(action); +if (efficiency < 15) return 0; +GameObserver * g = GameObserver::GetInstance(); +if (g->getCurrentGamePhase() < Constants::MTG_PHASE_FIRSTMAIN) return 0; + return efficiency; +} + +MTGAbility * AIMomirPlayer::getMomirAbility(){ + if (momirAbility) return momirAbility; + + GameObserver * g = GameObserver::GetInstance(); + momirAbility = g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR); + return momirAbility; +} + +int AIMomirPlayer::momir(){ + if (!game->hand->nb_cards) return 0; //nothing to discard :/ + getPotentialMana(); + int converted = potentialMana->getConvertedCost(); + int efficiency = 100; + int chance = 1 + (rand() % 100); + if (converted == 5) efficiency = 5 ; //Strategy: skip 5 drop + if (converted == 7) efficiency = 50; //Strategy: 7 drops have bad upkeep costs and the AI doesn't handle those right now... + if (converted > 8 ) converted = 8; + if (converted == 8) efficiency = 100 - game->inPlay->nb_cards; + + if (efficiency >= chance){ + int _cost[] = {Constants::MTG_COLOR_ARTIFACT,converted}; + ManaCost * cost = NEW ManaCost(_cost); + tapLandsForMana(potentialMana,cost); + delete cost; + MTGAbility * ability = getMomirAbility(); + MTGCardInstance * card = game->hand->cards[0]; + if (ability->isReactingToClick(card,cost)){ + AIAction * a = NEW AIAction(ability,card); + clickstream.push(a); + return 1; + } + } + return 0; +} + +int AIMomirPlayer::computeActions(){ +//Part of the strategy goes here. When should we put a land into play ? +/* +Another gift from Alex Majlaton on my first day playing Momir, and it has served me well ever since. It goes a little something like this: (a) if you are on the play, hit your Two through Four, skip your Five, and then hit all the way to Eight; (b) if you are on the draw and your opponent skips his One, you make Two through Eight; (c) if you are on the draw and your opponent hits a One, you match him drop-for-drop for the rest of the game. + +You skip your Five on the play because it is the weakest drop. There are plenty of serviceable guys there, but very few bombs compared to other drops +the general rule is this: if you want to get to Eight, you have to skip two drops on the play and one drop on the draw. +*/ +GameObserver * g = GameObserver::GetInstance(); + Player * p = g->currentPlayer; + if (!(g->currentlyActing() == this)) return 0; + if (chooseTarget()) return 1; + int currentGamePhase = g->getCurrentGamePhase(); + if (g->isInterrupting == this){ // interrupting + selectAbility(); + return 1; + }else if (p == this && g->mLayers->stackLayer()->count(0,NOT_RESOLVED) == 0){ //standard actions + CardDescriptor cd; + MTGCardInstance * card = NULL; + //No mana, try to get some + getPotentialMana(); + + + switch(currentGamePhase){ + case Constants::MTG_PHASE_FIRSTMAIN: + if (canPutLandsIntoPlay && (potentialMana->getConvertedCost() <8 || game->hand->nb_cards > 1) ){ + //Attempt to put land into play + cd.init(); + cd.setColor(Constants::MTG_COLOR_LAND); + card = cd.match(game->hand); + if (card){ + MTGAbility * putIntoPlay = g->mLayers->actionLayer()->getAbility(MTGAbility::PUT_INTO_PLAY); + AIAction * a = NEW AIAction(putIntoPlay,card); //TODO putinplay action + clickstream.push(a); + return 1; + } + } + momir(); + return 1; + break; + case Constants::MTG_PHASE_SECONDMAIN: + selectAbility(); + return 1; + break; + default: + return AIPlayerBaka::computeActions(); + break; + } + }else{ + return AIPlayerBaka::computeActions(); + } +} + +/* +int AIPlayerBaka::computeActions(){ + GameObserver * g = GameObserver::GetInstance(); + Player * p = g->currentPlayer; + if (!(g->currentlyActing() == this)) return 0; + if (chooseTarget()) return 1; + int currentGamePhase = g->getCurrentGamePhase(); + if (g->isInterrupting == this){ // interrupting + selectAbility(); + return 1; + }else if (p == this && g->mLayers->stackLayer()->count(0,NOT_RESOLVED) == 0){ //standard actions + CardDescriptor cd; + MTGCardInstance * card = NULL; + switch(currentGamePhase){ + case Constants::MTG_PHASE_FIRSTMAIN: + case Constants::MTG_PHASE_SECONDMAIN: + if (canPutLandsIntoPlay){ + //Attempt to put land into play + cd.init(); + cd.setColor(Constants::MTG_COLOR_LAND); + card = cd.match(game->hand); + if (card){ + AIAction * a = NEW AIAction(card); + clickstream.push(a); + return 1; + } + } + + //No mana, try to get some + getPotentialMana(); + if (potentialMana->getConvertedCost() > 0){ + + + //look for the most expensive creature we can afford + nextCardToPlay = FindCardToPlay(potentialMana, "creature"); + //Let's Try an enchantment maybe ? + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "enchantment"); + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "artifact"); + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "instant"); + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "sorcery"); + if (nextCardToPlay){ +#if defined (WIN32) || defined (LINUX) + char buffe[4096]; + sprintf(buffe, "Putting Card Into Play: %s", nextCardToPlay->getName()); + OutputDebugString(buffe); +#endif + + tapLandsForMana(potentialMana,nextCardToPlay->getManaCost()); + AIAction * a = NEW AIAction(nextCardToPlay); + clickstream.push(a); + return 1; + }else{ + selectAbility(); + } + }else{ + selectAbility(); + } + break; + case Constants::MTG_PHASE_COMBATATTACKERS: + chooseAttackers(); + break; + default: + selectAbility(); + break; + } + }else{ + switch(currentGamePhase){ + case Constants::MTG_PHASE_COMBATBLOCKERS: + chooseBlockers(); + break; + default: + break; + } + return 1; + } + return 1; +}; +*/ diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 3abcacb6e..6a7ae2193 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -121,6 +121,10 @@ ManaCost * AIPlayer::getPotentialMana(){ } +int AIPlayer::getEfficiency(AIAction * action){ + return action->getEfficiency(); +} + int AIAction::getEfficiency(){ //TODO add multiplier according to what the player wants if (efficiency != -1) return efficiency; @@ -129,6 +133,7 @@ int AIAction::getEfficiency(){ ActionStack * s = g->mLayers->stackLayer(); Player * p = g->currentlyActing(); if (s->has(ability)) return 0; + if (ability->cost && !(ability->cost->isExtraPaymentSet())) return 0; //Does not handle abilities with sacrifice yet switch (ability->aType){ case MTGAbility::DAMAGER: { @@ -226,7 +231,7 @@ int AIPlayer::selectAbility(){ OutputDebugString("We have a winner\n"); AIAction * a = ranking.begin()->first; int chance = 1 + rand() % 100; - if (a->getEfficiency() < chance){ + if (getEfficiency(a) < chance){ a = NULL; }else{ OutputDebugString("We REALLY have a winner\n"); @@ -262,6 +267,8 @@ int AIPlayer::effectBadOrGood(MTGCardInstance * card){ return BAKA_EFFECT_DONTKNOW; } + + int AIPlayer::chooseTarget(TargetChooser * tc){ Targetable * potentialTargets[50]; int nbtargets = 0; @@ -393,24 +400,25 @@ int AIPlayer::chooseBlockers(){ cd.setType("Creature"); cd.tapped = -1; MTGCardInstance * card = NULL; + GameObserver * g = GameObserver::GetInstance(); while((card = cd.nextmatch(game->inPlay, card))){ - GameObserver::GetInstance()->cardClick(card); + g->cardClick(card); + if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); int set = 0; while(!set){ if (!card->defenser){ - set = 1; + set = 1; }else{ - MTGCardInstance * attacker = card->defenser; - map::iterator it = opponentsToughness.find(attacker); - if ( it == opponentsToughness.end()){ - opponentsToughness[attacker] = attacker->toughness; - it = opponentsToughness.find(attacker); - } - if (opponentsToughness[attacker] > 0 && getStats() && getStats()->isInTop(attacker,3,false)){ - opponentsToughness[attacker]-= card->power; - set = 1; - }else{ - GameObserver * g = GameObserver::GetInstance(); + MTGCardInstance * attacker = card->defenser; + map::iterator it = opponentsToughness.find(attacker); + if ( it == opponentsToughness.end()){ + opponentsToughness[attacker] = attacker->toughness; + it = opponentsToughness.find(attacker); + } + if (opponentsToughness[attacker] > 0 && getStats() && getStats()->isInTop(attacker,3,false)){ + opponentsToughness[attacker]-= card->power; + set = 1; + }else{ g->cardClick(card); if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); } @@ -421,7 +429,7 @@ int AIPlayer::chooseBlockers(){ while((card = cd.nextmatch(game->inPlay, card))){ if (card->defenser && opponentsToughness[card->defenser] > 0){ while (card->defenser){ - GameObserver * g = GameObserver::GetInstance(); + g->cardClick(card); if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); } @@ -430,7 +438,6 @@ int AIPlayer::chooseBlockers(){ card = NULL; while((card = cd.nextmatch(game->inPlay, card))){ if(!card->defenser){ - GameObserver * g = GameObserver::GetInstance(); g->cardClick(card); if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); int set = 0; @@ -440,7 +447,6 @@ int AIPlayer::chooseBlockers(){ }else{ MTGCardInstance * attacker = card->defenser; if (opponentsToughness[attacker] <= 0 || (card->toughness <= card->defenser->power && opponentForce*2 defenser->nbOpponents()>1){ - GameObserver * g = GameObserver::GetInstance(); g->cardClick(card); if (g->mLayers->actionLayer()->menuObject) g->mLayers->actionLayer()->doReactTo(0); }else{ diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index af83bfbd3..b8e198922 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -4,6 +4,16 @@ #include "../include/Targetable.h" #include "../include/WEvent.h" +MTGAbility* ActionLayer::getAbility(int type){ + for (int i = 1; i < mCount; i++){ + MTGAbility * a = ((MTGAbility *)mObjects[i]); + if (a->aType == type){ + return a; + } + } + return NULL; +} + int ActionLayer::unstopableRenderInProgress(){ for (int i=0;istackLayer()->garbageCollect(); //clean stack history for this turn; mLayers->actionLayer()->Update(0); + for (int i=0; i < 2; i++){ + delete (players[i]->game->garbage); + players[i]->game->garbage = NEW MTGGameZone(); + } return nextGamePhase(); } diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index 44acb5304..e82798ba0 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -3,9 +3,10 @@ #include "../include/GameOptions.h" #include "../include/utils.h" #include "../include/AIPlayer.h" +#include "../include/AIMomirPlayer.h" #include "../include/PlayerData.h" #include "../include/DeckStats.h" - +#include "../include/MTGRules.h" #ifdef TESTSUITE #include "../include/TestSuiteAI.h" @@ -89,18 +90,18 @@ void GameStateDuel::Start() for (int i = 0; i<2; i ++){ if (mParent->players[i] == PLAYER_TYPE_HUMAN){ if (!deckmenu){ - decksneeded = 1; - deckmenu = NEW SimpleMenu(DUEL_MENU_CHOOSE_DECK, this, mFont, 35, 25, "Choose a Deck"); - char buffer[100]; - for (int j=1; j<6; j++){ - sprintf(buffer, RESPATH"/player/deck%i.txt",j); - std::ifstream file(buffer); - if(file){ - deckmenu->Add(j, GameState::menuTexts[j]); - file.close(); - decksneeded = 0; - } - } + decksneeded = 1; + deckmenu = NEW SimpleMenu(DUEL_MENU_CHOOSE_DECK, this, mFont, 35, 25, "Choose a Deck"); + char buffer[100]; + for (int j=1; j<6; j++){ + sprintf(buffer, RESPATH"/player/deck%i.txt",j); + std::ifstream file(buffer); + if(file){ + deckmenu->Add(j, GameState::menuTexts[j]); + file.close(); + decksneeded = 0; + } + } } } } @@ -110,6 +111,19 @@ void GameStateDuel::Start() } +void GameStateDuel::loadPlayerMomir(int playerId, int isAI){ + char * deckFile = RESPATH"/player/momir.txt"; + char * deckFileSmall = "momir"; + MTGDeck * tempDeck = NEW MTGDeck(deckFile, NULL, mParent->collection); + deck[playerId] = NEW MTGPlayerCards(mParent->collection,tempDeck); + if (!isAI){ //Human Player + mPlayers[playerId] = NEW HumanPlayer(deck[playerId],deckFileSmall); + }else{ + mPlayers[playerId] = NEW AIMomirPlayer(deck[playerId],deckFile,""); + } + delete tempDeck; +} + void GameStateDuel::loadPlayer(int playerId, int decknb, int isAI){ if (decknb){ if (!isAI){ //Human Player @@ -197,7 +211,14 @@ void GameStateDuel::Update(float dt) mParent->SetNextState(GAME_STATE_DECK_VIEWER); break; case DUEL_STATE_CHOOSE_DECK1: - if (mParent->players[0] == PLAYER_TYPE_HUMAN) + if (mParent->gameType == GAME_TYPE_MOMIR){ + for (int i = 0; i < 2; i++){ + int isAI = 1; + if (mParent->players[i] == PLAYER_TYPE_HUMAN) isAI = 0; + loadPlayerMomir(i, isAI); + } + mGamePhase = DUEL_STATE_PLAY; + }else if (mParent->players[0] == PLAYER_TYPE_HUMAN) deckmenu->Update(dt); #ifdef TESTSUITE else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){ @@ -280,13 +301,19 @@ void GameStateDuel::Update(float dt) case DUEL_STATE_PLAY: //Stop the music before starting the game if (GameApp::music){ - JSoundSystem::GetInstance()->StopMusic(GameApp::music); - SAFE_DELETE(GameApp::music); + JSoundSystem::GetInstance()->StopMusic(GameApp::music); + SAFE_DELETE(GameApp::music); } if (!game){ - GameObserver::Init(mPlayers, 2); - game = GameObserver::GetInstance(); - game->startGame(); + GameObserver::Init(mPlayers, 2); + game = GameObserver::GetInstance(); + game->startGame(); + if (mParent->gameType == GAME_TYPE_MOMIR){ + game->addObserver(NEW MTGMomirRule(-1, mParent->collection)); + for (int i = 0; i < 2; i++){ + game->players[i]->life+=4; + } + } } game->Update(dt); if (game->gameOver){ @@ -303,6 +330,16 @@ void GameStateDuel::Update(float dt) unlockedQuad = NEW JQuad(unlockedTex, 2, 2, 396, 96); GameOptions::GetInstance()->values[OPTIONS_DIFFICULTY_MODE_UNLOCKED] = GameOption(1); GameOptions::GetInstance()->save(); + }else{ + unlocked = isMomirUnlocked(); + if (unlocked){ + unlockedTex = JRenderer::GetInstance()->LoadTexture("graphics/momir_unlocked.png", TEX_TYPE_USE_VRAM); + unlockedQuad = NEW JQuad(unlockedTex, 2, 2, 396, 96); + GameOptions::GetInstance()->values[OPTIONS_MOMIR_MODE_UNLOCKED] = GameOption(1); + GameOptions::GetInstance()->save(); + } + } + if (unlocked){ JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/bonus.wav"); if (sample) JSoundSystem::GetInstance()->PlaySample(sample); } @@ -496,4 +533,11 @@ int GameStateDuel::isDifficultyUnlocked(){ } } return 0; +} + +int GameStateDuel::isMomirUnlocked(){ + if (GameOptions::GetInstance()->values[OPTIONS_MOMIR_MODE_UNLOCKED].getIntValue()) return 0; + Player *p = mPlayers[0]; + if (p->game->inPlay->countByType("land") == 8) return 1; + return 0; } \ No newline at end of file diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index e4f289e45..58f715e19 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -47,7 +47,9 @@ enum SUBMENUITEM_2PLAYER, SUBMENUITEM_DEMO, SUBMENUITEM_CANCEL, - SUBMENUITEM_TESTSUITE + SUBMENUITEM_TESTSUITE, + SUBMENUITEM_MOMIR, + SUBMENUITEM_CLASSIC, }; @@ -55,6 +57,7 @@ GameStateMenu::GameStateMenu(GameApp* parent): GameState(parent) { mGuiController = NULL; subMenuController = NULL; + gameTypeMenu = NULL; mIconsTexture = NULL; //bgMusic = NULL; timeIndex = 0; @@ -118,6 +121,7 @@ void GameStateMenu::Destroy() { SAFE_DELETE(mGuiController); SAFE_DELETE(subMenuController); + SAFE_DELETE(gameTypeMenu); SAFE_DELETE(mIconsTexture); for (int i = 0; i < 10 ; i++){ @@ -148,6 +152,9 @@ void GameStateMenu::Start(){ JSoundSystem::GetInstance()->StopMusic(GameApp::music); SAFE_DELETE(GameApp::music); } + + hasChosenGameType = 1; + if (GameOptions::GetInstance()->values[OPTIONS_MOMIR_MODE_UNLOCKED].getIntValue()) hasChosenGameType =0; } @@ -176,13 +183,7 @@ int GameStateMenu::nextCardSet(){ void GameStateMenu::End() { - //mEngine->EnableVSync(false); - // if (bgMusic) - // { - //JSoundSystem::GetInstance()->StopMusic(bgMusic); - //SAFE_DELETE(bgMusic); - // } JRenderer::GetInstance()->EnableVSync(false); } @@ -190,14 +191,6 @@ void GameStateMenu::End() void GameStateMenu::Update(float dt) { - /* - if (GameApp::music){ - if (mVolume < 2*GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME]){ - mVolume++; - JSoundSystem::GetInstance()->SetVolume(mVolume/2); - } - } - */ timeIndex += dt * 2; switch (MENU_STATE_MAJOR & currentState) @@ -258,8 +251,19 @@ void GameStateMenu::Update(float dt) case MENU_STATE_MAJOR_DUEL : if (MENU_STATE_MINOR_NONE == (currentState & MENU_STATE_MINOR)) { - mParent->SetNextState(GAME_STATE_DUEL); - currentState = MENU_STATE_MAJOR_MAINMENU; + if (!hasChosenGameType){ + currentState = MENU_STATE_MAJOR_SUBMENU; + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT); + subMenuController = NEW SimpleMenu(102, this, mFont, 150,60); + if (subMenuController){ + subMenuController->Add(SUBMENUITEM_CLASSIC,"Classic"); + subMenuController->Add(SUBMENUITEM_MOMIR, "Momir Basic"); + subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel"); + } + }else{ + mParent->SetNextState(GAME_STATE_DUEL); + currentState = MENU_STATE_MAJOR_MAINMENU; + } } } switch (MENU_STATE_MINOR & currentState) @@ -423,23 +427,18 @@ JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT); switch (controlId) { case MENUITEM_PLAY: - + subMenuController = NEW SimpleMenu(102, this, mFont, 150,60); + if (subMenuController){ + subMenuController->Add(SUBMENUITEM_1PLAYER,"1 Player"); + subMenuController->Add(SUBMENUITEM_2PLAYER, "2 Players"); + subMenuController->Add(SUBMENUITEM_DEMO,"Demo"); + subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel"); #ifdef TESTSUITE - subMenuController = NEW SimpleMenu(102, this, mFont, 150,60); -#else - subMenuController = NEW SimpleMenu(102, this, mFont, 150,60); -#endif - if (subMenuController){ - subMenuController->Add(SUBMENUITEM_1PLAYER,"1 Player"); - subMenuController->Add(SUBMENUITEM_2PLAYER, "2 Players"); - subMenuController->Add(SUBMENUITEM_DEMO,"Demo"); - subMenuController->Add(SUBMENUITEM_CANCEL, "Cancel"); -#ifdef TESTSUITE - subMenuController->Add(SUBMENUITEM_TESTSUITE, "Test Suite"); + subMenuController->Add(SUBMENUITEM_TESTSUITE, "Test Suite"); #endif currentState = MENU_STATE_MAJOR_SUBMENU | MENU_STATE_MINOR_NONE; - } - break; + } + break; case MENUITEM_DECKEDITOR: mParent->SetNextState(GAME_STATE_DECK_VIEWER); break; @@ -474,6 +473,20 @@ JLBFont * mFont = GameApp::CommonRes->GetJLBFont(Constants::MENU_FONT); subMenuController->Close(); currentState = MENU_STATE_MAJOR_MAINMENU | MENU_STATE_MINOR_SUBMENU_CLOSING; break; + + case SUBMENUITEM_CLASSIC: + this->hasChosenGameType = 1; + mParent->gameType = GAME_TYPE_CLASSIC; + subMenuController->Close(); + currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING; + break; + + case SUBMENUITEM_MOMIR: + this->hasChosenGameType = 1; + mParent->gameType = GAME_TYPE_MOMIR; + subMenuController->Close(); + currentState = MENU_STATE_MAJOR_DUEL | MENU_STATE_MINOR_SUBMENU_CLOSING; + break; #ifdef TESTSUITE case SUBMENUITEM_TESTSUITE: mParent->players[0] = PLAYER_TYPE_TESTSUITE; diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 001de4683..07e7ac2c8 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -54,6 +54,7 @@ MTGPlayerCards::~MTGPlayerCards(){ SAFE_DELETE(inPlay); SAFE_DELETE(stack); SAFE_DELETE(removedFromGame); + SAFE_DELETE(garbage); } void MTGPlayerCards::setOwner(Player * player){ @@ -82,6 +83,7 @@ void MTGPlayerCards::init(){ inPlay = NEW MTGInPlay(); stack = NEW MTGStack(); removedFromGame = NEW MTGRemovedFromGame(); + garbage = NEW MTGGameZone(); } @@ -130,8 +132,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone if (card->isToken){ if (to != g->players[0]->game->inPlay && to != g->players[1]->game->inPlay){ - //Token leaves play: we destroy it - //TODO DELETE Object + garbage->addCard(copy); return NULL; } } diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 120d3e71b..f276cab93 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -2,7 +2,7 @@ #include "../include/MTGRules.h" MTGPutInPlayRule::MTGPutInPlayRule(int _id):MTGAbility(_id, NULL){ - + aType=MTGAbility::PUT_INTO_PLAY; } int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ @@ -78,6 +78,7 @@ int MTGPutInPlayRule::testDestroy(){ } MTGAttackRule::MTGAttackRule(int _id):MTGAbility(_id,NULL){ + aType=MTGAbility::MTG_ATTACK_RULE; } int MTGAttackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ @@ -102,6 +103,7 @@ int MTGAttackRule::testDestroy(){ MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){ + aType=MTGAbility::MTG_BLOCK_RULE; } int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ @@ -134,3 +136,74 @@ int MTGBlockRule::reactToClick(MTGCardInstance * card){ int MTGBlockRule::testDestroy(){ return 0; } + + +// +// * Momir +// + +MTGMomirRule::MTGMomirRule(int _id, MTGAllCards * _collection):MTGAbility(_id, NULL){ + collection = _collection; + alreadyplayed = 0; + aType=MTGAbility::MOMIR; +} + +int MTGMomirRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){ + if (alreadyplayed) return 0; + Player * player = game->currentlyActing(); + Player * currentPlayer = game->currentPlayer; + LOG("CANPUTINPLAY- check if card belongs to current player\n"); + if (!player->game->hand->hasCard(card)) return 0; + LOG("CANPUTINPLAY- check if card is land or can be played\n"); + if (player == currentPlayer && !game->isInterrupting && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN)){ + LOG("CANPUTINPLAY- correct time to play\n"); + return 1; + } + return 0; +} + +int MTGMomirRule::reactToClick(MTGCardInstance * card_to_discard){ + if (!isReactingToClick(card_to_discard)) return 0; + Player * player = game->currentlyActing(); + ManaCost * cost = player->getManaPool(); + int converted = cost->getConvertedCost(); + player->getManaPool()->pay(cost); + player->game->putInZone(card_to_discard, player->game->hand, player->game->graveyard); + MTGCardInstance * card = genRandomCreature(converted); //TODO code this function + player->game->stack->addCard(card); + Spell * spell = NEW Spell(card); + spell->resolve(); + spell->source->isToken = 1; + delete spell; + alreadyplayed = 1; + return 1; +} + +MTGCardInstance * MTGMomirRule::genRandomCreature(int convertedCost){ + Player * p = game->currentlyActing(); + int total_cards = collection->totalCards(); + int start = (rand() % total_cards); + int id2 = start; + while (id2 < total_cards){ + MTGCard * card = collection->collection[id2]; + if (card->isACreature() && card->getManaCost()->getConvertedCost() == convertedCost){ + return NEW MTGCardInstance(card,p->game); + } + id2++; + if (id2 == start) return NULL; + if (id2 == total_cards) id2 = 0; + } + return NULL; +} + +//The Momir rule is never destroyed +int MTGMomirRule::testDestroy(){ + return 0; +} + +void MTGMomirRule::Update(float dt){ + if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_UNTAP){ + alreadyplayed = 0; + } + MTGAbility::Update(dt); +} diff --git a/projects/mtg/template.vcproj b/projects/mtg/template.vcproj index b6942707e..376d9a920 100644 --- a/projects/mtg/template.vcproj +++ b/projects/mtg/template.vcproj @@ -228,6 +228,10 @@ RelativePath=".\src\ActionStack.cpp" > + + @@ -529,6 +533,10 @@ RelativePath=".\include\ActionStack.h" > + +