From 266b3355c7c6dfdaabb86c1cd9460bfa23e1b87d Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 28 Nov 2022 15:13:55 -0500 Subject: [PATCH] v2.0.0: implement the cleave ability for sword weapons --- core/src/main/assets/interfaces/buffs.png | Bin 1470 -> 1493 bytes .../main/assets/interfaces/large_buffs.png | Bin 3122 -> 3187 bytes .../assets/messages/items/items.properties | 12 +++ .../items/weapon/melee/Greatsword.java | 20 ++++- .../items/weapon/melee/Longsword.java | 18 +++++ .../items/weapon/melee/Shortsword.java | 18 +++++ .../items/weapon/melee/Sword.java | 74 ++++++++++++++++++ .../items/weapon/melee/WornShortsword.java | 18 +++++ .../ui/BuffIndicator.java | 1 + 9 files changed, 160 insertions(+), 1 deletion(-) diff --git a/core/src/main/assets/interfaces/buffs.png b/core/src/main/assets/interfaces/buffs.png index 03e854791f6c5aa4c287b8e21cf87dea3c97838a..6075db9529d7ad173672bfc220dfb4a058e8a715 100644 GIT binary patch delta 1171 zcmV;E1Z?}h3)KsdSpxt70Fhkb1Z;9)B$Gh_Ab(#;L_t(|0c4Pcfn^~O1aZF0bNBpX zyk`2=3-=n-e>5@1SQJM*2_zCnPUQRnrq1UJxsn^X6GtB8NnS6d-dUEtlfctC2;@ct zilTr(iJMCws=BGG5L+~DbWcn^MWE{-(Dy@nzd(Y(IF3nRnkEsLKLnN}uqJ_R-}mjC zz<)baZ zl~BFWtnYA&Vtno)D~qOpedYzskU$aRi+|w=Rv@s#BlsB`^8o~Yefukqpj<`-`23$@ ze`bEA2~gm(nZPO&`1&sraM+x0c++^3F9HBcAQkxa*SAO^n?SY$Y(Sd8*9L{Z?tl>_ zP_mMNudyJof<*yFkYB_6H3$^IpLQU73vxMjfSvjmw?GCIz=D8K3IFaEm{=DZVt-R? ziEWV=J7QOu*&cR9#A07m#Ye&ct2q;?K&ePd7+$A9gKTUzTbr#W1d=3yz`G=Q2Z4rP zJ8uXD+Fqcu*MUG6_oo{KdV~Uf3JiwB;ozg1al8`{fQ1Bni?RYOvbmLv+$h=FPPX~V zZ*W1tFU)Vlz&f>Btz(rBDln*wCx2wT4|@A^fx&P(oel?>Z4@{-FuVtWkU*U*2tXDB z+lNd*0wDp+hr!-n4Qp>EFo|QnG#>)}J`6D5VBipe)q(&FbOikT*z*Kvzz%SJNPwT8 z0)!oSgDrtH0W^RK#N(I=aJ~dW0{Z;6D8L9xK>!9SA?Ak;umlN8$oUXp0Dn4yg%0ox z#-Rg!GVcIp`x zc0qUnJowDElC2T8t>BAj1p-GA_}US^+wTO9@r8Iyfwlw~Ccp0Sz_AlM#r97>37mNW zXFxw-zKbAmesO+&=>;4y9Dg_JwzZNgepJk@L@+=E5OWaZY=`x=4`af%qhX4(b zz{%-}nI3->IJ>%rfb4Y-IX{WE3OBbmH!}ghwnixYXe(DN@)ebjj$klPz-Zt%9M--k zYpzY)XNHvuoSxpDp4#kJ?P?YCtLAj~7^6>M#02i|AMPc<3E2c70DmH*xZRB0*GK40%tP;ES3=SLkBiqRlY_ zet#Ut{waX^K^Ej$7~)Gwpok%$o3dmrhHFr{ab6a0Pz*!2k51#jzeW2kuq=xRoGS!2 zX{gWrQy>qdqrM2lMF9gt+K4QMYZ>QdVF5}+fCvc;C_j80!3BYfk6^|?eE@;=T=@vL z4H01f&lm|w`%HiZk~e`DPN2MzfWeUCmw#y>puPwIXab)C>v|%EzZ3Yp1AGHM6DSD^ zx9y@^$U~=7vWB5$t!oG3JeC$G)(HF*pz%hUS?@?)GZ#zl3jn@0# zv3}O-Z(|XF5%?+irvQ+o{-^_+Q;ki1_7E>CfjOf+bsZuVF-ZJFgyi7)2_lh ziU1u8&@FWV(8K)n96+BUz<>b5(P%XMpl)dINdN$a0Bnmk0oqhH7mmGgn9GNGUVerP z0CvH@0|L{n*XvzVey}g!Bgh1JDs{b$@_oFmW9i zP;m#~ZEIj<2=LFRfB^q~3hKsMOIu@@lZ+Gu!3nmJJjqBY$&)^jl9G{*VeE52p8)KWF@F4mL0OtYprAP5!^BaH*JP&2vOaK5-V1Ed%_~RCQX*Lru z>HuGPE&;uOJDqEF008a?;6Jtr+}_>^fVcVOW(SmjzNhH^r~^tsr|vo+93&(F1R#GU z5ZVr`R%-$1MY=f!CnqQI6v+KwOhHEkCX&Z%dkV(Vle8~Iaru&wKHY@`uzUu<%gYM@ zmJ|S9y;lI}*`pfo5M|(bIo+{_KP%Z%y z?7IXq^!H62Yli^K2mp&Egum-R=1nD>bB=bMz%Lu9TtK|iVd{WU2LJ%;*?P7SUm3js O0000WO&-~WqkGO~v^w*bc3&w^l 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 CRQK`# delta 2753 zcmXBSc{o&i0|)TmIkPlo1|!2vmW-6GZYD}d97|-0DKbhmL*3MEF{!sjIAM`Y$bM;@OLPL8b?_Zjhl3yU0N01Tf*I}JH!c_)ouUw3^-eOnO-&aF9L}C75 zUUFP%%K9VKc_?~oN!jJj(n#%h-QI? z|83dQnC7S{X~Ro>NLFzZd!Mz#COqbkn|pg{4Eqyxpk_fpz5K@47yAK!Mzo% zC1KgbME#zWqp(bGtt^#{GnvH4vFQj<{_DbhvF5b;C3^eFM4It}yo zx4>D$87}YO(&Hq^rSmMO_iP&G4O&JGAt|4PMZ#R}Ui$qoj+Mkr6+^#zXWoS%JVpA3 z=&-7(8LWzAKN6e*bY%$Mta!5s&0cuw*%agA)0rF#@BC?aR_m7-Qom*;S#mE`0^ z5cJy<+zvnDpYKldPPLF9q%uD zA3b$seAVOE*G|r<8y45a#7N<-AF}Oo{ynF`eSD$cJL~a#Bj`G4X35r&L|Tg>&M%VW z0O+8Vza{QS-yWfA_{@D_AiY7$HvSAlezyprWZ;dXQx2uw#f@vUf{@N(QB8)Lf8V+x6df(V1O6pnB7?C)HhrAn!Lu&St;b&*_6sy_-lg9!7RaI!GZWkBMI#q znY!i{{sGz7xsKs8VSZS9dmOI^@rS|x`;}jVYI{k|@#f1I+}sGFGs{w%Sm1~InQ9z& z9Nk|X3mZ~z-$k`9oOj!M9SoFdR`AgRAx-Koj%5Lb2)K7 zAtjS-QRw#N4jt@adxBY7+q0Hya9bcjJFBp9Nfw-a{r<3e1l~&4!Ihx)gky@(1_E$@ z8~%FY`GW#5_D#QWxDdtJnI@lmbrHf|7FQ7mbp%4yBhQ}=koVo)L*?N&i^Z$=-?I|k zSjR1SQgPx9M{=*OjN4F6p_W|86GEVv@rYUTIuOt+Q6k~&7}_iw@$t$#z<7gk%FM9t z?n*6Te57GB2wes5!Gk5Ss&a75a97f__7Q!NGEJEf3r^+9+2IdHu0pHa>kA=ImK?gknv&td6tWscPWskIz*^W~tRmg7d|V z=);9GVb->G3|hKiO32ZF+qg@xr8{JDClnnuI6uN|GlN#n3MQE=t3=bmZg2lN^JucX zD%w@I(n6{gh!UnA3~C_p2Hd<)J@BhVEBJ1JrgEL&oibN+(+Dy}+_xD8YXZ-N*8Y;sbIv|iOd zn03Y=|F{`vJ|Dkjo4TkfP7gaLm^HbP>JUu0HiD>cVLD{!d$u`>m|{~m6{g60Ca$!` z$d(B67G_*3X{+cVkuQK!$k3o}yY4v4E!p6Z+-s}|8gbp_2iaCP4XmEfuPo!b5^+HM6yWIOK1Hci{Lo-emy~QYf!Zo~SYi-PMT$~`vAH+` zAK4X8&4>7iBk9NsLvD+y<$`l2H}!;?S&8Wa>ag>RI_8+=XFheOmWXBP&6qt#<%Lp?QqbOzRKT8aqA^87 zr{ZDN_wWf!k>pCB&i93Y!Wf!7LC*`e4(S&hk z=FHrTvieeo^8&O5sa>C~^g`?nR}*7BskgpZ4A^91fg?>xA$TN37|-TGQ}lPR{3WE? z*|T3LUg(9rGxt~7^y#(uSP2hj!Y=J8v6~mGEX<_a&9O2Y>6_}?-~W9|#b1*LE(arj zic5-58$rIyrGHCda}bep+?JODjU*+9W@tX9V4C|SPGlklgQ#fRY!H}P z1Mki~q+#z$#JsLG61xELMVo-qo2`Ld)3}wOr^qD6ZXzUNoi!fuzfG873h{DCV*f-` zhZisS^O5o>3)#=3gm!P>VSr-CJB8Wplgfhi4ML5gBivfYBhgeMKIdL zL1wfCl$Um~5T;Tbhf~$ZNGOFjB?wt>L7l cQgqruY2jSXLf2Sq82~@yvo651++8U7FG1_PVgLXD diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index a1753556c..b06c9c178 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -1532,6 +1532,8 @@ items.weapon.melee.greatshield.stats_desc=This weapon blocks 0-%d damage. This b items.weapon.melee.greatshield.desc=More like a mobile wall than a shield, this gigantic mass of metal aids defense, but doesn't leave much room for attacking. items.weapon.melee.greatsword.name=greatsword +items.weapon.melee.greatsword.ability_name=cleave +items.weapon.melee.greatsword.ability_desc=The duelist can _cleave_ an enemy with a greatsword. This deals +20% damage and is guaranteed to hit. If cleave kills an enemy it is instantaneous and lets the duelist use cleave again within 5 turns for free. items.weapon.melee.greatsword.desc=This towering blade inflicts heavy damage by investing its heft into every swing. items.weapon.melee.handaxe.name=hand axe @@ -1543,6 +1545,8 @@ items.weapon.melee.knuckles.stats_desc=This is a very fast weapon. items.weapon.melee.knuckles.desc=A piece of iron shaped to fit around the knuckles. Keeps the hands free, yet allows for better attacks than an empty fist. items.weapon.melee.longsword.name=longsword +items.weapon.melee.longsword.ability_name=cleave +items.weapon.melee.longsword.ability_desc=The duelist can _cleave_ an enemy with a longsword. This deals +23% damage and is guaranteed to hit. If cleave kills an enemy it is instantaneous and lets the duelist use cleave again within 5 turns for free. items.weapon.melee.longsword.desc=This sword's long razor-sharp steel blade shines reassuringly, though its size does make it quite heavy. items.weapon.melee.mace.name=mace @@ -1581,6 +1585,8 @@ items.weapon.melee.meleeweapon.ability_bad_position=That target can't be reached items.weapon.melee.meleeweapon.prompt=Select a Target items.weapon.melee.shortsword.name=shortsword +items.weapon.melee.shortsword.ability_name=cleave +items.weapon.melee.shortsword.ability_desc=The duelist can _cleave_ an enemy with a shortsword. This deals +30% damage and is guaranteed to hit. If cleave kills an enemy it is instantaneous and lets the duelist use cleave again within 5 turns for free. items.weapon.melee.shortsword.desc=A quite short sword, only a few inches longer than a dagger. items.weapon.melee.quarterstaff.name=quarterstaff @@ -1619,7 +1625,11 @@ items.weapon.melee.spear.ability_desc=The duelist can use the tip of a spear to items.weapon.melee.spear.desc=A slender wooden rod tipped with sharpened iron. items.weapon.melee.sword.name=sword +items.weapon.melee.sword.ability_name=cleave +items.weapon.melee.sword.ability_desc=The duelist can _cleave_ an enemy with a sword. This deals +27% damage and is guaranteed to hit. If cleave kills an enemy it is instantaneous and lets the duelist use cleave again within 5 turns for free. items.weapon.melee.sword.desc=A nicely balanced sword. Not too large, but still notably longer than a shortsword. +items.weapon.melee.sword$cleavetracker.name=cleave +items.weapon.melee.sword$cleavetracker.desc=The duelist is ready to follow up on her previous cleave. The next use of cleave will not cost any weapon ability charge.\n\nTurns remaining: %s. items.weapon.melee.warhammer.name=war hammer items.weapon.melee.warhammer.stats_desc=This is a rather accurate weapon. @@ -1630,6 +1640,8 @@ items.weapon.melee.whip.stats_desc=This weapon has tremendous reach. items.weapon.melee.whip.desc=While the barbed length of rope at the end of this weapon deals poor damage, its reach cannot be matched. items.weapon.melee.wornshortsword.name=worn shortsword +items.weapon.melee.wornshortsword.ability_name=cleave +items.weapon.melee.wornshortsword.ability_desc=The duelist can _cleave_ an enemy with a worn shortsword. This deals +33% damage and is guaranteed to hit. If cleave kills an enemy it is instantaneous and lets the duelist use cleave again within 5 turns for free. items.weapon.melee.wornshortsword.desc=A quite short sword, worn down through heavy use. It is both weaker and a bit lighter than a shortsword in better condition. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java index dababe1ec..abddf6342 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Greatsword.java @@ -22,6 +22,9 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; public class Greatsword extends MeleeWeapon { @@ -31,7 +34,22 @@ public class Greatsword extends MeleeWeapon { hitSound = Assets.Sounds.HIT_SLASH; hitSoundPitch = 1f; - tier=5; + tier = 5; + } + + @Override + public int abilityChargeUse() { + return Dungeon.hero.buff(Sword.CleaveTracker.class) != null ? 0 : 1; + } + + @Override + public String targetingPrompt() { + return Messages.get(this, "prompt"); + } + + @Override + protected void duelistAbility(Hero hero, Integer target) { + Sword.cleaveAbility(hero, target, 1.20f, this); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Longsword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Longsword.java index 690b4e7e2..a0f7eb107 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Longsword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Longsword.java @@ -22,6 +22,9 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; public class Longsword extends MeleeWeapon { @@ -34,4 +37,19 @@ public class Longsword extends MeleeWeapon { tier = 4; } + @Override + public int abilityChargeUse() { + return Dungeon.hero.buff(Sword.CleaveTracker.class) != null ? 0 : 1; + } + + @Override + public String targetingPrompt() { + return Messages.get(this, "prompt"); + } + + @Override + protected void duelistAbility(Hero hero, Integer target) { + Sword.cleaveAbility(hero, target, 1.23f, this); + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Shortsword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Shortsword.java index 047e61273..b187c9576 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Shortsword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Shortsword.java @@ -22,6 +22,9 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; public class Shortsword extends MeleeWeapon { @@ -34,4 +37,19 @@ public class Shortsword extends MeleeWeapon { tier = 2; } + @Override + public int abilityChargeUse() { + return Dungeon.hero.buff(Sword.CleaveTracker.class) != null ? 0 : 1; + } + + @Override + public String targetingPrompt() { + return Messages.get(this, "prompt"); + } + + @Override + protected void duelistAbility(Hero hero, Integer target) { + Sword.cleaveAbility(hero, target, 1.30f, this); + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Sword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Sword.java index 36f2106c2..56df0dd8e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Sword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/Sword.java @@ -22,7 +22,18 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Callback; public class Sword extends MeleeWeapon { @@ -34,4 +45,67 @@ public class Sword extends MeleeWeapon { tier = 3; } + @Override + public int abilityChargeUse() { + return Dungeon.hero.buff(CleaveTracker.class) != null ? 0 : 1; + } + + @Override + public String targetingPrompt() { + return Messages.get(this, "prompt"); + } + + @Override + protected void duelistAbility(Hero hero, Integer target) { + Sword.cleaveAbility(hero, target, 1.27f, this); + } + + public static void cleaveAbility(Hero hero, Integer target, float dmgMulti, MeleeWeapon wep){ + if (target == null) { + return; + } + + Char enemy = Actor.findChar(target); + if (enemy == null || enemy == hero || hero.isCharmedBy(enemy) || !Dungeon.level.heroFOV[target]) { + GLog.w(Messages.get(wep, "ability_no_target")); + return; + } + + if (!hero.canAttack(enemy)){ + GLog.w(Messages.get(wep, "ability_bad_position")); + return; + } + + hero.sprite.attack(enemy.pos, new Callback() { + @Override + public void call() { + hero.attack(enemy, dmgMulti, 0, Char.INFINITE_ACCURACY); + wep.onAbilityUsed(hero); + Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG); + + if (!enemy.isAlive()){ + hero.next(); + Buff.prolong(hero, CleaveTracker.class, 4f); //1 less as attack was instant + } else { + hero.spendAndNext(hero.attackDelay()); + if (hero.buff(CleaveTracker.class) != null) { + hero.buff(CleaveTracker.class).detach(); + } + } + } + }); + } + + public static class CleaveTracker extends FlavourBuff { + + { + type = buffType.POSITIVE; + } + + @Override + public int icon() { + return BuffIndicator.DUEL_CLEAVE; + } + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java index c3bc50ed0..8c77c964d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/WornShortsword.java @@ -22,6 +22,9 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; public class WornShortsword extends MeleeWeapon { @@ -36,4 +39,19 @@ public class WornShortsword extends MeleeWeapon { bones = false; } + @Override + public int abilityChargeUse() { + return Dungeon.hero.buff(Sword.CleaveTracker.class) != null ? 0 : 1; + } + + @Override + public String targetingPrompt() { + return Messages.get(this, "prompt"); + } + + @Override + protected void duelistAbility(Hero hero, Integer target) { + Sword.cleaveAbility(hero, target, 1.33f, this); + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java index 31b3f6f2d..61eeae573 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java @@ -111,6 +111,7 @@ public class BuffIndicator extends Component { public static final int INVERT_MARK = 57; public static final int NATURE_POWER= 58; public static final int AMULET = 59; + public static final int DUEL_CLEAVE = 60; public static final int SIZE_SMALL = 7; public static final int SIZE_LARGE = 16;