From d79f98373285e7d85c11e23d126428522d3a4d32 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Fri, 6 Sep 2019 18:45:30 -0400 Subject: [PATCH] Lavaland Update: Mechs and Scanners --- code/game/mecha/equipment/mecha_equipment.dm | 14 +- .../mecha/equipment/tools/mining_tools.dm | 143 ++++++++++-------- code/game/mecha/equipment/weapons/weapons.dm | 10 +- code/game/mecha/working/ripley.dm | 47 ++++-- code/game/turfs/simulated/floor.dm | 9 +- code/game/turfs/simulated/floor/asteroid.dm | 6 - code/game/turfs/simulated/minerals.dm | 7 +- .../mining/equipment/mineral_scanner.dm | 85 ++++------- icons/effects/ore_visuals.dmi | Bin 0 -> 23210 bytes 9 files changed, 164 insertions(+), 157 deletions(-) create mode 100644 icons/effects/ore_visuals.dmi diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 7b3dcbf899d..0db0dff7ea1 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -91,10 +91,18 @@ var/C = chassis.loc set_ready_state(0) chassis.use_power(energy_drain) - . = do_after(chassis.occupant, equip_cooldown, target=target) + . = do_after(chassis.occupant, equip_cooldown, target = target) set_ready_state(1) - if(!chassis || chassis.loc != C || src != chassis.selected) - return 0 + if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target) & chassis.dir)) + return FALSE + +/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, delay) + if(!chassis) + return + var/C = chassis.loc + . = do_after(chassis.occupant, delay, target = target) + if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target) & chassis.dir)) + return FALSE /obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M) if(istype(M)) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 635f1718134..445d881ee50 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -1,54 +1,69 @@ + // Drill, Diamond drill, Mining scanner +#define DRILL_BASIC 1 +#define DRILL_HARDENED 2 + /obj/item/mecha_parts/mecha_equipment/drill name = "exosuit drill" desc = "Equipment for engineering and combat exosuits. This is the drill that'll pierce the heavens!" icon_state = "mecha_drill" - equip_cooldown = 30 + equip_cooldown = 15 energy_drain = 10 force = 15 + sharp = TRUE + var/drill_delay = 7 + var/drill_level = DRILL_BASIC /obj/item/mecha_parts/mecha_equipment/drill/action(atom/target) if(!action_checks(target)) return - if(istype(target, /turf/space)) + if(isspaceturf(target)) return if(isobj(target)) var/obj/target_obj = target - if(target_obj.unacidable && !istype(target_obj, /obj/mecha)) + if(target_obj.unacidable && !ismecha(target_obj)) occupant_message("[target] is too durable to drill through.") return target.visible_message("[chassis] starts to drill [target].", "[chassis] starts to drill [target]...", - blind_message = "You hear drilling.") + "You hear drilling.") + if(do_after_cooldown(target)) + set_ready_state(FALSE) + log_message("Started drilling [target]") if(isturf(target)) var/turf/T = target T.drill_act(src) - else - log_message("Drilled through [target]") + set_ready_state(TRUE) + return + while(do_after_mecha(target, drill_delay)) if(isliving(target)) - if(istype(src , /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill)) - drill_mob(target, chassis.occupant, 120) - else - drill_mob(target, chassis.occupant) + drill_mob(target, chassis.occupant) + playsound(src, 'sound/weapons/drill.ogg', 40, TRUE) + else if(istype(target, /obj)) + var/obj/O = target + //O.take_damage(15, BRUTE, 0, FALSE, get_dir(chassis, target)) + O.ex_act(2)//TO-DO-OBJECT-DAMAGE: Kill off when everything is damageable + playsound(src, 'sound/weapons/drill.ogg', 40, TRUE) else - target.ex_act(2) + set_ready_state(TRUE) + return + set_ready_state(TRUE) /turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) return -/turf/simulated/floor/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) - ex_act(1) - /turf/simulated/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) - ex_act(2) + if(drill.do_after_mecha(src, 60 / drill.drill_level)) + drill.log_message("Drilled through [src]") + dismantle_wall(TRUE, FALSE) /turf/simulated/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) - if(istype(drill, /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill)) - if(drill.do_after_cooldown(src))//To slow down how fast mechs can drill through the station + if(drill.drill_level >= DRILL_HARDENED) + if(drill.do_after_mecha(src, 120 / drill.drill_level)) drill.log_message("Drilled through [src]") - ex_act(3) + dismantle_wall(TRUE, FALSE) else drill.occupant_message("[src] is too durable to drill through.") @@ -59,24 +74,17 @@ drill.log_message("Drilled through [src]") drill.move_ores() -/turf/simulated/floor/plating/asteroid/airless/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) - if(istype(drill, /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill)) - for(var/turf/simulated/floor/plating/asteroid/airless/M in range(1, src)) - M.gets_drilled() - else - for(var/turf/simulated/floor/plating/asteroid/airless/M in range(1, drill.chassis)) - if(get_dir(drill.chassis, M) & drill.chassis.dir) - M.gets_drilled() +/turf/simulated/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) + for(var/turf/simulated/floor/plating/asteroid/M in range(1, drill.chassis)) + if((get_dir(drill.chassis, M) & drill.chassis.dir) && !M.dug) + M.gets_dug() drill.log_message("Drilled through [src]") drill.move_ores() /obj/item/mecha_parts/mecha_equipment/drill/proc/move_ores() - if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/stack/ore/ore in range(1, chassis)) - if(get_dir(chassis, ore) & chassis.dir) - ore.Move(ore_box) + if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/mecha/working/ripley)) + var/obj/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~ + R.collect_ore() /obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/mecha/M) if(..()) @@ -84,25 +92,44 @@ return 1 return 0 -/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user, var/drill_damage=80) - target.visible_message("[chassis] drills [target] with [src].", \ - "[chassis] drills [target] with [src].") +/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user) + target.visible_message("[chassis] is drilling [target] with [src]!", + "[chassis] is drilling you with [src]!") add_attack_logs(user, target, "DRILLED with [src] (INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") - if(target.stat == DEAD && target.butcher_results) - target.harvest(chassis) // Butcher the mob with our drill. + if(target.stat == DEAD && target.getBruteLoss() >= 200) + add_attack_logs(user, target, "gibbed") + if(LAZYLEN(target.butcher_results)) + target.harvest(chassis) // Butcher the mob with our drill. + else + target.gib() else - target.take_organ_damage(drill_damage) + var/splatter_dir = get_dir(chassis, target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/organ/external/target_part = H.get_organ(ran_zone("chest")) + H.apply_damage(10, BRUTE, "chest", H.run_armor_check(target_part, "melee")) - if(target) - target.Paralyse(10) + //blood splatters + blood_color = H.dna.species.blood_color + new /obj/effect/temp_visual/dir_setting/bloodsplatter(H.drop_location(), splatter_dir, blood_color) + + //organs go everywhere + if(target_part && prob(10 * drill_level)) + target_part.droplimb() + else + target.adjustBruteLoss(10) + if(isalien(target)) + new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target.drop_location(), splatter_dir) /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill name = "diamond-tipped exosuit drill" desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!" icon_state = "mecha_diamond_drill" origin_tech = "materials=4;engineering=4" - equip_cooldown = 20 + equip_cooldown = 10 + drill_delay = 4 + drill_level = DRILL_HARDENED force = 15 @@ -111,35 +138,27 @@ desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals." icon_state = "mecha_analyzer" selectable = 0 - equip_cooldown = 30 - var/scanning = 0 + equip_cooldown = 15 + var/scanning_time = 0 -/obj/item/mecha_parts/mecha_equipment/mining_scanner/attach(obj/mecha/M) +/obj/item/mecha_parts/mecha_equipment/mining_scanner/Initialize(mapload) . = ..() - START_PROCESSING(SSobj, src) - M.occupant_sight_flags |= SEE_TURFS - if(M.occupant) - M.occupant.update_sight() + START_PROCESSING(SSfastprocess, src) -/obj/item/mecha_parts/mecha_equipment/mining_scanner/detach() - chassis.occupant_sight_flags &= ~SEE_TURFS - STOP_PROCESSING(SSobj, src) - if(chassis.occupant) - chassis.occupant.update_sight() +/obj/item/mecha_parts/mecha_equipment/mining_scanner/Destroy() + STOP_PROCESSING(SSfastprocess, src) return ..() /obj/item/mecha_parts/mecha_equipment/mining_scanner/process() if(!loc) + STOP_PROCESSING(SSfastprocess, src) qdel(src) - if(scanning) - return - if(istype(loc,/obj/mecha/working)) + if(istype(loc, /obj/mecha/working) && scanning_time <= world.time) var/obj/mecha/working/mecha = loc if(!mecha.occupant) return - var/list/occupant = list() - occupant |= mecha.occupant - scanning = 1 - mineral_scan_pulse(occupant,get_turf(loc)) - spawn(equip_cooldown) - scanning = 0 + scanning_time = world.time + equip_cooldown + mineral_scan_pulse(get_turf(src)) + +#undef DRILL_BASIC +#undef DRILL_HARDENED \ No newline at end of file diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 185ce411d9a..b4ec817c4cc 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -509,18 +509,20 @@ return /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma - equip_cooldown = 20 + equip_cooldown = 10 name = "217-D Heavy Plasma Cutter" desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demloishing solid obstacles." icon_state = "mecha_plasmacutter" item_state = "plasmacutter" + lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' + righthand_file = 'icons/mob/inhands/guns_righthand.dmi' energy_drain = 30 origin_tech = "materials=3;plasmatech=4;engineering=3" projectile = /obj/item/projectile/plasma/adv/mech fire_sound = 'sound/weapons/laser.ogg' -/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/M as obj) +/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/M) if(istype(M, /obj/mecha/working)) if(M.equipment.len&;#ZJL7`dMePw$- zDevDkQ5zPQhtGeoPtodb{_Q)0?<<;5k2cB5nG`cB06aR9nJDE4piF@C)wtM@V#ZwPlSI+L*DSq9!X)Vm>e-f@ojZ#MKW!7T#Rz zD1PLFd&O|v`%`6T;Mm@gJ41On&*N|DoNRnr_I{3+zIt|UR(J8>XXmSBzDeIbxv0Zp zambQn8Y=FAjF_jjnt|+-kJUx5e0D}~@mRJ;7-57qAm|8WVtDpuXx0MW;mP217;b4M z#vzi#QK6WazIj&Ox8L>PRT=i#7k=i^V&BO-73)4IbQowc8S99$Q~x<77~dBz;X`d^~<&60{^rjT+1I2&p&P1?H06+0kn+)2#0MRY-7Mt#cdvJ zW3bHw4g&x2Jn$vB_2k$o(p4eqfhaDB@!957iPNh+(8=2`OS{~lv>oQ9wpMd>ioE;8 z-zw58I9L7g3iHvP&lO60S;y)>)xti+bLNs2!E0l`D5O|!;Q$Z%lq)t&g^LzR&Rntz zvP&h8p^f{;AHJB%Q@rpNorelbF}Z>v_b8O~!04YCXZI zmaKt_4V}pjeYLepDZa8=RYQJGK$NQ+YK{%Z0){*f*(FeMeX3V9xQCYs}XUF z?t#6bghg-84)$H6x1rW7G^%rBKk+51eHnupi+_ty$cPr}ybTDWSf3!KVO}3hes7Ml zw`#D4)z0!B{pEQCVnmA89mrxn{Wz5TB z+mJ3%8D+>fIA(@!(Unbnm!X5baXD8~Fo4v&*_3d-XOrx|){*daa|xR*={q*sx{0>e z9(7pbKmBEVr$y_ag!j_qtzZ^6&TtDq@NTA|8a^J=4f$TFtFP}^nrfTMByN&wLN<*I z0|NsM?S@@{^bi^&%<5M{m^5-K?cTkBqX3$v&)x>b6g=Bkedx+W^jM;OqA_>WvmDqw zDp3!uPAZvuEW?YG$Tu9<95|M{&X}Fb$z(IBx9r%{X?)Wb+8afh!3vWuQcPdT!_d+6 zlkSWU>nLLQd=^G?E!Zw~Y|O10OIwY_LCRbeZe1rhc%Akhy?N56x_Gq4Z^}b3v^z^n zE}Ht;v&*gGu!u-(s(rY}Krv>EHrCPG`$S3qT>QHYCQ}J8-~EG6N49H&OO})^`;69j zg^si|rEZ4wZS(U}Mk_q&a5d!1H8kFPtY>q1%dQ@MKCgjEdGsQp<&YqIWxh`*e14PI(J5`3=9t5qEYZ-w{G3y6H+)9Fw?E) zoeDE-9eh68-;w}yrTb`A=Dj%Jax_eSqf>$dNN@eU7TWDpx>J;nia!l6_d!ty6Ofj~lj+Aiu4mbf&A8z+dgGvZL@qtwUpd z8n5tJUbIBQJ&WMS>&&DOM2Yx#@Ms*OZ`nOpAu8Zt@WwM+4i1aqc7*ov12 zrQeBWlDLE1;i z_vvO`X~*-zaV>__rPLQhB&AkmhKz>Qy^CCL5$QTmprPGHu^TKE|@$D+%95+ z_EC3t`rUtrTIG`<8%kEMMiIu3m^U~=;Z4*Oj5B80GWxk7xkjc>^WtJV!$zqlZ$O@f zYuFjZ7kGCwAy)GS__H6$HSwt{O=YTbxWF|1cZ2nIv)85b*N1~@=iV268Ljf{siD}F zIX_TWsobv<_3HfUUfPR!A#|Gnh8{1XL@6EfcNeA3NIhS8v@4pDQ&HJ(cgl5xtn7Wi9a?TVvJfSjhL@P_fmGoG?vuxH@-^hrEhH~Y8E)nbA=y|DQGIY8R;>QKU$5Qu)y=zx~C{8?` z6;lajNYr|M%f>;zb>VBNmjb5HMX|AF3kHH=D6GEo%F=;Xbaa9G#h|9~*!j{Vw-s0y zm`{R^mb`lP>Xi3rWuKgVV+fUcp_9C@punV44dyrK14JH0CD3cu0plN8dU3`IU0M6<4V=(8OL-&Y&e&ZXqWHfDyj zEsO|Sbf!!6!Ot};{UD_cG6L0*bMZH!MJG+m;c0CtSsvV#c{Egn8>hn zeR#Ox>5yG`N3n*FhLNFB&Gs?1H+x zPBta@uMGT=ElIV54M&;2bo z?tJB{Wgdt-m8-R5KxCgI0elV;Q^(p}g6vp`{sKm(!`57JKi`+dtE#2aD}WK1|KxzPFskj(PG2NxzEhR zJ)cQ6jykA=+mmi3_`B4D3sT1pSVR_NZP`J%(D3l^i^j%nS}jCQYB?$lbmhUny3)v$ zk_<>AuzMw@%TNa1y#S)qY~Q?2=FJE-0R+2J%SH)PuZGrh0#WC>I{WFt^gRikPB7+! zE~P4-1gR(vUms$@$(K4I6g8Vaj{mxO@aiqjI8QrBc=1;KOQ@{sF?^{d;FR1%J!1dEng*CHfSU`a}W;L6L7tvc4Y6Owu8U z0x=l}!`v>n{taP$?j4Q*KyXCKigWD+pJy(O{LplVAWayzGUxnB*XL8mxuA)L-*B9N z!C|r+_v>@JwT;FHB_XZTy}ZR`-tn zmHFP~_?!JVgKix33I3QI`1|F41qmCEtjSi#JKQ@iY%WYTC!RZY`Ph>wn1j;K3tCBA zmS&|0Z3L6a5VVcKe+PpnmS!3M?gjWqOt*3S@8GtL)xVoGw)wKn7fv*6 z^I#i;{}CRX;~n$g!m7D5!9)}1NYmcoID3`I9uLXnbF)o5StPap9+*gHG!CIX(tBE= z#nU6oiywl7;sm2!-KffVEE#e7a$*iy4qOw3wsRm73Q#cWacmT#(KBVuHt<@1K;L9Wo-9)NkP6nJ?6*Qa(CFyktti-JrL(zu(U(Zn)dxaee~aRb7kC zbGe&+CZNqOWTR0%@EE6yZc;)*B|+6vzk%l@_-E3pc__=q;bX!Z zOtXfsi61X9nJepNNp3&i>>fvZSXIoF_AS(Us)62gqIG({g8g;{A2{9Q@fs&*#o|)1 zw9z9CP7~irB(Y&PV2M{v1bi2kHKD`A;XE=C)l!h=t)f9N0Vp3}pPeE=Lnt$2=()5; zVm-;`a&qL{*zo&SU`b%*t#~QV%Z3y3=qt9!Rc5ODx=dqOAZxnavHV9nMS+UXSZLUM zW-=i=f|*mvy~j1d??tFCN*9kz3EqJr^UY_eUK17!l(Qc2h5OG~ zP(OP+)aaRH1bL!9>^m0&T-KypxiQw&Fx1eQrLJm{(%07)8R&IQ(t3;R)&d{iY<;lm zU;(d4A5zz&Qp1tm9@#0psIdWCIQs;j60lVQ_Puvn)HY*b{qyXSyv@qP>klcs9b;^R(ND79w zM0zTQ>9-w;IIlQccSLWdrw6kT59WShxnokcLyxiDvzy%e~E2;3=+z3k2>ufa~?k5O06l*)`4qP^n?@Fa2-KR}GqhKb}#?;ayXg>6Nuw z;S14WOAlnUkhJxY^?8Zf4I6CObrFbxA7@RJlQQO$rC4Um?R?2&REME)zp6(vP-w-* z2JQ3~Pe-z84%BVPf5l&#J4uH{{g`dS{yJqa!>Gkw@*!9MsRm^|TzW)!Bk^~@NXr2# zjQNRt8F-wZD)xo32E2U78*oq+b4abX)_M#LGZ^cEOv_!@3P?Tfb{XzTx|t*CDFFdK z1(!2lyvjSb{td0Kvcwfk-OC=dRi1AOBel4z&e#QzZIMYX>nW>m z9X-_6}IbZ*fKDAuQO3)V-Syp z7D;PsZ%gPar*(Ya~5 zH5)ozgLL?iG*C9Kj{u?u%;k;@R=!*}3$8b{6k=Q<<6)QlMj|TJAuMtaL%muGQT&`7 zPpo#|74?n+1cQ{5z|%GR@oDjTr<~cmDw*+&+NDu?nZ4IS15FIi?D?d8J`H-fZ?%6= zCquL(-D;WeXW065YQSvo_l9}Q`hocQfLy)a&MZCEnMgRn<77-#G`e;& zmpuwBgK$>rlK14q#>1AGZjN6w&E?y_+Oj^Uru=9&?|szn0BK6hAYWS5yp*GRiEEae z%+%o59WSn*E>N)TO_8m2pE?7gBH#TQ>SV6do>}cN0Vr$k6I0PcqN}fg@##|7_r*(c zEkxOLX7*kBxVhv=?Zgt)1#kf4~P;pp6O8PDr)KV z23~+LgFiL}Djm)k|4Ki}4vmq@B_93Vj3N9mMbq`8oge!I*hTFyXOdhw0(JE7d)>}}D2_c28siO2R*vc(bPNhvU}CXMHAbc#>fYq!tmp*eG1fiS z0#$E4l9(S&X4K1=l&eO2P(`m+pq8n5m;*QkWs;=Be_hrSIfB^&2UQVI3HQ83C*qrQqb1>T8~#GjpAG6?SLe`|h^#BF2>cSBwf5zeK61 zr+;_t3~8{`V#Rj8Ry>_{-K{ID-iWu=5<*)<+-uYnWZITB99GUx6q1Q@J*~roKB*$ zD~9cE3plV%RiC|5V6~nXastq3+Y<|1yO!nAq`q}9Lg}}u@O`VdrBkEY{_>{-#IW-c z39SKXGxIzAoTw;VdZo?)@pahPDEISy0f%Hj1lgFJa?+=Re?m+dSCDV4Da3sBG zpnV=)T$Q{sGSDD*)_7wMV<_oC;KUt39(S4YXgS{fR1+&s7A?p|FfQCm zDBAKwPfq6J8x>n`U*xtJTO_q?UDtN;eAqp>3!tj zJR;Sɦdqepkt4)aPf8J;OADSda;UMqCW(wV5~46Y+QMaVxiK=uv_@{jA)dAkgs)Vvx z7%|R&#$H@!Enzt99rUF2$as!ET>JgtT|?d7^~|aX6wIgW(nd@!))a7H@{F^E%WE7j~aCylK`ZtbuCn zp=>oqC_%b0XUEBF;SpS#(vwq31_;^N>M`>260Y80H)r`R|BG8iEpi$rDy{qm%=GRT z^yZrA3RoswU$1&#e^5s5wRZ3+AN*)yNxg+jK0}xu0BOF7Zq?zdgBCC9`Xxyeb0b8e zW%dc)2c^^=UTO_mI~+xRFEKBQWRlS?z(1w7wf?ia$M05M{3rq?b`NaiJ`?U|gJ+d;gVO>R|GC?siVa51 zYr0cqJ(XmJSTNf2M#31Ls2J}o4yXd9cPzcG8Y&7m&v z-3M-9FroF4KwNAryK%#PnieBdR$x9@?P?H9_+) zcJo6@ZtR+wLhs=TNj?}P^YZ)N#bP}~i3pg$pSau$SU*PQeD!YC;k9r*5{dNM9%T?D z8;BZ?w=NM96vX>z#J!G1V5JTmI8atrCYYC(*EhcgE;7avlWr7VX*Xbhj^BR6DL3!>P6r_iVr~j7B5*?N`n%?#A#-t^V1+uoPvnR`uJs}h z?t2$dqa=AH`Vr;{0uNMvqT|%z1f$jP#$$2L)REwT09De=jMQ&va&UcCZf?@W{NDuy zjPwNt?pA#x5D-5a>+wDV^J^j!67U49AoS*%qJl#613uv#hSYGWoz5bojYZKCd3a&^ ztrDbZ2?T{0Hj|wOZsda&<2+SG#Q`xfF+WgUJG&OHqM{-wBO|la1w*XhZhZp$Zt(s7 zm+9rpdI5)2pvXavsqxgT1fs!;#x(5l=Fb44#tbulIucpd5Q;gBFGBvr@Igsd*48KV z*_$ghNH&WgG7}qHRaN!&=7|WIY#GUB;>t{qadY%yJpferKA?M^J*o}B^2}9q3xTAr z#m0h11X^XbAi)pm-Wu^b?c(bC=Zn--0Wtr0xB>2oV3bp=_(6~1;b9lB_DC78t)M^A zId$sy1S1)9b90(xlz{)wulbXpbhiwH@!6>i={AkFT6%fYrWoyLX9^l~2&=b-U&eot zGFXY8T4y=eUPTmTMHKxmtn|2f)cVgkVRj!}7|L;0E)R2emy?z(CIRfrs;bsL`{8{; zV7U{(z_GEhh?(*F5T(0S)~n2|V;!gF*1{hrB^d*{UnyK^o^ymIuEw>rv^364fb!Iq zD$ikO@EE|r$;p;@vn)`z4gbF9;S<4LWm)SI^L5%7%-~dan5U;axM84nc3MV8Ty}PL zjsNt;209@EkjMojj-lbhRw*;BW4K;av zV8hU3c(F0t67#%clJH1xwZlLH8XFtY0=^(h$`v@BUn?c`76X`HR$nhxWqmTdkw9R~fE+m+sD15) zD~L75=1Pythg4-~@#gfWPoM5ZZ0buQl^ihQ@$vC~>&w$y^x>@~%N-B@kOs*`G_pPn z3pTkJ1JJ-50{}6#v%3%Eq2gXE6ZSy%PZJJE9drr7+6}eIO_pq6&p%FRp)|IOXd(2S z(L#g%s?z$8zF~yR#vVn`jq@t(5*%z%EwrCV+DksDr+0o$S{fv45izm&uC6YSvsLu< zF(I8_zh3Y2L3h;F)^cnv8l+X9AI0PGHs@_$xITXTc;RxdwVfSahkXH|1@`nDl$Vz` zd+cj(Y56T48@(7IBCX6X5Wz8BLLz}qL?U5I6QG{-PzaU4ar?&FJjd<8-zT15EJmS> z(PIgKoo~&H{J`rg@-UImg{k-@DWPFh@DvtdpI~Nid=deZ3HLOJyGtd?1heIa3~Z9> z=eKHDEoF?wyXuJLifdpu#6Bl5(zCR);|OqOW+q2s0s3FcA9F%z2?QJUQg8GvZ1h## z(4+R?vbD7}&ei$(`G0Nhj7qI2FTcKE^HYZru=H(?7#ph09gdBWzuy5=LJ*|2ho9Hx zho?Ao?LVqM9-EEjjo>ymEG{WIZ`i!Cv2maclQ_R43U#034MD-dF`^=MJW*3WKzaim z{Mz43dI)A*TuOUgA<<{aK=h^Q&lT;A(&+g7`Lj#}ZRlzN^3bl)pUdAZUT94aWdb>10@|Uo`i!zFTXGt{Cx%k=s0)hj}=q zzz}XqQjFMOK+<1PbGWCTSM4waEglNE3f|6O zX>YG@+N(|zeVBF#$GH