From 5754293e60605b779242638092ef2fe8ccd6455c Mon Sep 17 00:00:00 2001 From: Doublestrike Date: Sun, 29 Jan 2012 06:32:11 +0000 Subject: [PATCH] Releasing the beast: fully refactored quest submenu, featuring multiple quest support, preference editor, submenu tabs, and a host of other tools (and updates). --- .gitattributes | 9 + .gitignore | 1 + res/images/icons/IconMinus.png | Bin 0 -> 2004 bytes res/images/icons/IconPlus.png | Bin 0 -> 4200 bytes res/quest/quest.preferences | 91 +- src/main/java/forge/control/FControl.java | 5 + .../java/forge/control/home/ControlQuest.java | 523 +++++++-- src/main/java/forge/gui/GuiUtils.java | 19 + src/main/java/forge/model/FModel.java | 16 +- src/main/java/forge/quest/data/QuestData.java | 72 +- .../java/forge/quest/data/QuestDataIO.java | 19 +- .../forge/quest/data/QuestEventManager.java | 21 +- .../forge/quest/data/QuestPreferences.java | 960 ++++----------- .../java/forge/quest/data/QuestUtilCards.java | 16 +- .../java/forge/quest/gui/QuestOptions.java | 5 +- .../forge/quest/gui/QuestWinLoseHandler.java | 54 +- .../java/forge/view/home/HomeTopLevel.java | 21 + .../java/forge/view/home/QuestFileLister.java | 335 ++++++ src/main/java/forge/view/home/SubTab.java | 96 ++ src/main/java/forge/view/home/ViewQuest.java | 1030 +++++++++-------- .../forge/view/home/ViewQuestPreferences.java | 386 ++++++ .../java/forge/view/toolbox/DeckLister.java | 188 ++- .../java/forge/view/toolbox/FCheckBox.java | 43 + src/main/java/forge/view/toolbox/FLabel.java | 143 +++ .../java/forge/view/toolbox/FRadioButton.java | 45 + .../java/forge/view/toolbox/FScrollPane.java | 2 +- .../java/forge/view/toolbox/FTextArea.java | 25 + 27 files changed, 2671 insertions(+), 1454 deletions(-) create mode 100644 res/images/icons/IconMinus.png create mode 100644 res/images/icons/IconPlus.png create mode 100644 src/main/java/forge/view/home/QuestFileLister.java create mode 100644 src/main/java/forge/view/home/SubTab.java create mode 100644 src/main/java/forge/view/home/ViewQuestPreferences.java create mode 100644 src/main/java/forge/view/toolbox/FCheckBox.java create mode 100644 src/main/java/forge/view/toolbox/FLabel.java create mode 100644 src/main/java/forge/view/toolbox/FRadioButton.java create mode 100644 src/main/java/forge/view/toolbox/FTextArea.java diff --git a/.gitattributes b/.gitattributes index 126fb4d4627..7bb1ad98006 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10235,6 +10235,8 @@ res/images/icons/GoldIcon.png -text svneol=unset#image/png res/images/icons/GoldIconLarge.png -text svneol=unset#image/png res/images/icons/GoldIconSmall.png -text svneol=unset#image/png res/images/icons/HeartIcon.png -text svneol=unset#image/png +res/images/icons/IconMinus.png -text +res/images/icons/IconPlus.png -text res/images/icons/LeafIconSmall.png -text svneol=unset#image/png res/images/icons/Life.png -text svneol=unset#image/png res/images/icons/Mage01.jpg -text @@ -11330,12 +11332,15 @@ src/main/java/forge/view/Main.java -text src/main/java/forge/view/editor/EditorTopLevel.java -text src/main/java/forge/view/editor/package-info.java svneol=native#text/plain src/main/java/forge/view/home/HomeTopLevel.java -text +src/main/java/forge/view/home/QuestFileLister.java -text src/main/java/forge/view/home/SplashFrame.java -text src/main/java/forge/view/home/StartButton.java -text src/main/java/forge/view/home/SubButton.java -text +src/main/java/forge/view/home/SubTab.java -text src/main/java/forge/view/home/ViewConstructed.java -text src/main/java/forge/view/home/ViewDraft.java -text src/main/java/forge/view/home/ViewQuest.java -text +src/main/java/forge/view/home/ViewQuestPreferences.java -text src/main/java/forge/view/home/ViewSealed.java -text src/main/java/forge/view/home/ViewSettings.java -text src/main/java/forge/view/home/ViewUtilities.java -text @@ -11356,13 +11361,17 @@ src/main/java/forge/view/toolbox/CardFaceSymbols.java svneol=native#text/plain src/main/java/forge/view/toolbox/CardViewer.java -text src/main/java/forge/view/toolbox/DeckLister.java -text src/main/java/forge/view/toolbox/FButton.java -text +src/main/java/forge/view/toolbox/FCheckBox.java -text +src/main/java/forge/view/toolbox/FLabel.java -text src/main/java/forge/view/toolbox/FList.java -text src/main/java/forge/view/toolbox/FOverlay.java -text src/main/java/forge/view/toolbox/FPanel.java -text src/main/java/forge/view/toolbox/FProgressBar.java -text +src/main/java/forge/view/toolbox/FRadioButton.java -text src/main/java/forge/view/toolbox/FRoundedPanel.java -text src/main/java/forge/view/toolbox/FScrollPane.java -text src/main/java/forge/view/toolbox/FSkin.java -text +src/main/java/forge/view/toolbox/FTextArea.java -text src/main/java/forge/view/toolbox/FVerticalTabPanel.java -text src/main/java/forge/view/toolbox/package-info.java svneol=native#text/plain src/main/java/net/slightlymagic/braids/LICENSE.txt svneol=native#text/plain diff --git a/.gitignore b/.gitignore index 316283b4773..f0245a7bbc7 100644 --- a/.gitignore +++ b/.gitignore @@ -96,6 +96,7 @@ res/pics/ZEN res/pics/booster res/pics/icons res/pics/tokens +res/quest/data res/quest/questData.dat res/quest/questData.dat.xml res/reprintSetInfo.log diff --git a/res/images/icons/IconMinus.png b/res/images/icons/IconMinus.png new file mode 100644 index 0000000000000000000000000000000000000000..9b98e903f407b2f051d7f4e03d9d62d567ae7dc2 GIT binary patch literal 2004 zcmd6o`8V5%8pgj`B4cfj7LBTChqkAdM$jY-(J2~h6;+XnrPmsx5u#EwmRn1wt*t@@ z(S@Q#5n?N)l!>iXgTzu}i7l~>CAM7i4u%9tQ15F003Fc z^=mf|mHN+uL5H`^#FGsGk~x@bW={7x{2W^wXUh{`}h=JjL#Rmh6Cot^> z!}^6*@!KgWe%9ZH^^*&e3I{(|R$x?K735?>lKylOlTAGC{~g`%^||)N6aF}+GNHNnpUpj*gBbR*0fBP?}564(LtE?2jdc&aF{!JFU@ObY3SJ{n?g0rgfX<=pz}?twQ5{HEkJPd zh(~+!$%v&NJY0#BjL&8FpWu@E7yN4$XPHnVcYf$ZBXni$l5^G`bS2qrz*|QaXX110 zAn8S0C!mG@xTj5C(xP2$_8=U+>n?2-lJzX!Nxh$2w3hlqDt&^5>;_qd*JZ%PO)a{- ze+Cf3<&dyUb|l=Rxn)1iOM3h?q5SULQ2aY-nqt}QLns>-| z(w_e&IgnkT-Q5hzc@nHl4dAWb3%Y&d#>!cjW@17%rAWn) zz}Vm2a`f@>dE4?0#&F0_IyXraE-$dRw-LEW(xaW-UE78!oVzDDIvk=#v#=5hg_d=% z#wbv0n$Da0dK9+WFSRs#SW;^VKCmIklfzqBSj=s&PSu2casV+p{2Or);+nG&Q^EOl zcy-{A4yQhBv0CQVci+6NdE-GMD`H)f$z*2t$=$n19D#){XzS|Q2Q43zlvArJE9d^6 zAJ9LHPqmES;X^_@mi|$E{_88t(CN<9&sQYc1P~D8%4Ip4T?mQ9uG?`J9W?q6Xrk_~ zFdU)tSn=M%dE@6qWZ1%qjg5`$U5S%2EhA_*9o03L#wJ`;L2wOW;$tp(Y52Gsqblq} zW(kgfs|)#eeSLj*R6>-ktt}qJ2`9#iZO51PrFA$Lmz2CrPEPKO@j^Z8v-9=!J#xhR z{JJBEVOU{GlS_kB1$SLtPw_|V;57`NT`z4rm01#>&kx<-2_s2I;7KGB0gm>PW#GAu z5pY$LNJNN7R`1k!K@eDOR4F;-F6oxX{_!!_=E%w%~x8N~$1LxpWAHDKe8 zt_l8hdg;1Mi#4wJqK0F0+2+xJz`$Qciqv^y1IFNYJRWb~)YLTF@Q{vg<{ZxQw09O& zIhImZsI@<6-y$h@`uhA3+J+~9nM7`<*yR~#Z~G62OfPXCE9rjZErn-6Pf>AY(dypX zjEwwz`@z9MCoC4iji8R0domM5D4UjR|2=B?_h|_;n4fQkDk)iFU*w0 zu_L)rOr2pC@!We{U7Df}4xs^VRzR8+#kA6AKa8xQ%%{DKy1ULMoWt3X)62hfbohCA zKw)DO4dH!@og>OF%eeZ`;>TAnd~-`wzfaNZFIJdp%oDJNkVf3~n$0e=P^6xZQJb&P z`MIq|w$S_>ERVd`E5_+)P5vdTXaqNQDbvDLP7u+M;_ZlR5y3!RrxB zc1BhMcqc7CznVMjn%df0`-$Qoua#qsDV63p3`Zn!pPZTMsd|?iRbGr!V>zi;$X2qW z#so5F%w0rEE2^|6RaMo8mOY+YrEj}(Tjg09MAunv!OR_jM9fGp!CQqOX8Be0*RCz@ zVSAGN=)CkzWA+>d2L5B6nf@lxI@3k%wi4pu&o(Q}<7JYpTOyU=C_abzg*c;i3t))y g|DVY7U)bB1PK&WmNx%oR9nu=WnA=?|yXq19A2EcUFaQ7m literal 0 HcmV?d00001 diff --git a/res/images/icons/IconPlus.png b/res/images/icons/IconPlus.png new file mode 100644 index 0000000000000000000000000000000000000000..bb06ec2bbd798d85932735f9e4ef9d4a4615c367 GIT binary patch literal 4200 zcmZ9P2{e@Z|Hr?xF_y7sr?Et$NMdAZ?CTv`>}5#{w=g05GAKl4B1`s)l6CB48|2z4 z>Sj!`W|ysyrGAgP_kZsB&p9*CdCqy}`K;g1`}MhNPB6eQ3o-)$Fh+*DXQ3-;|BGgT zep@x2x&h#jH`3KQ?>D@Z!Q{=OC)h5_>?yO2*R7qh9=hB0lw}QXt*gz&#rAmxn~gWb zy=L6Wj3HHvM}0_;2)iKcY1o0{$47thyu$Ygb&Jnj9m{-#xtP+zTu2$UGL6%CpE&1y zWH2#vyXiwoKtO)re8IAcgN3h^RXay+p5;9{%G}e6nRGZAj_t|?(VjBk>4pE?>WKhu zDbt!$Qc}}#lwr1{NXmmWGwPa*+|Lvhk58c=k2y;oH~`dlS6VBvMzCvfw=0C?l6OQx zUvh=m{XCH5X`Mu^O7xoP(^&AK71(AnI__?*>NGztcdAr9iIW<-ymX>Y#G9w;4+ga5 zD>ogBu5xfsNTpa4N8~JIW8=5GTdspA(V4LV7_48J>xv{8+tnxEi2Q6>&{v#e^rnKZ z>JUJ-k5v6pq0UGhDs^7aF2e}_ecVxU@(lwE%;24E+2We;ud{C>l-!0NIWXOO7ALA<+|}LPS?e`3 zw0x{(fCW1=QC0MG>LmCSHMK#yIaZ%~@_Kwuj-=p5rQ7pFxIZBsr`6Tf)$x6OhPLMe z0~bG5Sv*ol-~$4-MaYlJ*%}v$>kJDli?pq@519*}@{V2{Dvd}kk;PL6-O}_rOh8Y> z)I*ZfSm8oRQ>LV}G^5as<8YVZnwt{ef9x#N%A-^PHEX2G=5{@js%hvx;1L@edtz^M z&=?KV)6+xI%C4}aEoZII^#6>YE60+hfuV^>t4YJ@h=@OttcYv(`HzRc%R3`+xMT!P z3MM7WTE)lm$Ldu<4L6IG$Gw z+#W=-3MlFtBHsYVwQa={Ck_Bb7bt)*bhav50>B*=hF~0RZEY~%?au?s&@ikivgXUH zh1+@nIkvSrc|&tF9L2%|6wx61&gIi54f$XzN^cw~2y9GD%wf>u%M5IkJf}LWi9I2E z%J;z2VgwH_uV)%SktDSNme#Kf+Z+vT+7E5)4%VKVLLApdkyr(fU(&_GT?hk!gA-<1 zV&AL5Vh#+&kt7Aq?3{s0}x85u=@ti`Um zmHmV}8n6l}_qafTddu`F$hv6YBo5dZb%3re&;YN3p@jTnmNK&cq-CMC(=37% zq^hdQ3+GjcU;76@Y|8usK}ko zGoV8p1EBUWLW2j)%KVEU`bu}w8IZCZR9jmMy&KsOtiw%g#i*D=zK~Q#gAxLHe|rc; z^i2Q0B9xryT$5zMR6v%Omp6kFarW$4R=#khecv%qdVW{`E*L`QJbx~TsRBq@`WJeMmlkJyE>Pn;n7WF0a|GT%2H%X{=JSWzO5QB%#&+;^(X+z?WhzB*AHwN;EM zOrBpq={kTs$X{y7Bt@39ugASX&TbfmPf^a*Y129h#;~l_+6w2#j~};W>G8m+8k-*@ z+MB;`5|R4yhlzHE*KaEh5w57Jvgwm5Dk{kBMHOdL)K|<@lweP~JQT+tS+tjD^|#KL zVfSQnz6%HlgqDv9dfByVP)B@6M_A%*%=75q=o$P1`DKgR*)Z%=ZnT?53AYQ4p!Sv; znQ;)Wh{A8hz6^VE!}rxB35J-*EAk~NNhgj~log6{r;)yX{Yq}n-?xdT`i=(AbkGQ? z$N~}XNUg$fny(K*jgowpVzk7U{QeI6F8x74HdYh@||x9t|VX7e{rec+=~azenQ@ZMgkRg1s2bzb(6BGSCp{J5YR4 z?bOM%4C9iXEn;KbWzjQD=V+R^Dm&&mBX&RI-%B~DWp}*<}bms z1(rv*Jr>?P(HV-gye0ZL`{t|uFa%@A^FPuK^Q7-ZHqSl%%v5|dnc^|pSSj`$9+G$W zhr#ilI1#lZpI5psepvr*6$lF3t%_`(K847p;}pRX^zS z=$WEdIW~u@9Zh^|EJf7pE57%FU&~`SMcrR<$<0dIz#=)c`n@{N`lOm#+Qj*Eg6=1$gN7?I)2?b}EzS)J)n zU&-#K;2oc`TML%T%N2K6`1+JI8WWl424AqF@IMh~{H05mbTNsvarfaGH@Y%2SZ^=~ ztbgFE-A8J?R&>i0FaPk3J<^n@o|~I{xj$25@$>XeKuVDUKjs?5WCnfVt4l(Dyc|Y4 zSA1&H9JTBYDmk|O3|=lQEZj7WyRv=#Hgs4pLGv$P%%1Rbw~QPKuIGhOHnSc+Y@XgZ zps9ic1TJoyVkeTLn&im0JM$lF%X4Rz^Pw^ri&l4q`yM&HJuBg}v$43iDEgdHTp5r= zPqXcIII$=?wII2KgzOGQTI!(!m{R*s|4i4cd`*+afQ}OyxKc*a_*IU4`-Xta135-H zHsx2H1m^WoF+JRKWkEYj)!u~@P?cN0=y))Eo|=ko5V#FT*HlNWKEM*%2TGj{y7g-; z!t6=YlX0h|u74=bMd;xW=8+NWRw<&^YK`yjrGoHFh74tQTEA7f(c?2U0^`#>8dY8J z(KilQi*$!q2eXT+8~S|tDBxFmsE$47(Acil)h5o0l8m0btu4PGnGyj z`0>J^5MFDC)>+7eMGNxG=WrDkT2=LSt=d(%Xo&`YJtOwB=YvCN23sqa>x;x?H{mQc z=HBk^f^DrQsQ@m_tI5uI5LbjOU{F&HS)cChgu-+W5O&X1@V5_Ks-)u7ANtsqjP`3C2hcmn)-Yo8?;QxIVplg`lCfQGk~LvUiydaufZuJIfr3L5rf;l)w= z`mKxS5IQu`zP!E~!X@+&% z9=!fl6#KJA#Ar1sL(XK&!7e_Z7kCM!w}pgPRHR2 zS8Z`B1T?I1&S60)6lz~HVR+1%8u!28fu=$w=ykV(%=!3j7y@d#4qf~=g}dC-yF7`($EPHJRd`8sGOgz-_Z z9M4U*pU6ZV29lg`d%C%E(d6Fg;UnA?&BI74}of(hEH$m$*dZ;z?wBAxO?|5BgwZiGK!T$w?8Jl+Ax+`oTob-^i0|8qFV@W>IZYcw6O)pv zeCby?*SNqs)?atI$IiXBjcD-39Z6LS+u2;c)|AEqOg(=;fjh0`PgQ8*zM0A&lwi|g zoQI4NQS%|IdQGpaeJq8Vw5iUm9PQ5lcMB{YR7IB)xwibNVd}ohC+rKeEVff@ zwO{l9_5)OJuIYJkGZ+*RG3MR*PjbSzD6z)R$ZMx&m=69peB{W}_2q@lK@n-+)=13U zYaM8TyCp_rHhIzY+_ic9(pG+5Bt~e!ZEGSI>RY+lNcL;_$s?4HwGd~Y__e?x!21HL z68*87UP?egHm!Dp8X%4v-B1rI>rMdKAiRL;YT|gy99Qnu93Uq7a=Cu}K~b`z6`wyZ z6f*b`+sstFTIF~yt=wz;%BPoU%5Jt_szfYg%n;d3+o;NpTvb+saOXPCKH{m4AOHm?yh6nvn$#I~rY1!C3p1W>YpOc5c%UJ(s g0snvd`2OurM*hz~8cJHcUjyi4q({&#)^-g4AG{t>(f|Me literal 0 HcmV?d00001 diff --git a/res/quest/quest.preferences b/res/quest/quest.preferences index 5ce6a6709f2..0e86036c203 100644 --- a/res/quest/quest.preferences +++ b/res/quest/quest.preferences @@ -1,30 +1,61 @@ -difficultyString=Easy,Normal,Hard,Very Hard -# Num of Wins for each Difficulty to gain a Booster, Rank, Duel vs Tougher AI Decks -winsForBooster=1,1,2,2 -winsForRankIncrease=3,4,5,6 -winsForMediumAI=10,9,8,7 -winsForHardAI=20,18,16,14 -winsForVeryHardAI=40,36,32,28 -# When starting a quest this is how much of each type you'll start with. Plus your starting Credits. -startingBasicLand=20 -startingSnowBasicLand=5 -startingCommons=82,80,78,76 -startingUncommons=20,18,16,15 -startingRares=10,10,10,8 -startingCredits=250 -# When winning a booster pack, this is what you'll expect to see in a pack. -boosterPackCommon=11 -boosterPackUncommon=3 -boosterPackRare=1 -# Match rewards that are used by the quest system -matchRewardBase=25 -matchRewardTotalWins=0.3 -matchRewardNoLosses=25 -matchRewardPoisonWinBonus=50 -matchRewardMilledWinBonus=40 -matchRewardAltWinBonus=100 -matchRewardWinOnFirstTurn=1500 -matchRewardWinByTurnFive=250 -matchRewardWinByTurnTen=50 -matchRewardWinByTurnFifteen=5 -matchRewardMullToZero=500 \ No newline at end of file +BOOSTER_COMMONS=11 +BOOSTER_UNCOMMONS=3 +BOOSTER_RARES=1 +REWARDS_BASE=30 +REWARDS_UNDEFEATED=25 +REWARDS_WINS_MULTIPLIER=0.3 +REWARDS_POISON=50 +REWARDS_MILLED=40 +REWARDS_MULLIGAN0=500 +REWARDS_ALTERNATIVE=100 +REWARDS_TURN15=5 +REWARDS_TURN10=50 +REWARDS_TURN5=250 +REWARDS_TURN1=1500 +STARTING_BASIC_LANDS=20 +STARTING_SNOW_LANDS=5 + +STARTING_COMMONS_EASY=82 +STARTING_COMMONS_MEDIUM=80 +STARTING_COMMONS_HARD=78 +STARTING_COMMONS_EXPERT=76 + +STARTING_UNCOMMONS_EASY=40 +STARTING_UNCOMMONS_MEDIUM=36 +STARTING_UNCOMMONS_HARD=32 +STARTING_UNCOMMONS_EXPERT=28 + +STARTING_RARES_EASY=20 +STARTING_RARES_MEDIUM=18 +STARTING_RARES_HARD=16 +STARTING_RARES_EXPERT=15 + +STARTING_CREDITS_EASY=250 +STARTING_CREDITS_MEDIUM=200 +STARTING_CREDITS_HARD=150 +STARTING_CREDITS_EXPERT=100 + +WINS_BOOSTER_EASY=1 +WINS_BOOSTER_MEDIUM=1 +WINS_BOOSTER_HARD=2 +WINS_BOOSTER_EXPERT=2 + +WINS_RANKUP_EASY=3 +WINS_RANKUP_MEDIUM=4 +WINS_RANKUP_HARD=5 +WINS_RANKUP_EXPERT=6 + +WINS_MEDIUMAI_EASY=10 +WINS_MEDIUMAI_MEDIUM=9 +WINS_MEDIUMAI_HARD=8 +WINS_MEDIUMAI_EXPERT=7 + +WINS_HARDAI_EASY=20 +WINS_HARDAI_MEDIUM=18 +WINS_HARDAI_HARD=16 +WINS_HARDAI_EXPERT=14 + +WINS_EXPERTAI_EASY=40 +WINS_EXPERTAI_MEDIUM=36 +WINS_EXPERTAI_HARD=32 +WINS_EXPERTAI_EXPERT=28 diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java index ed3e17a2a1c..b26db708ca6 100644 --- a/src/main/java/forge/control/FControl.java +++ b/src/main/java/forge/control/FControl.java @@ -190,6 +190,11 @@ public class FControl { return this.home; } + /** @return HomeTopLevel */ + public ControlHomeUI getHomeController() { + return this.home.getController(); + } + /** * Gets the match view. * diff --git a/src/main/java/forge/control/home/ControlQuest.java b/src/main/java/forge/control/home/ControlQuest.java index 4f3753b10a6..5375bc6e38a 100644 --- a/src/main/java/forge/control/home/ControlQuest.java +++ b/src/main/java/forge/control/home/ControlQuest.java @@ -4,23 +4,35 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import javax.swing.JOptionPane; +import javax.swing.JPanel; import javax.swing.SwingUtilities; import forge.AllZone; import forge.Command; import forge.Constant; +import forge.Singletons; import forge.control.FControl; import forge.deck.Deck; import forge.game.GameType; +import forge.gui.GuiUtils; import forge.gui.deckeditor.DeckEditorQuest; import forge.gui.deckeditor.DeckEditorShop; import forge.quest.data.QuestChallenge; import forge.quest.data.QuestData; +import forge.quest.data.QuestDataIO; import forge.quest.data.QuestEvent; +import forge.quest.data.QuestEventManager; +import forge.quest.data.QuestPreferences; +import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.QuestUtil; import forge.quest.data.item.QuestItemZeppelin; +import forge.quest.data.pet.QuestPetAbstract; import forge.view.GuiTopLevel; import forge.view.home.ViewQuest; @@ -31,20 +43,34 @@ import forge.view.home.ViewQuest; public class ControlQuest { private ViewQuest view; private QuestEvent event; - private final ActionListener actPetSelect, actPlantSelect; - private final MouseAdapter madStartGame; + private QuestData qData; + private QuestPreferences qPrefs; + private QuestEventManager qem; + private JPanel selectedTab; + + private final MouseAdapter madStartGame, madDuels, madChallenges, + madQuests, madDecks, madPreferences; + private final ActionListener actPetSelect, actPlantSelect, + actSpellShop, actBazaar, actEmbark, actNewDeck, actCurrentDeck; + private final Command cmdDeckExit, cmdDeckDelete, cmdDeckSelect, + cmdQuestSelect, cmdQuestDelete; + private Deck currentDeck; + private Map arrQuests; /** * Controls logic and listeners for quest mode in home screen. * * @param v0   ViewQuest */ + @SuppressWarnings("serial") public ControlQuest(ViewQuest v0) { + // Inits this.view = v0; + this.qem = new QuestEventManager(); + this.qPrefs = Singletons.getModel().getQuestPreferences(); + AllZone.setQuestEventManager(this.qem); - if (view.hasPreviousQuest()) { - updateDeckList(); - } + //========= Listener inits // Game start logic must happen outside of the EDT. madStartGame = new MouseAdapter() { @@ -60,14 +86,33 @@ public class ControlQuest { } }; + madDuels = new MouseAdapter() { @Override + public void mouseClicked(MouseEvent e) { view.showDuelsTab(); } }; + + madChallenges = new MouseAdapter() { @Override + public void mouseClicked(MouseEvent e) { view.showChallengesTab(); } }; + + madQuests = new MouseAdapter() { @Override + public void mouseClicked(MouseEvent e) { view.showQuestsTab(); } }; + + madDecks = new MouseAdapter() { @Override + public void mouseClicked(MouseEvent e) { + view.showDecksTab(); + if (ControlQuest.this.qem != null) { refreshDecks(); } + } + }; + + madPreferences = new MouseAdapter() { @Override + public void mouseClicked(MouseEvent e) { view.showPrefsTab(); } }; + actPetSelect = new ActionListener() { @Override public void actionPerformed(final ActionEvent actionEvent) { - if (view.getPetComboBox().getSelectedIndex() > 0) { - view.getQuestData().getPetManager().setSelectedPet( - (String) view.getPetComboBox().getSelectedItem()); + if (view.getCbxPet().getSelectedIndex() > 0) { + qData.getPetManager().setSelectedPet( + (String) view.getCbxPet().getSelectedItem()); } else { - view.getQuestData().getPetManager().setSelectedPet(null); + qData.getPetManager().setSelectedPet(null); } } }; @@ -75,98 +120,162 @@ public class ControlQuest { actPlantSelect = new ActionListener() { @Override public void actionPerformed(final ActionEvent actionEvent) { - view.getQuestData().getPetManager() - .setUsePlant(view.getPlantCheckBox().isSelected()); + qData.getPetManager() + .setUsePlant(view.getCbPlant().isSelected()); } }; + actSpellShop = new ActionListener() { @Override + public void actionPerformed(ActionEvent e) { showSpellShop(); } }; + + actBazaar = new ActionListener() { @Override + public void actionPerformed(ActionEvent e) { showBazaar(); } }; + + actEmbark = new ActionListener() { @Override + public void actionPerformed(ActionEvent e) { newQuest(); } }; + + actCurrentDeck = new ActionListener() { @Override + public void actionPerformed(ActionEvent e) { view.showDecksTab(); } }; + + actNewDeck = new ActionListener() { @Override + public void actionPerformed(ActionEvent e) { + final DeckEditorQuest editor = new DeckEditorQuest(qData); + editor.show(cmdDeckExit); + editor.setVisible(true); + } + }; + + cmdDeckExit = new Command() { + @Override + public void execute() { + AllZone.getQuestData().saveData(); + refreshDecks(); + GuiTopLevel g = ((GuiTopLevel) AllZone.getDisplay()); + g.getController().getHomeView().getBtnQuest().grabFocus(); + } + }; + + cmdDeckSelect = new Command() { + @Override + public void execute() { + currentDeck = view.getLstDecks().getSelectedDeck(); + view.setCurrentDeckStatus(); + } + }; + + cmdDeckDelete = new Command() { @Override + public void execute() { refreshDecks(); } }; + + cmdQuestSelect = new Command() { @Override + public void execute() { changeQuest(); } }; + + cmdQuestDelete = new Command() { @Override + public void execute() { refreshQuests(); } }; + addListeners(); } - private void addListeners() { - if (view.hasPreviousQuest()) { - view.getBtnStart().removeMouseListener(madStartGame); - view.getBtnStart().addMouseListener(madStartGame); - - view.getPetComboBox().removeActionListener(actPetSelect); - view.getPetComboBox().addActionListener(actPetSelect); - - view.getPlantCheckBox().removeActionListener(actPlantSelect); - view.getPlantCheckBox().addActionListener(actPlantSelect); - } - } - /** @return ViewQuest */ public ViewQuest getView() { return view; } - /** */ - private void updateDeckList() { - view.getLstDeckChooser().setListData(AllZone.getQuestData().getDeckNames().toArray()); - view.getLstDeckChooser().setSelectedIndex(0); + /** @return {@link forge.quest.gui.main.QuestEventManager} */ + public QuestEventManager getQEM() { + return this.qem; } - /** */ - public void showDeckEditor() { - final Command exit = new Command() { - private static final long serialVersionUID = -5110231879431074581L; - - @Override - public void execute() { - // saves all deck data - AllZone.getQuestData().saveData(); - updateDeckList(); - } - }; - - DeckEditorQuest g = new DeckEditorQuest(AllZone.getQuestData()); - g.show(exit); - g.setVisible(true); + /** @return {@link forge.Command} What to do when the deck editor exits. */ + public Command getExitCommand() { + return cmdDeckExit; } - private void updateCredits() { - view.getLblCredits().setText(Long.toString(view.getQuestData().getCredits())); + /** @return String   indicates the rank of this current quest */ + public String getRankString() { + return qData.getRank(); } - private void updateLife() { - view.getLblLife().setText(Long.toString(view.getQuestData().getLife())); + /** @return forge.deck.Deck */ + public Deck getCurrentDeck() { + return this.currentDeck; } - /** */ - public void showCardShop() { - final Command exit = new Command() { - private static final long serialVersionUID = 8567193482568076362L; - - @Override - public void execute() { - // saves all deck data - AllZone.getQuestData().saveData(); - updateDeckList(); - updateCredits(); - //updateLife(); - } - }; - - DeckEditorShop g = new DeckEditorShop(AllZone.getQuestData()); - g.show(exit); - g.setVisible(true); + /** @return */ + public Map getAllQuests() { + return arrQuests; } - /** */ - public void showBazaar() { - GuiTopLevel g = ((GuiTopLevel) AllZone.getDisplay()); + /** + * Updates visual state of tabber. + * @param tab0   JPanel tab object (can pass SubTab too). + */ + public void updateTabber(JPanel tab0) { + if (selectedTab != null) { + selectedTab.setEnabled(false); + } - g.getController().changeState(FControl.QUEST_BAZAAR); - g.validate(); - } // card shop button + tab0.setEnabled(true); + selectedTab = tab0; + } + + private void addListeners() { + view.getTabDuels().removeMouseListener(madDuels); + view.getTabDuels().addMouseListener(madDuels); + + view.getTabChallenges().removeMouseListener(madChallenges); + view.getTabChallenges().addMouseListener(madChallenges); + + view.getTabDecks().removeMouseListener(madDecks); + view.getTabDecks().addMouseListener(madDecks); + + view.getTabQuests().removeMouseListener(madQuests); + view.getTabQuests().addMouseListener(madQuests); + + view.getTabPreferences().removeMouseListener(madPreferences); + view.getTabPreferences().addMouseListener(madPreferences); + + view.getBtnEmbark().removeActionListener(actEmbark); + view.getBtnEmbark().addActionListener(actEmbark); + + view.getLstQuests().setSelectCommand(cmdQuestSelect); + view.getLstQuests().setEditCommand(cmdQuestDelete); + view.getLstQuests().setDeleteCommand(cmdQuestDelete); + + if (this.qem != null) { + view.getBtnStart().removeMouseListener(madStartGame); + view.getBtnStart().addMouseListener(madStartGame); + + view.getBtnBazaar().removeActionListener(actBazaar); + view.getBtnBazaar().addActionListener(actBazaar); + + view.getBtnNewDeck().removeActionListener(actNewDeck); + view.getBtnNewDeck().addActionListener(actNewDeck); + + view.getBtnCurrentDeck().removeActionListener(actCurrentDeck); + view.getBtnCurrentDeck().addActionListener(actCurrentDeck); + + view.getBtnSpellShop().removeActionListener(actSpellShop); + view.getBtnSpellShop().addActionListener(actSpellShop); + + view.getCbxPet().removeActionListener(actPetSelect); + view.getCbxPet().addActionListener(actPetSelect); + + view.getCbPlant().removeActionListener(actPlantSelect); + view.getCbPlant().addActionListener(actPlantSelect); + + view.getLstDecks().setSelectCommand(cmdDeckSelect); + view.getLstDecks().setDeleteCommand(cmdDeckDelete); + + view.getLstDecks().setExitCommand(cmdDeckExit); + } + } /** * The actuator for new quests. */ - public void newQuest() { + private void newQuest() { int difficulty = 0; - QuestData questData = new QuestData(); + QuestData newdata = new QuestData(); final String mode = view.getRadFantasy().isSelected() ? forge.quest.data.QuestData.FANTASY @@ -181,32 +290,197 @@ public class ControlQuest { } else if (view.getRadExpert().isSelected()) { difficulty = 3; } else { - JOptionPane.showMessageDialog(null, - "This should not be happening!", - "New Quest: Difficulty Bug!?", JOptionPane.ERROR_MESSAGE); + throw new IllegalStateException( + "ControlQuest() > newQuest(): Error starting new quest!"); + } + + final Object o = JOptionPane.showInputDialog(null, "Poets will remember your quest as:", "Quest Name", JOptionPane.OK_CANCEL_OPTION); + + if (o == null) { return; } + + final String questName = GuiUtils.cleanString(o.toString()); + + if (getAllQuests().get(questName) != null || questName.equals("")) { + JOptionPane.showMessageDialog(null, "Please pick another quest name, a quest already has that name."); return; } - if (questData.hasSaveFile()) { - // this will overwrite your save file! - final Object[] possibleValues = { "Yes", "No" }; - final Object choice = JOptionPane.showOptionDialog(null, - "Starting a new quest will overwrite your current quest. Continue?", "Start New Quest?", - JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, possibleValues, possibleValues[1]); + // Give the user a few cards to build a deck + newdata.newGame(difficulty, mode, view.getCbStandardStart().isSelected()); + newdata.setName(questName); + newdata.saveData(); - if (!choice.equals(0)) { - return; + view.getParentView().resetQuest(); + } // New Quest + + private void changeQuest() { + AllZone.setQuestData(view.getLstQuests().getSelectedQuest()); + this.qData = AllZone.getQuestData(); + this.qem = new QuestEventManager(); + this.qem.assembleAllEvents(); + AllZone.setQuestEventManager(this.qem); + + refreshDecks(); + refreshStats(); + } + + /** Resets quests, then retrieves and sets current quest. */ + public void refreshQuests() { + File dirQuests = new File("res/quest/data/"); + + // Temporary transition code between v1.2.2 and v1.2.3. + // Can be safely deleted after release of 1.2.3. + if (!dirQuests.exists()) { + dirQuests.mkdirs(); + } + File olddata = new File("res/quest/questData.dat"); + File newpath = new File(dirQuests.getPath() + "questData.dat"); + + if (olddata.exists()) { olddata.renameTo(newpath); } + // end block which can be deleted + + // Iterate over files and load quest datas for each. + File[] arrFiles = dirQuests.listFiles(); + arrQuests = new HashMap(); + for (File f : arrFiles) { + arrQuests.put(f.getName(), QuestDataIO.loadData(f)); + } + + // Populate list with available quest datas. + view.getLstQuests().setQuests(arrQuests.values().toArray(new QuestData[0])); + + // If there are quests available, force select. + if (arrQuests.size() > 0) { + final String questname = qPrefs.getPreference(QPref.CURRENT_QUEST); + + // Attempt to select previous quest. + if (arrQuests.get(questname) != null) { + view.getLstQuests().setSelectedQuestData(arrQuests.get(questname)); + } + else { + view.getLstQuests().setSelectedIndex(0); + } + + // Save in preferences. + qPrefs.setPreference(QPref.CURRENT_QUEST, + view.getLstQuests().getSelectedQuest().getName()); + + // Drop into AllZone. + AllZone.setQuestData(view.getLstQuests().getSelectedQuest()); + } + else { + AllZone.setQuestData(null); + } + + this.qData = AllZone.getQuestData(); + + if (qem.getAllDuels() == null) { + qem.assembleAllEvents(); + } + } + + /** Resets decks, then retrieves and sets current deck. */ + public void refreshDecks() { + Deck[] temp = (qData == null ? new Deck[] {} : qData.getDecks().toArray(new Deck[0])); + + view.getLstDecks().setDecks(temp); + + if (!view.getLstDecks().setSelectedDeck(currentDeck)) { + if (!view.getLstDecks().setSelectedIndex(0)) { + currentDeck = null; + } + else { + currentDeck = view.getLstDecks().getSelectedDeck(); } } - // give the user a few cards to build a deck - questData.newGame(difficulty, mode, view.getCbStandardStart().isSelected()); + view.setCurrentDeckStatus(); + } - questData.saveData(); + /** Updates all statistics in several panels. */ + public void refreshStats() { + if (qData == null) { return; } - // set global variable - AllZone.setQuestData(questData); - view.getParentView().resetQuest(); + // Stats panel + view.getLblCredits().setText("Credits: " + qData.getCredits()); + view.getLblLife().setText("Life: " + qData.getLife()); + view.getLblWins().setText("Wins: " + qData.getWin()); + view.getLblLosses().setText("Losses: " + qData.getLost()); + view.getBarProgress().setVisible(false); + view.setCurrentDeckStatus(); + + final int num = nextChallengeInWins(); + if (num == 0) { + view.getLblNextChallengeInWins().setText("Next challenge available now."); + } + else { + view.getLblNextChallengeInWins().setText("Next challenge available in " + num + " wins."); + } + + view.getLblWinStreak().setText( + "Win streak: " + qData.getWinStreakCurrent() + + " (Best:" + qData.getWinStreakBest() + ")"); + + // Start panel: pet, plant, zep. + if (this.qData.getMode().equals(QuestData.FANTASY)) { + final Set petList = this.qData.getPetManager().getAvailablePetNames(); + final QuestPetAbstract currentPet = this.qData.getPetManager().getSelectedPet(); + + // Pet list visibility + if (petList.size() > 0) { + view.getCbxPet().setEnabled(true); + view.getCbxPet().addItem("Don't summon a pet"); + for (final String pet : petList) { + view.getCbxPet().addItem("Summon " + pet); + } + + if (currentPet != null) { view.getCbxPet().setSelectedItem(currentPet.getName()); } + } else { + view.getCbxPet().setVisible(false); + } + + // Plant visiblity + if (this.qData.getPetManager().getPlant().getLevel() == 0) { + view.getCbPlant().setVisible(false); + } + else { + view.getCbPlant().setVisible(true); + view.getCbPlant().setSelected(this.qData.getPetManager().shouldPlantBeUsed()); + } + + // Zeppelin visibility + final QuestItemZeppelin zeppelin = (QuestItemZeppelin) this.qData.getInventory().getItem("Zeppelin"); + view.getCbZep().setVisible(zeppelin.hasBeenUsed()); + } + else { + view.getCbxPet().setVisible(false); + view.getCbPlant().setVisible(false); + view.getCbZep().setVisible(false); + } + } + + /** */ + @SuppressWarnings("serial") + private void showSpellShop() { + final Command exit = new Command() { + @Override + public void execute() { + AllZone.getQuestData().saveData(); + refreshStats(); + } + }; + + DeckEditorShop g = new DeckEditorShop(AllZone.getQuestData()); + g.show(exit); + g.setVisible(true); + } + + /** */ + private void showBazaar() { + GuiTopLevel g = ((GuiTopLevel) AllZone.getDisplay()); + + g.getController().changeState(FControl.QUEST_BAZAAR); + g.validate(); } /** */ @@ -216,7 +490,7 @@ public class ControlQuest { "ControlQuest() > startGame() must be accessed from outside the event dispatch thread."); } - if (view.getLstDeckChooser().getSelectedIndex() == -1) { + if (currentDeck == null) { JOptionPane.showMessageDialog(null, "A mysterious wall blocks your way." + "\n\rAn unseen sepulchral voice booms:" @@ -225,6 +499,8 @@ public class ControlQuest { return; } + view.getBarProgress().setVisible(true); + // If everything is OK, show progress bar and start inits. SwingUtilities.invokeLater(new Runnable() { @Override @@ -242,9 +518,9 @@ public class ControlQuest { event = view.getSelectedOpponent().getEvent(); AllZone.setQuestEvent(event); Constant.Runtime.setGameType(GameType.Quest); - final QuestItemZeppelin zeppelin = (QuestItemZeppelin) view.getQuestData().getInventory().getItem("Zeppelin"); + final QuestItemZeppelin zeppelin = (QuestItemZeppelin) qData.getInventory().getItem("Zeppelin"); zeppelin.setZeppelinUsed(false); - view.getQuestData().randomizeOpponents(); + qData.randomizeOpponents(); SwingUtilities.invokeLater(new Runnable() { @Override @@ -253,13 +529,8 @@ public class ControlQuest { } }); - String deckname = (String) view.getLstDeckChooser().getSelectedValue(); - Constant.Runtime.HUMAN_DECK[0] = view.getQuestData().getDeck(deckname); + Constant.Runtime.HUMAN_DECK[0] = currentDeck; Constant.Runtime.COMPUTER_DECK[0] = event.getEventDeck(); - final Deck humanDeck = view.getQuestData().getDeck(deckname); - - Constant.Runtime.HUMAN_DECK[0] = humanDeck; - Constant.Quest.OPP_ICON_NAME[0] = event.getIcon(); SwingUtilities.invokeLater(new Runnable() { @@ -278,11 +549,11 @@ public class ControlQuest { AllZone.getMatchState().reset(); if (event.getEventType().equals("challenge")) { - setupChallenge(humanDeck); + setupChallenge(currentDeck); } else { - setupDuel(humanDeck); + setupDuel(currentDeck); } - view.getQuestData().saveData(); + qData.saveData(); } }); } @@ -295,15 +566,15 @@ public class ControlQuest { * @param humanDeck * a {@link forge.deck.Deck} object. */ - final void setupDuel(final Deck humanDeck) { + private void setupDuel(final Deck humanDeck) { final Deck computer = event.getEventDeck(); Constant.Runtime.COMPUTER_DECK[0] = computer; AllZone.getGameAction().newGame( Constant.Runtime.HUMAN_DECK[0], Constant.Runtime.COMPUTER_DECK[0], - QuestUtil.getHumanStartingCards(view.getQuestData()), - QuestUtil.getComputerStartingCards(view.getQuestData()), - view.getQuestData().getLife(), 20); + QuestUtil.getHumanStartingCards(qData), + QuestUtil.getComputerStartingCards(qData), + qData.getLife(), 20); } /** @@ -317,15 +588,45 @@ public class ControlQuest { private void setupChallenge(final Deck humanDeck) { int extraLife = 0; - if (view.getQuestData().getInventory().getItemLevel("Gear") == 2) { + if (qData.getInventory().getItemLevel("Gear") == 2) { extraLife = 3; } AllZone.getGameAction().newGame( Constant.Runtime.HUMAN_DECK[0], Constant.Runtime.COMPUTER_DECK[0], - QuestUtil.getHumanStartingCards(view.getQuestData(), event), - QuestUtil.getComputerStartingCards(view.getQuestData(), event), - view.getQuestData().getLife() + extraLife, ((QuestChallenge) event).getAILife()); + QuestUtil.getHumanStartingCards(qData, event), + QuestUtil.getComputerStartingCards(qData, event), + qData.getLife() + extraLife, ((QuestChallenge) event).getAILife()); } + + /** + *

+ * nextChallengeInWins. + *

+ * + * @return a int. + */ + private int nextChallengeInWins() { + // Number of wins was 25, lowering the number to 20 to help short term + // questers. + if (qData.getWin() < 20) { + return 20 - qData.getWin(); + } + + // The int mul has been lowered by one, should face special opps more + // frequently. + final int challengesPlayed = qData.getChallengesPlayed(); + int mul = 5; + + if (qData.getInventory().hasItem("Zeppelin")) { + mul = 3; + } else if (qData.getInventory().hasItem("Map")) { + mul = 4; + } + + final int delta = (challengesPlayed * mul) - qData.getWin(); + + return (delta > 0) ? delta : 0; + } } diff --git a/src/main/java/forge/gui/GuiUtils.java b/src/main/java/forge/gui/GuiUtils.java index 02c49cca8bb..463f57f1046 100644 --- a/src/main/java/forge/gui/GuiUtils.java +++ b/src/main/java/forge/gui/GuiUtils.java @@ -409,4 +409,23 @@ public final class GuiUtils { overlay.removeAll(); overlay.hideOverlay(); } + + /** Duplicate in DeckEditorQuestMenu and + * probably elsewhere...can streamline at some point. + * + * @param in   {@link java.lang.String} + * @return {@link java.lang.String} + */ + public static String cleanString(final String in) { + final StringBuffer out = new StringBuffer(); + final char[] c = in.toCharArray(); + + for (int i = 0; (i < c.length) && (i < 20); i++) { + if (Character.isLetterOrDigit(c[i]) || (c[i] == '-') || (c[i] == '_') || (c[i] == ' ')) { + out.append(c[i]); + } + } + + return out.toString(); + } } diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index 8d1eecdaac5..ec32b8b3e6e 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -36,6 +36,7 @@ import forge.gui.input.InputControl; import forge.properties.ForgePreferences; import forge.properties.ForgeProps; import forge.properties.NewConstants; +import forge.quest.data.QuestPreferences; import forge.util.FileUtil; import forge.util.HttpUtil; @@ -57,7 +58,8 @@ public class FModel { private BuildInfo buildInfo; /** The preferences. */ - private ForgePreferences preferences; + private final QuestPreferences questPreferences; + private final ForgePreferences preferences; private FGameState gameState; /** @@ -84,12 +86,14 @@ public class FModel { // Instantiate preferences try { - this.setPreferences(new ForgePreferences("forge.preferences")); + this.preferences = new ForgePreferences("forge.preferences"); } catch (final Exception exn) { - // Log.error("Error loading preferences: " + exn); throw new RuntimeException(exn); } + // Instantiate quest preferences + this.questPreferences = new QuestPreferences(); + // TODO this single setting from preferences should not be here, or, // it should be here with all the other settings at the same time. // Unfortunately, they're tied up in legacy code in the Display interface, @@ -269,9 +273,9 @@ public class FModel { return this.preferences; } - /** @param fp0 {@link forge.properties.ForgePreferences} */ - public final void setPreferences(final ForgePreferences fp0) { - this.preferences = fp0; + /** @return {@link forge.quest.data.QuestPreferences} */ + public final QuestPreferences getQuestPreferences() { + return this.questPreferences; } /** @return {@link forge.model.FGameState} */ diff --git a/src/main/java/forge/quest/data/QuestData.java b/src/main/java/forge/quest/data/QuestData.java index 35b6d6d9219..9bd2227198a 100644 --- a/src/main/java/forge/quest/data/QuestData.java +++ b/src/main/java/forge/quest/data/QuestData.java @@ -24,6 +24,7 @@ import java.util.Map; import net.slightlymagic.maxmtg.Predicate; import forge.SetUtils; +import forge.Singletons; import forge.deck.Deck; import forge.error.ErrorViewer; import forge.item.CardPrinted; @@ -31,6 +32,7 @@ import forge.item.InventoryItem; import forge.item.ItemPool; import forge.properties.ForgeProps; import forge.properties.NewConstants; +import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.item.QuestInventory; import forge.quest.data.pet.QuestPetManager; import forge.util.MyRandom; @@ -68,6 +70,10 @@ public final class QuestData { /** The lost. */ private int lost; + private int winstreakBest = 0; + + private int winstreakCurrent = 0; + /** The credits. */ private long credits; // this money is good for all modes @@ -93,6 +99,9 @@ public final class QuestData { /** The difficulty. */ private String difficulty; + /** */ + private String name = ""; + // Quest mode - there should be an enum :( /** The mode. */ private String mode = ""; @@ -170,15 +179,25 @@ public final class QuestData { "What Do You Do With The Other Hand?", "Freelance Sorcerer, Works Weekends", "Should We Hire Commentators?", "Saltblasted For Your Talent", "Serra Angel Is Your Girlfriend", }; + /** */ + public QuestData() { + this("An Unknown Quest"); + } + /** *

* Constructor for QuestData. *

+ * + * @param s0   String name */ - public QuestData() { + public QuestData(String s0) { this.initTransients(); - this.myCards.addBasicLands(this.getCardPool(), QuestPreferences.getStartingBasic(), - QuestPreferences.getStartingSnowBasic()); + this.setName(s0); + + this.myCards.addBasicLands(this.getCardPool(), + Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.STARTING_BASIC_LANDS), + Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.STARTING_BASIC_LANDS)); this.randomizeOpponents(); } @@ -213,7 +232,7 @@ public final class QuestData { : CardPrinted.Predicates.Presets.IS_TRUE; this.myCards.setupNewGameCardPool(filter, diff); - this.setCredits(QuestPreferences.getStartingCredits()); + this.setCredits(Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.STARTING_CREDITS, diff)); this.mode = m0de; this.life = this.mode.equals(QuestData.FANTASY) ? 15 : 20; @@ -356,6 +375,12 @@ public final class QuestData { */ public void addLost() { this.lost++; + + if (winstreakCurrent > winstreakBest) { + winstreakBest = winstreakCurrent; + } + + winstreakCurrent = 0; } /** @@ -372,8 +397,13 @@ public final class QuestData { */ public void addWin() { // changes getRank() this.win++; + this.winstreakCurrent++; - final int winsToLvlUp = QuestPreferences.getWinsForRankIncrease(this.diffIndex); + if (winstreakCurrent > winstreakBest) { + winstreakBest = winstreakCurrent; + } + + final int winsToLvlUp = Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.WINS_RANKUP, this.diffIndex); if ((this.win % winsToLvlUp) == 0) { this.rankIndex++; } @@ -480,14 +510,15 @@ public final class QuestData { /** * Guess difficulty index. + * NOTE: Used in old UI only, soon to be deprecated. */ public void guessDifficultyIndex() { - final String[] diffStr = QuestPreferences.getDifficulty(); + /*final String[] diffStr = QuestPreferences.getDifficulty(); for (int i = 0; i < diffStr.length; i++) { if (this.difficulty.equals(diffStr[i])) { this.diffIndex = i; } - } + }*/ } // Level, read-only ( note: it increments in addWin() ) @@ -512,6 +543,15 @@ public final class QuestData { return QuestData.RANK_TITLES[this.rankIndex]; } + /** @return int */ + public int getWinStreakBest() { + return this.winstreakBest; + } + + /** @return int */ + public int getWinStreakCurrent() { + return this.winstreakCurrent; + } // decks management /** * Gets the deck names. @@ -522,6 +562,11 @@ public final class QuestData { return new ArrayList(this.getMyDecks().keySet()); } + /** @return List */ + public List getDecks() { + return new ArrayList(this.getMyDecks().values()); + } + /** * Removes the deck. * @@ -684,7 +729,8 @@ public final class QuestData { this.myDecks = myDecks0; } - public static final QuestPreconManager getPreconManager() { + /** @return QuestPreconManager */ + public static QuestPreconManager getPreconManager() { return preconManager; } @@ -726,4 +772,14 @@ public final class QuestData { public void setVersionNumber(final int versionNumber0) { this.versionNumber = versionNumber0; } + + /** @param s0   {@link java.lang.String} */ + public void setName(String s0) { + this.name = s0; + } + + /** @return {@link java.lang.String} */ + public String getName() { + return this.name; + } } diff --git a/src/main/java/forge/quest/data/QuestDataIO.java b/src/main/java/forge/quest/data/QuestDataIO.java index e654ff06e11..af8fb8a80d5 100644 --- a/src/main/java/forge/quest/data/QuestDataIO.java +++ b/src/main/java/forge/quest/data/QuestDataIO.java @@ -74,21 +74,27 @@ public class QuestDataIO { public QuestDataIO() { } + /** @return {@link forge.quest.data.QuestData} */ + public static QuestData loadData() { + return QuestDataIO.loadData(ForgeProps.getFile(NewConstants.Quest.XMLDATA)); + } + /** *

* loadData. *

* - * @return a {@link forge.quest.data.QuestData} object. + * @param xmlSaveFile   {@link java.io.File} + * @return {@link forge.quest.data.QuestData} */ - public static QuestData loadData() { + public static QuestData loadData(final File xmlSaveFile) { try { - // read file "questData" QuestData data = null; + String name = xmlSaveFile.getName() + .substring(0, xmlSaveFile.getName().length() - 4); - final File xmlSaveFile = ForgeProps.getFile(NewConstants.Quest.XMLDATA); if (!xmlSaveFile.exists()) { - return new QuestData(); + return new QuestData(name); } final GZIPInputStream zin = new GZIPInputStream(new FileInputStream(xmlSaveFile)); @@ -109,6 +115,7 @@ public class QuestDataIO { xStream.registerConverter(new GameTypeToXml()); xStream.alias("CardPool", ItemPool.class); data = (QuestData) xStream.fromXML(xml.toString()); + data.setName(name); if (data.getVersionNumber() != QuestData.CURRENT_VERSION_NUMBER) { QuestDataIO.updateSaveFile(data, xml.toString()); @@ -193,7 +200,7 @@ public class QuestDataIO { xStream.registerConverter(new CardPoolToXml()); xStream.alias("CardPool", ItemPool.class); - final File f = ForgeProps.getFile(NewConstants.Quest.XMLDATA); + final File f = new File("res/quest/data/" + qd.getName() + ".dat"); final BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(f)); final GZIPOutputStream zout = new GZIPOutputStream(bout); xStream.toXML(qd, zout); diff --git a/src/main/java/forge/quest/data/QuestEventManager.java b/src/main/java/forge/quest/data/QuestEventManager.java index 748d25bf684..822aa8d3f09 100644 --- a/src/main/java/forge/quest/data/QuestEventManager.java +++ b/src/main/java/forge/quest/data/QuestEventManager.java @@ -24,9 +24,11 @@ import java.util.List; import java.util.Random; import forge.AllZone; +import forge.Singletons; import forge.deck.DeckIO; import forge.properties.ForgeProps; import forge.properties.NewConstants; +import forge.quest.data.QuestPreferences.QPref; import forge.util.FileUtil; /** @@ -58,6 +60,12 @@ public class QuestEventManager { /** The all challenges. */ private List allChallenges = null; + private final QuestPreferences qpref; + + /** */ + public QuestEventManager() { + this.qpref = Singletons.getModel().getQuestPreferences(); + } /** *

* assembleAllEvents. @@ -354,31 +362,32 @@ public class QuestEventManager { * @return an array of {@link java.lang.String} objects. */ public final List generateDuels() { + if (AllZone.getQuestData() == null) { return null; } final int index = AllZone.getQuestData().getDifficultyIndex(); final List duelOpponents = new ArrayList(); - if (AllZone.getQuestData().getWin() < QuestPreferences.getWinsForMediumAI(index)) { + if (AllZone.getQuestData().getWin() < qpref.getPreferenceInt(QPref.WINS_MEDIUMAI, index)) { duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.easyAIduels, 0)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.easyAIduels, 1)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.easyAIduels, 2)); - } else if (AllZone.getQuestData().getWin() == QuestPreferences.getWinsForMediumAI(index)) { + } else if (AllZone.getQuestData().getWin() == qpref.getPreferenceInt(QPref.WINS_MEDIUMAI, index)) { duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.easyAIduels, 0)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.mediumAIduels, 0)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.mediumAIduels, 1)); - } else if (AllZone.getQuestData().getWin() < QuestPreferences.getWinsForHardAI(index)) { + } else if (AllZone.getQuestData().getWin() < qpref.getPreferenceInt(QPref.WINS_HARDAI, index)) { duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.mediumAIduels, 0)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.mediumAIduels, 1)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.mediumAIduels, 2)); } - else if (AllZone.getQuestData().getWin() == QuestPreferences.getWinsForHardAI(index)) { + else if (AllZone.getQuestData().getWin() == qpref.getPreferenceInt(QPref.WINS_HARDAI, index)) { duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.mediumAIduels, 0)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.hardAIduels, 0)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.hardAIduels, 1)); } - else if (AllZone.getQuestData().getWin() < QuestPreferences.getWinsForVeryHardAI(index)) { + else if (AllZone.getQuestData().getWin() < qpref.getPreferenceInt(QPref.WINS_EXPERTAI, index)) { duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.hardAIduels, 0)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.hardAIduels, 1)); duelOpponents.add(QuestEventManager.getDuelOpponentByNumber(this.hardAIduels, 2)); @@ -401,6 +410,8 @@ public class QuestEventManager { * @return a {@link java.util.List} object. */ public final List generateChallenges() { + if (AllZone.getQuestData() == null) { return null; } + final forge.quest.data.QuestData questData = AllZone.getQuestData(); final List challengeOpponents = new ArrayList(); diff --git a/src/main/java/forge/quest/data/QuestPreferences.java b/src/main/java/forge/quest/data/QuestPreferences.java index 6ccd66186af..a3a71423b28 100644 --- a/src/main/java/forge/quest/data/QuestPreferences.java +++ b/src/main/java/forge/quest/data/QuestPreferences.java @@ -18,8 +18,14 @@ package forge.quest.data; import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileNotFoundException; import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import forge.properties.ForgeProps; import forge.properties.NewConstants.Quest; @@ -32,89 +38,110 @@ import forge.properties.NewConstants.Quest; * @author Forge * @version $Id$ */ +@SuppressWarnings("serial") public class QuestPreferences implements Serializable { - /** Constant serialVersionUID=3266336025656577905L. */ - private static final long serialVersionUID = 3266336025656577905L; - /** Constant numDiff=4. */ - private static int numDiff = 4; + private Map preferenceValues; - // Descriptive difficulty names - /** Constant sDifficulty="{Easy, Normal, Hard, Very Hard}". */ - private static String[] sDifficulty = { "Easy", "Normal", "Hard", "Very Hard" }; + /** + * Preference identifiers, and their default values. + * When this class is instantiated, these enum values are used + * in a map that is populated with the current preferences + * from the text file. + */ + public enum QPref { /** */ + BOOSTER_COMMONS ("11"), /** */ + BOOSTER_UNCOMMONS ("3"), /** */ + BOOSTER_RARES ("1"), /** */ - // Default match wins it takes to gain a booster - /** Constant winsForBooster={1, 1, 2, 2}. */ - private static int[] winsForBooster = { 1, 1, 2, 2 }; - /** Constant winsForRankIncrease={1, 2, 3, 4}. */ - private static int[] winsForRankIncrease = { 1, 2, 3, 4 }; - /** Constant winsForMediumAI={6, 6, 11, 11}. */ - private static int[] winsForMediumAI = { 6, 6, 11, 11 }; - /** Constant winsForHardAI={9, 9, 21, 21}. */ - private static int[] winsForHardAI = { 9, 9, 21, 21 }; - /** Constant winsForVeryHardAI={29, 29, 31, 31}. */ - private static int[] winsForVeryHardAI = { 29, 29, 31, 31 }; + PENALTY_LOSS ("15"), /** */ + CURRENT_QUEST ("DEFAULT"), /** */ - // Default starting land for a quest - /** Constant startingBasicLand=20. */ - private static int startingBasicLand = 20; - /** Constant startingSnowBasicLand=20. */ - private static int startingSnowBasicLand = 20; + REWARDS_BASE ("25"), /** */ + REWARDS_UNDEFEATED ("25"), /** */ + REWARDS_WINS_MULTIPLIER ("0.3"), /** */ + REWARDS_POISON ("50"), /** */ + REWARDS_MILLED ("40"), /** */ + REWARDS_MULLIGAN0 ("500"), /** */ + REWARDS_ALTERNATIVE ("100"), /** */ + REWARDS_TURN15 ("5"), /** */ + REWARDS_TURN10 ("50"), /** */ + REWARDS_TURN5 ("250"), /** */ + REWARDS_TURN1 ("1500"), /** */ - // Default starting amount of each rarity - /** Constant startingCommons={45, 40, 40, 40}. */ - private static int[] startingCommons = { 45, 40, 40, 40 }; - /** Constant startingUncommons={20, 15, 15, 15}. */ - private static int[] startingUncommons = { 20, 15, 15, 15 }; - /** Constant startingRares={10, 10, 10, 10}. */ - private static int[] startingRares = { 10, 10, 10, 10 }; + STARTING_BASIC_LANDS ("20"), /** */ + STARTING_SNOW_LANDS ("5"), /** */ - /** Constant startingCredits=250. */ - private static int startingCredits = 250; + STARTING_COMMONS ("DIFFICULTY_INDEX_REQD"), /** */ + STARTING_COMMONS_EASY ("82"), /** */ + STARTING_COMMONS_MEDIUM ("80"), /** */ + STARTING_COMMONS_HARD ("78"), /** */ + STARTING_COMMONS_EXPERT ("76"), /** */ - /** Constant boosterPackRare=1. */ - private static int boosterPackRare = 1; - /** Constant boosterPackUncommon=3. */ - private static int boosterPackUncommon = 3; - /** Constant boosterPackCommon=9. */ - private static int boosterPackCommon = 9; + STARTING_UNCOMMONS ("DIFFICULTY_INDEX_REQD"), /** */ + STARTING_UNCOMMONS_EASY ("40"), /** */ + STARTING_UNCOMMONS_MEDIUM ("36"), /** */ + STARTING_UNCOMMONS_HARD ("32"), /** */ + STARTING_UNCOMMONS_EXPERT ("28"), /** */ - /** Constant matchRewardBase=10. */ - private static int matchRewardBase = 10; - /** Constant matchRewardTotalWins=0.3. */ - private static double matchRewardTotalWins = 0.3; - /** Constant matchRewardNoLosses=10. */ - private static int matchRewardNoLosses = 10; + STARTING_RARES ("DIFFICULTY_INDEX_REQD"), /** */ + STARTING_RARES_EASY ("20"), /** */ + STARTING_RARES_MEDIUM ("18"), /** */ + STARTING_RARES_HARD ("16"), /** */ + STARTING_RARES_EXPERT ("15"), /** */ - /** Constant matchRewardPoisonWinBonus=50. */ - private static int matchRewardPoisonWinBonus = 50; - /** Constant matchRewardMilledWinBonus=40. */ - private static int matchRewardMilledWinBonus = 40; - /** Constant matchRewardAltWinBonus=100. */ - private static int matchRewardAltWinBonus = 100; + STARTING_CREDITS ("DIFFICULTY_INDEX_REQD"), /** */ + STARTING_CREDITS_EASY ("250"), /** */ + STARTING_CREDITS_MEDIUM ("200"), /** */ + STARTING_CREDITS_HARD ("150"), /** */ + STARTING_CREDITS_EXPERT ("100"), /** */ - /** Constant matchRewardWinOnFirstTurn=1500. */ - private static int matchRewardWinOnFirstTurn = 1500; - /** Constant matchRewardWinByTurnFive=250. */ - private static int matchRewardWinByTurnFive = 250; - /** Constant matchRewardWinByTurnTen=50. */ - private static int matchRewardWinByTurnTen = 50; - /** Constant matchRewardWinByTurnFifteen=5. */ - private static int matchRewardWinByTurnFifteen = 5; - /** Constant matchRewardMullToZero=500. */ - private static int matchRewardMullToZero = 500; + WINS_BOOSTER ("DIFFICULTY_INDEX_REQD"), /** */ + WINS_BOOSTER_EASY ("1"), /** */ + WINS_BOOSTER_MEDIUM ("1"), /** */ + WINS_BOOSTER_HARD ("2"), /** */ + WINS_BOOSTER_EXPERT ("2"), /** */ - static { - // if quest.prefs exists - QuestPreferences.grabPrefsFromFile(); + WINS_RANKUP ("DIFFICULTY_INDEX_REQD"), /** */ + WINS_RANKUP_EASY ("3"), /** */ + WINS_RANKUP_MEDIUM ("4"), /** */ + WINS_RANKUP_HARD ("5"), /** */ + WINS_RANKUP_EXPERT ("6"), /** */ + + WINS_MEDIUMAI ("DIFFICULTY_INDEX_REQD"), /** */ + WINS_MEDIUMAI_EASY ("10"), /** */ + WINS_MEDIUMAI_MEDIUM ("9"), /** */ + WINS_MEDIUMAI_HARD ("8"), /** */ + WINS_MEDIUMAI_EXPERT ("7"), /** */ + + WINS_HARDAI ("DIFFICULTY_INDEX_REQD"), /** */ + WINS_HARDAI_EASY ("20"), /** */ + WINS_HARDAI_MEDIUM ("18"), /** */ + WINS_HARDAI_HARD ("16"), /** */ + WINS_HARDAI_EXPERT ("14"), /** */ + + WINS_EXPERTAI ("DIFFICULTY_INDEX_REQD"), /** */ + WINS_EXPERTAI_EASY ("40"), /** */ + WINS_EXPERTAI_MEDIUM ("36"), /** */ + WINS_EXPERTAI_HARD ("32"), /** */ + WINS_EXPERTAI_EXPERT ("28"); /** */ + + private final String strDefaultVal; + + /** @param s0   {@link java.lang.String} */ + QPref(String s0) { + this.strDefaultVal = s0; + } + + /** @return {@link java.lang.String} */ + public String getDefault() { + return strDefaultVal; + } } - /** - *

- * grabPrefsFromFile. - *

- */ - public static void grabPrefsFromFile() { + /** Instantiates a QuestPreferences object. */ + public QuestPreferences() { + preferenceValues = new HashMap(); try { final BufferedReader input = new BufferedReader(new FileReader(ForgeProps.getFile(Quest.PREFS))); String line = null; @@ -122,706 +149,157 @@ public class QuestPreferences implements Serializable { if (line.startsWith("#") || (line.length() == 0)) { continue; } + final String[] split = line.split("="); - - if (split[0].equals("difficultyString")) { - QuestPreferences.setDifficulty(split[1]); - } else if (split[0].equals("winsForBooster")) { - QuestPreferences.setWinsForBooster(split[1]); - } else if (split[0].equals("winsForRankIncrease")) { - QuestPreferences.setWinsForRank(split[1]); - } else if (split[0].equals("winsForMediumAI")) { - QuestPreferences.setWinsForMediumAI(split[1]); - } else if (split[0].equals("winsForHardAI")) { - QuestPreferences.setWinsForHardAI(split[1]); - } else if (split[0].equals("startingBasicLand")) { - QuestPreferences.setStartingBasic(split[1]); - } else if (split[0].equals("startingSnowBasicLand")) { - QuestPreferences.setStartingSnowBasic(split[1]); - } else if (split[0].equals("startingCommons")) { - QuestPreferences.setStartingCommons(split[1]); - } else if (split[0].equals("startingUncommons")) { - QuestPreferences.setStartingUncommons(split[1]); - } else if (split[0].equals("startingRares")) { - QuestPreferences.setStartingRares(split[1]); - } else if (split[0].equals("startingCredits")) { - QuestPreferences.setStartingCredits(split[1]); - } else if (split[0].equals("boosterPackCommon")) { - QuestPreferences.setNumCommon(split[1]); - } else if (split[0].equals("boosterPackUncommon")) { - QuestPreferences.setNumUncommon(split[1]); - } else if (split[0].equals("boosterPackRare")) { - QuestPreferences.setNumRares(split[1]); - } else if (split[0].equals("matchRewardBase")) { - QuestPreferences.setMatchRewardBase(split[1]); - } else if (split[0].equals("matchRewardTotalWins")) { - QuestPreferences.setMatchRewardTotalWins(split[1]); - } else if (split[0].equals("matchRewardNoLosses")) { - QuestPreferences.setMatchRewardNoLosses(split[1]); - } else if (split[0].equals("matchRewardMilledWinBonus")) { - QuestPreferences.setMatchRewardMilledWinBonus(split[1]); - } else if (split[0].equals("matchRewardPoisonWinBonus")) { - QuestPreferences.setMatchRewardPoisonWinBonus(split[1]); - } else if (split[0].equals("matchRewardAltWinBonus")) { - QuestPreferences.setMatchRewardAltWinBonus(split[1]); - } else if (split[0].equals("matchRewardWinOnFirstTurn")) { - QuestPreferences.setMatchRewardWinFirst(split[1]); - } else if (split[0].equals("matchRewardWinByTurnFive")) { - QuestPreferences.setMatchRewardWinByFifth(split[1]); - } else if (split[0].equals("matchRewardWinByTurnTen")) { - QuestPreferences.setMatchRewardWinByTen(split[1]); - } else if (split[0].equals("matchRewardWinByTurnFifteen")) { - QuestPreferences.setMatchRewardWinByFifteen(split[1]); - } else if (split[0].equals("matchRewardMullToZero")) { - QuestPreferences.setMatchMullToZero(split[1]); - } + this.setPreference(split[0], split[1]); } - } catch (final Exception e) { - System.out.println("Trouble grabbing quest data preferences. Using default values."); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + /** Saves prefs map to file. */ + public void save() { + BufferedWriter writer = null; + + try { + writer = new BufferedWriter(new FileWriter(ForgeProps.getFile(Quest.PREFS))); + for (QPref key : QPref.values()) { + if (key.getDefault().equals("DIFFICULTY_INDEX_REQD")) { + writer.newLine(); + continue; + } + writer.write(key + "=" + getPreference(key)); + writer.newLine(); + } + + writer.flush(); + writer.close(); + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } catch (IOException ex) { + ex.printStackTrace(); } } /** - *

- * getDifficulty. - *

+ * DUE TO BE DEPRECATED: + * Transition code between preference manager for v1.2.2 and v1.2.3. + * Should be able to delete very neatly after release of 1.2.3, + * perhaps sooner. * - * @return an array of {@link java.lang.String} objects. + * @param s0   {@link java.lang.String} identifier of preference + * @param s1   {@link java.lang.String} value */ - public static String[] getDifficulty() { - return QuestPreferences.sDifficulty; - } - - /** - *

- * getDifficulty. - *

- * - * @param index - * a int. - * @return a {@link java.lang.String} object. - */ - public static String getDifficulty(final int index) { - return QuestPreferences.sDifficulty[index]; - } - - /** - *

- * Getter for the field winsForBooster. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getWinsForBooster(final int index) { - return QuestPreferences.winsForBooster[index]; - } - - /** - *

- * Getter for the field winsForRankIncrease. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getWinsForRankIncrease(final int index) { - return QuestPreferences.winsForRankIncrease[index]; - } - - /** - *

- * Getter for the field winsForMediumAI. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getWinsForMediumAI(final int index) { - return QuestPreferences.winsForMediumAI[index]; - } - - /** - *

- * Getter for the field winsForHardAI. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getWinsForHardAI(final int index) { - return QuestPreferences.winsForHardAI[index]; - } - - /** - *

- * Getter for the field winsForVeryHardAI. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getWinsForVeryHardAI(final int index) { - return QuestPreferences.winsForVeryHardAI[index]; - } - - /** - *

- * getStartingBasic. - *

- * - * @return a int. - */ - public static int getStartingBasic() { - return QuestPreferences.startingBasicLand; - } - - /** - *

- * getStartingSnowBasic. - *

- * - * @return a int. - */ - public static int getStartingSnowBasic() { - return QuestPreferences.startingSnowBasicLand; - } - - /** - *

- * Getter for the field startingCommons. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getStartingCommons(final int index) { - return QuestPreferences.startingCommons[index]; - } - - /** - *

- * Getter for the field startingUncommons. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getStartingUncommons(final int index) { - return QuestPreferences.startingUncommons[index]; - } - - /** - *

- * Getter for the field startingRares. - *

- * - * @param index - * a int. - * @return a int. - */ - public static int getStartingRares(final int index) { - return QuestPreferences.startingRares[index]; - } - - /** - *

- * Getter for the field startingCredits. - *

- * - * @return a int. - */ - public static int getStartingCredits() { - return QuestPreferences.startingCredits; - } - - /** - *

- * getNumCommon. - *

- * - * @return a int. - */ - public static int getNumCommon() { - return QuestPreferences.boosterPackCommon; - } - - /** - *

- * getNumUncommon. - *

- * - * @return a int. - */ - public static int getNumUncommon() { - return QuestPreferences.boosterPackUncommon; - } - - /** - *

- * getNumRare. - *

- * - * @return a int. - */ - public static int getNumRare() { - return QuestPreferences.boosterPackRare; - } - - /** - *

- * Getter for the field matchRewardBase. - *

- * - * @return a int. - */ - public static int getMatchRewardBase() { - return QuestPreferences.matchRewardBase; - } - - /** - *

- * Getter for the field matchRewardTotalWins. - *

- * - * @return a double. - */ - public static double getMatchRewardTotalWins() { - return QuestPreferences.matchRewardTotalWins; - } - - /** - *

- * Getter for the field matchRewardNoLosses. - *

- * - * @return a int. - */ - public static int getMatchRewardNoLosses() { - return QuestPreferences.matchRewardNoLosses; - } - - /** - *

- * Getter for the field matchRewardPoisonWinBonus. - *

- * - * @return a int. - */ - public static int getMatchRewardPoisonWinBonus() { - return QuestPreferences.matchRewardPoisonWinBonus; - } - - /** - *

- * Getter for the field matchRewardMilledWinBonus. - *

- * - * @return a int. - */ - public static int getMatchRewardMilledWinBonus() { - return QuestPreferences.matchRewardMilledWinBonus; - } - - /** - *

- * Getter for the field matchRewardAltWinBonus. - *

- * - * @return a int. - */ - public static int getMatchRewardAltWinBonus() { - return QuestPreferences.matchRewardAltWinBonus; - } - - /** - *

- * getMatchRewardWinFirst. - *

- * - * @return a int. - */ - public static int getMatchRewardWinFirst() { - return QuestPreferences.matchRewardWinOnFirstTurn; - } - - /** - *

- * getMatchRewardWinByFifth. - *

- * - * @return a int. - */ - public static int getMatchRewardWinByFifth() { - return QuestPreferences.matchRewardWinByTurnFive; - } - - /** - *

- * getMatchRewardWinByTen. - *

- * - * @return a int. - */ - public static int getMatchRewardWinByTen() { - return QuestPreferences.matchRewardWinByTurnTen; - } - - /** - *

- * getMatchRewardWinByFifteen. - *

- * - * @return a int. - */ - public static int getMatchRewardWinByFifteen() { - return QuestPreferences.matchRewardWinByTurnFifteen; - } - - /** - *

- * getMatchMullToZero. - *

- * - * @return a int. - */ - public static int getMatchMullToZero() { - return QuestPreferences.matchRewardMullToZero; - } - - // setters - /** - *

- * setDifficulty. - *

- * - * @param diff - * a {@link java.lang.String} object. - */ - public static void setDifficulty(final String diff) { - QuestPreferences.sDifficulty = diff.split(","); - } - - /** - *

- * Setter for the field winsForBooster. - *

- * - * @param wins - * a {@link java.lang.String} object. - */ - public static void setWinsForBooster(final String wins) { - final String[] winsStr = wins.split(","); - - for (int i = 0; i < QuestPreferences.numDiff; i++) { - QuestPreferences.winsForBooster[i] = Integer.parseInt(winsStr[i]); + public void setPreference(String s0, String s1) { + try { + preferenceValues.put(QPref.valueOf(s0), s1); + } + catch (Exception e) { } } /** - *

- * setWinsForRank. - *

- * - * @param wins - * a {@link java.lang.String} object. + * @param q0   {@link forge.quest.data.CopyOfQuestPreferences.QPref} + * @param s0   {@link java.lang.String} value */ - public static void setWinsForRank(final String wins) { - final String[] winsStr = wins.split(","); + public void setPreference(QPref q0, String s0) { + preferenceValues.put(q0, s0); + } - for (int i = 0; i < QuestPreferences.numDiff; i++) { - QuestPreferences.winsForRankIncrease[i] = Integer.parseInt(winsStr[i]); + /** + * Returns a non-difficulty-indexed preference value. + * + * @param qp0   {@link forge.quest.data.CopyOfQuestPreferences.QPref} + * @return String + */ + public String getPreference(QPref qp0) { + String val; + + if (qp0.getDefault().equals("DIFFICULTY_INDEX_REQD")) { + // This error indicates that this is a preference + // value which is different based on difficulty. + // A difficulty index must be passed to determine + // which value is appropriate for this setting. + // To do this, use getPreference(QPref, int). + try { throw new Exception(); } + catch (Exception e1) { e1.printStackTrace(); } } + + val = preferenceValues.get(qp0); + if (val == null) { val = qp0.getDefault(); } + + return val; } /** - *

- * Setter for the field winsForMediumAI. - *

+ * Returns a preference value according to a difficulty index. * - * @param wins - * a {@link java.lang.String} object. + * @param qp0   {@link forge.quest.data.CopyOfQuestPreferences.QPref} + * @param i0   int difficulty index + * @return String */ - public static void setWinsForMediumAI(final String wins) { - final String[] winsStr = wins.split(","); + public String getPreference(QPref qp0, int i0) { + String val; + String newQPref = qp0.toString(); + QPref q; - for (int i = 0; i < QuestPreferences.numDiff; i++) { - QuestPreferences.winsForMediumAI[i] = Integer.parseInt(winsStr[i]); + switch(i0) { + case 0: newQPref += "_EASY"; break; + case 1: newQPref += "_MEDIUM"; break; + case 2: newQPref += "_HARD"; break; + case 3: newQPref += "_EXPERT"; break; + default: + try { throw new Exception(); } + catch (Exception e1) { + System.err.println("Difficulty index (" + i0 + ") out of bounds! "); + e1.printStackTrace(); + } } + + q = QPref.valueOf(newQPref); + val = preferenceValues.get(q); + if (val == null) { val = q.getDefault(); } + + return val; } /** - *

- * Setter for the field winsForHardAI. - *

+ * Returns a non-difficulty-indexed preference value, as an int. * - * @param wins - * a {@link java.lang.String} object. + * @param qp0   {@link forge.quest.data.CopyOfQuestPreferences.QPref} + * @return int */ - public static void setWinsForHardAI(final String wins) { - final String[] winsStr = wins.split(","); + public int getPreferenceInt(QPref qp0) { + return Integer.parseInt(getPreference(qp0)); + } - for (int i = 0; i < QuestPreferences.numDiff; i++) { - QuestPreferences.winsForHardAI[i] = Integer.parseInt(winsStr[i]); + /** + * Returns a difficulty-indexed preference value, as an int. + * + * @param qp0   {@link forge.quest.data.CopyOfQuestPreferences.QPref} + * @param i0   int difficulty index + * @return int + */ + public int getPreferenceInt(QPref qp0, int i0) { + return Integer.parseInt(getPreference(qp0, i0)); + } + + /** + * @param i   int + * @return String + */ + public static String getDifficulty(int i) { + String s; + switch(i) { + case 1: s = "EASY"; break; + case 2: s = "MEDIUM"; break; + case 3: s = "HARD"; break; + case 4: s = "EXPERT"; break; + default: s = "UNKNOWN"; } - } - - /** - *

- * setStartingBasic. - *

- * - * @param land - * a {@link java.lang.String} object. - */ - public static void setStartingBasic(final String land) { - QuestPreferences.startingBasicLand = Integer.parseInt(land); - } - - /** - *

- * setStartingSnowBasic. - *

- * - * @param land - * a {@link java.lang.String} object. - */ - public static void setStartingSnowBasic(final String land) { - QuestPreferences.startingSnowBasicLand = Integer.parseInt(land); - } - - /** - *

- * Setter for the field startingCommons. - *

- * - * @param rarity - * a {@link java.lang.String} object. - */ - public static void setStartingCommons(final String rarity) { - final String[] splitStr = rarity.split(","); - - for (int i = 0; i < QuestPreferences.numDiff; i++) { - QuestPreferences.startingCommons[i] = Integer.parseInt(splitStr[i]); - } - } - - /** - *

- * Setter for the field startingUncommons. - *

- * - * @param rarity - * a {@link java.lang.String} object. - */ - public static void setStartingUncommons(final String rarity) { - final String[] splitStr = rarity.split(","); - - for (int i = 0; i < QuestPreferences.numDiff; i++) { - QuestPreferences.startingUncommons[i] = Integer.parseInt(splitStr[i]); - } - } - - /** - *

- * Setter for the field startingRares. - *

- * - * @param rarity - * a {@link java.lang.String} object. - */ - public static void setStartingRares(final String rarity) { - final String[] splitStr = rarity.split(","); - - for (int i = 0; i < QuestPreferences.numDiff; i++) { - QuestPreferences.startingRares[i] = Integer.parseInt(splitStr[i]); - } - } - - /** - *

- * Setter for the field startingCredits. - *

- * - * @param credits - * a {@link java.lang.String} object. - */ - public static void setStartingCredits(final String credits) { - QuestPreferences.startingCredits = Integer.parseInt(credits); - } - - /** - *

- * setNumCommon. - *

- * - * @param pack - * a {@link java.lang.String} object. - */ - public static void setNumCommon(final String pack) { - QuestPreferences.boosterPackCommon = Integer.parseInt(pack); - } - - /** - *

- * setNumUncommon. - *

- * - * @param pack - * a {@link java.lang.String} object. - */ - public static void setNumUncommon(final String pack) { - QuestPreferences.boosterPackUncommon = Integer.parseInt(pack); - } - - /** - *

- * setNumRares. - *

- * - * @param pack - * a {@link java.lang.String} object. - */ - public static void setNumRares(final String pack) { - QuestPreferences.boosterPackRare = Integer.parseInt(pack); - } - - /** - *

- * Setter for the field matchRewardBase. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardBase(final String match) { - QuestPreferences.matchRewardBase = Integer.parseInt(match); - } - - /** - *

- * Setter for the field matchRewardTotalWins. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardTotalWins(final String match) { - QuestPreferences.matchRewardTotalWins = Double.parseDouble(match); - } - - /** - *

- * Setter for the field matchRewardNoLosses. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardNoLosses(final String match) { - QuestPreferences.matchRewardNoLosses = Integer.parseInt(match); - } - - /** - *

- * Setter for the field matchRewardPoisonWinBonus. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardPoisonWinBonus(final String match) { - QuestPreferences.matchRewardPoisonWinBonus = Integer.parseInt(match); - } - - /** - *

- * Setter for the field matchRewardMilledWinBonus. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardMilledWinBonus(final String match) { - QuestPreferences.matchRewardMilledWinBonus = Integer.parseInt(match); - } - - /** - *

- * Setter for the field matchRewardAltWinBonus. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardAltWinBonus(final String match) { - QuestPreferences.matchRewardAltWinBonus = Integer.parseInt(match); - } - - /** - *

- * setMatchRewardWinFirst. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardWinFirst(final String match) { - QuestPreferences.matchRewardWinOnFirstTurn = Integer.parseInt(match); - } - - /** - *

- * setMatchRewardWinByFifth. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardWinByFifth(final String match) { - QuestPreferences.matchRewardWinByTurnFive = Integer.parseInt(match); - } - - /** - *

- * setMatchRewardWinByTen. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardWinByTen(final String match) { - QuestPreferences.matchRewardWinByTurnTen = Integer.parseInt(match); - } - - /** - *

- * setMatchRewardWinByFifteen. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchRewardWinByFifteen(final String match) { - QuestPreferences.matchRewardWinByTurnFifteen = Integer.parseInt(match); - } - - /** - *

- * setMatchMullToZero. - *

- * - * @param match - * a {@link java.lang.String} object. - */ - public static void setMatchMullToZero(final String match) { - QuestPreferences.matchRewardMullToZero = Integer.parseInt(match); + return s; } } diff --git a/src/main/java/forge/quest/data/QuestUtilCards.java b/src/main/java/forge/quest/data/QuestUtilCards.java index d09dc6a3fa5..c60222dd494 100644 --- a/src/main/java/forge/quest/data/QuestUtilCards.java +++ b/src/main/java/forge/quest/data/QuestUtilCards.java @@ -24,6 +24,7 @@ import java.util.Map.Entry; import net.slightlymagic.braids.util.lambda.Lambda1; import net.slightlymagic.maxmtg.Predicate; import forge.SetUtils; +import forge.Singletons; import forge.card.BoosterGenerator; import forge.card.BoosterUtils; import forge.card.CardRarity; @@ -36,6 +37,7 @@ import forge.item.InventoryItem; import forge.item.ItemPool; import forge.item.ItemPoolView; import forge.item.PreconDeck; +import forge.quest.data.QuestPreferences.QPref; import forge.util.MyRandom; /** @@ -44,6 +46,7 @@ import forge.util.MyRandom; */ public final class QuestUtilCards { private final QuestData q; + private final QuestPreferences qpref; /** * Instantiates a new quest util cards. @@ -53,6 +56,7 @@ public final class QuestUtilCards { */ public QuestUtilCards(final QuestData qd) { this.q = qd; + this.qpref = Singletons.getModel().getQuestPreferences(); } /** @@ -93,9 +97,9 @@ public final class QuestUtilCards { * @return the array list */ public ArrayList addCards(final Predicate fSets) { - final int nCommon = QuestPreferences.getNumCommon(); - final int nUncommon = QuestPreferences.getNumUncommon(); - final int nRare = QuestPreferences.getNumRare(); + final int nCommon = qpref.getPreferenceInt(QPref.BOOSTER_COMMONS); + final int nUncommon = qpref.getPreferenceInt(QPref.BOOSTER_UNCOMMONS); + final int nRare = qpref.getPreferenceInt(QPref.BOOSTER_RARES); final ArrayList newCards = new ArrayList(); newCards.addAll(BoosterUtils.generateCards(fSets, nCommon, CardRarity.Common, null)); @@ -166,9 +170,9 @@ public final class QuestUtilCards { * the idx difficulty */ public void setupNewGameCardPool(final Predicate filter, final int idxDifficulty) { - final int nC = QuestPreferences.getStartingCommons(idxDifficulty); - final int nU = QuestPreferences.getStartingUncommons(idxDifficulty); - final int nR = QuestPreferences.getStartingRares(idxDifficulty); + final int nC = qpref.getPreferenceInt(QPref.STARTING_COMMONS, idxDifficulty); + final int nU = qpref.getPreferenceInt(QPref.STARTING_UNCOMMONS, idxDifficulty); + final int nR = qpref.getPreferenceInt(QPref.STARTING_RARES, idxDifficulty); this.addAllCards(BoosterUtils.getQuestStarterDeck(filter, nC, nU, nR)); } diff --git a/src/main/java/forge/quest/gui/QuestOptions.java b/src/main/java/forge/quest/gui/QuestOptions.java index 969ff56fecd..eba53c7f805 100644 --- a/src/main/java/forge/quest/gui/QuestOptions.java +++ b/src/main/java/forge/quest/gui/QuestOptions.java @@ -43,7 +43,6 @@ import forge.error.ErrorViewer; import forge.gui.GuiUtils; import forge.quest.data.QuestData; import forge.quest.data.QuestDataIO; -import forge.quest.data.QuestPreferences; /** *

@@ -131,7 +130,7 @@ public class QuestOptions extends JFrame { *

*/ private void setupRadioButtonText() { - final String[] diff = QuestPreferences.getDifficulty(); + /*final String[] diff = QuestPreferences.getDifficulty(); final JRadioButton[] b = { this.easyRadio, this.mediumRadio, this.hardRadio, this.veryHardRadio }; for (int i = 0; i < diff.length; i++) { @@ -140,7 +139,7 @@ public class QuestOptions extends JFrame { final int numGames = numberLevels * QuestPreferences.getWinsForRankIncrease(i); b[i].setText(String.format("%s - %d", diff[i], numGames)); - } + }*/ } // setupRadioButtonText() diff --git a/src/main/java/forge/quest/gui/QuestWinLoseHandler.java b/src/main/java/forge/quest/gui/QuestWinLoseHandler.java index ee97b42f40c..03c729a3d9d 100644 --- a/src/main/java/forge/quest/gui/QuestWinLoseHandler.java +++ b/src/main/java/forge/quest/gui/QuestWinLoseHandler.java @@ -49,6 +49,7 @@ import forge.quest.data.QuestChallenge; import forge.quest.data.QuestData; import forge.quest.data.QuestEvent; import forge.quest.data.QuestPreferences; +import forge.quest.data.QuestPreferences.QPref; import forge.quest.data.QuestUtil; import forge.util.MyRandom; import forge.view.GuiTopLevel; @@ -75,13 +76,14 @@ public class QuestWinLoseHandler extends ControlWinLose { /** String constraint parameters for title blocks and cardviewer blocks. */ private final String constraintsTitle = "w 95%!, gap 0 0 20px 10px"; - private final String constraintsText = "w 95%!,, h 150px!, gap 0 0 0 20px"; + private final String constraintsText = "w 95%!,, h 180px!, gap 0 0 0 20px"; private final String constraintsCards = "w 95%!, h 330px!, gap 0 0 0 20px"; private class CommonObjects { private FMatchState matchState; private QuestData qData; private QuestEvent qEvent; + private QuestPreferences qPrefs; } private final CommonObjects model; @@ -98,6 +100,7 @@ public class QuestWinLoseHandler extends ControlWinLose { this.model.matchState = AllZone.getMatchState(); this.model.qData = AllZone.getQuestData(); this.model.qEvent = AllZone.getQuestEvent(); + this.model.qPrefs = Singletons.getModel().getQuestPreferences(); this.wonMatch = this.model.matchState.isMatchWonBy(AllZone.getHumanPlayer().getName()); this.skin = Singletons.getView().getSkin(); this.isAnte = Singletons.getModel().getPreferences().isPlayForAnte(); @@ -217,7 +220,7 @@ public class QuestWinLoseHandler extends ControlWinLose { // Win or lose, still a chance to win a booster, frequency set in // preferences final int outcome = this.wonMatch ? this.model.qData.getWin() : this.model.qData.getLost(); - if ((outcome % QuestPreferences.getWinsForBooster(this.model.qData.getDifficultyIndex())) == 0) { + if ((outcome % this.model.qPrefs.getPreferenceInt(QPref.WINS_BOOSTER, this.model.qData.getDifficultyIndex())) == 0) { this.awardBooster(); } @@ -274,12 +277,14 @@ public class QuestWinLoseHandler extends ControlWinLose { */ @Override public final void actionOnQuit() { + int x = Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.PENALTY_LOSS); + // Record win/loss in quest data if (this.wonMatch) { this.model.qData.addWin(); } else { this.model.qData.addLost(); - this.model.qData.subtractCredits(15); + this.model.qData.subtractCredits(x); } this.model.qData.getCards().clearShopList(); @@ -317,7 +322,7 @@ public class QuestWinLoseHandler extends ControlWinLose { int credEstates = 0; // Basic win bonus - final int base = QuestPreferences.getMatchRewardBase(); + final int base = this.model.qPrefs.getPreferenceInt(QPref.REWARDS_BASE); double multiplier = 1; String diff = AllZone.getQuestEvent().getDifficulty(); @@ -332,8 +337,11 @@ public class QuestWinLoseHandler extends ControlWinLose { } else if (diff.equalsIgnoreCase("expert")) { multiplier = 3; } - credBase += (int) ((base * multiplier) + (QuestPreferences.getMatchRewardTotalWins() * this.model.qData - .getWin())); + + credBase += (int) ((base * multiplier) + + (Double.parseDouble(this.model.qPrefs.getPreference(QPref.REWARDS_WINS_MULTIPLIER)) + * this.model.qData.getWin())); + sb.append(diff + " opponent: " + credBase + " credits.
"); // Gameplay bonuses (for each game win) boolean hasNeverLost = true; @@ -375,7 +383,7 @@ public class QuestWinLoseHandler extends ControlWinLose { } // Mulligan to zero final int cntCardsHumanStartedWith = humanRating.getOpeningHandSize(); - final int mulliganReward = QuestPreferences.getMatchMullToZero(); + final int mulliganReward = this.model.qPrefs.getPreferenceInt(QPref.REWARDS_MULLIGAN0); if (0 == cntCardsHumanStartedWith) { credGameplay += mulliganReward; @@ -407,8 +415,8 @@ public class QuestWinLoseHandler extends ControlWinLose { // Undefeated bonus if (hasNeverLost) { - credUndefeated += QuestPreferences.getMatchRewardNoLosses(); - final int reward = QuestPreferences.getMatchRewardNoLosses(); + credUndefeated += this.model.qPrefs.getPreferenceInt(QPref.REWARDS_UNDEFEATED); + final int reward = this.model.qPrefs.getPreferenceInt(QPref.REWARDS_UNDEFEATED); sb.append(String.format("You have not lost once! " + "Bonus: %d credits.
", reward)); } @@ -581,11 +589,12 @@ public class QuestWinLoseHandler extends ControlWinLose { } private void penalizeLoss() { + int x = Singletons.getModel().getQuestPreferences().getPreferenceInt(QPref.PENALTY_LOSS); this.icoTemp = GuiUtils.getResizedIcon("HeartIcon.png", 0.5); this.lblTemp1 = new TitleLabel("Gameplay Results"); - this.lblTemp2 = new JLabel("You lose! You have lost 15 credits."); + this.lblTemp2 = new JLabel("You lose! You have lost " + x + " credits."); this.lblTemp2.setFont(skin.getFont(14)); this.lblTemp2.setForeground(Color.white); this.lblTemp2.setHorizontalAlignment(SwingConstants.CENTER); @@ -625,18 +634,13 @@ public class QuestWinLoseHandler extends ControlWinLose { case LifeReachedZero: return 0; // nothing special here, ordinary kill case Milled: - return QuestPreferences.getMatchRewardMilledWinBonus(); + return this.model.qPrefs.getPreferenceInt(QPref.REWARDS_MILLED); case Poisoned: - return QuestPreferences.getMatchRewardPoisonWinBonus(); - case DidNotLoseYet: - return QuestPreferences.getMatchRewardAltWinBonus(); // Felidar, - // Helix - // Pinnacle, - // etc. - case SpellEffect: - return QuestPreferences.getMatchRewardAltWinBonus(); // Door to - // Nothingness, - // etc. + return this.model.qPrefs.getPreferenceInt(QPref.REWARDS_POISON); + case DidNotLoseYet: // Felidar, Helix Pinnacle, etc. + return this.model.qPrefs.getPreferenceInt(QPref.REWARDS_UNDEFEATED); + case SpellEffect: // Door to Nothingness, etc. + return this.model.qPrefs.getPreferenceInt(QPref.REWARDS_UNDEFEATED); default: return 0; } @@ -655,13 +659,13 @@ public class QuestWinLoseHandler extends ControlWinLose { int credits = 0; if (iTurn == 1) { - credits = QuestPreferences.getMatchRewardWinFirst(); + credits = this.model.qPrefs.getPreferenceInt(QPref.REWARDS_TURN1); } else if (iTurn <= 5) { - credits = QuestPreferences.getMatchRewardWinByFifth(); + credits = this.model.qPrefs.getPreferenceInt(QPref.REWARDS_TURN5); } else if (iTurn <= 10) { - credits = QuestPreferences.getMatchRewardWinByTen(); + credits = this.model.qPrefs.getPreferenceInt(QPref.REWARDS_TURN10); } else if (iTurn <= 15) { - credits = QuestPreferences.getMatchRewardWinByFifteen(); + credits = this.model.qPrefs.getPreferenceInt(QPref.REWARDS_TURN15); } return credits; diff --git a/src/main/java/forge/view/home/HomeTopLevel.java b/src/main/java/forge/view/home/HomeTopLevel.java index 9cbefc06d8e..a7e966befaa 100644 --- a/src/main/java/forge/view/home/HomeTopLevel.java +++ b/src/main/java/forge/view/home/HomeTopLevel.java @@ -22,6 +22,7 @@ import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import javax.swing.AbstractAction; +import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; @@ -262,4 +263,24 @@ public class HomeTopLevel extends FPanel { public ControlHomeUI getController() { return control; } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnConstructed() { + return this.btnConstructed; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnSealed() { + return this.btnSealed; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnDraft() { + return this.btnDraft; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnQuest() { + return this.btnQuest; + } } diff --git a/src/main/java/forge/view/home/QuestFileLister.java b/src/main/java/forge/view/home/QuestFileLister.java new file mode 100644 index 00000000000..e5cf4526bca --- /dev/null +++ b/src/main/java/forge/view/home/QuestFileLister.java @@ -0,0 +1,335 @@ +package forge.view.home; + +import java.awt.Color; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.border.MatteBorder; + +import net.miginfocom.swing.MigLayout; +import forge.Command; +import forge.Singletons; +import forge.gui.GuiUtils; +import forge.quest.data.QuestData; +import forge.view.toolbox.FLabel; +import forge.view.toolbox.FSkin; + +/** + * Creates file list/table for quick deleting, editing, and basic info. + * + */ +@SuppressWarnings("serial") +public class QuestFileLister extends JPanel { + private ImageIcon icoDelete, icoDeleteOver, icoEdit, icoEditOver; + private FSkin skin; + private RowPanel previousSelect; + private RowPanel[] rows; + private Command cmdRowSelect, cmdRowDelete, cmdRowEdit; + private final Color clrDefault, clrHover, clrActive, clrBorders; + + /** */ + public QuestFileLister() { + this(true, true); + } + + /** + * Creates deck list for selected decks for quick deleting, editing, and basic info. + * Set "selectable" and "editable" to show those buttons, or not. + * + * @param deletable {@link java.lang.Boolean} + * @param editable {@link java.lang.Boolean} + */ + public QuestFileLister(final boolean deletable, final boolean editable) { + super(); + this.skin = Singletons.getView().getSkin(); + + this.clrDefault = new Color(0, 0, 0, 0); + this.clrHover = skin.getColor(FSkin.SkinProp.CLR_HOVER); + this.clrActive = skin.getColor(FSkin.SkinProp.CLR_ACTIVE); + this.clrBorders = skin.getColor(FSkin.SkinProp.CLR_BORDERS); + + this.setOpaque(false); + this.setLayout(new MigLayout("insets 0, gap 0, wrap")); + + icoDelete = new ImageIcon("res/images/icons/DeleteIcon.png"); + icoDeleteOver = new ImageIcon("res/images/icons/DeleteIconOver.png"); + icoEdit = new ImageIcon("res/images/icons/EditIcon.png"); + icoEditOver = new ImageIcon("res/images/icons/EditIconOver.png"); + } + + /** @param qd0   {@link forge.quest.data.QuestData}[] */ + public void setQuests(QuestData[] qd0) { + this.removeAll(); + List tempRows = new ArrayList(); + + // Title row + // Note: careful with the widths of the rows here; + // scroll panes will have difficulty dynamically resizing if 100% width is set. + final JPanel rowTitle = new JPanel(); + rowTitle.setBackground(skin.getColor(FSkin.SkinProp.CLR_ZEBRA)); + rowTitle.setLayout(new MigLayout("insets 0, gap 0")); + rowTitle.add(new FLabel("Delete", SwingConstants.CENTER), "w 15%!, h 20px!, gap 0 0 5px 0"); + rowTitle.add(new FLabel("Edit", SwingConstants.CENTER), "w 15%!, h 20px!, gap 0 0 5px 0"); + rowTitle.add(new FLabel("Name", SwingConstants.CENTER), "w 40%!, h 20px!, gap 0 0 5px 0"); + rowTitle.add(new FLabel("Mode", SwingConstants.CENTER), "w 15%!, h 20px!, gap 0 0 5px 0"); + rowTitle.add(new FLabel("Record", SwingConstants.CENTER), "w 15%!, h 20px!, gap 0 0 5px 0"); + this.add(rowTitle, "w 98%!, h 30px!, gapleft 1%"); + + RowPanel row; + for (QuestData qd : qd0) { + row = new RowPanel(qd); + row.add(new DeleteButton(row), "w 15%!, h 20px!, gap 0 0 5px 0"); + row.add(new EditButton(row), "w 15%!, h 20px!, gaptop 5px"); + row.add(new FLabel(qd.getName()), "w 40%!, h 20px!, gap 0 0 5px 0"); + row.add(new FLabel(qd.getMode(), SwingConstants.CENTER), "w 15%!, h 20px!, gap 0 0 5px 0"); + row.add(new FLabel(qd.getWin() + "/" + qd.getLost(), SwingConstants.CENTER), "w 15%!, h 20px!, gap 0 0 5px 0"); + this.add(row, "w 98%!, h 30px!, gap 1% 0 0 0"); + tempRows.add(row); + } + + rows = tempRows.toArray(new RowPanel[0]); + revalidate(); + } + + /** @return {@link forge.deck.Deck} */ + public QuestData getSelectedQuest() { + return previousSelect.getQuestData(); + } + + private class DeleteButton extends JButton { + public DeleteButton(final RowPanel r0) { + super(); + setRolloverEnabled(true); + setPressedIcon(icoDeleteOver); + setRolloverIcon(icoDeleteOver); + setIcon(icoDelete); + setOpaque(false); + setContentAreaFilled(false); + setBorder(null); + setBorderPainted(false); + setToolTipText("Delete this deck"); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + if (!r0.selected) { + r0.setBackground(clrHover); + r0.setOpaque(true); + } + } + @Override + public void mouseExited(MouseEvent e) { + if (!r0.selected) { + r0.setBackground(clrDefault); + r0.setOpaque(false); + } + } + @Override + public void mouseClicked(MouseEvent e) { + deleteFile(r0); + } + }); + } + } + + private class EditButton extends JButton { + public EditButton(final RowPanel r0) { + super(); + setRolloverEnabled(true); + setPressedIcon(icoEditOver); + setRolloverIcon(icoEditOver); + setIcon(icoEdit); + setOpaque(false); + setContentAreaFilled(false); + setBorder(null); + setBorderPainted(false); + setToolTipText("Edit this deck"); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + if (!r0.selected) { + r0.setBackground(clrHover); + r0.setOpaque(true); + } + } + @Override + public void mouseExited(MouseEvent e) { + if (!r0.selected) { + r0.setBackground(clrDefault); + r0.setOpaque(false); + } + } + @Override + public void mouseClicked(MouseEvent e) { + editFileName(r0.getQuestData().getName()); + } + }); + } + } + + private class RowPanel extends JPanel { + private boolean selected = false; + private QuestData questData; + + public RowPanel(QuestData qd0) { + super(); + setOpaque(false); + setBackground(new Color(0, 0, 0, 0)); + setLayout(new MigLayout("insets 0, gap 0")); + setBorder(new MatteBorder(0, 0, 1, 0, clrBorders)); + questData = qd0; + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + if (!selected) { + ((RowPanel) e.getSource()).setBackground(clrHover); + ((RowPanel) e.getSource()).setOpaque(true); + } + } + @Override + public void mouseExited(MouseEvent e) { + if (!selected) { + ((RowPanel) e.getSource()).setBackground(clrDefault); + ((RowPanel) e.getSource()).setOpaque(false); + } + } + @Override + public void mousePressed(MouseEvent e) { + selectHandler((RowPanel) e.getSource()); + } + }); + } + + public void setSelected(boolean b0) { + selected = b0; + setOpaque(b0); + setBackground(b0 ? clrActive : clrHover); + } + + public boolean isSelected() { + return selected; + } + + public QuestData getQuestData() { + return questData; + } + } + + /** @return {@link java.lang.Integer} */ + public int getSelectedIndex() { + for (int i = 0; i < rows.length; i++) { + if (rows[i].isSelected()) { return i; } + } + return -1; + } + + /** Selects a row programatically. + * @param i0   int + * @return boolean success + */ + public boolean setSelectedIndex(int i0) { + if (i0 >= rows.length) { return false; } + selectHandler(rows[i0]); + return true; + } + + /** + * @param qd0   Quest data object to select (if exists in list) + * @return boolean success + */ + public boolean setSelectedQuestData(QuestData qd0) { + for (RowPanel r : rows) { + if (r.getQuestData().getName().equals(qd0.getName())) { + selectHandler(r); + return true; + } + } + return false; + } + + /** @param c0   {@link forge.Command} command executed on row select. */ + public void setSelectCommand(Command c0) { + this.cmdRowSelect = c0; + } + + /** @param c0   {@link forge.Command} command executed on row edit. */ + public void setEditCommand(Command c0) { + this.cmdRowEdit = c0; + } + + /** @param c0   {@link forge.Command} command executed on delete. */ + public void setDeleteCommand(Command c0) { + this.cmdRowDelete = c0; + } + + private void selectHandler(RowPanel r0) { + if (previousSelect != null) { + previousSelect.setSelected(false); + } + r0.setSelected(true); + previousSelect = r0; + + if (cmdRowSelect != null) { cmdRowSelect.execute(); } + } + + private void editFileName(String s0) { + final Object o = JOptionPane.showInputDialog(null, + "Rename Quest to:", "Quest Rename", JOptionPane.OK_CANCEL_OPTION); + + if (o == null) { return; } + + final String questName = GuiUtils.cleanString(o.toString()); + + boolean exists = false; + + for (RowPanel r : rows) { + if (r.getQuestData().getName().equalsIgnoreCase(questName)) { + exists = true; + break; + } + } + + if (exists || questName.equals("")) { + JOptionPane.showMessageDialog(null, "Please pick another quest name, a quest already has that name."); + return; + } + else { + File newpath = new File("res/quest/data/" + questName + ".dat"); + File oldpath = new File("res/quest/data/" + s0 + ".dat"); + + oldpath.renameTo(newpath); + } + + if (cmdRowEdit != null) { cmdRowEdit.execute(); } + } + + private void deleteFile(RowPanel r0) { + final QuestData qd = r0.getQuestData(); + + final int n = JOptionPane.showConfirmDialog(null, + "Are you sure you want to delete \"" + qd.getName() + + "\" ?", "Delete Deck", JOptionPane.YES_NO_OPTION); + + if (n == JOptionPane.NO_OPTION) { + return; + } + + new File("res/quest/data/" + r0.getQuestData().getName() + ".dat").delete(); + + if (cmdRowDelete != null) { cmdRowDelete.execute(); } + + this.remove(r0); + this.repaint(); + this.revalidate(); + } +} diff --git a/src/main/java/forge/view/home/SubTab.java b/src/main/java/forge/view/home/SubTab.java new file mode 100644 index 00000000000..7219d2373d3 --- /dev/null +++ b/src/main/java/forge/view/home/SubTab.java @@ -0,0 +1,96 @@ +package forge.view.home; + +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Graphics; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JLabel; +import javax.swing.JPanel; + +import forge.Singletons; +import forge.view.toolbox.FSkin; + +/** Standardized tab for submenus in home screen. */ +public class SubTab extends JPanel { + private static final long serialVersionUID = -2193833603356739321L; + private final Color clrBorders, clrHover; + private final MouseAdapter madHover; + private final FSkin skin; + + private boolean enabled = false; + private boolean hovering = false; + private int w, h; + + /** @param s0   {@link java.lang.String} tab text */ + public SubTab(String s0) { + super(); + this.setOpaque(false); + this.skin = Singletons.getView().getSkin(); + this.clrBorders = skin.getColor(FSkin.SkinProp.CLR_BORDERS); + this.clrHover = skin.getColor(FSkin.SkinProp.CLR_HOVER); + this.setCursor(new Cursor(Cursor.HAND_CURSOR)); + + this.madHover = new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + hovering = true; + repaint(); + } + @Override + public void mouseExited(MouseEvent e) { + hovering = false; + repaint(); + } + }; + this.removeMouseListener(madHover); + this.addMouseListener(madHover); + + final JLabel lbl = new JLabel(s0); + lbl.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); + lbl.setFont(skin.getFont(12)); + this.add(lbl); + } + + /** @param b0   {@link java.lang.Boolean} */ + public void setEnabled(boolean b0) { + this.enabled = b0; + this.repaint(); + } + + /** @return {@link java.lang.Boolean} */ + public boolean isEnabled() { + return this.enabled; + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + w = getWidth(); + h = getHeight(); + + g.setColor(clrBorders); + + if (this.enabled) { + g.drawLine(0, h - 1, 3, h - 1); // SW + g.drawLine(3, 10, 3, h); // W + g.drawArc(3, 0, 20, 20, 90, 90); //NW + g.drawLine(13, 0, w - 13, 0); //N + g.drawArc(w - 23, 0, 20, 20, 90, -90); //NE + g.drawLine(w - 3, 10, w - 3, h); //E + g.drawLine(w - 3, h - 1, w, h - 1); //SE + } + else if (this.hovering) { + g.drawLine(0, h - 1, w, h - 1); + g.setColor(clrHover); + g.fillArc(3, 0, 20, 20, 90, 90); //NW + g.fillArc(w - 23, 0, 20, 20, 90, -90); //NE + g.fillRect(3, 10, w - 6, h - 12); // Bottom + g.fillRect(13, 0, w - 26, 10); // Top + } + else { + g.drawLine(0, h - 1, w, h - 1); + } + } +} diff --git a/src/main/java/forge/view/home/ViewQuest.java b/src/main/java/forge/view/home/ViewQuest.java index aa9c636ec16..315142133b9 100644 --- a/src/main/java/forge/view/home/ViewQuest.java +++ b/src/main/java/forge/view/home/ViewQuest.java @@ -1,48 +1,42 @@ package forge.view.home; -import java.awt.Graphics; -import java.awt.event.ActionEvent; +import java.awt.Color; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.util.List; -import java.util.Set; -import javax.swing.AbstractAction; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; -import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; -import javax.swing.JTextArea; import javax.swing.SwingConstants; -import javax.swing.border.LineBorder; import javax.swing.border.MatteBorder; import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Singletons; import forge.control.home.ControlQuest; -import forge.gui.GuiUtils; +import forge.game.GameType; import forge.properties.ForgeProps; import forge.properties.NewConstants; import forge.quest.data.QuestChallenge; -import forge.quest.data.QuestData; -import forge.quest.data.QuestDataIO; import forge.quest.data.QuestDuel; import forge.quest.data.QuestEvent; -import forge.quest.data.QuestEventManager; -import forge.quest.data.item.QuestItemZeppelin; -import forge.quest.data.pet.QuestPetAbstract; -import forge.view.toolbox.FList; +import forge.view.toolbox.DeckLister; +import forge.view.toolbox.FCheckBox; +import forge.view.toolbox.FLabel; import forge.view.toolbox.FProgressBar; +import forge.view.toolbox.FRadioButton; +import forge.view.toolbox.FRoundedPanel; import forge.view.toolbox.FScrollPane; import forge.view.toolbox.FSkin; +import forge.view.toolbox.FTextArea; /** * Populates Swing components of Quest mode in home screen. @@ -52,424 +46,473 @@ import forge.view.toolbox.FSkin; public class ViewQuest extends JScrollPane { private final FSkin skin; private final HomeTopLevel parentView; - private QuestEventManager qem; - private QuestData questData; - private JPanel viewport; + private final ControlQuest control; + private final String eventPanelConstraints; + private final Color clrBorders; + private final JPanel pnlViewport, pnlTabber, pnlStats, + pnlDuels, pnlChallenges, pnlStart, pnlTitle, pnlNewQuest, + pnlDecks, pnlLoadQuest, pnlPrefs, + tabDuels, tabChallenges, tabDecks, tabQuests, tabPreferences; + private final JLabel lblTitle, lblLife, lblCredits, + lblWins, lblLosses, lblNextChallengeInWins, lblWinStreak; + + private final JButton btnBazaar, btnSpellShop, btnStart, btnEmbark, btnNewDeck, btnCurrentDeck; + + private final JCheckBox cbPlant, cbZep, cbStandardStart; + private final JComboBox cbxPet; + private final JRadioButton radEasy, radMedium, radHard, radExpert, radFantasy, radClassic; + private SelectablePanel selectedOpponent; - private JList lstDeckChooser; - private ControlQuest control; - private FProgressBar barProgress; - private JRadioButton radEasy, radMedium, radHard, radExpert, radFantasy, radClassic; - private JCheckBox cbStandardStart, cbPlant, cbZep; - private JComboBox cbxPet; - private JLabel lblPlant, lblPet, lblZep, lblLife, lblCredits; - private boolean previousQuestExists = false; - private JButton btnStart; + private DeckLister lstDecks; + private QuestFileLister lstQuests; + private final FProgressBar barProgress; /** * Populates Swing components of Quest mode in home screen. * - * @param v0   HomeTopLevel parent view + * @param v0   {@link forge.view.home.HomeTopLevel} parent view */ - public ViewQuest(HomeTopLevel v0) { - // Basic init stuff - super(VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_AS_NEEDED); - this.setOpaque(false); + public ViewQuest(final HomeTopLevel v0) { + // Display + super(VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); this.setBorder(null); - this.getVerticalScrollBar().setUnitIncrement(16); - parentView = v0; - skin = Singletons.getView().getSkin(); - - // Title and viewport. Panel is put into scroll pane for resize safety. - viewport = new JPanel(); - viewport.setOpaque(false); - viewport.setLayout(new MigLayout("insets 0, gap 0, wrap 2")); + this.setOpaque(false); this.getViewport().setOpaque(false); + this.getVerticalScrollBar().setUnitIncrement(16); - JLabel lblTitle = new JLabel(); - lblTitle.setOpaque(true); - lblTitle.setBorder(new MatteBorder(0, 0, 1, 0, skin.getColor(FSkin.SkinProp.CLR_BORDERS))); - lblTitle.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblTitle.setBackground(skin.getColor(FSkin.SkinProp.CLR_THEME).darker()); - lblTitle.setFont(skin.getBoldFont(20)); - viewport.add(lblTitle, "w 90%!, h 50px!, gap 5% 0 2% 0, span 2"); + // Non-final inits + this.parentView = v0; + this.skin = Singletons.getView().getSkin(); + this.clrBorders = skin.getColor(FSkin.SkinProp.CLR_THEME).darker().darker(); + this.eventPanelConstraints = "w 100%!, h 80px!, gap 0 0 5px 5px"; - File f = new File("res/quest/questData.dat"); - if (f.exists()) { - AllZone.setQuestData(QuestDataIO.loadData()); - questData = AllZone.getQuestData(); - previousQuestExists = true; + // Final component inits + tabDuels = new SubTab("Duels"); + tabChallenges = new SubTab("Challenges"); + tabDecks = new SubTab("Decks"); + tabQuests = new SubTab("Quests"); + tabPreferences = new SubTab("Preferences"); - lblTitle.setText(" " + questData.getRank()); + pnlTabber = new JPanel(); + pnlTitle = new FRoundedPanel(); + pnlStats = new JPanel(); + pnlDuels = new JPanel(); + pnlChallenges = new JPanel(); + pnlStart = new JPanel(); + pnlDecks = new JPanel(); + pnlNewQuest = new JPanel(); + pnlLoadQuest = new JPanel(); + pnlPrefs = new JPanel(); - JLabel lblStats = new JLabel("Wins: " + questData.getWin() - + " / Losses: " + questData.getLost()); - lblStats.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblStats.setFont(skin.getBoldFont(18)); - lblStats.setHorizontalAlignment(SwingConstants.CENTER); - viewport.add(lblStats, "h 35px!, ax center, span 2"); + lblTitle = new FLabel("New Quest"); + lblLife = new FLabel(); + lblCredits = new FLabel(); + lblWins = new FLabel(); + lblLosses = new FLabel(); + lblNextChallengeInWins = new FLabel(); + lblWinStreak = new FLabel(); - // Quest events - populateQuestEvents(); + radEasy = new FRadioButton("Easy"); + radMedium = new FRadioButton("Medium"); + radHard = new FRadioButton("Hard"); + radExpert = new FRadioButton("Expert"); + radFantasy = new FRadioButton("Fantasy"); + radClassic = new FRadioButton("Classic"); - // Quest options - populateQuestOptions(); + btnCurrentDeck = new SubButton(); + btnBazaar = new SubButton("Bazaar"); + btnSpellShop = new SubButton("Spell Shop"); + btnStart = new StartButton(parentView); + btnEmbark = new SubButton("Embark!"); + btnNewDeck = new SubButton("Build a New Deck"); + cbxPet = new JComboBox(); + cbStandardStart = new FCheckBox("Standard (Type 2) Starting Pool"); + cbPlant = new FCheckBox("Summon Plant"); + cbZep = new FCheckBox("Launch Zeppelin"); + barProgress = new FProgressBar(); - // Start button - populateStartArea(); - } - else { - lblTitle.setText(" New Quest"); - } + lstDecks = new DeckLister(GameType.Quest); + lstQuests = new QuestFileLister(); - // New Quest + // Final layout of parent panel + pnlViewport = new JPanel(); + pnlViewport.setOpaque(false); + pnlViewport.setLayout(new MigLayout("insets 0, gap 0, wrap, alignx center, hidemode 3")); + + final String constraints = "w 90%!, gap 0 0 0 20px, alignx center"; + pnlViewport.add(pnlTabber, constraints + ", h 20px!"); + pnlViewport.add(pnlTitle, constraints + ", h 60px!"); + pnlViewport.add(pnlStats, constraints); + pnlViewport.add(pnlDuels, constraints); + pnlViewport.add(pnlChallenges, constraints); + pnlViewport.add(pnlStart, constraints); + pnlViewport.add(pnlLoadQuest, constraints); + pnlViewport.add(pnlNewQuest, constraints); + pnlViewport.add(pnlDecks, constraints); + pnlViewport.add(pnlPrefs, constraints); + + // Drop into scroll pane, init values from controller. + this.setViewportView(pnlViewport); + + // Lay out each child panel, starting with previous quests. + populateLoadQuest(); + populateTabber(); + populateTitle(); + populateStats(); + populateDuels(); + populateChallenges(); + populateStart(); + populateDecks(); populateNewQuest(); + populatePrefs(); - // Drop into scroll pane, init controller. - this.setViewportView(viewport); - control = new ControlQuest(this); + // Init controller, select quest and deck, then start in duels tab. + this.control = new ControlQuest(this); + control.refreshQuests(); + control.refreshDecks(); + this.showDuelsTab(); } //========= POPULATION METHODS - //...mainly here to avoid one big lump of a constructor. + /** Layout and details for Swing components in title panel. */ + private void populateTabber() { + tabDuels.setToolTipText("Available Duels"); + tabChallenges.setToolTipText("Available Challenges"); + tabDecks.setToolTipText("Edit or create decks"); + tabQuests.setToolTipText("Load a Quest, or start a new Quest"); + tabPreferences.setToolTipText("Change Preference Settings"); - private void populateQuestEvents() { - // Retrieve quest events, or generate (on first run) - this.qem = AllZone.getQuestEventManager(); + final String constraints = "w 20%!, h 20px!"; + pnlTabber.setOpaque(false); + pnlTabber.setLayout(new MigLayout("insets 0, gap 0, align center")); - if (this.qem == null) { - this.qem = new QuestEventManager(); - this.qem.assembleAllEvents(); - AllZone.setQuestEventManager(this.qem); - } - - JPanel duelsContainer = new JPanel(); - duelsContainer.setOpaque(false); - duelsContainer.setLayout(new MigLayout("insets 0, gap 0, wrap")); - - JPanel challengesContainer = new JPanel(); - challengesContainer.setOpaque(false); - challengesContainer.setLayout(new MigLayout("insets 0, gap 0, wrap")); - - List duels = qem.generateDuels(); - List challenges = qem.generateChallenges(); - - for (QuestDuel d : duels) { - SelectablePanel temp = new SelectablePanel(d); - duelsContainer.add(temp, "w 100%, h 70px:70px, gapbottom 5px"); - } - - for (QuestChallenge c : challenges) { - SelectablePanel temp = new SelectablePanel(c); - challengesContainer.add(temp, "w 100%, h 70px:70px, gapbottom 5px"); - } - - if (challenges.size() == 0) { - JLabel lblTeaser = new JLabel("(Next challenge available in " - + nextChallengeInWins() + " wins.)"); - lblTeaser.setHorizontalAlignment(SwingConstants.CENTER); - lblTeaser.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblTeaser.setFont(skin.getBoldFont(16)); - challengesContainer.add(lblTeaser, "w 100%!, ax center, ay top"); - } - - JLabel lblDuels = new JLabel("Available Duels"); - lblDuels.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblDuels.setHorizontalAlignment(SwingConstants.CENTER); - lblDuels.setFont(skin.getItalicFont(14)); - - JLabel lblChallenges = new JLabel("Available Challenges"); - lblChallenges.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblChallenges.setHorizontalAlignment(SwingConstants.CENTER); - lblChallenges.setFont(skin.getItalicFont(14)); - - viewport.add(lblDuels, "w 48%, gap 1% 1% 2% 1%"); - viewport.add(lblChallenges, "w 48%, gap 0 0 2% 1%, wrap"); - viewport.add(duelsContainer, " w 48%, gap 1% 1% 1% 2%, ay top"); - viewport.add(challengesContainer, " w 48%, gap 0 0 1% 2%, wrap"); - - // Select first event. - selectedOpponent = (SelectablePanel) duelsContainer.getComponent(0); - selectedOpponent.setBackground(skin.getColor(FSkin.SkinProp.CLR_ACTIVE)); + pnlTabber.add(tabDuels, constraints); + pnlTabber.add(tabChallenges, constraints); + pnlTabber.add(tabDecks, constraints); + pnlTabber.add(tabQuests, constraints); + pnlTabber.add(tabPreferences, constraints); } - /** */ - private void populateQuestOptions() { - JPanel optionsContainer = new JPanel(); - optionsContainer.setOpaque(false); - optionsContainer.setLayout(new MigLayout("insets 0, gap 0")); - optionsContainer.setBorder(new MatteBorder(0, 0, 1, 0, skin.getColor(FSkin.SkinProp.CLR_BORDERS))); - - lblCredits = new JLabel("Credits: " + Long.toString(questData.getCredits())); - lblCredits.setIcon(GuiUtils.getResizedIcon(new ImageIcon("res/images/icons/CoinStack.png"), 26, 26)); - lblCredits.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblCredits.setIconTextGap(5); - lblCredits.setHorizontalAlignment(SwingConstants.CENTER); - lblCredits.setFont(skin.getBoldFont(14)); - - lblLife = new JLabel("Life: " + Long.toString(questData.getLife())); - lblLife.setIcon(GuiUtils.getResizedIcon(new ImageIcon("res/images/icons/Life.png"), 26, 26)); - lblLife.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblLife.setIconTextGap(5); - lblLife.setHorizontalAlignment(SwingConstants.CENTER); - lblLife.setFont(skin.getBoldFont(14)); - - SubButton btnEditor = new SubButton(""); - btnEditor.setAction(new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - control.showDeckEditor(); - } - }); - btnEditor.setText("Deck Editor"); - - SubButton btnCardShop = new SubButton(""); - btnCardShop.setAction(new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - control.showCardShop(); - } - }); - btnCardShop.setText("Card Shop"); - - SubButton btnBazaar = new SubButton(""); - btnBazaar.setAction(new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - control.showBazaar(); - } - }); - btnBazaar.setText("Bazaar"); - - lstDeckChooser = new FList(); - - optionsContainer.add(btnEditor, "w 35%, h 30px!, gap 10% 5% 10px 10px"); - optionsContainer.add(lblCredits, "w 35%!, h 30px!, wrap"); - - optionsContainer.add(new FScrollPane(lstDeckChooser), "w 35%, h 110px!, gap 10% 5% 0 10px, span 1 3"); - optionsContainer.add(lblLife, "w 35%, h 30px!, gap 0 0 0 10px, wrap"); - - optionsContainer.add(btnCardShop, "w 35%, h 30px!, gap 0 0 0 10px, wrap"); - optionsContainer.add(btnBazaar, "w 35%, h 30px!, gap 0 0 0 10px, wrap"); - - if (!questData.isFantasy()) { - lblLife.setVisible(false); - btnBazaar.setVisible(false); - } - - viewport.add(optionsContainer, "w 90%, gap 5% 0 1% 1%, span 2 1"); + /** Layout and details for Swing components in title panel. */ + private void populateTitle() { + pnlTitle.setLayout(new MigLayout("insets 0, gap 0, align center")); + pnlTitle.setBackground(skin.getColor(FSkin.SkinProp.CLR_THEME).darker()); + ((FRoundedPanel) pnlTitle).setBorderColor(clrBorders); + pnlTitle.add(lblTitle, "h 70%!, gap 0 0 0 10%!"); } - private void populateStartArea() { - JPanel pnlButtonContainer = new JPanel(); - pnlButtonContainer.setOpaque(false); - pnlButtonContainer.setLayout(new MigLayout("insets 0, gap 0, wrap 2, ax center, hidemode 3")); + /** Layout permanent parts of stats panel. */ + private void populateStats() { + pnlStats.setOpaque(false); + pnlStats.setBorder(new MatteBorder(1, 0, 1, 0, clrBorders)); - cbxPet = new JComboBox(); - cbxPet.setFont(skin.getFont(14)); - - cbPlant = new OptionsCheckBox("Summon Plant"); - cbPlant.setFont(skin.getFont(14)); - cbZep = new OptionsCheckBox("Launch Zeppelin"); - cbZep.setFont(skin.getFont(14)); - - lblPet = new JLabel(GuiUtils.getResizedIcon( - new ImageIcon("res/images/icons/PetIcon.png"), 30, 30)); - lblPlant = new JLabel(GuiUtils.getResizedIcon( - new ImageIcon("res/images/icons/PlantIcon.png"), 30, 30)); - lblZep = new JLabel(GuiUtils.getResizedIcon( - new ImageIcon("res/images/icons/ZeppelinIcon.png"), 30, 30)); - - btnStart = new StartButton(parentView); - - barProgress = new FProgressBar(); - barProgress.setVisible(false); - - pnlButtonContainer.add(lblPet, "w 30px!, h 30px!, gapright 10px"); - pnlButtonContainer.add(cbxPet, "w 30%!, h 30px!, gapbottom 10px, wrap"); - - pnlButtonContainer.add(lblPlant, "w 30px!, h 30px!, gapright 10px"); - pnlButtonContainer.add(cbPlant, "w 30%!, h 30px!, gapbottom 10px, wrap"); - - pnlButtonContainer.add(lblZep, "w 30px!, h 30px!, gapright 10px"); - pnlButtonContainer.add(cbZep, "w 30%!, h 30px!, gapbottom 10px, wrap"); - - pnlButtonContainer.add(btnStart, "span 2 1"); - pnlButtonContainer.add(barProgress, "w 150px!, h 30px!, span 2 1"); - - viewport.add(pnlButtonContainer, "w 100%!, gapbottom 2%, gaptop 2%, span 2"); - - if (this.questData.getMode().equals(QuestData.FANTASY)) { - final Set petList = this.questData.getPetManager().getAvailablePetNames(); - final QuestPetAbstract pet = this.questData.getPetManager().getSelectedPet(); - - // Pet list visibility - if (petList.size() > 0) { - cbxPet.setEnabled(true); - cbxPet.addItem("Don't summon a pet"); - for (final String aPetList : petList) { - cbxPet.addItem(aPetList); - } - - if (pet != null) { cbxPet.setSelectedItem(pet.getName()); } - } else { - cbxPet.setVisible(false); - lblPet.setVisible(false); - } - - // Plant visiblity - if (this.questData.getPetManager().getPlant().getLevel() == 0) { - cbPlant.setVisible(false); - lblPlant.setVisible(false); - } - else { - cbPlant.setSelected(this.questData.getPetManager().shouldPlantBeUsed()); - } - - // Zeppelin visibility - final QuestItemZeppelin zeppelin = (QuestItemZeppelin) this.questData.getInventory().getItem("Zeppelin"); - cbZep.setVisible(zeppelin.hasBeenUsed()); - lblZep.setVisible(zeppelin.hasBeenUsed()); - } - else { - cbxPet.setVisible(false); - lblPet.setVisible(false); - cbPlant.setVisible(false); - lblPlant.setVisible(false); - cbZep.setVisible(false); - lblZep.setVisible(false); - } + lblLife.setIcon(new ImageIcon("res/images/icons/Life.png")); + lblCredits.setIcon(new ImageIcon("res/images/icons/CoinStack.png")); + lblWins.setIcon(new ImageIcon("res/images/icons/IconPlus.png")); + lblLosses.setIcon(new ImageIcon("res/images/icons/IconMinus.png")); + lblNextChallengeInWins.setText("No challenges available."); + btnBazaar.setToolTipText("Peruse the Bazaar"); + btnSpellShop.setToolTipText("Travel to the Spell Shop"); } + /** Layout permanent parts of duels panel. */ + private void populateDuels() { + pnlDuels.setOpaque(false); + pnlDuels.setLayout(new MigLayout("insets 0, wrap")); + } + + /** Layout permanent parts of challenges panel. */ + private void populateChallenges() { + pnlChallenges.setOpaque(false); + pnlChallenges.setLayout(new MigLayout("insets 0, wrap")); + } + + /** Layout permanent parts of start panel. */ + private void populateStart() { + pnlStart.setOpaque(false); + pnlStart.setLayout(new MigLayout("insets 0, wrap, align center, hidemode 3")); + pnlStart.add(cbxPet, "gap 0 0 0 5px, align center"); + pnlStart.add(cbPlant, "gap 0 0 5px 5px, align center"); + pnlStart.add(cbZep, "gap 0 0 5px 5px, align center"); + pnlStart.add(btnStart, ""); + } + + /** Layout permanent parts of decks panel. */ + private void populateDecks() { + final FScrollPane scr = new FScrollPane(lstDecks); + scr.setBorder(null); + scr.getViewport().setBorder(null); + + pnlDecks.setOpaque(false); + pnlDecks.setLayout(new MigLayout("insets 0, wrap, alignx center, wrap")); + + pnlDecks.add(btnNewDeck, "w 40%!, h 35px!, gap 25%! 0 0 20px"); + pnlDecks.add(scr, "w 90%!, h 350px!"); + } + + /** Layout permanent parts of quest load panel. */ + private void populateLoadQuest() { + // New quest notes + final FRoundedPanel pnl = new FRoundedPanel(); + pnl.setLayout(new MigLayout("insets 0, align center")); + pnl.setBorderColor(clrBorders); + pnl.setBackground(skin.getColor(FSkin.SkinProp.CLR_THEME)); + pnl.add(new FLabel("Load a previous Quest"), "h 24px!, gap 2px 2px 2px 2px"); + + final FLabel lbl = new FLabel("To use quest files " + + "from previous versions, put them into " + + "the res/quest/data directory, and restart Forge.", SwingConstants.CENTER); + lbl.setFontScaleFactor(0.8); + + final FScrollPane scr = new FScrollPane(lstQuests); + scr.setBorder(null); + scr.getViewport().setBorder(null); + + pnlLoadQuest.setOpaque(false); + pnlLoadQuest.setLayout(new MigLayout("insets 0, gap 0, alignx center, wrap")); + pnlLoadQuest.add(pnl, "w 99%, gap 0 0 0 10px"); + pnlLoadQuest.add(lbl, "w 99%!, h 18px!, gap 2px 2px 0 4px"); + pnlLoadQuest.add(scr, "w 99%!, h 200px!, gap 0 0 0 30px"); + } + + /** Layout permanent parts of new quests panel. */ private void populateNewQuest() { - if (previousQuestExists) { - JLabel lblNew = new JLabel(" Embark on a new Quest"); - lblNew.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - lblNew.setBackground(skin.getColor(FSkin.SkinProp.CLR_THEME).darker()); - lblNew.setOpaque(true); - lblNew.setBorder(new MatteBorder(1, 0, 1, 0, skin.getColor(FSkin.SkinProp.CLR_BORDERS))); - lblNew.setFont(skin.getBoldFont(16)); - viewport.add(lblNew, "w 90%!, h 50px!, gap 5% 5% 2%, span 2"); + // New quest notes + final FRoundedPanel pnl1 = new FRoundedPanel(); + pnl1.setLayout(new MigLayout("insets 0, align center")); + pnl1.setBorderColor(clrBorders); + pnl1.setBackground(skin.getColor(FSkin.SkinProp.CLR_THEME)); + pnl1.add(new FLabel("Start a new quest"), "h 24px!, gap 2px 2px 2px 2px"); - JLabel lblNotes = new JLabel("" - + "Start a new Quest will delete your current player decks, credits and win loss record." - + "
Fantasy adds a Bazaar and the occasional fantasy themed opponent for you to battle." - + ""); - lblNotes.setFont(skin.getFont(14)); - lblNotes.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - viewport.add(lblNotes, "w 90%, gapleft 5%, span 2"); - } - - radEasy = new OptionsRadio("Easy - 50 games"); - radMedium = new OptionsRadio("Medium - 100 games"); - radHard = new OptionsRadio("Hard - 150 games"); - radExpert = new OptionsRadio("Expert - 200 games"); - - ButtonGroup group1 = new ButtonGroup(); + final ButtonGroup group1 = new ButtonGroup(); group1.add(radEasy); group1.add(radMedium); group1.add(radHard); group1.add(radExpert); - radFantasy = new OptionsRadio("Fantasy"); - radClassic = new OptionsRadio("Classic"); - radEasy.setSelected(true); radClassic.setSelected(true); - ButtonGroup group2 = new ButtonGroup(); + final ButtonGroup group2 = new ButtonGroup(); group2.add(radFantasy); group2.add(radClassic); - cbStandardStart = new OptionsCheckBox("Standard (Type 2) Starting Pool"); + final JPanel pnl2 = new JPanel(); + pnl2.setOpaque(false); + pnl2.setLayout(new MigLayout("insets 0, gap 0")); - SubButton btnEmbark = new SubButton(""); - btnEmbark.setAction(new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - control.newQuest(); - } - }); - btnEmbark.setText("Embark!"); + final String constraints = "w 30%!, h 40px!"; + pnl2.add(radEasy, constraints + ", gap 15% 5% 0 0"); + pnl2.add(radFantasy, constraints + ", wrap"); + pnl2.add(radMedium, constraints + ", gap 15% 5% 0 0"); + pnl2.add(radClassic, constraints + ", wrap"); + pnl2.add(radHard, constraints + ", gap 15% 5% 0 0"); + pnl2.add(cbStandardStart, constraints + ", wrap"); + pnl2.add(radExpert, constraints + ", gap 15% 5% 0 0, wrap"); - JPanel optionsContainer = new JPanel(); - optionsContainer.setOpaque(false); - optionsContainer.setLayout(new MigLayout("insets 0, gap 0")); + pnl2.add(btnEmbark, "w 40%!, h 30px!, gapleft 30%, gaptop 3%, span 3 1"); - String constraints = "w 30%!, h 40px!"; - optionsContainer.add(radEasy, constraints + ", gap 15% 5% 0 0"); - optionsContainer.add(radFantasy, constraints + ", wrap"); - optionsContainer.add(radMedium, constraints + ", gap 15% 5% 0 0"); - optionsContainer.add(radClassic, constraints + ", wrap"); - optionsContainer.add(radHard, constraints + ", gap 15% 5% 0 0"); - optionsContainer.add(cbStandardStart, constraints + ", wrap"); - optionsContainer.add(radExpert, constraints + ", gap 15% 5% 0 0, wrap"); - - optionsContainer.add(btnEmbark, "w 40%!, h 30px!, gapleft 30%, gaptop 3%, span 3 1"); - - viewport.add(optionsContainer, "w 100%!, gaptop 2%, span 2"); + pnlNewQuest.setLayout(new MigLayout("insets 0, gap 0, align center, wrap")); + pnlNewQuest.setOpaque(false); + pnlNewQuest.add(pnl1, "w 99%, gap 0 0 0 10px"); + pnlNewQuest.add(pnl2, "w 99%!"); } - //========= CUSTOM CLASSES + /** Layout permanent parts of prefs panel. */ + private void populatePrefs() { + pnlPrefs.setOpaque(false); + pnlPrefs.setLayout(new MigLayout("insets 0, gap 0")); + pnlPrefs.add(new ViewQuestPreferences(), "w 100%!"); + } - /** Consolidates radio button styling in one place. */ - private class OptionsRadio extends JRadioButton { - public OptionsRadio(String txt0) { - super(); - setText(txt0); - setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); - setOpaque(false); + private void hideAllPanels() { + pnlTitle.setVisible(false); + pnlStats.setVisible(false); + pnlDuels.setVisible(false); + pnlChallenges.setVisible(false); + pnlStart.setVisible(false); + pnlDecks.setVisible(false); + pnlNewQuest.setVisible(false); + pnlLoadQuest.setVisible(false); + pnlPrefs.setVisible(false); + } - this.addMouseListener(new MouseAdapter() { - @Override - public void mouseEntered(MouseEvent e) { - setOpaque(true); - } + //========= UPDATE METHODS + /** Update transitory parts of duels panel. */ + public void updateDuels() { + if (AllZone.getQuestData() == null) { return; } - @Override - public void mouseExited(MouseEvent e) { - setOpaque(false); - } - }); + pnlDuels.removeAll(); + final List duels = control.getQEM().generateDuels(); + + for (QuestDuel d : duels) { + SelectablePanel temp = new SelectablePanel(d); + pnlDuels.add(temp, this.eventPanelConstraints); } } - /** Consolidates checkbox styling in one place. */ - private class OptionsCheckBox extends JCheckBox { - public OptionsCheckBox(String txt0) { - super(); - setText(txt0); - setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); - setOpaque(false); + /** Update transitory parts of challenges panel. */ + public void updateChallenges() { + if (AllZone.getQuestData() == null) { return; } - this.addMouseListener(new MouseAdapter() { - @Override - public void mouseEntered(MouseEvent e) { - setOpaque(true); - } + pnlChallenges.removeAll(); + final List challenges = control.getQEM().generateChallenges(); - @Override - public void mouseExited(MouseEvent e) { - setOpaque(false); - } - }); + for (QuestChallenge c : challenges) { + SelectablePanel temp = new SelectablePanel(c); + pnlChallenges.add(temp, this.eventPanelConstraints); + } + } + + /** Update transitory parts of stats panel. */ + public void updateStats() { + pnlStats.removeAll(); + + if (AllZone.getQuestData().isFantasy()) { + pnlStats.setLayout(new MigLayout("insets 0, gap 0")); + + pnlStats.add(btnBazaar, "w 15%!, h 70px!, gap 0 4% 10px 10px, span 1 2"); + pnlStats.add(lblWins, "w 30%!, h 25px!, gap 0 2% 12px 0"); + pnlStats.add(lblLosses, "w 30%!, h 25px!, gap 0 4% 12px 0"); + pnlStats.add(btnSpellShop, "w 14.5%!, h 70px!, gap 0 0 10px 10px, span 1 2, wrap"); + pnlStats.add(lblCredits, "w 30%!, h 25px!, gap 0 2% 0 0"); + pnlStats.add(lblLife, "w 30%!, h 25px!, gap 0 4% 0 0 0, wrap"); + pnlStats.add(lblWinStreak, "h 20px!, align center, span 4 1, wrap"); + pnlStats.add(lblNextChallengeInWins, "h 20px!, align center, span 4 1, wrap"); + pnlStats.add(btnCurrentDeck, "w 40%!, h 26px!, align center, span 4 1, gap 0 0 0 5px"); + } + else { + pnlStats.setLayout(new MigLayout("insets 0, gap 0, align center")); + lblCredits.setHorizontalAlignment(SwingConstants.CENTER); + + pnlStats.add(lblWins, "w 150px!, h 25px!, gap 0 50px 5px 5px, align center"); + pnlStats.add(lblCredits, "w 150px!, h 25px!, gap 0 0 5px 5px, align center, wrap"); + pnlStats.add(lblLosses, "w 150px!, h 25px!, gap 0 50px 0 5px, align center"); + pnlStats.add(btnSpellShop, "w 150px!, h 25px!, gap 0 0 0 5px, align center, wrap"); + pnlStats.add(lblWinStreak, "h 20px!, align center, span 4 1, wrap"); + pnlStats.add(lblNextChallengeInWins, "h 20px!, align center, span 4 1, gap 0 0 10px 5px, wrap"); + pnlStats.add(btnCurrentDeck, "w 40%!, h 26px!, align center, span 4 1, gap 0 0 0 5px"); + } + } + + //========= TAB SHOW METHODS + /** Display handler for duel tab click. */ + public void showDuelsTab() { + control.updateTabber(tabDuels); + this.hideAllPanels(); + pnlTitle.setVisible(true); + + if (AllZone.getQuestData() == null) { + lblTitle.setText("Start a new Quest in the \"Quests\" tab."); + return; + } + + setCurrentDeckStatus(); + updateDuels(); + updateStats(); + lblTitle.setText("Duels: " + control.getRankString()); + pnlStats.setVisible(true); + pnlDuels.setVisible(true); + + if (control.getCurrentDeck() != null) { + pnlStart.setVisible(true); + + // Select first event. + selectedOpponent = (SelectablePanel) pnlDuels.getComponent(0); + selectedOpponent.setBackground(skin.getColor(FSkin.SkinProp.CLR_ACTIVE)); + } + } + + /** Display handler for duel tab click. */ + public void showChallengesTab() { + control.updateTabber(tabChallenges); + this.hideAllPanels(); + pnlTitle.setVisible(true); + + if (AllZone.getQuestData() == null) { + lblTitle.setText("Start a new Quest in the \"Quests\" tab."); + return; + } + + setCurrentDeckStatus(); + updateChallenges(); + updateStats(); + lblTitle.setText("Challenges: " + control.getRankString()); + pnlStats.setVisible(true); + pnlChallenges.setVisible(true); + + // Select first event. + if (pnlChallenges.getComponentCount() > 0) { + pnlStart.setVisible(true); + selectedOpponent = (SelectablePanel) pnlChallenges.getComponent(0); + selectedOpponent.setBackground(skin.getColor(FSkin.SkinProp.CLR_ACTIVE)); + } + } + + /** Display handler for decks tab click. */ + public void showDecksTab() { + control.updateTabber(tabDecks); + this.hideAllPanels(); + pnlTitle.setVisible(true); + + if (AllZone.getQuestData() == null) { + lblTitle.setText("Start a new Quest in the \"Quests\" tab."); + return; + } + else { + lblTitle.setText("Quest Deck Manager"); + pnlDecks.setVisible(true); + } + } + + /** Display handler for quests tab click. */ + public void showQuestsTab() { + control.updateTabber(tabQuests); + this.hideAllPanels(); + + pnlNewQuest.setVisible(true); + pnlLoadQuest.setVisible(true); + } + + /** Display handler for quests tab click. */ + public void showPrefsTab() { + control.updateTabber(tabPreferences); + + this.hideAllPanels(); + + lblTitle.setText("Quest Preferences"); + pnlTitle.setVisible(true); + pnlPrefs.setVisible(true); + } + + /** Toggles red, bold font if no current deck. */ + public void setCurrentDeckStatus() { + if (control.getCurrentDeck() == null) { + btnCurrentDeck.setBackground(Color.red.darker()); + btnCurrentDeck.setText(" Build, then select a deck in the \"Decks\" tab. "); + } + else { + btnCurrentDeck.setBackground(skin.getColor(FSkin.SkinProp.CLR_INACTIVE)); + btnCurrentDeck.setText("Current deck: " + control.getCurrentDeck().getName()); } } /** Selectable panels for duels and challenges. */ - public class SelectablePanel extends JPanel { + public class SelectablePanel extends FRoundedPanel { private QuestEvent event; + private Color clrDefault, clrHover, clrSelected; /** @param e0   QuestEvent */ public SelectablePanel(QuestEvent e0) { super(); - setBorder(new LineBorder(skin.getColor(FSkin.SkinProp.CLR_BORDERS), 1)); - setBackground(skin.getColor(FSkin.SkinProp.CLR_INACTIVE)); - setLayout(new MigLayout("insets 0, gap 0")); + this.clrSelected = skin.getColor(FSkin.SkinProp.CLR_ACTIVE); + this.clrDefault = skin.getColor(FSkin.SkinProp.CLR_INACTIVE); + this.clrHover = skin.getColor(FSkin.SkinProp.CLR_HOVER); this.event = e0; + this.setBackground(clrDefault); + this.setLayout(new MigLayout("insets 0, gap 0")); + final File base = ForgeProps.getFile(NewConstants.IMAGE_ICON); File file = new File(base, event.getIcon()); @@ -477,27 +520,21 @@ public class ViewQuest extends JScrollPane { file = new File(base, "Unknown.jpg"); } - JLabel lblIcon = new JLabel(GuiUtils.getResizedIcon(new ImageIcon(file.toString()), 60, 60)); + FLabel lblIcon = new FLabel(new ImageIcon(file.toString())); + lblIcon.setIconScaleFactor(1); lblIcon.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - this.add(lblIcon, "h 60px!, w 60px!, gap 5px 5px 5px 5px, span 1 2"); + this.add(lblIcon, "h 60px!, w 60px!, gap 10px 10px 10px 0, span 1 2"); // Name - JLabel lblName = new JLabel(event.getTitle() + ": " + event.getDifficulty()); - lblName.setFont(skin.getBoldFont(18)); - lblName.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - this.add(lblName, "h 20px!, gap 1% 1% 5px 5px, wrap"); + final FLabel lblName = new FLabel(event.getTitle() + ": " + event.getDifficulty()); + lblName.setFontScaleFactor(1); + this.add(lblName, "h 20px!, gap 0 0 10px 5px, wrap"); // Description - final JTextArea tarDesc = new JTextArea(); + final FTextArea tarDesc = new FTextArea(); tarDesc.setText(event.getDescription()); tarDesc.setFont(skin.getItalicFont(12)); - tarDesc.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - tarDesc.setOpaque(false); - tarDesc.setWrapStyleWord(true); - tarDesc.setLineWrap(true); - tarDesc.setFocusable(false); - tarDesc.setEditable(false); - this.add(tarDesc, " h 35px!, w 75%!, gap 1% 0 0 5px"); + this.add(tarDesc, "w 80%!, h 30px!"); this.setToolTipText("" + event.getTitle() + ": " + event.getDifficulty() @@ -510,24 +547,24 @@ public class ViewQuest extends JScrollPane { SelectablePanel src = (SelectablePanel) e.getSource(); if (selectedOpponent != null) { - selectedOpponent.setBackground(skin.getColor(FSkin.SkinProp.CLR_INACTIVE)); + selectedOpponent.setBackground(clrDefault); } selectedOpponent = src; - src.setBackground(skin.getColor(FSkin.SkinProp.CLR_ACTIVE)); + src.setBackground(clrSelected); } @Override public void mouseEntered(MouseEvent e) { if (selectedOpponent != e.getSource()) { - setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); + setBackground(clrHover); } } @Override public void mouseExited(MouseEvent e) { if (selectedOpponent != e.getSource()) { - setBackground(skin.getColor(FSkin.SkinProp.CLR_INACTIVE)); + setBackground(clrDefault); } } }); @@ -537,142 +574,213 @@ public class ViewQuest extends JScrollPane { public QuestEvent getEvent() { return event; } - - @Override - public void paintComponent(Graphics g) { - g.setColor(getBackground()); - g.clearRect(0, 0, getWidth(), getHeight()); - g.fillRect(0, 0, getWidth(), getHeight()); - super.paintComponent(g); - } - } - - /** - *

- * nextChallengeInWins. - *

- * - * @return a int. - */ - private int nextChallengeInWins() { - final QuestData questData = AllZone.getQuestData(); - - // Number of wins was 25, lowereing the number to 20 to help short term - // questers. - if (questData.getWin() < 20) { - return 20 - questData.getWin(); - } - - // The int mul has been lowered by one, should face special opps more - // frequently. - final int challengesPlayed = questData.getChallengesPlayed(); - int mul = 5; - - if (questData.getInventory().hasItem("Zeppelin")) { - mul = 3; - } else if (questData.getInventory().hasItem("Map")) { - mul = 4; - } - - final int delta = (challengesPlayed * mul) - questData.getWin(); - - return (delta > 0) ? delta : 0; } //========= RETRIEVAL FUNCTIONS - - /** @return JList */ - public JList getLstDeckChooser() { - return lstDeckChooser; - } - - /** @return JRadioButton */ + /** @return {@link javax.swing.JRadioButton} */ public JRadioButton getRadEasy() { return radEasy; } - /** @return JRadioButton */ + /** @return {@link javax.swing.JRadioButton} */ public JRadioButton getRadMedium() { return radMedium; } - /** @return JRadioButton */ + /** @return {@link javax.swing.JRadioButton} */ public JRadioButton getRadHard() { return radHard; } - /** @return JRadioButton */ + /** @return {@link javax.swing.JRadioButton} */ public JRadioButton getRadExpert() { return radExpert; } - /** @return JRadioButton */ + /** @return {@link javax.swing.JRadioButton} */ public JRadioButton getRadFantasy() { return radFantasy; } - /** @return JRadioButton */ + /** @return {@link javax.swing.JRadioButton} */ public JRadioButton getRadClassic() { return radClassic; } - /** @return JCheckBox */ + /** @return {@link javax.swing.JCheckBox} */ public JCheckBox getCbStandardStart() { return cbStandardStart; } - /** @return SelectablePanel */ + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbPlant() { + return cbPlant; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbZep() { + return cbZep; + } + + /** @return {@link javax.swing.JComboBox} */ + public JComboBox getCbxPet() { + return cbxPet; + } + + /** @return {@link forge.view.home.ViewQuest.SelectablePanel} */ public SelectablePanel getSelectedOpponent() { return selectedOpponent; } - /** @return HomeTopLevel */ + /** @return {@link forge.view.home.HomeTopLevel} */ public HomeTopLevel getParentView() { return parentView; } - /** @return ControlQuest */ + /** @return {@link forge.control.home.ControlQuest} */ public ControlQuest getController() { return control; } - /** @return JComboBox */ - public JComboBox getPetComboBox() { - return cbxPet; + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblTitle() { + return lblTitle; } - /** @return JCheckBox */ - public JCheckBox getPlantCheckBox() { - return cbPlant; - } - - /** @return QuestData instance currently in use in this view */ - public QuestData getQuestData() { - return questData; - } - - /** @return boolean */ - public boolean hasPreviousQuest() { - return previousQuestExists; - } - - /** @return JLabel */ + /** @return {@link javax.swing.JLabel} */ public JLabel getLblLife() { return lblLife; } - /** @return JLabel */ + /** @return {@link javax.swing.JLabel} */ public JLabel getLblCredits() { return lblCredits; } - /** @return JButton */ + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblWins() { + return lblWins; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblLosses() { + return lblLosses; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblNextChallengeInWins() { + return lblNextChallengeInWins; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblWinStreak() { + return lblWinStreak; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnCurrentDeck() { + return btnCurrentDeck; + } + + /** @return {@link javax.swing.JButton} */ public JButton getBtnStart() { return btnStart; } - /** @return FProgressBar */ + /** @return {@link javax.swing.JButton} */ + public JButton getBtnBazaar() { + return btnBazaar; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnSpellShop() { + return btnSpellShop; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnEmbark() { + return btnEmbark; + } + + /** @return {@link javax.swing.JButton} */ + public JButton getBtnNewDeck() { + return btnNewDeck; + } + + /** @return {@link forge.view.toolbox.FProgressBar} */ public FProgressBar getBarProgress() { return barProgress; } + + //========== CONTAINER RETRIEVAL + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStats() { + return this.pnlStats; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlTitle() { + return this.pnlTitle; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlDuels() { + return this.pnlDuels; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlChallenges() { + return this.pnlChallenges; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStart() { + return this.pnlStart; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlLoadQuest() { + return pnlLoadQuest; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getpnlPrefs() { + return pnlPrefs; + } + + /** @return {@link forge.view.toolbox.DeckLister} */ + public DeckLister getLstDecks() { + return this.lstDecks; + } + + /** @return {@link forge.view.home.QuestFileLister} */ + public QuestFileLister getLstQuests() { + return this.lstQuests; + } + + //========== TAB RETRIEVAL + /** @return {@link javax.swing.JPanel} */ + public JPanel getTabDuels() { + return tabDuels; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getTabChallenges() { + return tabChallenges; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getTabDecks() { + return tabDecks; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getTabQuests() { + return tabQuests; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getTabPreferences() { + return tabPreferences; + } } diff --git a/src/main/java/forge/view/home/ViewQuestPreferences.java b/src/main/java/forge/view/home/ViewQuestPreferences.java new file mode 100644 index 00000000000..80bac2ab442 --- /dev/null +++ b/src/main/java/forge/view/home/ViewQuestPreferences.java @@ -0,0 +1,386 @@ +package forge.view.home; + +import java.awt.Color; +import java.awt.Font; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import net.miginfocom.swing.MigLayout; +import forge.Singletons; +import forge.quest.data.QuestPreferences; +import forge.quest.data.QuestPreferences.QPref; +import forge.view.toolbox.FLabel; +import forge.view.toolbox.FSkin; + +/** + * TODO: Write javadoc for this type. + * + */ +@SuppressWarnings("serial") +public class ViewQuestPreferences extends JPanel { + private final FSkin skin; + private final QuestPreferences prefs; + private final JPanel pnlDifficulty, pnlBooster, pnlRewards; + private final FLabel lblErrRewards, lblErrBooster, lblErrDifficulty; + private String constraints1, constraints2; + + private enum ErrType { + REWARDS, + DIFFICULTY, + BOOSTER + } + + /** */ + public ViewQuestPreferences() { + this.setOpaque(false); + this.setLayout(new MigLayout("insets 0, gap 0, wrap")); + this.skin = Singletons.getView().getSkin(); + this.prefs = Singletons.getModel().getQuestPreferences(); + + pnlRewards = new JPanel(); + pnlDifficulty = new JPanel(); + pnlBooster = new JPanel(); + + lblErrRewards = new FLabel("Rewards Error"); + lblErrDifficulty = new FLabel("Difficulty Error"); + lblErrBooster = new FLabel("Booster Error"); + + lblErrRewards.setForeground(Color.red); + lblErrRewards.setFontStyle(Font.BOLD); + lblErrDifficulty.setForeground(Color.red); + lblErrDifficulty.setFontStyle(Font.BOLD); + lblErrBooster.setForeground(Color.red); + lblErrBooster.setFontStyle(Font.BOLD); + + // Rewards panel + pnlRewards.setOpaque(false); + pnlRewards.setLayout(new MigLayout("insets 0, gap 0, wrap 2")); + + pnlRewards.add(new FLabel("Rewards", new ImageIcon("res/images/icons/CoinIcon.png")), "w 100%!, h 30px!, span 2 1"); + pnlRewards.add(lblErrRewards, "w 100%!, h 30px!, span 2 1"); + + constraints1 = "w 60px, h 26px!"; + constraints2 = "w 150px!, h 26px!"; + + pnlRewards.add(new FLabel("Base winnings"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_BASE, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("No losses"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_UNDEFEATED, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("Poison win"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_POISON, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("Milling win"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_MILLED, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("Mulligan 0 win"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_MULLIGAN0, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("Alternative win"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_ALTERNATIVE, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("Win by turn 15"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN15, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("Win by turn 10"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN10, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("Win by turn 5"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN5, ErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel("First turn win"), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN1, ErrType.REWARDS), constraints1); + + // Difficulty table panel + pnlDifficulty.setOpaque(false); + pnlDifficulty.setLayout(new MigLayout("insets 0, gap 0, wrap 5")); + + pnlDifficulty.add(new FLabel("Difficulty Adjustments", new ImageIcon("res/images/icons/NotesIcon.png")), "w 100%!, h 30px!, span 5 1"); + pnlDifficulty.add(lblErrDifficulty, "w 100%!, h 30px!, span 5 1"); + + constraints1 = "w 60px!, h 26px!"; + constraints2 = "w 150px!, h 26px!"; + + pnlDifficulty.add(new FLabel(""), constraints2); + pnlDifficulty.add(new FLabel("Easy"), constraints1); + pnlDifficulty.add(new FLabel("Medium"), constraints1); + pnlDifficulty.add(new FLabel("Hard"), constraints1); + pnlDifficulty.add(new FLabel("Expert"), constraints1); + + pnlDifficulty.add(new FLabel("Wins For Booster"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Wins For Rank Increase"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Wins For Medium AI"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Wins For Hard AI"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Wins For Expert AI"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Starting commons"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Starting uncommons"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Starting rares"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Starting credits"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_EASY, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_MEDIUM, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_HARD, ErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_EXPERT, ErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel("Starting basic lands"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_BASIC_LANDS, ErrType.DIFFICULTY), constraints1 + ", wrap"); + + pnlDifficulty.add(new FLabel("Starting snow lands"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_SNOW_LANDS, ErrType.DIFFICULTY), constraints1 + ", wrap"); + + pnlDifficulty.add(new FLabel("Penalty for loss"), constraints2); + pnlDifficulty.add(new PrefInput(QPref.PENALTY_LOSS, ErrType.DIFFICULTY), constraints1 + ", wrap"); + + // Booster breakdown panel + pnlBooster.setOpaque(false); + pnlBooster.setLayout(new MigLayout("insets 0, gap 0, wrap 2")); + + pnlBooster.add(new FLabel("Booster Pack Ratios", new ImageIcon("res/images/icons/BookIcon.png")), "w 100%!, h 30px!, span 2 1"); + pnlBooster.add(lblErrBooster, "w 100%!, h 30px!, span 2 1"); + + constraints1 = "w 60px!, h 26px!"; + constraints2 = "w 150px!, h 26px!"; + pnlBooster.add(new FLabel("Common"), constraints2); + pnlBooster.add(new PrefInput(QPref.BOOSTER_COMMONS, ErrType.BOOSTER), constraints1); + + pnlBooster.add(new FLabel("Uncommon"), constraints2); + pnlBooster.add(new PrefInput(QPref.BOOSTER_UNCOMMONS, ErrType.BOOSTER), constraints1); + + pnlBooster.add(new FLabel("Rare"), constraints2); + pnlBooster.add(new PrefInput(QPref.BOOSTER_RARES, ErrType.BOOSTER), constraints1); + + constraints1 = "w 100%!, gap 0 0 20px 0"; + this.add(pnlRewards, constraints1); + this.add(pnlDifficulty, constraints1); + this.add(pnlBooster, constraints1); + + resetErrors(); + } + + private class PrefInput extends JTextField { + private final QPref qpref; + private final ErrType err; + private final Color clrHover, clrActive, clrText; + private boolean isFocus = false; + private String previousText = ""; + + /** + * @param qp1   {@link forge.quest.data.QuestPreferences.QPref} + * preferences ident enum + * @param e0   {@link forge.view.home.ViewQuestPreference.ErrType} + * where error should display to + */ + public PrefInput(QPref qp0, ErrType e0) { + super(); + + this.qpref = qp0; + this.err = e0; + this.clrHover = skin.getColor(FSkin.SkinProp.CLR_HOVER); + this.clrActive = skin.getColor(FSkin.SkinProp.CLR_ACTIVE); + this.clrText = skin.getColor(FSkin.SkinProp.CLR_TEXT); + + this.setOpaque(false); + this.setBorder(null); + this.setFont(skin.getFont(13)); + this.setForeground(clrText); + this.setCaretColor(clrText); + this.setBackground(clrHover); + this.setHorizontalAlignment(SwingConstants.CENTER); + this.setText(prefs.getPreference(qpref)); + this.setPreviousText(prefs.getPreference(qpref)); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + if (isFocus) { return; } + setOpaque(true); + repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + if (isFocus) { return; } + setOpaque(false); + repaint(); + } + }); + + this.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + isFocus = true; + setOpaque(true); + setBackground(clrActive); + } + + @Override + public void focusLost(FocusEvent e) { + isFocus = false; + setOpaque(false); + setBackground(clrHover); + + // TODO for slight performance improvement + // check if value has changed before validating + validateAndSave(PrefInput.this); + } + }); + } + + public QPref getQPref() { + return this.qpref; + } + + public ErrType getErrType() { + return this.err; + } + + public String getPreviousText() { + return this.previousText; + } + + public void setPreviousText(String s0) { + this.previousText = s0; + } + } + + private int temp1, temp2; + /** + * Checks validity of values entered into prefInputs. + * @param i0   a PrefInput object + */ + private void validateAndSave(PrefInput i0) { + if (i0.getText().equals(i0.getPreviousText())) { return; } + + int val = Integer.parseInt(i0.getText()); + resetErrors(); + + switch (i0.getQPref()) { + case STARTING_CREDITS_EASY: case STARTING_CREDITS_MEDIUM: + case STARTING_CREDITS_HARD: case STARTING_CREDITS_EXPERT: + case REWARDS_MILLED: case REWARDS_MULLIGAN0: + case REWARDS_ALTERNATIVE: case REWARDS_TURN5: + if (val > 500) { + showError(i0, "Value too large (maximum 500)."); + return; + } + break; + case BOOSTER_COMMONS: + temp1 = prefs.getPreferenceInt(QPref.BOOSTER_UNCOMMONS); + temp2 = prefs.getPreferenceInt(QPref.BOOSTER_RARES); + + if (temp1 + temp2 + val > 15) { + showError(i0, "Booster packs must have maximum 15 cards."); + return; + } + break; + case BOOSTER_UNCOMMONS: + temp1 = prefs.getPreferenceInt(QPref.BOOSTER_COMMONS); + temp2 = prefs.getPreferenceInt(QPref.BOOSTER_RARES); + + if (temp1 + temp2 + val > 15) { + showError(i0, "Booster packs must have maximum 15 cards."); + return; + } + break; + case BOOSTER_RARES: + temp1 = prefs.getPreferenceInt(QPref.BOOSTER_COMMONS); + temp2 = prefs.getPreferenceInt(QPref.BOOSTER_UNCOMMONS); + + if (temp1 + temp2 + val > 15) { + showError(i0, "Booster packs must have maximum 15 cards."); + return; + } + break; + case REWARDS_TURN1: + if (val > 2000) { + showError(i0, "Value too large (maximum 2000)."); + return; + } + break; + default: + if (val > 100) { + showError(i0, "Value too large (maximum 100)."); + return; + } + break; + } + + prefs.setPreference(i0.getQPref(), i0.getText()); + prefs.save(); + i0.setPreviousText(i0.getText()); + } + + private void showError(PrefInput i0, String s0) { + String s = "Save failed: " + s0; + switch(i0.getErrType()) { + case BOOSTER: + lblErrBooster.setVisible(true); + lblErrBooster.setText(s); + break; + case DIFFICULTY: + lblErrDifficulty.setVisible(true); + lblErrDifficulty.setText(s); + break; + case REWARDS: + lblErrRewards.setVisible(true); + lblErrRewards.setText(s); + break; + default: + } + + i0.setText(i0.getPreviousText()); + } + + private void resetErrors() { + lblErrBooster.setVisible(false); + lblErrDifficulty.setVisible(false); + lblErrRewards.setVisible(false); + } +} diff --git a/src/main/java/forge/view/toolbox/DeckLister.java b/src/main/java/forge/view/toolbox/DeckLister.java index c9f4ce40745..7441d4ef0dc 100644 --- a/src/main/java/forge/view/toolbox/DeckLister.java +++ b/src/main/java/forge/view/toolbox/DeckLister.java @@ -1,6 +1,7 @@ package forge.view.toolbox; import java.awt.Color; +import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; @@ -18,12 +19,15 @@ import javax.swing.border.MatteBorder; import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Command; +import forge.Constant; import forge.Singletons; import forge.deck.Deck; import forge.deck.DeckIO; import forge.deck.DeckManager; import forge.game.GameType; import forge.gui.deckeditor.DeckEditorCommon; +import forge.gui.deckeditor.DeckEditorQuest; +import forge.view.GuiTopLevel; /** * Creates deck list for selected decks for quick deleting, editing, and basic info. @@ -36,20 +40,20 @@ public class DeckLister extends JPanel { private ImageIcon icoEdit; private ImageIcon icoEditOver; private FSkin skin; - private RowPanel previousSelection = null; + private RowPanel previousSelect; private RowPanel[] rows; private GameType gametype; - private Command cmdExit; + private Command cmdEditorExit, cmdDelete, cmdRowSelect; + private final Color clrDefault, clrHover, clrActive, clrBorders; /** * Creates deck list for selected decks for quick deleting, editing, and basic info. * "selectable" and "editable" assumed true. * * @param gt0 {@link forge.game.GameType} - * @param cmd0 {@link forge.Command}, when exiting deck editor */ - public DeckLister(GameType gt0, Command cmd0) { - this(gt0, cmd0, true, true); + public DeckLister(GameType gt0) { + this(gt0, null); } /** @@ -58,14 +62,18 @@ public class DeckLister extends JPanel { * * @param gt0 {@link forge.game.GameType} * @param cmd0 {@link forge.Command}, when exiting deck editor - * @param deletable {@link java.lang.Boolean} - * @param editable {@link java.lang.Boolean} */ - public DeckLister(GameType gt0, Command cmd0, boolean deletable, boolean editable) { + public DeckLister(GameType gt0, Command cmd0) { super(); - skin = Singletons.getView().getSkin(); - gametype = gt0; - cmdExit = cmd0; + this.skin = Singletons.getView().getSkin(); + this.gametype = gt0; + this.cmdEditorExit = cmd0; + + this.clrDefault = new Color(0, 0, 0, 0); + this.clrHover = skin.getColor(FSkin.SkinProp.CLR_HOVER); + this.clrActive = skin.getColor(FSkin.SkinProp.CLR_ACTIVE); + this.clrBorders = skin.getColor(FSkin.SkinProp.CLR_BORDERS); + this.setOpaque(false); this.setLayout(new MigLayout("insets 0, gap 0, wrap")); @@ -83,18 +91,20 @@ public class DeckLister extends JPanel { // Title row // Note: careful with the widths of the rows here; // scroll panes will have difficulty dynamically resizing if 100% width is set. - JPanel rowTitle = new JPanel(); - rowTitle.setBackground(skin.getColor(FSkin.SkinProp.CLR_INACTIVE)); + JPanel rowTitle = new TitlePanel(); + rowTitle.setBackground(skin.getColor(FSkin.SkinProp.CLR_ZEBRA)); rowTitle.setLayout(new MigLayout("insets 0, gap 0")); - rowTitle.add(new TitleLabel("Delete"), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new TitleLabel("Edit"), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new TitleLabel("Deck Name"), "w 60%!, h 20px!, gaptop 5px"); - rowTitle.add(new TitleLabel("Main"), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new TitleLabel("Side"), "w 10%!, h 20px!, gaptop 5px"); + rowTitle.add(new FLabel("Delete", SwingConstants.CENTER), "w 10%!, h 20px!, gaptop 5px"); + rowTitle.add(new FLabel("Edit", SwingConstants.CENTER), "w 10%!, h 20px!, gaptop 5px"); + rowTitle.add(new FLabel("Deck Name", SwingConstants.CENTER), "w 60%!, h 20px!, gaptop 5px"); + rowTitle.add(new FLabel("Main", SwingConstants.CENTER), "w 10%!, h 20px!, gaptop 5px"); + rowTitle.add(new FLabel("Side", SwingConstants.CENTER), "w 10%!, h 20px!, gaptop 5px"); this.add(rowTitle, "w 98%!, h 30px!, gapleft 1%"); RowPanel row; for (Deck d : decks0) { + if (d.getName() == null) { continue; } + row = new RowPanel(d); row.add(new DeleteButton(row), "w 10%!, h 20px!, gaptop 5px"); row.add(new EditButton(row), "w 10%!, h 20px!, gaptop 5px"); @@ -136,9 +146,17 @@ public class DeckLister extends JPanel { this.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { - if (r0.selected) { return; } - r0.setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); - r0.setOpaque(true); + if (!r0.selected) { + r0.setBackground(clrHover); + r0.setOpaque(true); + } + } + @Override + public void mouseExited(MouseEvent e) { + if (!r0.selected) { + r0.setBackground(clrDefault); + r0.setOpaque(false); + } } @Override public void mouseClicked(MouseEvent e) { @@ -164,9 +182,17 @@ public class DeckLister extends JPanel { this.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { - if (r0.selected) { return; } - r0.setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); - r0.setOpaque(true); + if (!r0.selected) { + r0.setBackground(clrHover); + r0.setOpaque(true); + } + } + @Override + public void mouseExited(MouseEvent e) { + if (!r0.selected) { + r0.setBackground(clrDefault); + r0.setOpaque(false); + } } @Override public void mouseClicked(MouseEvent e) { @@ -176,30 +202,43 @@ public class DeckLister extends JPanel { } } + // Here only to prevent visual artifact problems from translucent skin colors. + private class TitlePanel extends JPanel { + @Override + public void paintComponent(Graphics g) { + g.setColor(getBackground()); + g.clearRect(0, 0, getWidth(), getHeight()); + g.fillRect(0, 0, getWidth(), getHeight()); + super.paintComponent(g); + } + } + private class RowPanel extends JPanel { - private Color bgDefault = null; private boolean selected = false; private Deck deck; public RowPanel(Deck d0) { super(); setOpaque(false); + setBackground(new Color(0, 0, 0, 0)); setLayout(new MigLayout("insets 0, gap 0")); - setBorder(new MatteBorder(0, 0, 1, 0, skin.getColor(FSkin.SkinProp.CLR_BORDERS))); + setBorder(new MatteBorder(0, 0, 1, 0, clrBorders)); deck = d0; this.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { - if (selected) { return; } - setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); - setOpaque(true); + if (!selected) { + ((RowPanel) e.getSource()).setBackground(clrHover); + ((RowPanel) e.getSource()).setOpaque(true); + } } @Override public void mouseExited(MouseEvent e) { - if (selected) { return; } - setBackground(bgDefault); - setOpaque(false); + if (!selected) { + ((RowPanel) e.getSource()).setBackground(clrDefault); + ((RowPanel) e.getSource()).setOpaque(false); + } } @Override public void mousePressed(MouseEvent e) { @@ -209,9 +248,9 @@ public class DeckLister extends JPanel { } public void setSelected(boolean b0) { - bgDefault = (b0 ? skin.getColor(FSkin.SkinProp.CLR_ACTIVE) : null); selected = b0; - setBackground(bgDefault); + setOpaque(b0); + setBackground(b0 ? clrActive : clrHover); } public boolean isSelected() { @@ -223,15 +262,6 @@ public class DeckLister extends JPanel { } } - private class TitleLabel extends JLabel { - public TitleLabel(String txt0) { - super(txt0); - setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); - setFont(skin.getFont(11)); - setHorizontalAlignment(SwingConstants.CENTER); - } - } - private class MainLabel extends JLabel { public MainLabel(String txt0) { super(txt0); @@ -254,7 +284,6 @@ public class DeckLister extends JPanel { setHorizontalAlignment(SwingConstants.CENTER); setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); setFont(skin.getBoldFont(12)); - setHorizontalAlignment(SwingConstants.CENTER); } } @@ -267,19 +296,68 @@ public class DeckLister extends JPanel { return -1; } + /** Selects a row programatically. + * @param i0   int + * @return boolean Was able to select, or not. + */ + public boolean setSelectedIndex(int i0) { + if (i0 >= rows.length) { return false; } + selectHandler(rows[i0]); + return true; + } + + /** + * @param d0   Deck object to select (if exists in list) + * @return boolean Found deck, or didn't. + */ + public boolean setSelectedDeck(Deck d0) { + for (RowPanel r : rows) { + if (r.getDeck() == d0) { + selectHandler(r); + return true; + } + } + return false; + } + + /** @param c0   {@link forge.Command} command executed on delete. */ + public void setDeleteCommand(Command c0) { + this.cmdDelete = c0; + } + + /** @param c0   {@link forge.Command} command executed on row select. */ + public void setSelectCommand(Command c0) { + this.cmdRowSelect = c0; + } + + /** @param c0   {@link forge.Command} command executed on editor exit. */ + public void setExitCommand(Command c0) { + this.cmdEditorExit = c0; + } + private void selectHandler(RowPanel r0) { - if (previousSelection != null) { - previousSelection.setSelected(false); + if (previousSelect != null) { + previousSelect.setSelected(false); } r0.setSelected(true); - previousSelection = r0; + previousSelect = r0; + + if (cmdRowSelect != null) { cmdRowSelect.execute(); } } private void editDeck(Deck d0) { - DeckEditorCommon editor = new DeckEditorCommon(gametype); - editor.show(cmdExit); - editor.getCustomMenu().showDeck(d0, gametype); - editor.setVisible(true); + if (gametype == GameType.Quest) { + Constant.Runtime.HUMAN_DECK[0] = d0; + final DeckEditorQuest editor = new DeckEditorQuest(AllZone.getQuestData()); + editor.show(cmdEditorExit); + editor.setVisible(true); + } + else { + final DeckEditorCommon editor = new DeckEditorCommon(gametype); + editor.show(cmdEditorExit); + editor.getCustomMenu().showDeck(d0, gametype); + editor.setVisible(true); + } } private void deleteDeck(RowPanel r0) { @@ -318,6 +396,11 @@ public class DeckLister extends JPanel { address1.delete(); address2.delete(); } + else if (gametype.equals(GameType.Quest)) { + AllZone.getQuestData().removeDeck(d0.getName()); + AllZone.getQuestData().saveData(); + ((GuiTopLevel) AllZone.getDisplay()).getController().getHomeView().getBtnQuest().grabFocus(); + } else { deckmanager.deleteDeck(d0.getName()); @@ -326,6 +409,9 @@ public class DeckLister extends JPanel { } this.remove(r0); + this.repaint(); this.revalidate(); + + if (cmdDelete != null) { cmdDelete.execute(); } } } diff --git a/src/main/java/forge/view/toolbox/FCheckBox.java b/src/main/java/forge/view/toolbox/FCheckBox.java new file mode 100644 index 00000000000..f0c6b566b04 --- /dev/null +++ b/src/main/java/forge/view/toolbox/FCheckBox.java @@ -0,0 +1,43 @@ +package forge.view.toolbox; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JCheckBox; + +import forge.Singletons; + +/** + * A custom instance of JCheckBox using Forge skin properties. + */ +public class FCheckBox extends JCheckBox { + private static final long serialVersionUID = -8633657166511001814L; + private final FSkin skin; + + /** */ + public FCheckBox() { + this(""); + } + + /** @param s0   {@link java.lang.String} */ + public FCheckBox(final String s0) { + super(s0); + this.skin = Singletons.getView().getSkin(); + this.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); + this.setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); + this.setFont(skin.getFont(14)); + this.setOpaque(false); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + setOpaque(true); + } + + @Override + public void mouseExited(MouseEvent e) { + setOpaque(false); + } + }); + } +} diff --git a/src/main/java/forge/view/toolbox/FLabel.java b/src/main/java/forge/view/toolbox/FLabel.java new file mode 100644 index 00000000000..dc3a800307a --- /dev/null +++ b/src/main/java/forge/view/toolbox/FLabel.java @@ -0,0 +1,143 @@ +package forge.view.toolbox; + +import java.awt.Font; +import java.awt.Image; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JLabel; + +import forge.Singletons; + +/** + * A custom instance of JLabel using Forge skin properties. + * + * Font size can be scaled to a percentage of label height (60% by default). + * + * Font scaling can be toggled. + */ +@SuppressWarnings("serial") +public class FLabel extends JLabel { + private final FSkin skin; + private final ComponentAdapter cadResize; + private boolean scaleAuto; + private double fontScaleFactor = 0.6; + private double iconScaleFactor = 0.8; + private double aspectRatio; + private Image img = null; + private int w, h; + private int fontStyle = Font.PLAIN; + + /** */ + public FLabel() { + this(""); + } + + /** @param i0   {@link javax.swing.ImageIcon} */ + public FLabel(final Icon i0) { + this(""); + this.setIcon(i0); + } + + /** + * @param s0   {@link java.lang.String} + * @param i0   {@link javax.swing.ImageIcon} + */ + public FLabel(final String s0, final Icon i0) { + this(s0); + this.setIcon(i0); + } + + /** + * @param s0   {@link java.lang.String} text + * @param align0   Text alignment + */ + public FLabel(final String s0, final int align0) { + this(s0); + this.setHorizontalAlignment(align0); + } + + /** @param s0   {@link java.lang.String} */ + public FLabel(final String s0) { + super(s0); + this.skin = Singletons.getView().getSkin(); + this.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); + + this.cadResize = new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + switch (fontStyle) { + case Font.BOLD: + setFont(skin.getBoldFont((int) (getHeight() * fontScaleFactor))); + break; + case Font.ITALIC: + setFont(skin.getItalicFont((int) (getHeight() * fontScaleFactor))); + break; + default: + setFont(skin.getFont((int) (getHeight() * fontScaleFactor))); + } + + if (img == null) { return; } + aspectRatio = img.getWidth(null) / img.getHeight(null); + h = (int) (getHeight() * iconScaleFactor); + w = (int) (h * aspectRatio * iconScaleFactor); + if (w == 0 || h == 0) { return; } + + FLabel.super.setIcon(new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH))); + } + }; + + this.setScaleAuto(true); + } + + /** @param b0   {@link java.lang.boolean} */ + public void setScaleAuto(final boolean b0) { + this.scaleAuto = b0; + if (scaleAuto) { + this.addComponentListener(cadResize); + } + else { + this.removeComponentListener(cadResize); + } + } + + /** + * Sets whether bold or italic font should be used for this label. + * + * @param i0   Font.BOLD or Font.ITALIC + */ + public void setFontStyle(int i0) { + this.fontStyle = i0; + } + + /** @param d0   Scale factor for font size relative to label height, percent. */ + public void setFontScaleFactor(final double d0) { + this.fontScaleFactor = d0; + } + + /** @param d0   Scale factor for icon size relative to label height, percent. */ + public void setIconScaleFactor(final double d0) { + this.iconScaleFactor = d0; + } + + /** @return {@link java.lang.boolean} */ + public boolean isScaleAuto() { + return this.scaleAuto; + } + + @Override + public void setIcon(final Icon i0) { + if (scaleAuto) { + // Setting the icon in the usual way leads to scaling problems. + // So, only the image is saved, and scaled along with the font + // in the resize adapter. + if (i0 == null) { return; } + this.img = ((ImageIcon) i0).getImage(); + } + else { + super.setIcon(i0); + } + } +} diff --git a/src/main/java/forge/view/toolbox/FRadioButton.java b/src/main/java/forge/view/toolbox/FRadioButton.java new file mode 100644 index 00000000000..5e2e8a84ec9 --- /dev/null +++ b/src/main/java/forge/view/toolbox/FRadioButton.java @@ -0,0 +1,45 @@ +package forge.view.toolbox; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JRadioButton; + +import forge.Singletons; + +/** + * A custom instance of JRadioButton using Forge skin properties. + */ +public class FRadioButton extends JRadioButton { + private static final long serialVersionUID = -2366973722131882766L; + private final FSkin skin; + + /** */ + public FRadioButton() { + this(""); + } + + /** @param s0   {@link java.lang.String} */ + public FRadioButton(String s0) { + super(); + this.setText(s0); + this.skin = Singletons.getView().getSkin(); + this.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); + this.setBackground(skin.getColor(FSkin.SkinProp.CLR_HOVER)); + this.setFont(skin.getFont(14)); + this.setOpaque(false); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + setOpaque(true); + } + + @Override + public void mouseExited(MouseEvent e) { + setOpaque(false); + } + }); + } + +} diff --git a/src/main/java/forge/view/toolbox/FScrollPane.java b/src/main/java/forge/view/toolbox/FScrollPane.java index bbbceb967be..1f17b73a30d 100644 --- a/src/main/java/forge/view/toolbox/FScrollPane.java +++ b/src/main/java/forge/view/toolbox/FScrollPane.java @@ -25,6 +25,6 @@ public class FScrollPane extends JScrollPane { skin = Singletons.getView().getSkin(); setBorder(new LineBorder(skin.getColor(FSkin.SkinProp.CLR_BORDERS), 1)); - setBackground(skin.getColor(FSkin.SkinProp.CLR_ZEBRA)); + setOpaque(false); } } diff --git a/src/main/java/forge/view/toolbox/FTextArea.java b/src/main/java/forge/view/toolbox/FTextArea.java new file mode 100644 index 00000000000..379d06ec775 --- /dev/null +++ b/src/main/java/forge/view/toolbox/FTextArea.java @@ -0,0 +1,25 @@ +package forge.view.toolbox; + +import javax.swing.JTextArea; + +import forge.Singletons; + +/** + * A custom instance of JTextArea using Forge skin properties. + * + */ +@SuppressWarnings("serial") +public class FTextArea extends JTextArea { + private final FSkin skin; + /** */ + public FTextArea() { + super(); + this.skin = Singletons.getView().getSkin(); + this.setForeground(skin.getColor(FSkin.SkinProp.CLR_TEXT)); + this.setOpaque(false); + this.setWrapStyleWord(true); + this.setLineWrap(true); + this.setFocusable(false); + this.setEditable(false); + } +}