X\e~FJHp^X ( @ (//(  0/80@0?/8 0( ?G@POWOXOP?H0@/7@O_``h_hPX 0(P_oppxow_g@O/8'' 7p`o?G/7 0??H/8`/o?GOX@H0?/pOW?H/8 7OP?G/7( P0@PX@O0@ 0O @H/@' 00@@P0?'_OP@H( 7/7' ^^^^^^^^^^^^^^^^^^^^^^^^^^TeeBBBBeTT^^^^^^^eBDJ33333JJDBeZ^^^^TD33==#####==3JDBT^^^^eJ=###=3DeZ^^TB3# #=3JBZ^^T3#  #=JBT^^J# Sll #=JBZ^T# %,68??86,/@A*< ##45('.6787-9%:;*<=#$+&,--.,/01)2 3 $%&&'%($!)* ##  !"#     ??d#q@'ARMOR_CONSTANT.1 AT_MAGICAL1 AT_PHYSICAL0ATTACK2B_ACTIVE1 B_INVALID2B_NORMAL0 B_TEXT_ONLY3 ES_ACCURACY6 ES_DAMAGE2 ES_DEFENSE4ES_MAGIC_DAMAGE3ES_MAGIC_DEFENSE5ES_MAXHP0 ES_MOVEMENT1FOREST1GRASS0IT_OTHER1 IT_WEAPON0 MAP_HEIGHT24 MAP_WIDTH24 MAX_ITEMS3 MAX_LEVEL3 MAX_UNITS12MOVE1MSG_TIME3NONE0 SQUARE_SIZE32USE_ITEM3 EFF_NO_ATTACK0 EFF_HALF_MOVE1 EFF_LESS_DEF2 EFF_LESS_ACC3 EFF_LESS_ATT4 EFF_SLEEP5 EFF_FLIGHT6 EFF_MORE_MOVE7 NUM_EFFECTS8 MAX_COUNTERS2` TestSprite  sxs5a3 b(fdH@Q@ @ u!U|l C5ͧ4exX1bǯB +R1}2N e M]STreeOld  ~xs5a3 b(fdH@Q@"dj> # iiDOTDJS3i`6+hj>|=x\>2RQkCA!ŗ% -b;]e'D9oV>}>WQ\x;biQ|Tpa/"\a@t xs5a3 b(fdH@Q@ \VSI/ BZ񔛏?0 *QIĸ|OR#9_~6-Q|vQ7|pRRcم3◦?5 h~8<قb#d>cZT7í)7KSSoldier  xݑ10 E#\br'ĥIM#~֮om8AEy:wG⿴)޷G7:V6e/[{gݎ;')4hfS;eƔ(EC^žYOP:,zmJ{HMM^|OAlZ8Vrɷ)o\An[ɩ j xݔM 0t>^Iȝ$gJk|@53%[.a:t'(/yw[kMXwK8\Y65<'*tvM2>]xJ LU1 GE!c^`L,R.^jdMٟ\4ޙR3-`2 md[sJ^4 xݕA 0Et>^IȝI&cB6 ~~LrtIs^wҍ i{So}w>ݽX^Vgfʖ)oi|IGr>zJ~}ј2ahHůwAԟ_ꏭS`q m_`֟{4gZRF=k}f~ y ?6}b+%% xݕK!Dǽp=B8 wj&Z d@ɤ1zbyuM4\t#4[/Tozs r˻koV^Q{?wvR>rJ~"7#CJ+_`L,~T}~~nxϡ=04>_'N|c73߉NS^i>Sr[•擏SButton  txС0DDaD L!ٷO{Y[]vS9 SIronSword  txs5a3 b(fdH@Q@("i[pVP^V౗r+k84:🦆C ͧ8V`S hԊQ+FX+hd>=h"f;"SBow  xs5a3 b(fdH@Q@(" )((| RڙOC O+P͇XAM[0̧GpO5+pO *xZAqV"b:V" dzDIt/VdXAhbY^Fª,%`EN Q4> SSteelShield  Rxs5a3 b(fdH@Q@(ڙ hj8 hj8%VFdQe>`QGpG($(SMineOld  xs5a3 b(fdH@Q@à@v -'d( '(Hy(i50CCȨ̧hFpZfRp)8$jP4`Rb)5ȳ?J@Qd*`0\sSStaff  cxs5a3 b(fdH@Q@À!~kA6V uFh$xa4a ^Q`@uãP-Og+hHY#SRingOld  xs5a3 b(fdH@Q@(EL@A42+YAdB[A^'IVP˿|1ʈ7H2Sh>%Q<8JD0C#bRi8Q%-:*Z_^SpSArcher  xՓA @ Eǽp}p5z!Ws o!Nc/7e8?P M?I|Ĝg?x}6 os}! jPMFIBAZr_@zkg]_H_N5^Qf0ޗc1{.iK7hV>|%s|yCf #_rw iU[/` xՓA 0Et^U-)b(fefΐm<1K> 9Ϛbk[/^)G2. G#~+"H)m~~Ģ}㔲i.c65V>|k2;)[ 2,wQ[w[6"Ȁ xՓ 0 E{zݢ\ +|C'"?I|NĜg?x}6 _Йh1D.ш6"IHI$yF'YoS7f܋# Ҿy,foG3S]%_r63MQui&]G1~CBC Yns#v]m!o?PSKnight  x 0 E{ޑv9F`4##A ׏xpgaºun}'mO-ZNJߦd[Y1#Z6g)FS3>SZgxhHً )e${ײ?w N%.E~MV'c~0h/ x 0 EýcH 3]5ktvr# 9>.NTޯ۰ wՍaIݜ,& +zO^O)V/vjJ#vųdjJҍf)ya^&TټYMfo;?ng>[tH=Z9")xFoᗂ x 0 E{ȱw$ kF`GWV"DKOIxV ?0n҅Lxj9~e gtOi~=v.oFΌ¶珞]P?ö-Βߟ)G2>L4d9ʟ-z{Yo{A;J/p. l x 0 E{ȱH ktdYD U~$ĆkNԌ6zZWƴzI݂Ǫ"Ʒ)ȱ)N@ZE"#z L1> :cD )e$zsYu|wN!.=E|/^\;SWarrior  xݓA ! E9@wNɪC7h3Ȅ/H2`~ڮVΣ{?wBH1RRyu~r(S%e.IwLxD%gk |,cC>Ī]O|YHR)2y~M~ɶ}37GٻcR/!d $ xݓA! Eǽp=N܉;@-h $LTnۺuZ.tyyRxS~L䘨x_sys]ʿcj·Nz|;%t_O#*|N>g)f}뢜J~6އhiN+9^rO"L')SKO1TՇMTCG7)\6i{~|6:G{hkɎeםbH3?^]?NB!fjwi;k.3)Sd|>yq=O xݓA! Eǽp=N܉;@|K%擐2y?;z^Jۺm\eŐRxSyDGTU|3]$;R)S 1uSkw'LUOWmkG|GwY|{Y!f}?ٚ_ C4̴ŎOIosL)sy&d 70#.6y _O?|SMage  xݕ1 Eݽر;R=N)wJ"_##Z@>z(| mӧVO4nĉ4/kߥU,9)|$ eر>HвȐ|}7`ծ2/R3RH /'23GjoYO$Yj!↭ xݕK D}e#wʝP5DQG8>thqqK2q"ͣv_/aHC#%5Ke-Bbz,~xAz/io{׮b2s wm^̎w䫫(7[-*%ʎ xݕ1 ILHo'?9ևii >xȸqq4ָ@]Z"dzW*tRl|9XwbҜb}j!eر>"Az6~N"CUG|~R^7Q*@Fq(>‰E??8twiߟa|?R{zU܇g2+ xݕK0 D˞d>RkNSL 0;@1lEhqq0y5Ŵa>H+"KNoUD,uKmy񩐦mX#>X;[ 5_߸'I\3hUtź>cL{})=e-tr^ժ!:ZSCavalry  x Pz=;RkdNމ88}J[)3CNjsm]|N3؏=xG;Χ8'G{̗ȇ=QWn|ةw>>Wu2Ǣs)41gwǸFk,=]F1}S&NtD.>}ܥ׻LL xA tteB}k;2L  fxz_r4^4eܖ(e;wɾSZiJ?߲:7{~O!#2ׯ=2,S8}6ˏx߹{4yݲb#Q4b]*Qc| J/_} x Pz=;R=kdNDH> iGJz9OWku`;Cjݩw~Y#ھHa/-Y^ rǂ19 Q'{瞱>vVP|p?Dh M̷_#5-|"}޷)~]a9Br_ނ;go( xA tteB}k;◯2)D fxYKUK39Vv8|#ߝ^3sOMU=Sx>x(9X|O/R@O5=YA9[A3qYA Xz".SMace  ~xs5a3 b(fdH@Q@ðB:qPDkid+J1H"b(z^h@ k&@FZA,T7 ZP|D~ yϴ̋mzt=nLGh'+R|߭r/8B^ 8RW #[DAgdo#P \)󑬣"߬J*`bz~r'`8@\ T^)6 SWeakMagic2  xs5a3 b(fdH@Q@ÈC5<+HQLjASOv I/پh! ڙO$ %Í )^Hu K- TFsaEP"h)V%NAZnDf[2rfPd #9!g%3 SCaltrops  vxs5a3 b(fdH@QY ŘʈQOb4]D'I1!Ia(EQBj>%$yVpd+hZ2Z|D1䰌QG G" SBoltSmall  Wxs5a3 b(fdH@Q@(Eh r1dDkɳFdA¯ *Z|"NE\ZX1F(EC pC SBoltLarge  wxs5a3 b(fdH@Q@(EhXώ!#ZOupO-[O[[0!"b܀2`PgJ"CTg A&IM$TZ*U ̧)@w3P6k|LiX]HpQ OS@05Jp.q>j>A+OÀ#c|2<;+O7i pY=hx Fh+zm SOldGrass  x0 D02vT}j$+/z,뾭pl9qؔ9agO;ڼ@ ?Kr~mZa(1ea( l$2' qfr s9RcޅϞ|)%'X7Y4ɆǹF;_בUuȹ,.UuRsFy{Tku=JnRι.ed'@)KXp?(f`˴@7&> r]ćo>Xy[*x#SGrass  #x 0 >L <@){_˦s`1|d(:$^v >|ZW(_GV=" PTI͍9lPQ(Kw7;:]a4RTM.ai$=/xt,i|vQI~8b1 crSTree  (x10 E9A6$@ 8T%8jHi>NnƧiϴeupWގis{~YF>c;_\2*>LvJwmOjoi;ax'}&7J NߨUq>(ն{[?H.SMine  Ox10 C()yA@OA|3ш!x,{-N?}uNe ic r IJ $@L[x}3[yhgm9՞ %Sn-0a/;Y[DfޟG@\Y:W.g {g20_H& o: Br奂S^YD| H4*7pJj÷I貊,N:3llo!|_L# p2~>\*CeᦐaN_yxHYlɯ52hC%2e=A'9~YʹCs޵, SSteelSword  rxs5a3 b(fdH@Q@("i[pVP^V౗r+k84:@S!E ԴbԊQ+ OO+hg(^ SMythrilSword  txs5a3 b(fdH@Q@("i[pVP^V౗r+k84:M O+p88ШVZ1V|zZA;G DUUSIronAxe  xs5a3 b(fdH@Q@("i[pV$+ D#+cZA-KqYjX,H +̧S \h b|VPn>~+b>+e>T4sh"ޓX) SSteelAxe  |xͱ 0к{q[XPBn:[Vۚ=ט?? f탎츯"8"D J% 4@:,\"gQQI ~`q-Bn_nzX SAdamantAxe  xs5a3 b(fdH@Q@("i[pV$+. Y7 jY խ4VBVcr[AXA-󑭠eE SIronSpear  Uxs5a3 b(fdH@Q@("i[pVZ1jŨV PD#+Z1jup+hg("_A SSteelSpear  Txs5a3 b(fdH@Q@("i[pVZ1jŨV̊ H`ԊQ+ḣ[A;G;"PSLance  dxs5a3 b(fdH@Q@("i[pV N+k4 .OS"0j@VZ1jŰF ڙ?HEb ` SIronMace  }xs5a3 b(fdH@Q@("i[pVZ D + 4`-rV2r1C㲂ccZAu2I YA#VQ4h)^y SSteelMace  }x; 0Dc,-46b|t;V A6Wa<"NT5 @@B:\z*&b"PG "[?s"+t|U DSFlail  xs5a3 b(fdH@Q@("i[pVZg@!V h ZD7 Y(*0T45 @ŔIb\ v揢QD#(h= SShortBow  xs5a3 b(fdH@Q@(" )((| RڙOC O+P͇XAM[0̧GpO5+pO *xZAqV"b:V" dzDIt/VdXAhbY^Fª,%`EN Q4>SSuperiorShortbow  x= F;zg Ķq|L{~upYƸ;A,U*pg%P?BV9^/X-^S SSylvanShortbow  x1 Eq=qN\ `ږ6,τ篃fGu{vyP+yU)?($-/p_LQ* "Z_;+_d9T`! z`UoeX5^uN SLongBow  xs5a3 b(fdH@Q@(" Vͧ` ZY3VV O+ $*[aг#F >"8Bi(Y7Ԋ X>e$xS2 SSuperiorLongbow  xs5a3 b(fdH@Q@("30ͧ Y7FV O + dZi3F >"BiY7Ԋ X>e$S2uvSSylvanLongbow  xs5a3 b(fdH@Q@("3ͧ` ZY3VV O+ $*[aг#F >"8Bi(Y7Ԋ X>e$xS2. SWeakMagic  {xs5a3 b(fdH@Q@À!Nk! G0x¨F@ hԵ 3b7pLDDZAȥh>-:*Z_^Sp SShieldMagic  |xs5a3 b(fdH@Q@À!Nk! G0x¨F@ hT 44l7pLDDZAȥh>-:*Z_n Sp SAttackMagic  |xs5a3 b(fdH@Q@À!Nk! G0x¨F@ bB|Zib> |킛l8&pBp"N4i/B/śSArtilleryMagic  ~xs5a3 b(fdH@Q@À!Nk! G0x¨F@ vaOe+`?hh> L) nTS;ͤ SPowerCharm  xs5a3 b(fdH@Q@(EL@A42+YAdB[A^'IVP˿|1ʈ7H2Sh>%Q<8JD0C#bRi8Q%ɏ/}:~>Ul]mj7[|*vDM*\fA' \dpqVgMq-_7JN}2?__;OGSf_L3-4g-p!/XST"[/lB  SCloudSpell  xs5a3 b(fdH@Q@( 2%RD |"yC um2 I '%%H"=Kj,&c>&|h4XjÉxiGV"-j.R OI wI|}G^8f 5c "/ SAcidSpell  xT90 +;`d̈?s=%J&nvz:ڰ*a?9RI" ~hm>eZax SSleepSpell  xU; 8:zgD񥝠8{V yyLP,΋E 8޻BЬ e=u]M0a*մoG12J."S јߨK"o)?RDl~iE !̔ vfrxsr41\2~_2m SFlySpell  x1 ڱOQ)N5sH Nm٘XQ,/LG3^b,]b~~ u|` 837jICԋpW7h z%?>q,_܂u.ǒL+   SVulnerary  lxs5a3 b(fdH@Q@(?hDOAh>V:m>1VPbZAt02cSp:O OE4@ 2SElixir  lxs5a3 b(fdH@Q@(Rш2T+h|⭠u*%|bQ)r`>.+e8jMͧt0 ?ß;h SGreaterCharm  xs5a3 b(fdH@Q@(EL@A42+YAdB[A^'IVP˿|1ʈ7H2Sh>%Q<83&U!G6j.ŤW,@&uh8XAFz |-ĘOV4l!k5SʿShSWizard  xݕ Ec2@]Xsu 8B_)ͳb|W5zкn%Q1?|Yɓ;DRVM֖Al|kLMˊ],c1q0_}gI2_0b"k5|djJ+>1D2rs3 ȗtHcuW>|EQ _ xݕ 0 E˝8r^pg v̑V7i$[lYMZkQ\8 Qޅ?~,{8*rm2(]?jŷG)g8VhXV|Œl|#2v1y2rz避rb Eh 2W{[SV\/*!K  xݕ 0 EpH kS)5&~d_Rd;"1(a >sȊBNVIՖAj\טp_S /k9 { Ϻ߫%fI2"Y9#S3vZqJ62rz避sb ȗ_mE5z: xݕ E{1ޑ2@]#;F`'HqJQ%dg/kQL[5:*U#+s ;۝Y%U[>vb%s6_cj]V|MES8Zl~>Yk+}aƇHz_;8%9rzzEe7>|jedצ+r~6EQ H+ SNobility  xݔ E{ޑ2@];"RGlx\iů_.tGs,)}So=;Oef8F*Y9՝_%o廛/8[d(k6~}"AXe~i?UF7[r>{'^:{e>/iVKO ;/i?i2OO[Uc?_i{DM\ xݔ c2@]#;y'vrS"RCrl,pg`[/i#&RͲMX~~B #qOkGg Ybd?Ի&5#W"i>>{VY>UF~-Y~yVtd/4SMҴTGgf|R')v' 0 xݔA E`]^fkN;9|ı0UiBHK϶>MU[֒üR"Ѽ [ώcۭHBE0jڻ\9]a+|Gr.h6; |fy>Ce>Y67 ٗ:~LVL"jZ# QuN>vHߓJ xݔM ! s{wNL*tFixBH&\Mů_.9vv,8A"%+"qO_BC>u>6&)v#ٮ$ftLUd?jmT/jϷfk)~t^3hdd,_BiOOQ|$?3?a.*m>x.(SPegasusKnight  xM q\tO^sp'#SGC/2)6]$"<;i`bH 3sSr\%]MG|| _W=q6_^ܗH\e+/31ܯUcLb+qc1eq_sYFV4(v4se-,eS' IT xA0Et p5Ne`g4@7)WpE>o{|ʹsҪY>$?.O|F5c߇(fvcb'WCC+9ﲬ7_>etxʊ |<- :D x픱 DI\L{9؉G$ EN0|2_],.VM:QQ1vN_~B5>kr>@~ʦs@}C߁B3au*'1|z7Jb>s,&>#i׌|:>ߚ)(4&,_|xwʆ |\|? SDrakeRider  x͔ c2@]kdvb'b*=ň!|&1X.iqq.Qǂ˙ey9V|>[OON]c|k>_%eZ23W56H\5G9Uɪ؟_s=(r9$fҎ׷s$[U915gwގ_?!V-r~|bWJ(w'G x͔ cH52;ul@?O s#_oѰZZ$](Y˷v3rrG5zڒqwrS|ϟߴ")L,߿O%6oz5Gu&V\r./~`iU1ɹ*:yK\'ː4a* Wʻ]fOQ x͔ EcH52Gvb'b*}Lj6`}$gtu&<.G K,Y9Gȱ#G5zڎ(sb.1d56'˴Mebg1g>/ {(#*Vι|dLfUϯyBY9{^Σ13YViLWH9*g_;;o/OAd4S"'VPߍr7{W–Q x͕ {ޑ2@]kdvb'myzH8 *&iBZG .gs{9 |Q 6GqSS?3?7T4&vs&iqbc (>gbi#*li!s9ܜG񣊙oc&)ɹ*gA|7;o/OAlD\gi/Xe>|.v'/9 SSecondWind  xs5a3 b(fdH@Q@(" 1' 7ΣQ4uc^m]}vyP~ \OYG nߵ@-f!ԗ*B}(tcXpa.lq$2t5%h~L~s+OV^v a(ghv,O+bZ(r^B7l:O20e22rB;,ƈhD47TZ)S]]HwA?|h_ SCaltropsOld  x풽 Fu\Hda0nL5T46-@;zղ󬄃|ï{kF|(E .1as"2I$iY6*<5%h )9 1"EC&V10m YA(Ju=~ГsM  SBigSword [x}]ř7xg4vf?1b`Cln 9PA81xl ÉG`G{"힋peMrꮪgfvOSo[7zԵ] _s~ͫVO@ @ @ @ @ @ @ @0pZ틕+Ϯ^zt>QzXAB>fʕ/Bo_, @ r\yVMHu[귮f}yō=xOX.\W(C (@VgBlxwbKx@ t3Mul0]/_Y%pz4=߾0s ldF@]֭{'P AgAdĀŖ{Zdxs+psjԒ%ΧW AdE-w .h&ob.`A.f\_ʔC @0r);E =={;6o{W~/^<_|c{>ܻ ĦrS-m 14]n`a.Pcd;x'f>? ACc@@<^s|7lh9ǪUS `E/lhhOB""}E٧ÙOWӓNy[Oxnwiu+4@ 4ly̱C =&V*Owq0xeK;lt<9@ f).;1rzeim?7/\Ȇ@ &q-/ߘiCQFc(`bѢ ^Oo@0۱r);t6E63e>E 6hxL   תUolܻ3a?;qo=={z=57@ /CCc뻶ܯ4՝Qx30۸q7$>Si=3إg7pMW(i߲)̛̟]Zp9)fљ{v˼U6 ?lh'U6cKXb'ȭyxF~}=9OiG%H'9s>mVӪUo = |}W܌gb^8.|lٗ&㶚;ݛ|)_ҥ_RE7̸. B_|QP$gdkԮx_ĩVȇJ.5Jv2M.u٦f#=%lkqwCq0N"9įm[9^^qW2N+3)Dxr"{g0?LK}E)&$RS)4KE\ :uTŘ2?(h7P8$Lrฑc&t# Jo!9qGNi'p..f>QEftIm sVSpGPTb(ؗII-3:i_>eR"yĢx e)T9#H'S!_ȗ uB@'Qs!Nrw3uܻc&uz߻۷Y7ςqO7>fj_lذOS=Dopxط qe`L7t~=w<8< n "n݃~fqH|$'d(@,7`TOkEvN#19Pg^`C[ԙr uXK1Orc1:3N/1{8=#dS9u Į5>3?άΜ|͒i '&H![\׭P2ǝ8S!AFppo'lqЅ%Ƚ)]gh%:MRt"8}b"ÂlL0K(`5M5Q@FډQixoa܀<]O=뙧~Nl= ?~a?ȓleMMxk嶭Wq7!y.l3зܖJN%!t5 ;]dƶ#xw۶R"uxSaF,e#wA1 prBAw;|Ew ~-K۶Wƭ[O&|ES(,:`]Ŝp!Ky  *IdZm[+}df+pZZ _ů*ܕ?#M+,-1 E66o7`bZс;(l/~z OCʕp7a7V@bx (RI„3T%PWgL«ݸ#POyxat <ןn?z|3gIp?1A/ =3StQB2>)O[+E/='α&_qc@PrĠr jS!@F>8#ۤm{xD9p{RyH~&>J;\GqD3'h7אhB < +BDVהxqb^zCo/ 8vA$dlC\ -f#tj7nJPW"0+:duo2CL5VB2QMܧj;Vfr#tS};Ȑ?гSY1zEVV6ai!Xti"UO&evuaS?|:G,BՕ}Q -zsVҵDp}ϰ)4NюNy5)O+armџCCԍl?}rVGY3Jh{b#˗\zy*M) ߸13ApL"/o/'@i4? X[mIP3 qqUG ^]3?s$$ EWՔ' jdeK4h4Ex ֡x G+bd/OU_՝OMq6"闳n 9fPRҿrlsBX] }rZuP0rD"r(2Tsl(: ;K%X!1BF\RQ脘A۴ˡp,SRY|.9f%"}xeՆ?,Qbͪ3b ؐ"bJ;N[-ڡsS;U݉LIy'z{/VR_I}(HdcɒPL0en"Z9p3z+6}- kޅhzC쌼ӫz}ސrvq]lug?s }{9??5ff'}N}[xwɇG<}6}M&L}ڙŹ?z3Sï)j{&_|?&o*h:1~BlORԽ{ )(o=Ix*9(S$^GT~H:jy|;u~ '%K[98Iیɩ#qL GbL"廑^-C$ NR}5PJbT AŒՈnIT8A4;|@`IDOW*3$g9ѕ+ڏQ=kɫo?2˞Q\)SQ$O@̒ߠ"8J SFz3[IG:Q]x&/.]HJ_Rg *zF I>.'m&<*l'S`̥_SޑIe6GGR5G{TI€*ƺC#۷uuoXO /:DtР) O z !'Qdz<^ҷȫZo/aA܃*,څ/C=P_x(&V!K H e YDDrxF'U/znP2 >>9@?58ÍP΢z5}a$wIj 0wЧ Flr}:Kbj)ԛ:ǓH0ZpCw#bk&gڌѭ;\ZN?֔$!mN"Yv;$0Q2'1LyęTĞGH1I 䨑uvI/~\r0KF;JcܗL&{fъ2=%8#N$f"i=0,򟙰r5s0SLaKjn̖RW1S sT1u Ǎ^TÍbSvAfp+5d\XG{0޵~bDhQ% 6._":'!hK{$P}B1yFZ>(xoэVVb4HlAxQ"z6@ ɄܓLտVwzwO`{hv3J+; ʡY´QN<&#ctqm #57'2:[kzMқ= v6?gբͭ7qIwvJ{^hd$'ZSR&|Wf,&0&PeKeI RCfnȜ=~Hc{SQtΣTJ)T ;?JI9uLR/QbԸ:Ӵ%h 8k=5}D2e\(YQĹcW)8 eФDTJ=*T8d3׬#L4{I+3n+F|;r(J/ۇQH$!gT i@]sT~iIgbʱ/flP+~t<3S$Y!Y̛E=.v+FKa6 i١Oʶz`N; zxu 2;H.u2 !A{8FIYWNA>x;@??~?:n|5(Ó>|&?0i09od ގhOwA>y8}tB-cp кбg3 JREM֬&Z~g֋y7bUFxiVR]*UXD-I])YKlhxJpSn9\PLH9&Rݺ!('`j0q*q}7;t_@m)M,Oa(24/ISA|tsi_ ji[75Ў|7ZoiNV Bk/mrF2%B"5UpSjU3~"FJp&fOZFd a-4ID"2dT%OKvWM4EdLAъC xĊ2T9t"Ќh.H"F6ܘs~h{M+7DVJz%' 4Vj\U߾HiAr/I<}%ΗxgHyVgRM 3L]2cZzS*xœA(%0,޳uTSq*ys60*?i0$gg?aqaȫz⮿F!Vagu f\hB0, !J_aKb)`= I$h-4Mei/}ivP~MlD$Ol"Ɂ9K5-|y dDZOB^NN%D):{'4T{i^7P -!&`lYCi\]4BGd Y$F+ ;x)imBv{AH0Aͮ}FVȊ-'gJOwDE$>ɢYsZ{ '3 46QQ~V`lI!j[c F) Eq 'GAs2V;q$9IZCC&*hJH*:nghaLJKX[<|0ɒ4OGb1탎GᒔLαoZ:,$\YkęHw^5˙(9Q9i;~TDe;#Q1;[9 Jxa^l8IF?27+'\5٪d+x"u.]eaDT0EzO- ?lofY:48`xd̩aqhaOHbM {X"8Xz`?T|ݑLOÑ--yk3r ` Zޓ0էI?07``$ >i3JΈr_񇼸q@DDydm $mld;8 .M "JSԌPUUT+d[Φ4;L;)FG!9Y6/(uޟLz pO&qNRdnqQJf?DCs*n6YqONeF$h'?GL}y,+"Y?TdgʼnI,L:D#w" }rV TSFR84cIxp0RId!-s3RAGBo&Beh̀$YAzn87?`Xfv Ey?6Im:c'FoN Q<mA x*!d쩃JHFhd":T97cCȂ52'v0> "*'E*ۖv =i\t5L󆱙h@ۍR3 D+FHd'RmsbcNץ 9*uq.D6k9;wCv$10^Keblu ȲeG&-Gʑ'58ƍ 9k ة%ehYw2;6^#JWtrZAux|g˖̀,_> ફ}RP  pls:vѢˠ7A@rp'oϳdj͛|zbl/!M*X=?B 3"cD$pΐ%Ɩ,DHh?bîgR{k^A{nPZxd]"1M~:s=VdZt2K5`Q;3ljA2opBU!+9TƃC'ӄpf4^`YZre}GG9d#cʓ~J6MATL*v#6Qmș;%qH*MذԲH5m]7CF]vfC/)'|4I\*"sD+}D@3e,\Li*e6f=׬zӦffG:ggd>fz͇㟲7*0ԮAF[ߙ-65Ki&GOv3-408 ӎd4ptҥ_^xqo tt5ٮ#Yl{hƉu> JFigvӓ)?D* =Җa7C: 'F?$CXy@Āq5Rض5yضu%=?ǀ[67O3Q(B6lG ) ?wz03'@r= YK` ʹSdySa,L?pu* .Vv sbbJ5F *Q Y,\?}w>v8gɰӕ)$GE>*f2+Y2Qm .gXmkO1aV,%INY8pکqYe1B(; 42w~3C) I)et~x%v- cXlrY VYT9I'N:ds ׂ.;}x_-^|Aeڻ Ypf洖CMۛhk&m/ԭsSl6+WIܩ}_m"ͦѺNrK5Yͧ5k,xet_d.|'^s&$vl<|YP)´a#Sq1BI^5\ㅿ==.=H^j55UCM:͙7^{/-иJ*z ׼SD+5.(<ң`r!܆y, !~RЦcә%~ gkzr婥K94 W]/[6rt8W;E=sbA>U}DM=>h2wpp .#CCyPg}E6t2/ .QMsO`O[f>x| eK0V/UDUBZꃖ^ܝ1KЍ_ NT+d @ԐR/jfbl9%7?A 0aL0Ѿ}"=@x @+dbY}#]PIH1NWT[4k$VȰg:ϚYh8T ̚|~TOyn2aџf˦j} ;*/(hp3 6 *2{ǥ-pm,:\uw@ gj@V{׭[@ᆉ+6)@3p4OL>rqkE2c i<󍾎GF *3tk׎ l1;&^߯6/z?FIxݽ;weS`Bb pf$iw<2@X@cwN'ƪAGwЦ A`(Jmb|X]+qυHN$FX!@b3z6f؎GsiڃطYu>uC[o q^uݪ0FP.歗٘dfnN'3i9}=^5A."fMD{c&Y2똤@0ۡSNG{q|5ztׯUg޿t5u%Cۋy~>m*)d٠Xtgʤx8GoWpY:X' aF#7/ P5ΦfqO_UƹA,}XnQ.nBX.k4ՆT7qF|ڮ-otv=zbgyU2 ԅ@!~z ]r]bM'|ͤOY̵-.Yz^q4l#W$[:+}D[ wI&o[sQfv{"ym KGu0=Gytx1CէF)}U/eAkU$n[ IK9? IQ_FJEN)ym~ۜ [Զi،gȕIЭA~+ 7ĠI.u1)pqWY\3VCI:ůI5LϫecUۼJLUM:7cǙJM_]f,Xp^?M Ohot0V mZVONC_Jt˗U%U Z_IΛ;HxA*\T6/~io+懹=E#=>oLE96ʄV[FCf8T8UhhߋyF}.T' =ɧ)7rؼeڑsݹ-R(ݡh@p ebւr2 +Zkjш+GC:{|NӰL̻ȤI'׬X˅ /]w:4G' tnڎȆ:.']xr\ i,3̇*pHّ>]yݺ^6 --5IvrBcdW^&ÊPi~Ү[2.{lޠLO]Nt2cTi!eFT8iI&nֲ=7t  u(\~sZpd7Xn%>{.H%zXPOĸGawL9W˶å0_mi+;G9j?#:-|U,3犢g^ ,wnXn-fl!tF+[LZuw3qu<6qiavxuq׭pg-V}N+;6o5;ޯȆol~Cظqj ]r04lW8,9'[W,gv+w뒜7|@fd NEckk4.|Yx`p|U$Ys{bُNDnVX$(F^PW5G[cQqt!Xqu jiFVjAq1|c `/K~=xё|2/_ X`LX7rYX”o!;Mgʷi]Jo8GCٖBەx:h]h4T#zI9 (~1f P[k7OZ0$+o!wO+?io 9ov&$[pQԒ7& #S=;+ʯ4Q%xK~nW`%SWneVƜm[:Ǝ}#ײq/m@rcѢK78rf7`v'mel=M96)MȽʔpP=f8wŊM_?U+RF%[8]6!Ǭ;GjVoo+Dx$9[1q ;ֲA3m@nV Wjng.Q.YDb.[9BAU@(q]dּҥ_4l}`}KBqWA-t܈YG۷ SƷ^wݾ>ے4e_#7` ?]ޖV.gVÙ|Mr7|*cXl_nY2@y(ʝV|&53إt+'˥SRR؉HBqFԲ㪫 l'{;#i7]6]7$K=~[&+V,_>բX1}=tݚ*<@osa3|ço nݥ9-';6Gct%=MZ5SsI672j@t2T+o4pV-,.t+6|}bELJƦA66pUW{&S#bzB34_/!u\ZjށL`C{6'|Ϯ>WDssnNygM 5]e-A۩Y_6,[( `A#ld8o Zqu-YB +7r :Ca+÷ Juxy@ۓ,|#'7CjxR4ol|#Ĝ[ ⍠oz+|W^źu{3+_g&YFvSd9OlL4L6Z|#gprcR:)>*6'YFNnVDss IYl|H~|ù=I*b%W"zrăN ]{}1ثnl4JF$("67^T\ilo82O;oۓ\!jf*f.!:gHr9QpF+P ϣolZ.DOދc j!RA?946ikSW_6Vo8g߰>[9n!= ;7=bt_2*%-ۙds|#fGox3q &Ď|]^ͬI*̓h3˧Z-Po!ŬԔ ؓ需ezN$–- ;7{S/+ 腞|}esۙds|#:[~UatT M%!O7+&)&UɲeY4zlMI4C<)75b5[EpN=m"U'\afAt[VZFw1=8J:TAbm|#mv BcH|Ja$!4:wJp=H* "@&DH֮6dKm@ɠ$p\4\q)7fuoȿInʴ}Vo87KG-瘢\v&Y)ʤt|#\8 M >{370100644v֬]^^qWt ,Q Apړv&vo(#-Oiؓ!t"D^仆ox7Q4tr\S6rJOCptloNЭ spQ} ®73(|c pW韊ǀUFV474bҥ1Ol;.Ld-΃iK˒ \LQs[MZo3VxΫ3K0Qo8۫Zf V7*. (z'\%ߨ9Z溄oxw4J~'_Vztz\%-ot5o&*m[-%#MHW>잲Kes+wibA2P.N?ɕL.oE+-[2계 ' Gᛢw/o[Lhr `#oPx+ĠkU7*PDt"ɕs1 7\#[2&|wЛ[׸OnU7lV|&IMF k O7.7 !%Hr|h^=κoîQWS}י%@੿fǤ{d|RnU7gh؇gatvq=%֬!^}{W7Z6$z ű;=K l]Lm|&R Ϫ]#{Z c&֤=|OrkFQFd%>cR4ލd;Ftoo×# N,(c@o)5GTם]F* KF})!8%v&46t^-ݚ|#xxM0{Q7f̗ 3,|۹7jn=ryew Y ̶{ɨ8pjf)<9Ǔ`U/z+Fj f/FN_iܲyko,ߨyW#Rz.>0JUx.FdG'ЭY7”9d  }*Ej'߰@seّ< \Ɍ6Qqek57FUtB1O7 vJ;.>(Uy'|u>[v ,u}KF=M6J&*Vpd |y7]_B6/2)|#۹7jQ l7\;}roɨǨ|ڍD9O'8vӔbǘds|QʧZU!߰AKg/!|c&sS>Nv#ݼg'?nO$LPy|5o-1rV%?t%l櫲ͬ X™(ebZcSLꜵ+B! [FÖҭj=R}}]r4.Bs N_i.=!=q>jye[tEs@=Z+F;JWI;zk Gl+A՞W\h7sYi\--=mtZ K_ZnBs  yW [9tϘg=mWtռO+iS?*3Iv%! ȬLK$`vk{W= ˝tbcOS5TCST*dU2()l'ݪXhk6! y ms6hr}vqjoԲNqkOHbV0xtg͔VJh5m3a9QWsodX6ڳVL kNjt=2ߖZ;$WDҭvk=rм|a~4`7KO|V8&J_mc66 e'y8 ? 4.Ku]5ƒ}aE?շ>g LI6?>"߂"=ҭ굎Fv8cNuݚ ߘp ^Bl9fi sXy]Xm3Js C0D#wYBƌS"S2r֜n"9mtzaF}gȪpQ7r*.3ZP[dɔo韊|SA;d{}/k/ai~XFz/ãc,-^ V窚b|#H y2)NcHƦI4,gNؤzlC=js6j ¦_o@gh3VATxkњ$X÷Ej&բ7>7EY~e>jKF#)+9!3 3r6 Ȓ"rukV!<ܦj!|2WQiQ)ݳǘhxG`n^Tth 1:þNA:j MEl~YîeI6GIB+[-:Mj]Úpƛd \2v ]@𷾵p*f lȑ.Pox&oqȔU$jlFdb}tp2f&X!UK=GϋMTG vҭvh ?[Xs[lDR+]p?*=A㳅!DiZ l_%&*]@!(/Xi"UJo9h8O)3$;."J-i\iV* b&|C E3)5zR &*]-؂ #Մoh8+%:yu!oLb *@o8miyA1Ny|0>M=7Z&Xi 7]UaN(O rb S9dVh`TurJW3k0q7N=J: VZlA0vPxJzX@CǍSbf VZlA0zMZcba!qv&-؂ Pt^O;}C?g6iApM&*7Z&X 7ljohqJ#}nw7Z&X 7+P)7W(y)W{t7Z&X K,Tg7 |ӎM֠Ҵ\dJ+|CP걷!Dԑ&S\at.7Z&X 6ȹ c|iKନtTO- AKWº!x՞d([fH&oJ#Lu֦ΚM h 1u֯8TczK&oJ3 Eb9u\AgY}QyU72[KUxNg~Y[;"1qYF+*|C,|)}d#wx"tŢ|yE|\VHUYQN_at\&AAFڏfFFa2Wh^6!6M?6U)w.C0?rx%U+66l.KnoioԎJBGm\5[ MB3( 2Z,hywƤ:KYo(%W+#P,_#`^@/!tyu E\%M4~?Ni, )lo4&X爧$]Z. , I]J|УV@v#`"|1_7(,X&4`]le89]YA=7`AFu+Ul$XsXIqVq:GH7'|C QFRu.! W(|au7 @ L :!|C zщ*dn@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ aK battleStepy{ var i, j, battleOver, remainingPlayers, goldText; // left click if (mouse_check_button_pressed(mb_left)) { battleLeftClick(); } // find movable squares if (currentOrder == MOVE) { for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) { map[i,j].tempVal = -1; if (map[i,j].unit != noone) if (map[i,j].unit.owner != currentPlayer) if (selectedUnit.effects[EFF_FLIGHT] == 0) map[i,j].tempVal = 99; // don't allow moving over enemy units } map[selectedUnit.x/SQUARE_SIZE, selectedUnit.y/SQUARE_SIZE].tempVal = effectiveStat(ES_MOVEMENT, selectedUnit); if (selectedUnit.effects[EFF_FLIGHT] == 0) moveCheck(selectedUnit.x/SQUARE_SIZE, selectedUnit.y/SQUARE_SIZE); else moveCheckFly(selectedUnit.x/SQUARE_SIZE, selectedUnit.y/SQUARE_SIZE); for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) if (map[i,j].unit != noone) if (map[i,j].unit.owner != currentPlayer) map[i,j].tempVal = -1; } // adjust button graphics // move button /*if (currentOrder == MOVE) { menu.moveButton.state = B_ACTIVE; } else { menu.moveButton.state = B_INVALID; if (selectedUnit != noone) if (selectedUnit.owner == currentPlayer && selectedUnit.moved == false) menu.moveButton.state = B_NORMAL; } // attack button if (currentOrder == ATTACK) { menu.attackButton.state = B_ACTIVE; } else { menu.attackButton.state = B_INVALID; if (selectedUnit != noone) if (selectedUnit.owner == currentPlayer && selectedUnit.attacked == false && selectedUnit.weapon != noone) menu.attackButton.state = B_NORMAL; } // use item button if (currentOrder == USE_ITEM) { menu.useItemButton.state = B_ACTIVE; } else { menu.useItemButton.state = B_INVALID; if (selectedUnit != noone) if (selectedUnit.owner == currentPlayer && selectedUnit.attacked == false) for (i = 0; i < MAX_ITEMS; i += 1) if (selectedUnit.items[i] != noone) if (selectedUnit.items[i].charges != 0 && (selectedUnit.items[i].charges == -1 || selectedUnit.itemUses[i] > 0)) menu.useItemButton.state = B_NORMAL; }*/ // adjust text // moneyText //menu.moneyText.text = "Money: " + string(currentPlayer.money); // check for end of battle //if (mouse_check_button_pressed(mb_middle)) battleOver = true; for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) if (map[i,j].moneyLeft > 0) battleOver = false; if (global.game.roundsLeft == 0) battleOver = false; remainingPlayers = numPlayers; for (i = 0; i < numPlayers; i += 1) if (players[i].numUnits == 0) remainingPlayers -= 1; if (remainingPlayers == 0) { lastPlayer = currentPlayer; battleOver = true; } if (remainingPlayers == 1) { for (i = 0; i < numPlayers; i += 1) if (players[i].numUnits > 0) lastPlayer = players[i]; battleOver = true; // give remaining gold to surviving player /*for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) if (map[i,j].special == 1) if (map[i,j].moneyLeft > 0) { lastPlayer.money += map[i,j].moneyLeft; }*/ } if (battleOver) { // end battle endBattle(); } }battleLeftClick9{ var i, j, target, goldText; if (mouse_x < MAP_WIDTH * SQUARE_SIZE) // mouse is on grid { if (currentOrder == NONE) { if (map[mouse_x div SQUARE_SIZE, mouse_y div SQUARE_SIZE].unit == selectedUnit && selectedUnit != noone) { if (selectedUnit.owner == currentPlayer) doubleClick(); } else // select unit selectedUnit = map[mouse_x div SQUARE_SIZE, mouse_y div SQUARE_SIZE].unit; } else { if (currentOrder == MOVE) { // move unit battleMoveUnit(mouse_x - (mouse_x mod SQUARE_SIZE), mouse_y - (mouse_y mod SQUARE_SIZE)); currentOrder = NONE; } if (currentOrder == ATTACK) { // attack target = map[mouse_x div SQUARE_SIZE, mouse_y div SQUARE_SIZE].unit; battleAttack(selectedUnit, target, 0); currentOrder = NONE; } if (currentOrder == USE_ITEM) { target = map[mouse_x div SQUARE_SIZE, mouse_y div SQUARE_SIZE].unit; if (target != noone) useItem(selectedUnit, target); currentOrder = NONE; } } } else // mouse is on menu { /*if (mouseOnButton(menu.moveButton)) { // move if (selectedUnit != noone) if (selectedUnit.owner == currentPlayer && selectedUnit.moved == false) { currentOrder = MOVE; } } if (mouseOnButton(menu.attackButton)) { // attack (requires weapon) if (selectedUnit != noone) if (selectedUnit.owner == currentPlayer && selectedUnit.attacked == false && selectedUnit.weapon != noone) { currentOrder = ATTACK; } } if (mouseOnButton(menu.useItemButton)) { // use item if (selectedUnit != noone) if (selectedUnit.owner == currentPlayer && selectedUnit.attacked == false) for (i = 0; i < MAX_ITEMS; i += 1) if (selectedUnit.items[i] != noone) if (selectedUnit.items[i].charges != 0 && (selectedUnit.items[i].charges == -1 || selectedUnit.itemUses[i] > 0)) { //useItem(); break; } }*/ if (mouseOnButton(menu.endTurnButton)) { // end turn // give money for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) if (map[i,j].special == 1 && map[i,j].unit != noone) if (map[i,j].moneyLeft >= map[i,j].moneyRate) { map[i,j].moneyLeft -= map[i,j].moneyRate; map[i,j].unit.owner.money += map[i,j].moneyRate; goldText = instance_create(i * SQUARE_SIZE + SQUARE_SIZE/2, j * SQUARE_SIZE + SQUARE_SIZE/2, DamageText); damageTextInit(goldText, "+" + string(map[i,j].moneyRate), 0); goldText.color = c_yellow; if (map[i,j].moneyLeft == 0) map[i,j].sprite_index = SGrass; } // reduce duration for status effects for (i = 0; i < currentPlayer.numUnits; i += 1) for (j = 0; j < NUM_EFFECTS; j += 1) if (currentPlayer.units[i].effects[j] > 0) currentPlayer.units[i].effects[j] -= 1; // end turn currentOrder = NONE; currentPlayerIndex = (currentPlayerIndex + 1) mod numPlayers; currentPlayer = players[currentPlayerIndex]; menu.header.text = currentPlayer.name + "'s turn"; for (i = 0; i < currentPlayer.numUnits; i += 1) { currentPlayer.units[i].moved = false; currentPlayer.units[i].attacked = false; currentPlayer.units[i].counters = MAX_COUNTERS; if (currentPlayer.units[i].effects[EFF_NO_ATTACK] != 0) currentPlayer.units[i].attacked = true; if (currentPlayer.units[i].effects[EFF_SLEEP] != 0) { currentPlayer.units[i].moved = true; currentPlayer.units[i].attacked = true; } } } // check for clicking unit list for (i = 0; i < currentPlayer.numUnits; i += 1) { if (mouse_x > menu.unitsX + (i mod menu.unitsPerLine) * SQUARE_SIZE && mouse_x < menu.unitsX + (i mod menu.unitsPerLine) * SQUARE_SIZE + SQUARE_SIZE && mouse_y > menu.unitsY + (i div menu.unitsPerLine) * SQUARE_SIZE && mouse_y < menu.unitsY + (i div menu.unitsPerLine) * SQUARE_SIZE + SQUARE_SIZE) { // select unit selectedUnit = currentPlayer.units[i]; } } } } battleDraw{ var i, j, tempX, tempY; // draw money info on menu drawMoneyInfo(menu.moneyInfoX, menu.moneyInfoX2, menu.moneyInfoY); // draw unit info on menu if (selectedUnit != noone) { drawUnitInfo(selectedUnit, menu.unitInfoX, menu.unitInfoX2, menu.unitInfoY); } // draw terrain info tempX = mouse_x div SQUARE_SIZE; tempY = mouse_y div SQUARE_SIZE; //if (mouse_x < MAP_WIDTH * SQUARE_SIZE && mouse_x > 0 && mouse_y > 0 && mouse_y < MAP_HEIGHT * SQUARE_SIZE) if (tempX >= 0 && tempX < MAP_WIDTH && tempY >= 0 && tempY < MAP_HEIGHT) drawTerrainInfo(map[tempX, tempY], menu.terrainInfoX, menu.terrainInfoX2, menu.terrainInfoY); // draw unit list on menu for (i = 0; i < currentPlayer.numUnits; i += 1) { draw_sprite(currentPlayer.units[i].sprite_index, currentPlayer.units[i].image_index, menu.unitsX + (i mod menu.unitsPerLine) * SQUARE_SIZE, menu.unitsY + (i div menu.unitsPerLine) * SQUARE_SIZE); } // draw selected unit stuff if (selectedUnit != noone) { // draw movement options if (currentOrder == MOVE) { draw_set_color(c_gray); draw_set_alpha(.7); for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) if (map[i,j].tempVal >= 0) draw_rectangle(i * SQUARE_SIZE, j * SQUARE_SIZE, i * SQUARE_SIZE + SQUARE_SIZE, j * SQUARE_SIZE + SQUARE_SIZE, false); // redraw selected unit draw_sprite(selectedUnit.sprite_index, selectedUnit.image_index, selectedUnit.x, selectedUnit.y); } // draw attack options if (currentOrder == ATTACK) { draw_set_color(c_maroon); draw_set_alpha(.5); for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) if (abs(i - (selectedUnit.x / SQUARE_SIZE)) + abs(j - (selectedUnit.y / SQUARE_SIZE)) <= selectedUnit.weapon.range) draw_rectangle(i * SQUARE_SIZE, j * SQUARE_SIZE, i * SQUARE_SIZE + SQUARE_SIZE, j * SQUARE_SIZE + SQUARE_SIZE, false); // redraw selected unit draw_sprite(selectedUnit.sprite_index, selectedUnit.image_index, selectedUnit.x, selectedUnit.y); } if (currentOrder == USE_ITEM) { draw_set_color(c_maroon); draw_set_alpha(.5); for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) if (abs(i - (selectedUnit.x / SQUARE_SIZE)) + abs(j - (selectedUnit.y / SQUARE_SIZE)) <= selectedUnit.items[unitItemIndex].range) draw_rectangle(i * SQUARE_SIZE, j * SQUARE_SIZE, i * SQUARE_SIZE + SQUARE_SIZE, j * SQUARE_SIZE + SQUARE_SIZE, false); // redraw selected unit draw_sprite(selectedUnit.sprite_index, selectedUnit.image_index, selectedUnit.x, selectedUnit.y); } // draw selection box draw_set_color(c_red); draw_set_alpha(1); draw_rectangle(selectedUnit.x, selectedUnit.y, selectedUnit.x + SQUARE_SIZE, selectedUnit.y + SQUARE_SIZE, true); // drow selection box on unit list for (i = 0; i < currentPlayer.numUnits; i += 1) { if (currentPlayer.units[i] == selectedUnit) draw_rectangle(menu.unitsX + (i mod menu.unitsPerLine) * SQUARE_SIZE, menu.unitsY + (i div menu.unitsPerLine) * SQUARE_SIZE, menu.unitsX + (i mod menu.unitsPerLine) * SQUARE_SIZE + SQUARE_SIZE, menu.unitsY + (i div menu.unitsPerLine) * SQUARE_SIZE + SQUARE_SIZE, true); } } }battleMenuInitH{ header = instance_create(SQUARE_SIZE * MAP_WIDTH + 64, 16, Button); buttonInit(header, "", 128, 32, ButtonFont); header.state = B_TEXT_ONLY; moneyInfoX = SQUARE_SIZE * MAP_WIDTH + 32; moneyInfoX2 = 1024 - 32; moneyInfoY = 48; //moneyText = instance_create(SQUARE_SIZE * MAP_WIDTH + 64, 48, Button); //buttonInit(moneyText, "", 128, 32, ButtonFont); //moneyText.state = B_TEXT_ONLY; /*moveButton = instance_create(SQUARE_SIZE * MAP_WIDTH + 64, 80, Button); buttonInit(moveButton, "Move", 128, 32, ButtonFont); attackButton = instance_create(SQUARE_SIZE * MAP_WIDTH + 64, 128, Button); buttonInit(attackButton, "Attack", 128, 32, ButtonFont); useItemButton = instance_create(SQUARE_SIZE * MAP_WIDTH + 64, 176, Button); buttonInit(useItemButton, "Use Item", 128, 32, ButtonFont); */ endTurnButton = instance_create(SQUARE_SIZE * MAP_WIDTH + 64, 768 - 176, Button); buttonInit(endTurnButton, "End Turn", 128, 32, ButtonFont); unitsX = SQUARE_SIZE * MAP_WIDTH + 64; unitsY = 768 - 128; unitsPerLine = 4; unitInfoX = SQUARE_SIZE * MAP_WIDTH + 32; unitInfoX2 = 1024 - 32; unitInfoY = 224 - 32; terrainInfoX = SQUARE_SIZE * MAP_WIDTH + 32; terrainInfoX2 = 1024 - 32; terrainInfoY = 450; }battleMoveUnit{ // argument0: x destination for unit // argument1: y destination for unit // unit must be selected and owned by current player and must not have moved yet var i, j, movingUnit; if (map[argument0/SQUARE_SIZE, argument1/SQUARE_SIZE].tempVal >= 0 // destination within range && map[argument0 / SQUARE_SIZE, argument1 / SQUARE_SIZE].unit == noone)// destination empty { // animation movingUnit = instance_create(selectedUnit.x, selectedUnit.y, MovingUnit); movingUnitInit(movingUnit, argument0, argument1, selectedUnit); // move the unit map[selectedUnit.x / SQUARE_SIZE, selectedUnit.y / SQUARE_SIZE].unit = noone; selectedUnit.x = argument0; selectedUnit.y = argument1; map[selectedUnit.x / SQUARE_SIZE, selectedUnit.y / SQUARE_SIZE].unit = selectedUnit; selectedUnit.moved = true; } } battleInit({ var i, j, terrainType, mapFile, newUnit; // initialize battle selectedUnit = noone; numPlayers = global.game.numPlayers; for (i = 0; i < numPlayers; i += 1) players[i] = global.game.players[i]; currentPlayerIndex = 0; currentPlayer = players[currentPlayerIndex]; currentOrder = NONE; menu = instance_create(MAP_WIDTH * SQUARE_SIZE, 0, BattleMenu); menu.header.text = currentPlayer.name + "'s turn"; // create terrain mapFile = file_text_open_read(working_directory + "\" + global.game.mapName); for (j = 0; j < MAP_HEIGHT; j+=1) { for (i = 0; i < MAP_WIDTH; i+=1) { terrainType = file_text_read_real(mapFile); map[i,j] = instance_create(SQUARE_SIZE * i, SQUARE_SIZE * j, Terrain); terrainInit(map[i,j], terrainType); } } // place units for (i = 0; i < numPlayers; i += 1) { placeUnits(players[i], file_text_read_real(mapFile), file_text_read_real(mapFile)); } file_text_close(mapFile); // unspend units for (i = 0; i < numPlayers; i += 1) for (j = 0; j < players[i].numUnits; j += 1) { players[i].units[j].moved = false; players[i].units[j].attacked = false; } }  selectionInit{ var file, i, fileName; // posistion unit/item lists x = 32; y = 32; // load in units file = file_text_open_read(working_directory + "\units.dat"); for (i = 0; !file_text_eof(file); i += 1) { units[i] = instance_create(x + i * SQUARE_SIZE, y, Unit); unitInit(units[i], file); } numUnits = i; file_text_close(file); selectedUnit = noone; // load in weapons if (variable_global_exists("numWeapons")) { for (i = 0; i < global.numWeapons; i += 1) global.weapons[i].visible = true; } else { file = file_text_open_read(working_directory + "\weapons.dat"); for (i = 0; !file_text_eof(file); i += 1) { global.weapons[i] = instance_create(x + i * SQUARE_SIZE, y + SQUARE_SIZE, Item); weaponInit(global.weapons[i], file); } global.numWeapons = i; file_text_close(file); } // load in items if (variable_global_exists("numItems")) { for (i = 0; i < global.numItems; i += 1) global.items[i].visible = true; } else { file = file_text_open_read(working_directory + "\items.dat"); for (i = 0; !file_text_eof(file); i += 1) { global.items[i] = instance_create(x + i * SQUARE_SIZE, y + 2 * SQUARE_SIZE, Item); itemInit(global.items[i], file); } global.numItems = i; file_text_close(file); } selectedItem = noone; // set up players numPlayers = global.game.numPlayers; for (i = 0; i < numPlayers; i += 1) { players[i] = global.game.players[i]; } currentPlayerIndex = 0; currentPlayer = players[currentPlayerIndex]; arrangeUnits(currentPlayer); // display first player's units // buttons finishedButton = instance_create(500, 575, Button); buttonInit(finishedButton, "Finished", 128, 32, ButtonFont); hireButton = instance_create(64 + numUnits * SQUARE_SIZE, y, Button); buttonInit(hireButton, "Hire Mercenary", 160, 32, ButtonFont); buyItemButton = instance_create(64 + global.numItems * SQUARE_SIZE, y + SQUARE_SIZE * 2, Button); buttonInit(buyItemButton, "Buy Item", 128, 32, ButtonFont); unitCost = instance_create(64 + 160 + numUnits * SQUARE_SIZE, y, Button); buttonInit(unitCost, "", 128, 32, ButtonFont); unitCost.state = B_TEXT_ONLY; itemCost = instance_create(64 + 128 + global.numItems * SQUARE_SIZE, y + SQUARE_SIZE * 2, Button); buttonInit(itemCost, "", 128, 32, ButtonFont); itemCost.state = B_TEXT_ONLY; moneyDisplay = instance_create(500, 525, Button); buttonInit(moneyDisplay, "", 128, 32, ButtonFont); moneyDisplay.state = B_TEXT_ONLY; header = instance_create(0, 0, Button); buttonInit(header, currentPlayer.name + ", purchase mercenaries.", 640, 32, ButtonFont); header.state = B_TEXT_ONLY; errorMsg = instance_create(150, 600, Button); buttonInit(errorMsg, "", 350, 32, Courier); errorMsg.state = B_TEXT_ONLY; // unit info unitInfoX = 468; unitInfoX2 = 660; unitInfoY = 150; // item info itemInfoX = 208; itemInfoX2 = 400; itemInfoY = 150; // map list mapListX = 700; mapListY = 150; // find maps numMaps = 0; fileName = file_find_first(working_directory + "\*.map", 0); while (fileName != "") { mapList[numMaps] = filename_name(fileName); numMaps += 1; fileName = file_find_next(); } file_find_close(); mapList[numMaps] = "Random"; selectedMapIndex = 0; } selectionStep{ var i, newUnit; // buttons // money moneyDisplay.text = "Gold: " + string(currentPlayer.money); // hire button & unit cost hireButton.state = B_INVALID; unitCost.text = "Cost: -"; if (selectedUnit != noone) { if (selectedUnit.owner == noone) { if (selectedUnit.cost <= currentPlayer.money) if (currentPlayer.numUnits < MAX_UNITS) hireButton.state = B_NORMAL; unitCost.text = "Cost: " + string(selectedUnit.cost); } } // item button & item cost buyItemButton.state = B_INVALID; itemCost.text = "Cost: -"; if (selectedItem != noone && selectedUnit != noone) if (canEquip(selectedUnit, selectedItem)) if (selectedUnit.owner == currentPlayer && selectedItem.cost <= currentPlayer.money) if ((selectedItem.type == IT_WEAPON && selectedUnit.weapon == noone) || (selectedItem.type == IT_OTHER && selectedUnit.items[MAX_ITEMS - 1] == noone)) buyItemButton.state = B_NORMAL; if (selectedItem != noone) itemCost.text = "Cost: " + string(selectedItem.cost); // finished button if (currentPlayer.numUnits > 0) finishedButton.state = B_NORMAL; else finishedButton.state = B_INVALID; // left click if (mouse_check_button_pressed(mb_left)) { selectionLeftClick(); } }unitInit// Initializes Unit variables by reading from a file // argument0 = Unit id // argument1 = file id { var i, flying; with (argument0) { name = file_text_read_string(argument1); file_text_readln(argument1); damage = file_text_read_real(argument1); magicDamage = file_text_read_real(argument1); defense = file_text_read_real(argument1); magicDefense = file_text_read_real(argument1); maxHP = file_text_read_real(argument1); accuracy = file_text_read_real(argument1); movement = file_text_read_real(argument1); cost = file_text_read_real(argument1); weaponTypes = file_text_read_real(argument1); if (file_text_read_real(argument1)) flying = true; else flying = false; for (i = 1; i <= MAX_LEVEL; i += 1) file_text_readln(argument1); sprite_index = TestSprite; if (name == "Nobility") sprite_index = SNobility if (name == "Knight") sprite_index = SKnight; if (name == "Warrior") sprite_index = SWarrior; if (name == "Archer") sprite_index = SArcher; if (name == "Mage") sprite_index = SMage; if (name == "Soldier") sprite_index = SSoldier; if (name == "Cavalry") sprite_index = SCavalry; if (name == "Pegasus Knight") sprite_index = SPegasusKnight; if (name == "Drake Rider") sprite_index = SDrakeRider; if (name == "Wizard") sprite_index = SWizard; image_index = 0; image_speed = 0; weapon = noone; for (i = 0; i < MAX_ITEMS; i += 1) { items[i] = noone; itemUses[i] = 0; } level = 1; for (i = 0; i < NUM_EFFECTS; i += 1) effects[i] = 0; if (flying) effects[EFF_FLIGHT] = -1; currentHP = maxHP; owner = noone; counters = MAX_COUNTERS; moved = false; attacked = false; } }unitCopy// copies data from one unit to another // argument0 = unit to copy to // argument1 = source unit { var i; with (argument0) { name = argument1.name; maxHP = argument1.maxHP; movement = argument1.movement; accuracy = argument1.accuracy; damage = argument1.damage; magicDamage = argument1.magicDamage; defense = argument1.defense; magicDefense = argument1.magicDefense; weaponTypes = argument1.weaponTypes; cost = argument1.cost; sprite_index = argument1.sprite_index; image_index = argument1.image_index; image_speed = 0; weapon = argument1.weapon; for (i = 0; i < MAX_ITEMS; i += 1) { items[i] = argument1.items[i]; itemUses[i] = argument1.itemUses[i]; } level = argument1.level; for (i = 0; i < NUM_EFFECTS; i += 1) effects[i] = argument1.effects[i]; currentHP = argument1.currentHP; owner = argument1.owner; counters = argument1.counters; moved = argument1.moved; attacked = argument1.attacked; } } battleAttack // attacking unit has a weapon // argument0 = attacking unit // argument1 = attacked unit // argument2 = 0 if attack, 1 if counter { var i, damageText, damage, mistCharm, delay, projectile; if (argument1 != noone) if (argument0.owner != argument1.owner && abs(argument0.x/SQUARE_SIZE - argument1.x/SQUARE_SIZE) + abs(argument0.y/SQUARE_SIZE - argument1.y/SQUARE_SIZE) <= argument0.weapon.range && !(argument0.weapon.weaponType >= 6 && argument0.weapon.weaponType <= 7 && abs(argument0.x/SQUARE_SIZE - argument1.x/SQUARE_SIZE) + abs(argument0.y/SQUARE_SIZE - argument1.y/SQUARE_SIZE) == 1)) { // make projectile delay = 0; if (argument0.weapon.weaponType == 8 || argument0.weapon.weaponType == 9 || argument0.weapon.weaponType == 6 || argument0.weapon.weaponType == 7) { projectile = instance_create(argument0.x, argument0.y, Projectile); delay = projectileInit(projectile, argument1.x, argument1.y, argument0.weapon.name, argument1); } // check if hit mistCharm = 0; for (i = 0; i < MAX_ITEMS; i += 1) if (argument1.items[i] != noone) if (argument1.items[i].ability == 4) mistCharm = argument1.items[i].itemAccuracy; if (effectiveStat(ES_ACCURACY, argument0) - mistCharm - (argument2 * 10) > random(1) * 100) { // deal damage if (argument0.weapon.damageType == AT_PHYSICAL) // deal physical damage { damage = ceil((2 * (1 + effectiveStat(ES_DAMAGE, argument0)) - (1.5 * effectiveStat(ES_DEFENSE, argument1))) * (random(.4) + .8)); if (damage < 0) damage = 0; } if (argument0.weapon.damageType == AT_MAGICAL) // deal magic damage { damage = ceil((2 * (effectiveStat(ES_MAGIC_DAMAGE, argument0)) - (1.5 * effectiveStat(ES_MAGIC_DEFENSE, argument1))) * (random(.4) + .8)); if (damage < 0) damage = 0; } argument1.currentHP -= damage; // display damage damageText = instance_create(argument1.x + SQUARE_SIZE/2, argument1.y + SQUARE_SIZE/2, DamageText); damageTextInit(damageText, "-" + string(damage), delay); } else { damageText = instance_create(argument1.x + SQUARE_SIZE/2, argument1.y + SQUARE_SIZE/2, DamageText); damageTextInit(damageText, "Miss", delay); } // check for death if (argument1.currentHP <= 0) unitDie(argument1); else if (argument2 == 0 && argument1.weapon != noone && argument1.counters > 0 && argument1.effects[EFF_SLEEP] == 0 && argument1.effects[EFF_NO_ATTACK] == 0) { // counter attack argument1.counters -= 1; battleAttack(argument1, argument0, 1); } argument0.attacked = true; argument0.moved = true; } } buttonInitc // argument0 = Button // argument1 = text // argument2 = width // argument3 = height // argument4 = font { with (argument0) { text = argument1; state = B_NORMAL; //sprite_index = SButton; //image_speed = 0; width = argument2; height = argument3; font = argument4; } } buttonDraw// draw the button and its text { if (state != B_TEXT_ONLY) { // draw button draw_set_color(make_color_rgb(144, 61, 0)); draw_set_alpha(1); draw_rectangle(x, y, x + width, y + height, false); // draw outline if (state == B_ACTIVE) { draw_set_color(c_red); draw_rectangle(x + 1, y + 1, x + width - 1, y + height - 1, true); } else draw_set_color(c_black); draw_rectangle(x, y, x + width, y + height, true); } // draw the text draw_set_font(font); draw_set_halign(fa_center); draw_set_valign(fa_middle); draw_set_color(c_black); draw_set_alpha(1); draw_text(x + width / 2, y + height / 2, text); // fade if invalid if (state == B_INVALID) { draw_set_color(c_gray); draw_set_alpha(.7); draw_rectangle(x, y, x + width, y + height, false); } } mouseOnButton// checks whether the mouse is currently over a button // argument0 = Button { with (argument0) { if (mouse_x > x && mouse_y > y && mouse_x < x + width && mouse_y < y + height) return true; else return false; } } selectionDraw{ var i; // draw unit info if (selectedUnit != noone) drawUnitInfo(selectedUnit, unitInfoX, unitInfoX2, unitInfoY); // draw item info if (selectedItem != noone) drawItemInfo(selectedItem, itemInfoX, itemInfoX2, itemInfoY); // draw box on selected item if (selectedItem != noone) { draw_set_color(c_blue); draw_set_alpha(1); draw_rectangle(selectedItem.x, selectedItem.y, selectedItem.x + SQUARE_SIZE, selectedItem.y + SQUARE_SIZE, true); } // draw box on selected unit if (selectedUnit != noone) { draw_set_color(c_red); draw_set_alpha(1); draw_rectangle(selectedUnit.x, selectedUnit.y, selectedUnit.x + SQUARE_SIZE, selectedUnit.y + SQUARE_SIZE, true); } // draw map list draw_set_font(Courier); draw_set_halign(fa_left); draw_set_valign(fa_top); draw_set_color(c_black); draw_set_alpha(1); draw_text(mapListX, mapListY, "Select a map:"); maxMapWidth = string_width(""); for (i = 0; i < numMaps + 1; i += 1) { draw_text(mapListX, mapListY + SQUARE_SIZE * (1 + i), mapList[i]); if (maxMapWidth < string_width(mapList[i])) maxMapWidth = string_width(mapList[i]); } // box around selected map draw_set_color(c_red); draw_rectangle(mapListX, mapListY + SQUARE_SIZE * (1 + selectedMapIndex), mapListX + string_width(mapList[selectedMapIndex]), mapListY + SQUARE_SIZE * (2 + selectedMapIndex), true); }selectionLeftClick{ var i; // clicked on weapon for (i = 0; i < global.numWeapons; i += 1) { if (mouse_x > global.weapons[i].x && mouse_y > global.weapons[i].y && mouse_x < global.weapons[i].x + SQUARE_SIZE && mouse_y < global.weapons[i].y + SQUARE_SIZE) { selectedItem = global.weapons[i]; } } // clicked on item for (i = 0; i < global.numItems; i += 1) { if (mouse_x > global.items[i].x && mouse_y > global.items[i].y && mouse_x < global.items[i].x + SQUARE_SIZE && mouse_y < global.items[i].y + SQUARE_SIZE) { selectedItem = global.items[i]; } } // clicked on unit for (i = 0; i < currentPlayer.numUnits; i += 1) { if (mouse_x > currentPlayer.units[i].x && mouse_y > currentPlayer.units[i].y && mouse_x < currentPlayer.units[i].x + SQUARE_SIZE && mouse_y < currentPlayer.units[i].y + SQUARE_SIZE) // select unit selectedUnit = currentPlayer.units[i]; } for (i = 0; i < numUnits; i += 1) if (mouse_x > units[i].x && mouse_x < units[i].x + SQUARE_SIZE && mouse_y > units[i].y && mouse_y < units[i].y + SQUARE_SIZE) { // select unit selectedUnit = collision_point(mouse_x, mouse_y, Unit, false, false); } // clicked on map for (i = 0; i < numMaps + 1; i += 1) { if (mouse_x > mapListX && mouse_y > mapListY + SQUARE_SIZE * (1 + i) && mouse_x < mapListX + maxMapWidth && mouse_y < mapListY + SQUARE_SIZE * (2 + i)) selectedMapIndex = i; } // clicked on hire button if (mouseOnButton(hireButton)) { if (selectedUnit != noone) { // purchase unit if (currentPlayer.numUnits < MAX_UNITS && selectedUnit.owner == noone && currentPlayer.money >= selectedUnit.cost) { currentPlayer.units[currentPlayer.numUnits] = instance_create(currentPlayer.x, currentPlayer.y + currentPlayer.numUnits * SQUARE_SIZE, Unit); unitCopy(currentPlayer.units[currentPlayer.numUnits], selectedUnit); currentPlayer.units[currentPlayer.numUnits].owner = currentPlayer; currentPlayer.units[currentPlayer.numUnits].moved = false; currentPlayer.units[currentPlayer.numUnits].attacked = false; currentPlayer.units[currentPlayer.numUnits].image_index = currentPlayerIndex; currentPlayer.numUnits += 1; currentPlayer.money -= selectedUnit.cost; } else { if (currentPlayer.numUnits >= MAX_UNITS) setTempText(errorMsg, "You can't have more than " + string(MAX_UNITS) + " mercenaries."); if (selectedUnit.owner != noone) setTempText(errorMsg, "You must select a mercenary to hire."); if (currentPlayer.money < selectedUnit.cost) setTempText(errorMsg, "You can't afford that mercenary."); } } else setTempText(errorMsg, "You must select a mercenary to hire."); } // clicked on buy item button if (mouseOnButton(buyItemButton)) if (selectedItem != noone) if (selectedUnit != noone) if (canEquip(selectedUnit, selectedItem)) if (selectedUnit.owner == currentPlayer) if (currentPlayer.money >= selectedItem.cost) { // buy item if space in inv if (selectedItem.type == IT_WEAPON) if (selectedUnit.weapon == noone) { currentPlayer.money -= selectedItem.cost; selectedUnit.weapon = selectedItem; } else setTempText(errorMsg, "The selected mercenary already has a weapon."); if (selectedItem.type == IT_OTHER) for (i = 0; i < MAX_ITEMS; i += 1) { if (selectedUnit.items[i] == noone) { selectedUnit.items[i] = selectedItem; currentPlayer.money -= selectedItem.cost; if (selectedUnit.items[i].charges > 0) selectedUnit.itemUses[i] = selectedUnit.items[i].charges; break; } if (i == MAX_ITEMS - 1) setTempText(errorMsg, "Mercenaries can't have more than " + string(MAX_ITEMS) + " items."); } } else setTempText(errorMsg, "You can't afford that item."); else setTempText(errorMsg, "You must select one of your mercenaries"); else setTempText(errorMsg, "The selected mercenary can't equip that item."); else setTempText(errorMsg, "You must select one of your mercenaries.") else setTempText(errorMsg, "You must select an item."); // clicked on finished button and has at least 1 unit if (mouseOnButton(finishedButton) && currentPlayer.numUnits > 0) { for (i = 0; i < currentPlayer.numUnits; i += 1) { currentPlayer.units[i].visible = false; } currentPlayerIndex += 1; if (currentPlayerIndex < numPlayers) { // next player currentPlayer = players[currentPlayerIndex]; header.text = currentPlayer.name + ", purchase units."; arrangeUnits(currentPlayer); selectedUnit = noone; for (i = 0; i < numUnits; i += 1) units[i].image_index = currentPlayerIndex; } else { // choose map if (selectedMapIndex == numMaps) selectedMapIndex = floor(random(numMaps)); global.game.mapName = mapList[selectedMapIndex]; // start battle global.battle = instance_create(0, 0, Battle); for (i = 0; i < global.numItems; i += 1) global.items[i].visible = false; for (i = 0; i < global.numWeapons; i += 1) global.weapons[i].visible = false; with (finishedButton) instance_destroy(); with (hireButton) instance_destroy(); with (buyItemButton) instance_destroy(); with (unitCost) instance_destroy(); with (itemCost) instance_destroy(); with (moneyDisplay) instance_destroy(); with (header) instance_destroy(); with (errorMsg) instance_destroy(); for (i = 0; i < numUnits; i += 1) with (units[i]) instance_destroy(); instance_destroy(); } } else if (mouseOnButton(finishedButton)) setTempText(errorMsg, "You must hire at least one mercenary."); } drawUnitInfo// draws information about the selected unit // selected unit must be a unit // argument0 = selected unit // argument1 = X // argument2 = X2 // argument3 = Y { var weaponString, itemString, leftString, rightString, i; leftString = "Class:" + "#Level:" + "#Hit Points:" + "#Movement:" + "#Accuracy:" + "#Power:" + "#Magic:" + "#Armor:" + "#Magic Resistance:" + "#Weapon:" + "#Items:"; if (argument0.weapon == noone) weaponString = "none"; else weaponString = argument0.weapon.name; itemString = ""; for (i = 0; i < MAX_ITEMS; i += 1) { if (argument0.items[i] != noone) { itemString += argument0.items[i].name; leftString += "#"; if (argument0.items[i].charges > 0) itemString += " (" + string(argument0.itemUses[i]) + "/" + string(argument0.items[i].charges) + ")" + "#"; else itemString += "#"; } } if (itemString == "") { itemString = "none#"; leftString += "#"; } rightString = argument0.name + "#" + string(argument0.level) + "#" + string(argument0.currentHP) + "/" + string(argument0.maxHP) + "#" + string(argument0.movement) + " (" + string(effectiveStat(ES_MOVEMENT, argument0)) + ")" + "#" + string(argument0.accuracy) + " (" + string(effectiveStat(ES_ACCURACY, argument0)) + ")" + "#" + string(argument0.damage) + " (" + string(effectiveStat(ES_DAMAGE, argument0)) + ")" + "#" + string(argument0.magicDamage) + " (" + string(effectiveStat(ES_MAGIC_DAMAGE, argument0)) + ")" + "#" + string(argument0.defense) + " (" + string(effectiveStat(ES_DEFENSE, argument0)) + ")" + "#" + string(argument0.magicDefense) + " (" + string(effectiveStat(ES_MAGIC_DEFENSE, argument0)) + ")" + "#" + weaponString + "#" + itemString; leftString += "Other:#"; if (argument0.effects[EFF_NO_ATTACK] != 0) rightString += "Can't Attack (" + string(argument0.effects[EFF_NO_ATTACK]) + ")#"; if (argument0.effects[EFF_HALF_MOVE] != 0) rightString += "Half Movement (" + string(argument0.effects[EFF_HALF_MOVE]) + ")#"; if (argument0.effects[EFF_LESS_DEF] != 0) rightString += "-2 Defense (" + string(argument0.effects[EFF_LESS_DEF]) + ")#"; if (argument0.effects[EFF_LESS_ACC] != 0) rightString += "-20 Accuracy (" + string(argument0.effects[EFF_LESS_ACC]) + ")#"; if (argument0.effects[EFF_LESS_ATT] != 0) rightString += "-2 Power (" + string(argument0.effects[EFF_LESS_ATT]) + ")#"; if (argument0.effects[EFF_SLEEP] != 0) rightString += "Asleep (" + string(argument0.effects[EFF_SLEEP]) + ")#"; if (argument0.effects[EFF_FLIGHT] != 0) if (argument0.effects[EFF_FLIGHT] == -1) rightString += "Flying#"; else rightString += "Flying (" + string(argument0.effects[EFF_FLIGHT]) + ")#"; if (argument0.effects[EFF_MORE_MOVE] != 0) rightString += "+2 Movement (" + string(argument0.effects[EFF_MORE_MOVE]) + ")#"; draw_set_font(Courier); draw_set_halign(fa_left); draw_set_valign(fa_top); draw_set_color(c_black); draw_set_alpha(1); draw_text(argument1, argument3, leftString); draw_set_halign(fa_right); draw_text(argument2, argument3, rightString); }itemInit // Initializes Item variables by reading from a file // argument0 = Item id // argument1 = File id { with (argument0) { name = file_text_read_string(argument1); file_text_readln(argument1); limitType = file_text_read_real(argument1); weaponType = file_text_read_real(argument1); itemAccuracy = file_text_read_real(argument1); range = file_text_read_real(argument1); charges = file_text_read_real(argument1); ability = file_text_read_real(argument1); movement = file_text_read_real(argument1); damage = file_text_read_real(argument1); magicDamage = file_text_read_real(argument1); accuracy = file_text_read_real(argument1); defense = file_text_read_real(argument1); magicDefense = file_text_read_real(argument1); cost = file_text_read_real(argument1); repairCost = file_text_read_real(argument1); file_text_readln(argument1); type = IT_OTHER; damageType = 0; power = 0; sprite_index = TestSprite; if (name == "Vulnerary") sprite_index = SVulnerary; if (name == "Elixir") sprite_index = SElixir; if (name == "Second Wind") sprite_index = SSecondWind; if (name == "Second Strike") sprite_index = SSecondStrike; if (name == "Wooden Shield") sprite_index = SWoodShield; if (name == "Steel Shield") sprite_index = SSteelShield; if (name == "Adamant Shield") sprite_index = SAdamantShield; if (name == "Shielding Charm") sprite_index = SShieldCharm; if (name == "Power Charm") sprite_index = SPowerCharm; if (name == "Precision Charm") sprite_index = SPrecisionCharm; if (name == "Speed Charm") sprite_index = SSpeedCharm; if (name == "Mist Charm") sprite_index = SMistCharm; if (name == "Greater Charm") sprite_index = SGreaterCharm; if (name == "Net") sprite_index = SNet; if (name == "Caltrops") sprite_index = SCaltrops; if (name == "Acid Spell") sprite_index = SAcidSpell; if (name == "Cloud Spell") sprite_index = SCloudSpell; if (name == "Weaken Spell") sprite_index = SWeakenSpell; if (name == "Thieve Spell") sprite_index = SThieveSpell; if (name == "Sleep Spell") sprite_index = SSleepSpell; if (name == "Fly Spell") sprite_index = SFlySpell; } }unitDie! // argument0 = Unit being killed { var i, pastUnit; with (argument0) { // rearrange unit array pastUnit = false; for (i = 0; i < owner.numUnits; i += 1) { if (pastUnit == true) owner.units[i-1] = owner.units[i]; if (owner.units[i] == argument0) pastUnit = true; } // decrease unit count owner.numUnits -= 1; // if during battle, remove from map and deselect if (instance_exists(global.battle)) { global.battle.map[x/SQUARE_SIZE, y/SQUARE_SIZE].unit = noone; if (global.battle.selectedUnit == argument0) global.battle.selectedUnit = noone; } instance_destroy(); } } terrainInit// initializes a terrain square by reading from terrain file // argument0 = Terrain pointer // argument1 = terrain type # { var terrainFile, i; with (argument0) { terrainFile = file_text_open_read(working_directory + "\terrain.dat"); for (i = 0; i < argument1; i += 1) { file_text_readln(terrainFile); file_text_readln(terrainFile); } name = file_text_read_string(terrainFile); movement = file_text_read_real(terrainFile); defense = file_text_read_real(terrainFile); special = file_text_read_real(terrainFile); file_text_close(terrainFile); if (special == 1) { moneyLeft = 50 + 100 * global.game.numPlayers; moneyRate = 50; } else { moneyLeft = 0; moneyRate = 0; } unit = noone; if (name == "Grass") sprite_index = SGrass; if (name == "Forest") sprite_index = STree; if (name == "Gold") sprite_index = SMine; if (name == "Bricks") sprite_index = SBrick; } } moveCheck// finds the squares a unit can move to // map[x,y].tempVal will be -1 for unreachable squares, and >= 0 otherwise // argument0 = x // argument1 = y { // check north if (argument1 > 0) if (map[argument0, argument1 - 1].tempVal < map[argument0, argument1].tempVal - map[argument0, argument1 - 1].movement) { map[argument0, argument1 - 1].tempVal = map[argument0, argument1].tempVal - map[argument0, argument1 - 1].movement; moveCheck(argument0, argument1 - 1); } // check east if (argument0 < MAP_WIDTH - 1) if (map[argument0 + 1, argument1].tempVal < map[argument0, argument1].tempVal - map[argument0 + 1, argument1].movement) { map[argument0 + 1, argument1].tempVal = map[argument0, argument1].tempVal - map[argument0 + 1, argument1].movement; moveCheck(argument0 + 1, argument1); } // check south if (argument1 < MAP_HEIGHT - 1) if (map[argument0, argument1 + 1].tempVal < map[argument0, argument1].tempVal - map[argument0, argument1 +1].movement) { map[argument0, argument1 + 1].tempVal = map[argument0, argument1].tempVal - map[argument0, argument1 +1].movement; moveCheck(argument0, argument1 + 1); } // check west if (argument0 > 0) if (map[argument0 - 1, argument1].tempVal < map[argument0, argument1].tempVal - map[argument0 - 1, argument1].movement) { map[argument0 - 1, argument1].tempVal = map[argument0, argument1].tempVal - map[argument0 - 1, argument1].movement; moveCheck(argument0 - 1, argument1); } } placeUnits // argument0 = player // argument1 = x // argument2 = y { var x1, y1, xAmp, yAmp, i; x1 = 0; y1 = 0; xAmp = 1; yAmp = -1; i = 0; while(i < argument0.numUnits) { // place unit if possible if (x1 + argument1 >= 0 && x1 + argument1 < MAP_WIDTH && y1 + argument2 >= 0 && y1 + argument2 < MAP_HEIGHT) if (map[x1 + argument1, y1 + argument2].unit == noone && map[x1 + argument1, y1 + argument2].movement != 50) { argument0.units[i].x = (argument1 + x1) * SQUARE_SIZE; argument0.units[i].y = (argument2 + y1) * SQUARE_SIZE; argument0.units[i].visible = true; map[argument0.units[i].x / SQUARE_SIZE, argument0.units[i].y / SQUARE_SIZE].unit = argument0.units[i]; i += 1; } // update square if (!(x1 <= 0 && y1 == 0)) { if (x1 > xAmp) x1 -= 1; if (x1 < xAmp) x1 += 1; if (x1 == xAmp) { if (xAmp > 0) xAmp = -xAmp; else xAmp = -xAmp + 1; } } if (y1 > yAmp) y1 -= 1; if (y1 < yAmp) y1 += 1; if (y1 == yAmp) { if (yAmp > 0) yAmp = -yAmp - 1; else yAmp = -yAmp; } } }gameInit // argument0 = game instance // argument1 = number of players { with (argument0) { roundsLeft = 4; // set up players numPlayers = argument1; for (i = 0; i < numPlayers; i += 1) { players[i] = instance_create(64, 128, Player); players[i].numUnits = 0; players[i].money = 1000; players[i].name = get_string("Player " + string(i + 1) + ", enter your name:", "Player " + string(i + 1)); } // start game by going to selection screen global.selection = instance_create(0, 0, Selection); } } endBattle.{ var i, j; // create next screen if (global.game.roundsLeft > 0) { // give gold for (i = 0; i < numPlayers; i += 1) players[i].money += 100; if (global.game.roundsLeft == 1) for (i = 0; i < numPlayers; i += 1) players[i].money += 1000; // next screen global.game.roundsLeft -= 1; global.results = instance_create(0, 0, Results); resultsInit(); } else { global.scoreScreen = instance_create(0, 0, ScoreScreen); scoreScreenInit(ScoreScreen, lastPlayer); } // destroy battle // destroy Terrain for (i = 0; i < MAP_WIDTH; i += 1) for (j = 0; j < MAP_HEIGHT; j += 1) with (map[i,j]) instance_destroy(); // destroy menu objects with (menu.header) instance_destroy(); //with (menu.moneyText) // instance_destroy(); /*with (menu.moveButton) instance_destroy(); with (menu.attackButton) instance_destroy(); with (menu.useItemButton) instance_destroy();*/ with (menu.endTurnButton) instance_destroy(); // destroy menu with (menu) instance_destroy(); // destroy battle instance_destroy(); }  resultsInit { var i, j, k; with (global.results) { // set player pointers numPlayers = global.game.numPlayers; for (i = 0; i < numPlayers; i += 1) { players[i] = global.game.players[i]; } currentPlayerIndex = 0; currentPlayer = players[currentPlayerIndex]; // level up and hide all units and clear status effects and recharge items and counters for (i = 0; i < numPlayers; i += 1) for (j = 0; j < players[i].numUnits; j += 1) { players[i].units[j].counters = MAX_COUNTERS; for (k = 0; k < MAX_ITEMS; k += 1) if (players[i].units[j].items[k] != noone) if (players[i].units[j].items[k].charges > 0) players[i].units[j].itemUses[k] = players[i].units[j].items[k].charges; for (k = 0; k < NUM_EFFECTS; k += 1) if (players[i].units[j].effects[k] != -1) players[i].units[j].effects[k] = 0; players[i].units[j].visible = false; if (players[i].units[j].level < MAX_LEVEL) unitLevelUp(players[i].units[j]); } selectedUnit = noone; selectedItemUnit = noone; selectedItemType = IT_WEAPON; selectedItemNum = 0; costWidth = 64; itemListX = costWidth + SQUARE_SIZE + currentPlayer.x; moneyX1 = 400; moneyX2 = 650; moneyY = 50; unitInfoX = 384; unitInfoX2 = 616; unitInfoY = 150; itemInfoX = 384; itemInfoX2 = 616 itemInfoY = 350; // header screenHeader = instance_create(0, 0, Button); buttonInit(screenHeader, "", 1024, 32, ButtonFont); screenHeader.state = B_TEXT_ONLY; // show results for first player and set values arrangeResults(); // buttons fireUnit = instance_create(400, 600, Button); buttonInit(fireUnit, "Release Mercenary", 160, 32, ButtonFont); discardItem = instance_create(400, 650, Button); buttonInit(discardItem, "Discard Item", 160, 32, ButtonFont); finishedButton = instance_create(400, 700, Button); buttonInit(finishedButton, "Finished", 160, 32, ButtonFont); // text unitCostHeader = instance_create(currentPlayer.x + SQUARE_SIZE, currentPlayer.y - 32, Button); buttonInit(unitCostHeader, "Cost:", costWidth, 32, ButtonFont); unitCostHeader.state = B_TEXT_ONLY; itemCostHeader = instance_create(itemListX + SQUARE_SIZE * (MAX_ITEMS + 1), currentPlayer.y - 32, Button); buttonInit(itemCostHeader, "Repair Costs:", costWidth, 32, ButtonFont); itemCostHeader.state = B_TEXT_ONLY; } } unitLevelUp// unit level must not already be at max // argument0 = unit { var unitFile, tempString; with (argument0) { level += 1; unitFile = file_text_open_read(working_directory + "\units.dat"); // find correct line tempString = file_text_read_string(unitFile); while (tempString != name) { repeat (MAX_LEVEL + 1) file_text_readln(unitFile); tempString = file_text_read_string(unitFile); } repeat (level) file_text_readln(unitFile); // change stats damage = file_text_read_real(unitFile); magicDamage = file_text_read_real(unitFile); defense = file_text_read_real(unitFile); magicDefense = file_text_read_real(unitFile); maxHP = file_text_read_real(unitFile); accuracy = file_text_read_real(unitFile); movement = file_text_read_real(unitFile); cost = file_text_read_real(unitFile); weaponTypes = file_text_read_real(unitFile); flying = file_text_read_real(unitFile); // heal currentHP = maxHP; file_text_close(unitFile); } } arrangeUnits>// reveal and position the already owned units of a player // argument0 = player { var i; with (argument0) { for (i = 0; i < numUnits; i += 1) { units[i].visible = true; units[i].x = x; units[i].y = y + i * SQUARE_SIZE; } } }arrangeResults // displays results for currentPlayer and sets total costs { var i, j, currentUnit, tempItemCost; totalUnitCost = 0; totalItemCost = 0; // header screenHeader.text = currentPlayer.name; // unit list arrangeUnits(currentPlayer); // costs for (i = 0; i < currentPlayer.numUnits; i += 1) { currentUnit = currentPlayer.units[i]; // display unit costs unitCosts[i] = instance_create(currentUnit.x + SQUARE_SIZE, currentUnit.y, Button); buttonInit(unitCosts[i], string(round(currentUnit.cost/2)), costWidth, 32, ButtonFont); unitCosts[i].state = B_TEXT_ONLY; totalUnitCost += real(unitCosts[i].text); // display equipment costs tempItemCost = 0; if (currentUnit.weapon != noone) tempItemCost += currentUnit.weapon.repairCost; for (j = 0; j < MAX_ITEMS; j += 1) if (currentUnit.items[j] != noone) tempItemCost += currentUnit.items[j].repairCost; totalItemCost += tempItemCost; itemCosts[i] = instance_create(itemListX + SQUARE_SIZE * (MAX_ITEMS + 1), currentUnit.y, Button); buttonInit(itemCosts[i], string(tempItemCost), costWidth, 32, ButtonFont); itemCosts[i].state = B_TEXT_ONLY; } // totals totalHeader = instance_create(currentPlayer.x - 32, currentPlayer.y + currentPlayer.numUnits * SQUARE_SIZE, Button); buttonInit(totalHeader, "Total:", 64, 32, ButtonFont); totalHeader.state = B_TEXT_ONLY; unitTotalButton = instance_create(currentPlayer.x + SQUARE_SIZE, currentPlayer.y + currentPlayer.numUnits * SQUARE_SIZE, Button); buttonInit(unitTotalButton, string(totalUnitCost), costWidth, 32, ButtonFont); unitTotalButton.state = B_TEXT_ONLY; itemTotalButton = instance_create(itemListX + SQUARE_SIZE * (MAX_ITEMS + 1), currentPlayer.y + currentPlayer.numUnits * SQUARE_SIZE, Button); buttonInit(itemTotalButton, string(totalItemCost), costWidth, 32, ButtonFont); itemTotalButton.state = B_TEXT_ONLY; } drawResults2 { var i, j; // draw unit info if (selectedUnit != noone) drawUnitInfo(selectedUnit, unitInfoX, unitInfoX2, unitInfoY); // draw equipment info if (selectedItemUnit != noone) { if (selectedItemType == IT_WEAPON) drawItemInfo(selectedItemUnit.weapon, itemInfoX, itemInfoX2, itemInfoY); if (selectedItemType == IT_OTHER) drawItemInfo(selectedItemUnit.items[selectedItemNum], itemInfoX, itemInfoX2, itemInfoY); } // draw equipment for (i = 0; i < currentPlayer.numUnits; i += 1) { if (currentPlayer.units[i].weapon != noone) draw_sprite(currentPlayer.units[i].weapon.sprite_index, 0, itemListX, currentPlayer.units[i].y); for (j = 0; j < MAX_ITEMS; j += 1) if (currentPlayer.units[i].items[j] != noone) draw_sprite(currentPlayer.units[i].items[j].sprite_index, 0, itemListX + SQUARE_SIZE * (1 + j), currentPlayer.units[i].y); } // draw unit selection box if (selectedUnit != noone) { draw_set_color(c_red); draw_set_alpha(1); draw_rectangle(selectedUnit.x, selectedUnit.y, selectedUnit.x + SQUARE_SIZE, selectedUnit.y + SQUARE_SIZE, true); } // draw item selection box if (selectedItemUnit != noone) { draw_set_color(c_blue); draw_set_alpha(1); if (selectedItemType == IT_WEAPON) draw_rectangle(itemListX, selectedItemUnit.y, itemListX + SQUARE_SIZE, selectedItemUnit.y + SQUARE_SIZE, true); if (selectedItemType == IT_OTHER) draw_rectangle(itemListX + SQUARE_SIZE * (1 + selectedItemNum), selectedItemUnit.y, itemListX + SQUARE_SIZE * (2 + selectedItemNum), selectedItemUnit.y + SQUARE_SIZE, true); } // draw remaining money stuff draw_set_font(ButtonFont); draw_set_halign(fa_left); draw_set_valign(fa_top); draw_set_color(c_black); draw_set_alpha(1); draw_text(moneyX1, moneyY, "Gold:" + "#Total Costs:" + "#Remaining Gold:"); draw_set_halign(fa_right); draw_text(moneyX2, moneyY, string(currentPlayer.money) + "#" + string(totalUnitCost + totalItemCost) + "#" + string(currentPlayer.money - (totalUnitCost + totalItemCost))); } resultsStepa{ // left click if (mouse_check_button_pressed(mb_left)) resultsLeftClick(); // buttons // release unit button if (selectedUnit == noone) fireUnit.state = B_INVALID; else fireUnit.state = B_NORMAL; // discard item button if (selectedItemUnit == noone) discardItem.state = B_INVALID; else discardItem.state = B_NORMAL; // finished button if (totalUnitCost + totalItemCost > currentPlayer.money) finishedButton.state = B_INVALID; else finishedButton.state = B_NORMAL; }resultsLeftClick { var i, j; // check each unit for (i = 0; i < currentPlayer.numUnits; i += 1) { // check for click on unit if (mouse_x > currentPlayer.units[i].x && mouse_y > currentPlayer.units[i].y && mouse_x < currentPlayer.units[i].x + SQUARE_SIZE && mouse_y < currentPlayer.units[i].y + SQUARE_SIZE) selectedUnit = currentPlayer.units[i]; // check for click on item if (mouse_x > itemListX && mouse_x < itemListX + SQUARE_SIZE * (1 + MAX_ITEMS) && mouse_y > currentPlayer.y + i * SQUARE_SIZE && mouse_y < currentPlayer.y + (i + 1) * SQUARE_SIZE) { // check weapon if (currentPlayer.units[i].weapon != noone && mouse_x < itemListX + SQUARE_SIZE) { selectedItemUnit = currentPlayer.units[i]; selectedItemType = IT_WEAPON; } // check other items for (j = 0; j < MAX_ITEMS; j += 1) { if (currentPlayer.units[i].items[j] != noone && mouse_x > itemListX + SQUARE_SIZE * (1 + j) && mouse_x < itemListX + SQUARE_SIZE * (2 + j)) { selectedItemUnit = currentPlayer.units[i]; selectedItemType = IT_OTHER; selectedItemNum = j; } } } } // check buttons // release unit button if (mouseOnButton(fireUnit) && selectedUnit != noone) { // remove unit and rearrange unArrangeResults(); unitDie(selectedUnit); selectedUnit = noone; selectedItemUnit = noone; arrangeResults(); } // discard item button if (mouseOnButton(discardItem) && selectedItemUnit != noone) { // remove item if (selectedItemType == IT_WEAPON) selectedItemUnit.weapon = noone; if (selectedItemType == IT_OTHER) removeItem(selectedItemUnit, selectedItemNum); // deselect item selectedItemUnit = noone // rearrange unArrangeResults(); arrangeResults(); } // finished button if (mouseOnButton(finishedButton) && totalUnitCost + totalItemCost <= currentPlayer.money) { currentPlayer.money -= (totalUnitCost + totalItemCost); unArrangeResults(); for (i = 0; i < currentPlayer.numUnits; i += 1) currentPlayer.units[i].visible = false; currentPlayerIndex += 1; if (currentPlayerIndex < numPlayers) { // next player currentPlayer = players[currentPlayerIndex]; selectedUnit = noone; selectedItemUnit = noone; arrangeResults(); } else { // destroy self and goto selection screen with (unitCostHeader) instance_destroy(); with (itemCostHeader) instance_destroy(); with (screenHeader) instance_destroy(); with (fireUnit) instance_destroy(); with (discardItem) instance_destroy(); with (finishedButton) instance_destroy(); global.selection = instance_create(0, 0, Selection); instance_destroy(); } } }unArrangeResults// destroys objects associated with current unit arrangement { var i; for (i = 0; i < currentPlayer.numUnits; i += 1) { with (unitCosts[i]) instance_destroy(); with (itemCosts[i]) instance_destroy(); } with (totalHeader) instance_destroy(); with (unitTotalButton) instance_destroy(); with (itemTotalButton) instance_destroy(); } drawItemInfo// draws info about an item // argument0 = item // argument1 = X // argument2 = X2 // argument3 = Y { var leftString, rightString; draw_set_font(Courier); draw_set_halign(fa_left); draw_set_valign(fa_top); draw_set_color(c_black); draw_set_alpha(1); leftString = ""; rightString = ""; with (argument0) { if (type == IT_WEAPON) { leftString += "Weapon:" + "#Damage Type:" + "#Range:" + "#Accuracy:" + "#Power:"; rightString += name; if (damageType == 0) rightString += "#Normal"; else rightString += "#Magic"; rightString += "#" + string(range) + "#" + string(accuracy) + "#" + string(power); } else { leftString += "Item:"; rightString += name; } // additional info // limit if (limitType != 0) { leftString += "#Limit:"; rightString += "#1 "; if (limitType == 3) rightString += "shield "; if (limitType == 4) rightString += "charm "; rightString += "per unit"; } // charges if (charges != 0) { leftString += "#Uses:"; if (charges < 0) rightString += "#Unlimited"; else rightString += "#" + string(charges) + " per battle"; } // stats //if (HP > 0) // rightString += "#+" + string(HP) + " Hit Points"; if (movement > 0) rightString += "#+" + string(movement) + " Movement"; if (type == IT_OTHER && accuracy > 0) rightString += "#+" + string(accuracy) + " Accuracy"; if (damage > 0) rightString += "#+" + string(damage) + " Power"; if (magicDamage > 0) rightString += "#+" + string(magicDamage) + " Magic"; if (defense > 0) rightString += "#+" + string(defense) + " Armor"; if (magicDefense > 0) rightString += "#+" + string(magicDefense) + " Magic Resistance"; // abilities if (ability == 1) { if (itemAccuracy < 99) rightString += "#Restores " + string(itemAccuracy) + " hit points"; else rightString += "#Restores all hit points"; } if (ability == 2) rightString += "#Allows an extra move"; if (ability == 3) rightString += "#Allows an extra attack"; if (ability == 4) rightString += "#" + string(itemAccuracy) + "% less chance to be hit"; if (ability == 5) rightString += "#" + "Prevents target from attacking"; if (ability == 6) rightString += "#" + "Reduces target's movement speed"; if (ability == 7) rightString += "#" + "Reduces target's armor"; if (ability == 8) rightString += "#" + "Reduces target's accuracy"; if (ability == 9) rightString += "#" + "Reduces target's power"; if (ability == 10) rightString += "#" + "Steals 50 gold"; if (ability == 11) rightString += "#" + "Puts target to sleep"; if (ability == 12) rightString += "#" + "Allows target to fly"; } draw_text(argument1, argument3, leftString); draw_set_halign(fa_right); draw_text(argument2, argument3, rightString); }drawTerrainInfoP// draws info about a terrain // argument0 = Terrain pointer // argument1 = X // argument2 = X2 // argument3 = Y { draw_set_font(Courier); draw_set_halign(fa_left); draw_set_valign(fa_top); draw_set_color(c_black); draw_set_alpha(1); if (argument0.special == 1) { draw_text(argument1, argument3, "Terrain:" + "#Movement:" + "#Defense:" + "#Gold:" + "#Gold per turn:"); draw_set_halign(fa_right); if (argument0.movement != 50) draw_text(argument2, argument3, argument0.name + "#" + string(argument0.movement) + "#" + string(argument0.defense) + "#" + string(argument0.moneyLeft) + "#" + string(argument0.moneyRate)); else draw_text(argument2, argument3, argument0.name + "#Impassible" + "#" + string(argument0.defense) + "#" + string(argument0.moneyLeft) + "#" + string(argument0.moneyRate)); } else { draw_text(argument1, argument3, "Terrain:" + "#Movement:" + "#Defense:"); draw_set_halign(fa_right); if (argument0.movement != 50) draw_text(argument2, argument3, argument0.name + "#" + string(argument0.movement) + "#" + string(argument0.defense)); else draw_text(argument2, argument3, argument0.name + "#Impassible" + "#" + string(argument0.defense)); } } removeItem// causes a unit to lose an item (not a weapon) // argument0 = unit // argument1 = item index { var i; with (argument0) { // remove item items[argument1] = noone; // rearrange items for (i = 0; i < MAX_ITEMS - 1; i += 1) if (items[i] == noone && items[i + 1] != noone) { items[i] = items[i + 1]; itemUses[i] = itemUses[i + 1]; items[i + 1] = noone; } } } effectiveStatG// returns the units's effective stat, taking into account items and terrain // assumes that if there is any terrain instance, then unit must be on terrain and must be called by Battle // argument0 = stat // argument1 = unit { var i, statValue, terrain; if (instance_exists(Terrain)) terrain = map[argument1.x/SQUARE_SIZE, argument1.y/SQUARE_SIZE]; else terrain = noo