From ae4f4d3ed62d2956a2a82f86a689211450eefd7b Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 17 Apr 2025 20:30:52 -0700 Subject: [PATCH] traitor only lasts 30 seconds, 50% defense debuff --- resources/images/TraitorIcon.png | Bin 14635 -> 0 bytes resources/images/TraitorIcon.svg | 92 ++++++++++++++++++++++-- src/core/configuration/Config.ts | 1 + src/core/configuration/DefaultConfig.ts | 5 +- src/core/game/Game.ts | 1 + src/core/game/GameImpl.ts | 2 +- src/core/game/PlayerImpl.ts | 11 ++- 7 files changed, 104 insertions(+), 8 deletions(-) delete mode 100644 resources/images/TraitorIcon.png diff --git a/resources/images/TraitorIcon.png b/resources/images/TraitorIcon.png deleted file mode 100644 index 23f5d252a36fc69778271715b5035fea069da85b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14635 zcmeHtcT|+ivTx6jb54?moMA|kVaOSWAQ>eLIgMlxVaOnYAX$lmf{KEI2!b-8B1u3* z1j!&l1wl}fg!kdz=bXLYz3bj})_U*1Gc2IGyXse6zpk$CZ)VcaX8Kg*r^o>SRE7pR z768B@5e`U+p?^OjM)m<YKF{bwux;AU$z8wt4p5HltaA(@4ApP-2 zvB779YCDP%!w0`SRga0w%3|A(UJl-ijhwo4%)4nZFa50D>*poP^L4RKD_g9@gS};v zBcsbKTXpR#d%?f9UnHq37};m%*K4qRDWkZxd&CM!5QwZpGJ z1`jW%J)_Y$(qMl(k@TyI^$dB>R-nw|F*^i1cbT*{)>N!(#k#7!6FLijNCooo&Besqmx9>C zgI)bdQ%t>ZuTQp_^YX)AYO5Zql9%`QQj?bNKh!xF)<#{Jop#MfCP;fGySA9(r(27; zc4gHyW0A+U-nRHDJPjN6kzzcetmz zIBK==-C%R>N7HXh4gt@?Cf35EJ=bzZ+Yb-)MmvRkzxU)$d(GG_oNcHxChRaYA26^D zQOdetNiMunQ@qC#+R^{XdAHGTaq5Am)CM^GhMvc{z>BK zyzFxB)0zIsnXT=HTK~60Q8L?M74csfre3d~VSh-KJvA2D#rXo~u<7U9d_l8OE+pIh zOaB4UlXvo!=>bkcKU)V@^&Ont#SjZkPxp&jn{I4QwoWd6JIB1&mX~F_KUwR+#Y{MM zxqgCt!B!P~uJsci&6)6SVmeS9WldCRTpRu5?VR_sIL7#jeRQ$>{jX)!&bxK0Pmd3h zHF-}N->rJ)kgi8r(`FiH4tv6NzK6^J%c*4aZ~!UzGrOrBT=;BlFs0tI&NWyc@i=@4 zBTfg}yZzUTK0dtB^(C=~Zg<7Ew8;bGnK9g)7#w^^t92$PeVx5#*cH3S^E}w}RG!rv z1L@pH%g{6Q){=_s=^d}O+FHR zwdixyl^Bq%OFC%LzAbvpqwtNT;aBx*9ifIUQ(uAi_V!k5p(44FeNTT>oo_sI^_G8Z z{u4_P!NCW;iuVVIoTtwEv-d=QQ1Ke}y`Sh9FZPu+lzw1LKHXqg3;F3fy7Fa2)^*wW zDTC?j&Dy9nv= zT!~;P3{mrNxayH+j!B;g25fWCxF1>?n@w)_P*49>AOT=mi?j z5}EToL$QBo^qxme3T9Zzd}hNF7F4LJ-K(v@5zT%~75XI4S;J&JHvYg=fFat|2HnBL zoA5QmHq2=3plEURV(+aX#HB_@VQCU?oWM8Fl*BtbGxw{P>FSW&;-M{NHs314d5e>r zIa6LQdiB!yKg4pH0U+WX>);H^MBk@=9u}@t6 zh}wKx+Ma7&o)HzNSK+--lh7h|E^((;oq8?$>`p}?6)A1G#$&W)Lk`{&caJ*j9W^Vw z+c|_L7CS-M#Jo-!LDrRoJATNlX8bJwmBkF z`x;V;MTe?NwF~=Ie8i)4R@s}#kiFoABql1bq|KIr)Ob#+`$5#$op1gl#@e$>zH-6} z;ys#7v_gZ}V#nwY4{4%iE9S&-=c}s4-y;e-IO}!0bArlkHBpE!_Gd=2wTNQiF*)C0 z&+PB5+|-)lO08#O;YC>#SYi{q z%WgNn<2kmU-3hqv-0CvRa+7zscEpQM{8qVj`JKzP!@~wa815yzQ&NH-Hw{qVl&XW? zvfTPIZ_aJ9!Y~$J=PyFeCO8nv&sbseg2(SgP0H@uZf7qZZt)v8Qgl&+N)P7QxQoJI z_HY&1Q}vH&-#(~W5R?$BD1QH;2=gNxm$lqKB}b-t372 zT_l<^O~+vWEuU{W1|(3%qra%KsH#LnU!xujqhQW|5;QJQqOJ6p>w?8=eNg(Qm^JZ2 zt^%ihUlw^Ms;GA`<0VO=Lg3+hVg^Y-`vx=1Q6^GvR!7A1;%PmLP&7Il@0R>_F??we z`Dlgx$oQFd(?L_?>81NTt5Xc3w*1q23o<)~FMaB&6yX};CHnn?3-NJQY>he@%k18F zaZw2`5I%m+MPlkG_;I<_`}vSljABz!71LJAB3EB9Rn`n8m$MqJZL>5FEsw+<a2rFkT%TIGC z$)Otul|hY>++K4=govBdcasCy?t5_J6K&7(q)fck^zIxW%=7Kc%G}jj#S^gkBCFfY;{G_KW?mETa!Tv+q;$^)6<~m_5xPN73kO!50B6GTL^*_Lw$xY!_o6_%0_Jd)AwLJ#q}~iSzk_+Y zZiJe)h@pTkL;Tbvg97C>)5zNwynSr*2{p%qcx(jy5=alS-!ws2c&2AtD1XKET#5_}jLd7Eag6suu<3v`(?tZCYvn9nYWG_j z&2=U!kpyMF)VNi4AK|N-LR=Ab6<=xc@;aP}e=g9c8R`bj!k5RKW33y8%W6quw5GUu zmdjrq^x){suURc;Wb=NymKc|@&NwLR<9r@19?>BgE$pdi{}|U&PNvSQH)3t%yjpYZ zZPX#5SKJhEo?z+o>Kapf21q_u`k7mCTE6RO9f(I?f>qXaN5GmdW%)%S=E^dED^Q79Tj>F6d zrjX`mot1y_+SN~JCqd`ikT_>i^<{xsM!_0_?4eVswjbmKd8G|)<_mT z{+=xpoI8|M_+~_xN<@#&1f!Uyc~9yaM;!VVnuL|fBhNMd3j6ik#smsFNo`L87fa@C z=J#yz!>3EG8duS@&0g~6Nbu0C?YTBAR+E~r-PpXFE}m@|!c>qbC&v{q$Q3yD*`2Bb zSN$NHfH^NYKAhSs+xgsC4q(<)AV>A+j&F<=%gPJ(_#Z6R9QQ_XOM;Hm*ta;7hwoOe z2RJ%CyVf^-en=}eB~3q+Ee%Jir~S}6KL0aijW_s;GQ;0w4oE-y`J5TIB_Y0wgSkFP zZ!ra%V&|QmLGR4e%ayrD5ShDR`EYH-Y*X{-&YqcO$(t)&!;ExJIyx%1=oms7)p}We zB;C_vj;QEQ(2FxzzbngZdCR|;y_MG?T+K&C9s3TCB4v28He^e6lRxBHLJ45&Wt0_< zQo)kBBVj=$lfZVi-D`!hc8iFjfmrIc%Z+>UgDP*uhwY@Nmd)H7)1UAhlH64M#8eX0 z@yzx5wNqpCDgs$6i1LEa7QWKqnomC4Kdj|%w^yGpZ2_mdBMLUNm%eT$p*RMz%O zq+WgrruNj-Mn4*+X3d>3?mliqPgL>-W5b&`87cfN#_)0xxQHrt>7YEobLKm_u!e6g zfetnKReiG&n}bj*k^81+Lu?ageE0c1tGzjYo?CHcgcHYKs=jsSqijA=W()PBCtu?W z8Pa}a1PKLZVl1f)2&zavPNMnJKA^0}x#v^!yL{0TwPcriHyf%}@l|+AR&=jm=?b-a z(!nWF&WfH1;m>2ZnH*LCa+s$GvnCDr5{n6y1!<) z5vi(C{I*P5Y=cB>;iw~v_^icpw@`fMVGzlDDw}WpEOq(QikEj{PU*>3J`iE*jayR> ziIhvfiJlhFHt$Iocs{ta&#XMmNl5s{K!IOQs!@nL{rIwkXpj87k!hEY7w?-u%F?c3 z-ZD`KiEcM4?T#Ry)9K$oQ+`s~*CeKSN@Ktpf}gx@jo&W_8KL1=Xl|b!J(Q6=-n-y2 zNn)7Cd5sxGsj@Oo0{`&o0}3G;&cWJuzHrY=)Krk$X4o>r;t~4?2DzRy^ln>=ecy)C z_%WSgitFQYi(F3JOP#w{^@ndp9z1DILW*!#r7m6mY@%B9U?s$mwWOcqjjdr$Cc>w- zBtm`7WEi3RMbk1$)#b5KEl=5+*$4;)-)?l!Z2lyuX zahqTG<3UHpZ~oUEZm%#2M#tTze6P)%`*dbJV}BP_}-Up1^aI&_ot z1w!OBCv-P=X+l1i(uV2|0Jsrlhi6$hS zt=3Nkmg<1!=`O8A3RU^URju2eGW#wcf8OA;*;(lSdGS-!b*;;nPCQ*G z+r<2CVH)XB)3Pm<{Nb=4R>|(NVaZFeN~Dn`*=?wC<-SK-30k|;@zSizSn-suroBJ_ zt->QGeIk|xjX)>on71Kk_>Ni9DN72*Bbf)1R6|9Lgq?pxq-f7BgbIIzSy`=}TRN3C zBPZVJJ^xfWgF*h>dw#uOz=;09U;6xYIlGLY%A+XxdM=_Jo7Pp5%qt`Guk=mg{7nz8 z-kta*TRdcw{oG+R-=i)w#Aw;~b_9-fy1{&<25wt=F6YXJ(<@(i-idx<4pQ*1Ml{8vDtU0%W zT!=WrWyT#|)-Bb@SuF%-sM4F31C=yh8s%5ceXJKU?5{e!q%PesHe>>;?Qeekx*=5{ze&qwhA_A99D z6sL>fhKZd2!2Oizyf(%VvdDM0b0($b&DGSIbB~ppn~!!WXHBiuOQ+=KDa&V`X;y1q z)Iz2%dbU(|C$2x2*B{;CqdXUW6}$KH%4MZFn`#TqQ~JI}5ftgvK=s;-x}A+D!U@>lOSE?sVCNb3*S9aJMI^|JML?@8<2fQFgxEl z7ejAet>io0qZSV*AxND6ewR-IZ8NA$$KJUV?rIgf6h~t!oN&M;By6?IuxIaF)$0(I zR|)FGpKQxowxFDn1<~m?w`ovUO!WxtQB4hR&7Yx^yki>W>e~iKWMZD{&dI%DjrE-4 zE_(8HL}DSN>1ws>qle(FMuP6c-T_HL1|}kYiSC4Ij1$Z2f;@*tcJAfl_m%UsW~Z!2 zDsM7H^QDXqvvh{N+|fVS|L}G~nN3_EwRKL2|5tjlS4L9#j{H>XS_KC~$YX|2EKNid z=62dY886AYS6oXL51*k@VhEwm@X~Ce^@!Z8a2d=P*|cAIJ@(`}+*`l34QUax^Hnf5 z>PlU;&OV(eQ&Kx~h+~n6sP=n9%P%Sj_1cQMax3#jz3&Jm=_zII>cyt(%s-cF5}8Z$ zh%@e$rDhfh?{^NT zEXc`3E!|V@6A(4@;dk3k^q&a>YfR`y8G?;YlgfEth3BV~=|8*TcZCHWt8tMvYt1wd zdcS6E*6C(8aj3LZmW$Ful!}pRx0wf6rBTa;PV?9}<_AfmlSbA;M=s4-JksqJ2s733 zI+~cfB34V_%VU#7eJ3s~!R(9McB+V1dRx@Xl#32!RH(I`22ahPp@C! z)V2s}lXJY|ds*tOpYjXiyc>MGEB%=ao5Soch_Egw-F+<R(_JLEe1WPd}eW9O74nKoWKvAcbl8lISI#$1lQWt zp2kKdpriRG3&aDpdtYU~`B9eb>Hkt^MsIUEuk@0~ma-%$s;77av&W9^5fO7+HZHCV z?b=-3LlF7Yol)r^=qtYLI`)v);#?5D1#aK%P^|po^B>C+kbZc>Ajwd_(f{uewA_Z zCxe*lS}l}qWp5Rj;)W!UjbFA$$6tRY$f|yjAAn2Hc7CKa?#s2#wX(K0BU^G511Qf2 zed@EEDTh9q3G;?Ng0VFvh`_qI`MQT7T-`mr1Jroe zTibaN-WWAr8+lWtDOTIv%iAC-$lWr^%*rjw*G&n-tD#P=8lemU_`8R=AR_$z0)mwz z)Odg6Dns%~w-hhpw@Qew8n3M>8lfE+0M5&xK}f3g7aAr;|*m6Dc3O8NUs{na8k zL^liq`Ex@5twpdE^huVKg?n&dXpoz`ZkT&O2;W~JFmC^}$A$*^{SF7?Cgtwu?hmO3 zLtdr-=2G9#6#Y+&6AC=N{jtBTAhQ3a8RG5nFS7nNx08|I;rw+XkoiAx|EB$q*ncZS zTBfGTI)QGXC(|?3QR6-FuZ#(F^TsIu7G+Mm$;&97MoK6uxhYD>VHD&gTrj7lC8Uvx zvhs2=NH<0I(|>_7365^uc65n_&)nxJfv$y&0)8 z|G5K>ntmY0o$LTWx@@40DyJCe4)%p%*Jx08Tf=8%f0B^kKGCDSH8w<_lK^MWkZHCv zH1uH8Xdrlpn-=8ah!p_9ALcWGz+*7vX`>$gD-NK@yh0!neq4xzZEVwk!?5MxeHs9a zP%qeVI!AmcAoIAjj~w?T7Ob=yPXT~qKe5ijQp`f%S)2seT&a7Yd$b!qyUz{w*R3HB zv&1+)M{`*B*dLt_E^KFpLLLIZZtgu1V0RCqn;fS{j_Y5$HLxF>dqjjHp?9YGwN!j* zD=2qBE$f6tjW~EYDX={t2fr!B7XVIYF#eesJb?k`c6Pww2iX2>9dq?+w_T-&INk1Y zy7+<$Hv!S3k+lw32|*D{_n&QaB>qqshFctb-`epP6%N40T%-EqXp#`*x2s{dkI%Hj zS>+5a1LyDW_KER4Sat~a$G~9_D+e)%EGyVqL@Tla8Fi_JLnd4YL6&A*FV9;^}j_5n2(F6 zF4%Z{kR9K|>q9?YM)S*Z_dsz=`9jaGFDj zup*%?MnK?#0CqxOlQ+eHBP_n?H5KT2QNfuIofAlo&o#1csjlGA79)fVdmH-6_5wWo>yB&f8jyt9uqrcp!nIyoNgWlTFcg;8Xyh%sIW* z<`+dUd(b1ctP4Y0CHIb_L9wpVqMtBG?!zjPkmG_y%8C=tMw0--uVI6)d4U4RkIU!W zD$WT6#WpQfKSV(CoBCJkHbnTAJblP&V2DWFm;VWf*D4teU}M$`uR_!pc+d%9Q#0xg%N18Y2>C2YQeBg zY7~s%1)ECo(NEd3hg)k~%NL_b@UW@d5qnb-14VwiFvKS+T||xrVR7)lk_|`>#W=7e z?>yt#TP+C>JSGRpVS7XN>f|`tby-~)8Xixquoyh4wyLUMRuqW_xqyJZs*GlyH&kmh%83w6SwYrsrSR zz9}MWxDCn)NqPG@Jj`Gy1Q}01=Mp5ak|FxJJkG#Sv}D}<+)I!^O2*Y+&ZYxH0W!}1 z3MEL`CFSV9X$J`#{}6Ub*?;%YszO3#qz;T$xs&)$A)dIustD>){D+{d^|u}?01c7! zm$N|vDxOj{p~xK2`jBcZPetm(P{O>7CBe%aL|{&s3Ken}edT(n_erSLG86gNR=wlkjrr$XLku_y`S016)67;zz;o6B;fQ zqnqIrI5-Z$^$`{Fs7LAiV8j zSleMM(aJSbVSvAx#XMUMfQtZrlY|IY5g1s8JzN*JI~qSYg_!8m2S(6o0RS3|{q%qH zQv<8Z+-wJZDIO4=^hKn9jh!`$p(+PBSC|JS5g=qNlz`SJwHzLt4#%Iej4co}L0rs_ zra?j30`njx!Zjl4oSjb+1cNK8NZX|Q@pxh8_}4Q8=1q;v0x?L06;d&RYcF(%;`X3S zpN+GFJav$G07jg%$oYH*obAyg$d4xJfT}RyPs%{ORNbFRh2xwFJvk(|H|d6?5r@;X z>D*9mAv^4dAzQKmq%dF)I+Q?N2y=(N*Z-Y|-{6ABAtjU;R#~L$K#}K|T6;qlG%0 ze(wfGTxb$NM;OHNB%$+O0<_A28L}wRc5sq=Tp=3i0%Q&^mxv`Mg{~6Neh7g5cW8g8{cWV21|l9{3BdGGhXf#p*eEB2a%vH} zGn_PpVSj53zI9v^eShOiZ7hDsW=RrA|Dmwv<0r@w5lJW+!`M5$^EoFHe;zM8WWJwbLM zl%g0sOXhqshy27OB8WnVn~Upg7rUTAXY}qHEPdvA73#um zgi{w2Faq(|#OGVHs=xVhS@(oNLHG}LhMX>jwiN9Ke46co9+bTG6k(pP>@;B@PO`s* zeHq##JejoNF~!`sH*5f+?Go|HNhe8)Ce!I5;3{xhn=}^GhLW@e}mSmmAjnDggqK#5d3qoC(LF880iY52%oXPBiQM zq{^LaohB8E;4XIzqM+7Pa8j)v~$e`E+YLPZemn)*l zXnBYR=pp5N-rA1hB3Vd>KNsItqyXvgU%^insX%n|Cn95)1`kA_d&XRXl3a?(_f0wk zc6Ln3iV#bHdqUmE9qcU$6%rXO;w^7=NRaF#3idIB1W`DVtglB)`Y|Iip0L1BXCNmUy}nZZ7*Ep=|QMR3ym8;J)ylvkATCALm_1ts!ZM_zDU6F$ zSch~_thg419jFHdaFkiF6J=uVekk0b10s%Yf=KA38>3R`CTf9%ZYrg2l08UhraIkC zZYP~91#>O$5T7Fk8RwkiCbQU~Th|zE!a)`{Bz%~S7taXP}gA8DZs1-_% zZvLVw;5-Dz`EM`+N>)TAW(4z`Ftr2TkiiZtZal_zC7Q%JI2pDprw}cLrvlm} z9h)Q=ZgLz9WW@;sYIU5r6&RbxtE}Q2bJJ%Q&l5~0YEyTgngofD9SO*~4cP7g#WC>6 z!deuxa(Sh&W!(tcBAtP;cJmNppp59Wuhk^L)KH!U9FD+F)R+n9L{s~My!&j+U7%P6 zHqSoiS~A8_3*jh(3Cc@OahyDcDP~dg;U*yqtrS|+(YKCpz@ZN8mWffnJL0!0ip8!mb}VI3$s0vT!aODa@B*yk*QZeJq23mg?72B_)4=0(mK7&Zc6Jj?w9 z!MA{`)KWNA8^FN~K0SrcW&y;^`p=*$4oaM%(!^dFOBey|D78c^h^zyOl%V?(5uOL2 zj&>GQpwkJztGfLRhiAvVrXyFw$kL_FKOw1fuDR0b0w zi<)-70Ru#6NPz$%@b$|W5(p0w$Ad_aXS;%8&s&NuAAZ%z)gRgCsc(zreZIK4G>5spw zW}BuV2dWBiUp8JqK84}F;R|cA#9n&@SsuS)DOUoiUT>1%P4Q|MAAQ@c5RU=P;hvJm zOi;*RXT8ff036lzKw%BJ#g1M+{tm_c_uJ^d98xD@Uiddy7< zjPQFZO;3+#2*CCAkD154bYS%yA#|1d-(I-zLz2ET*ge - - - + + + + + + + + + + + + + + + + diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index 35fa3368c..2fdf9a813 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -119,6 +119,7 @@ export interface Config { difficultyModifier(difficulty: Difficulty): number; // 0-1 traitorDefenseDebuff(): number; + traitorDuration(): number; nukeMagnitudes(unitType: UnitType): NukeMagnitude; defaultNukeSpeed(): number; nukeDeathFactor(humans: number, tilesOwned: number): number; diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 4f36e1183..e0c4d240c 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -141,7 +141,10 @@ export class DefaultConfig implements Config { } traitorDefenseDebuff(): number { - return 0.8; + return 0.5; + } + traitorDuration(): number { + return 30 * 10; // 30 seconds } spawnImmunityDuration(): Tick { return 5 * 10; diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 25a7c9328..b82016ed9 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -315,6 +315,7 @@ export interface Player { // State & Properties isAlive(): boolean; isTraitor(): boolean; + markTraitor(): void; largestClusterBoundingBox: { min: Cell; max: Cell } | null; lastTileChange(): Tick; diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index 8a1051fb3..06bcc57ba 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -518,7 +518,7 @@ export class GameImpl implements Game { ); } if (!other.isTraitor()) { - (breaker as PlayerImpl).isTraitor_ = true; + breaker.markTraitor(); } const breakerSet = new Set(breaker.alliances()); diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index bec1b255a..7f2786183 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -68,7 +68,7 @@ export class PlayerImpl implements Player { // 0 to 100 private _targetTroopRatio: bigint; - isTraitor_ = false; + markedTraitorTick = -1; private embargoes: Set = new Set(); @@ -373,7 +373,14 @@ export class PlayerImpl implements Player { } isTraitor(): boolean { - return this.isTraitor_; + return ( + this.markedTraitorTick >= 0 && + this.mg.ticks() - this.markedTraitorTick < + this.mg.config().traitorDuration() + ); + } + markTraitor(): void { + this.markedTraitorTick = this.mg.ticks(); } createAllianceRequest(recipient: Player): AllianceRequest {