From e3cf50b32ce5f5b6b7bd811017457be0dc3d8fee Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Sun, 20 Jan 2019 16:32:26 +0100 Subject: [PATCH 1/6] Push ZScript version to 3.8 and adapt accordingly to level global removal. This isn't guaranteed to be 100% stable at the moment. --- zmapinfo.txt | 5 +++++ zscript.txt | 2 +- zscript/biorifle.zsc | 6 +++--- zscript/eightball.zsc | 2 +- zscript/enforcer.zsc | 2 +- zscript/flakcannon.zsc | 16 ++++++++-------- zscript/impacthammer.zsc | 2 +- zscript/minigun.zsc | 2 +- zscript/mk_coordutil.zsc | 2 +- zscript/pulsegun.zsc | 10 +++++----- zscript/ripper.zsc | 2 +- zscript/shockrifle.zsc | 18 +++++++++--------- zscript/utcommon.zsc | 25 +++++++++++++------------ zscript/utgore.zsc | 2 +- zscript/uthud.zsc | 21 +++++++++------------ zscript/warheadlauncher.zsc | 24 ++++++++++++------------ 16 files changed, 72 insertions(+), 69 deletions(-) diff --git a/zmapinfo.txt b/zmapinfo.txt index 958dc67..a7a49c4 100644 --- a/zmapinfo.txt +++ b/zmapinfo.txt @@ -7,3 +7,8 @@ GameInfo BorderFlat = "TEMPBG" Border = 0,0,"","","","","","","","" } + +// titlemaps need a mapinfo entry in devbuilds +map TITLEMAP "UT Logo Map" +{ +} diff --git a/zscript.txt b/zscript.txt index e2ceb1f..9147f59 100644 --- a/zscript.txt +++ b/zscript.txt @@ -1,4 +1,4 @@ -version "3.7" +version "3.8" #include "zscript/mk_matrix.zsc" #include "zscript/mk_coordutil.zsc" diff --git a/zscript/biorifle.zsc b/zscript/biorifle.zsc index 8aa2475..b82e595 100644 --- a/zscript/biorifle.zsc +++ b/zscript/biorifle.zsc @@ -158,7 +158,7 @@ Class BioXLight : DynamicLight override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(64*lifetime); args[LIGHT_GREEN] = int(255*lifetime); args[LIGHT_BLUE] = int(48*lifetime); @@ -213,7 +213,7 @@ Class BioGel : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( !bNOGRAVITY ) { roll += rollvel; @@ -608,7 +608,7 @@ Class BioGlob : BioGel override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; Vector3 ofs = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); for ( int i=0; i<2; i++ ) { diff --git a/zscript/eightball.zsc b/zscript/eightball.zsc index 316ffb5..4a5fc89 100644 --- a/zscript/eightball.zsc +++ b/zscript/eightball.zsc @@ -411,7 +411,7 @@ Class UTRocketLauncher : UTWeapon // lock-on check action void A_CheckTarget() { - let t = ThinkerIterator.Create("Actor"); + let t = level.CreateThinkerIterator("Actor"); Actor a; double closest = double.max; invoker.LockedTarget = null; diff --git a/zscript/enforcer.zsc b/zscript/enforcer.zsc index 74b6d02..f016fbb 100644 --- a/zscript/enforcer.zsc +++ b/zscript/enforcer.zsc @@ -117,7 +117,7 @@ Class UTCasing : Actor override void Tick() { Super.Tick(); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; if ( InStateSequence(CurState,ResolveState("Death")) ) { deadtimer++; diff --git a/zscript/flakcannon.zsc b/zscript/flakcannon.zsc index 4432890..fd2520e 100644 --- a/zscript/flakcannon.zsc +++ b/zscript/flakcannon.zsc @@ -55,7 +55,7 @@ Class ChunkLight : DynamicLight Destroy(); return; } - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(255*(10-target.frame)*0.1); args[LIGHT_GREEN] = int(224*(10-target.frame)*0.1); args[LIGHT_BLUE] = int(128*(10-target.frame)*0.1); @@ -84,7 +84,7 @@ Class ChunkTrail : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( InStateSequence(CurState,FindState("Death")) ) return; if ( !target ) { @@ -121,7 +121,7 @@ Class FlakAccumulator : Thinker static void Accumulate( Actor victim, int amount ) { - let ti = ThinkerIterator.Create("FlakAccumulator",STAT_USER); + let ti = victim.level.CreateThinkerIterator("FlakAccumulator",STAT_USER); FlakAccumulator a, match = null; while ( a = FlakAccumulator(ti.Next()) ) { @@ -131,7 +131,7 @@ Class FlakAccumulator : Thinker } if ( !match ) { - match = new("FlakAccumulator"); + match = new("FlakAccumulator"); // another thinker created through new(), this all looks like a big catastrophe waiting to happen match.ChangeStatNum(STAT_USER); match.victim = victim; } @@ -141,7 +141,7 @@ Class FlakAccumulator : Thinker static int GetAmount( Actor victim ) { - let ti = ThinkerIterator.Create("FlakAccumulator",STAT_USER); + let ti = victim.level.CreateThinkerIterator("FlakAccumulator",STAT_USER); FlakAccumulator a; while ( a = FlakAccumulator(ti.Next()) ) { @@ -194,7 +194,7 @@ Class FlakChunk : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( waterlevel > 0 ) { vel.xy *= 0.98; @@ -336,7 +336,7 @@ Class SlugSmoke : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; lifetime += lifespeed; let s = Spawn("UTSmoke",pos); s.vel = (FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5)); @@ -370,7 +370,7 @@ Class SlugLight : DynamicLight override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(224*lifetime); args[LIGHT_BLUE] = int(128*lifetime); diff --git a/zscript/impacthammer.zsc b/zscript/impacthammer.zsc index 81461dd..bbe1956 100644 --- a/zscript/impacthammer.zsc +++ b/zscript/impacthammer.zsc @@ -152,7 +152,7 @@ Class ImpactHammer : UTWeapon if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4); } // push aside projectiles - let t = ThinkerIterator.Create("Actor"); + let t = level.CreateThinkerIterator("Actor"); Actor m; while ( m = Actor(t.Next()) ) { diff --git a/zscript/minigun.zsc b/zscript/minigun.zsc index 35b6110..084d6a1 100644 --- a/zscript/minigun.zsc +++ b/zscript/minigun.zsc @@ -47,7 +47,7 @@ Class MinigunTracer : Actor override void Tick() { Super.Tick(); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; Vector3 dir = level.Vec3Diff(pos,dest); if ( dir.length() < 160 ) { diff --git a/zscript/mk_coordutil.zsc b/zscript/mk_coordutil.zsc index 709a425..f61f2c3 100644 --- a/zscript/mk_coordutil.zsc +++ b/zscript/mk_coordutil.zsc @@ -9,7 +9,7 @@ Class dt_CoordUtil { // projects a world point onto screen // view matrix setup mostly pulled from gutawer's code - static Vector3 WorldToScreen( Vector3 vect, Vector3 eye, double pitch, double yaw, double roll, double vfov ) + static Vector3 WorldToScreen( LevelLocals level, Vector3 vect, Vector3 eye, double pitch, double yaw, double roll, double vfov ) { double ar = Screen.getWidth()/double(Screen.getHeight()); double fovr = (ar>=1.3)?1.333333:ar; diff --git a/zscript/pulsegun.zsc b/zscript/pulsegun.zsc index 78add62..dc85f95 100644 --- a/zscript/pulsegun.zsc +++ b/zscript/pulsegun.zsc @@ -91,7 +91,7 @@ Class ViewPulseSpark : PulseSpark Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; ofs += vvel; vvel *= 0.9; scale *= 0.8; @@ -149,7 +149,7 @@ Class PulseExplLight : DynamicLight override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(64*lifetime); args[LIGHT_GREEN] = int(255*lifetime); lifetime -= 1./ReactionTime; @@ -372,7 +372,7 @@ Class PulseBolt : Actor { if ( !damagedactor ) { - accdamage = min(0.5*(level.time-lasthit),0.1); + accdamage = min(0.5*(level.maptime-lasthit),0.1); t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](80,100)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x)); accdamage = 0; } @@ -381,7 +381,7 @@ Class PulseBolt : Actor t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](80,100)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x)); accdamage = 0; } - lasthit = level.time; + lasthit = level.maptime; damagedactor = t.Results.HitActor; accdamage += 1./TICRATE; if ( accdamage > 0.17 ) @@ -506,7 +506,7 @@ Class StarterBolt : PulseBolt override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( !target ) { Destroy(); diff --git a/zscript/ripper.zsc b/zscript/ripper.zsc index 03aec45..ab951bf 100644 --- a/zscript/ripper.zsc +++ b/zscript/ripper.zsc @@ -171,7 +171,7 @@ Class Razor2AltLight : DynamicLight override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(240*lifetime); args[LIGHT_BLUE] = int(224*lifetime); diff --git a/zscript/shockrifle.zsc b/zscript/shockrifle.zsc index 1247e97..dee5336 100644 --- a/zscript/shockrifle.zsc +++ b/zscript/shockrifle.zsc @@ -72,7 +72,7 @@ Class ShockRifleWave : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; alpha -= 1/50.; } States @@ -99,7 +99,7 @@ Class SuperShockRifleWave : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; alpha -= 1/50.; } States @@ -127,7 +127,7 @@ Class ShockBeamRing : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; alpha -= 1./ReactionTime; } States @@ -154,7 +154,7 @@ Class SuperShockBeamRing : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; alpha -= 1./ReactionTime; } States @@ -295,7 +295,7 @@ Class ShockBeam : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( !moving ) return; // step trace tracedir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); @@ -522,7 +522,7 @@ Class SuperShockBeam : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( !moving ) return; // step trace tracedir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); @@ -765,7 +765,7 @@ Class ShockExplLight : DynamicLight override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(160*lifetime); args[LIGHT_GREEN] = int(128*lifetime); args[LIGHT_BLUE] = int(255*lifetime); @@ -791,7 +791,7 @@ Class SuperShockExplLight : DynamicLight override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(160*lifetime); args[LIGHT_BLUE] = int(128*lifetime); @@ -982,7 +982,7 @@ Class ViewShockSpark : ShockSpark Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; ofs += vvel; vvel *= 0.9; scale *= 0.8; diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index 4a24757..c039703 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -213,7 +213,7 @@ Class UTPlayer : DoomPlayer } if ( !footsteps ) footsteps = CVar.GetCVar('flak_footsteps',players[consoleplayer]); if ( !footsteps.GetBool() ) return; - double ang = level.time/(20*TICRATE/35.)*360.; + double ang = level.maptime/(20*TICRATE/35.)*360.; bool forcefootstep = false; if ( player.onground && !bNoGravity && !lastground && (waterlevel < 2) ) { @@ -899,7 +899,7 @@ Class UTViewSpark : UTSpark Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; ofs += vvel; vvel.z -= 0.1; scale *= 0.8; @@ -941,7 +941,7 @@ Class UTChip : Actor override void Tick() { Super.Tick(); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; if ( InStateSequence(CurState,ResolveState("Death")) ) { deadtimer++; @@ -1004,7 +1004,7 @@ Class UTBubble : Actor override void Tick() { Super.Tick(); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; vel *= 0.96; vel.z += 0.05; if ( (waterlevel <= 0) || !Random[Puff](0,100) ) Destroy(); @@ -1052,7 +1052,7 @@ Class UTSmoke : Actor override void Tick() { Super.Tick(); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; vel *= 0.96; vel.z += 0.01; A_FadeOut(1/32.); @@ -1144,7 +1144,7 @@ Class UTViewSmoke : UTSmoke Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; ofs += vvel; vvel *= 0.96; vvel.z += 0.01; @@ -1516,7 +1516,7 @@ Class UTMainHandler : StaticEventHandler private Actor AddLight( Vector3 pos, Color col, int radius ) { - Actor l = Actor.Spawn("PointLightAttenuated",pos); + Actor l = currentSession.levelinfo[0].Spawn("PointLightAttenuated",pos); if ( !l ) return null; l.args[0] = col.r; l.args[1] = col.g; @@ -1527,7 +1527,7 @@ Class UTMainHandler : StaticEventHandler private Actor AddAmbient( Vector3 pos, String snd, double volume = 1., double attenuation = ATTN_NORM ) { - Actor a = Actor.Spawn("MapSpot",pos); + Actor a = currentSession.levelinfo[0].Spawn("MapSpot",pos); if ( !a ) return null; a.A_PlaySound(snd,CHAN_BODY,volume,true,attenuation); return a; @@ -1537,6 +1537,7 @@ Class UTMainHandler : StaticEventHandler { if ( gamestate != GS_LEVEL || e.IsSaveGame ) return; // prettify Kinsie's test map for a more Unreal feel + let level = currentSession.levelinfo[0]; if ( level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33" ) { TextureID deftex = TexMan.CheckForTexture("-noflat-",TexMan.Type_Any); @@ -1735,7 +1736,7 @@ Class UTMainHandler : StaticEventHandler return; } // generic gibbing - let a = Actor.Spawn("UTGibber",e.Thing.pos); + let a = e.Thing.level.Spawn("UTGibber",e.Thing.pos); a.vel = e.Thing.vel; a.Scale = e.Thing.Scale; a.Translation = e.Thing.BloodTranslation; @@ -1750,7 +1751,7 @@ Class UTMainHandler : StaticEventHandler } // attach damage accumulator for corpses if ( !flak_corpsedamage ) return; - let a = Actor.Spawn("ShredCorpseHitbox",e.Thing.pos); + let a = e.Thing.level.Spawn("ShredCorpseHitbox",e.Thing.pos); a.target = e.Thing; } @@ -1775,7 +1776,7 @@ Class UTMainHandler : StaticEventHandler if ( !a || !a.bSHOOTABLE || !Source.CheckSight(a,0xf) || (a == Source) || (Source.Distance3D(a) > ExplosionRadius) ) continue; Vector3 midpoint = a.Vec3Offset(0,0,a.height*0.5); - a.vel += Level.Vec3Diff(Source.pos,midpoint).unit()*(MomentumTransfer/(Thinker.TICRATE*a.mass)); + a.vel += Source.level.Vec3Diff(Source.pos,midpoint).unit()*(MomentumTransfer/(Thinker.TICRATE*a.mass)); } } @@ -1789,7 +1790,7 @@ Class UTMainHandler : StaticEventHandler static void DoSwing( Actor target, Vector2 dir, double initial, double inc, int steps, int mode = 0, int delay = 0, double rmul = 1.0 ) { if ( !flak_swingers ) return; - let s = new("Swinger"); + let s = new("Swinger"); // this looks unsafe, shouldn't there be a way to create thinkers in specifc level? s.ChangeStatNum(Thinker.STAT_USER); s.target = target; s.dir = dir; diff --git a/zscript/utgore.zsc b/zscript/utgore.zsc index bc634b2..930c07c 100644 --- a/zscript/utgore.zsc +++ b/zscript/utgore.zsc @@ -151,7 +151,7 @@ Class UTBloodTrail : Actor override void Tick() { Super.Tick(); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; if ( !target ) return; SetOrigin(target.pos,true); double ang, pt; diff --git a/zscript/uthud.zsc b/zscript/uthud.zsc index e82eeb3..23dd938 100644 --- a/zscript/uthud.zsc +++ b/zscript/uthud.zsc @@ -42,9 +42,6 @@ Class UTHud : BaseStatusBar double CurX, CurY; double FracTic; - // Ugh... - const TINTSTYLE = (1|2<<8|1<<16|12<<24); - override void Init() { Super.Init(); @@ -211,7 +208,7 @@ Class UTHud : BaseStatusBar if ( opacity == -1 ) opacity = self.opacity; if ( opacity >= 16 ) Screen.DrawTexture(tx,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,bgcolor); double alpha = clamp(opacity/15.,0.0,1.0); - Screen.DrawTexture(tx,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_RenderStyle,TINTSTYLE,DTA_FillColor,(tint!="Black")?tint:tintcolor); + Screen.DrawTexture(tx,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,(tint!="Black")?tint:tintcolor); } private void UTDrawPlainTex( TextureID tx, double sx = 1.0, int opacity = -1 ) { @@ -264,13 +261,13 @@ Class UTHud : BaseStatusBar if ( value < 0 ) { if ( opacity+7 > 15 ) Screen.DrawTexture(BigNum[11],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,bgcolor); - Screen.DrawTexture(BigNum[11],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_RenderStyle,TINTSTYLE,DTA_FillColor,DrawColor); + Screen.DrawTexture(BigNum[11],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,DrawColor); CurX += step; } for ( int i=0; i 15 ) Screen.DrawTexture(BigNum[digits.CharCodeAt(i)-0x30],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_FillColor,bgcolor); - Screen.DrawTexture(BigNum[digits.CharCodeAt(i)-0x30],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_RenderStyle,TINTSTYLE,DTA_FillColor,DrawColor); + Screen.DrawTexture(BigNum[digits.CharCodeAt(i)-0x30],false,CurX/ss,CurY/ss,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_LegacyRenderStyle,STYLE_AddShaded,DTA_FillColor,DrawColor); CurX += ((i=1.0) ) CurY -= 64*hudsize*HScale; DrawColor = tintcolor; - double whiten = ((level.time+fractic)-lastfrag)/Thinker.TICRATE; + double whiten = ((currentsession.time+fractic)-lastfrag)/Thinker.TICRATE; if ( whiten < 3.0 ) { if ( tintcolor == GoldColor ) @@ -542,7 +539,7 @@ Class UTHud : BaseStatusBar } private void DrawIdentifyInfo() { - double lalpha = 2.0-((level.time+fractic)-lastseentic)/Thinker.TICRATE; + double lalpha = 2.0-((currentsession.time+fractic)-lastseentic)/Thinker.TICRATE; if ( !lastseen || (lalpha <= 0) ) return; String cl1 = "Teal", cl2 = "Cyan"; if ( deathmatch && (lastseen.player.GetTeam() < teams.size()) ) @@ -616,19 +613,19 @@ Class UTHud : BaseStatusBar Super.Tick(); if ( deathmatch||teamplay ) { - if ( CPlayer.fragcount != lastfragcnt ) lastfrag = level.time; + if ( CPlayer.fragcount != lastfragcnt ) lastfrag = currentsession.time; lastfragcnt = CPlayer.fragcount; } else { - if ( CPlayer.killcount != lastfragcnt ) lastfrag = level.time; + if ( CPlayer.killcount != lastfragcnt ) lastfrag = currentsession.time; lastfragcnt = CPlayer.killcount; } vtracer.ignore = CPlayer.mo; vtracer.trace(CPlayer.mo.Vec2OffsetZ(0,0,CPlayer.viewz),CPlayer.mo.CurSector,(cos(CPlayer.mo.angle)*cos(CPlayer.mo.pitch),sin(CPlayer.mo.angle)*cos(CPlayer.mo.pitch),-sin(CPlayer.mo.pitch)),1000,0); if ( vtracer.Results.HitType != TRACE_HitActor ) return; lastseen = vtracer.Results.HitActor; - lastseentic = level.time; + lastseentic = currentsession.time; } private void DrawUTHUD() diff --git a/zscript/warheadlauncher.zsc b/zscript/warheadlauncher.zsc index 675925b..1968dc6 100644 --- a/zscript/warheadlauncher.zsc +++ b/zscript/warheadlauncher.zsc @@ -48,9 +48,9 @@ Class ShockWave : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( alpha <= 0 ) return; - if ( !t ) t = ThinkerIterator.Create("Actor"); + if ( !t ) t = level.CreateThinkerIterator("Actor"); icount++; if ( icount == 4 ) Spawn("WarheadSubExplosion",pos); lifespan--; @@ -164,7 +164,7 @@ Class WarheadExplodLight : DynamicLight override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(192*lifetime); args[LIGHT_BLUE] = int(128*lifetime); @@ -224,7 +224,7 @@ Class WarheadTrail : Actor override void Tick() { Super.Tick(); - if ( level.frozen || globalfreeze ) return; + if ( isFrozen() ) return; vel *= 0.99; A_FadeOut(0.1); } @@ -275,7 +275,7 @@ Class WarShell : Actor override void Tick() { Super.Tick(); - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( !bMISSILE ) return; if ( vel.length() > 0 ) { @@ -375,7 +375,7 @@ Class GuidedWarShell : WarShell justleft = false; bHITOWNER = true; } - if ( globalfreeze || level.frozen ) return; + if ( isFrozen() ) return; if ( !bMISSILE ) return; if ( !target || !target.player || (target.Health <= 0) ) { @@ -482,7 +482,7 @@ Class RedeemerHUD : HUDMessageBase // shootable targetting if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && !CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() ) { - if ( !t ) t = ThinkerIterator.Create("Actor"); + if ( !t ) t = camera.level.CreateThinkerIterator("Actor"); if ( !tr ) tr = new("MidTracer"); t.Reinit(); ta.Clear(); @@ -490,10 +490,10 @@ Class RedeemerHUD : HUDMessageBase Vector3 vdir = (cos(ViewAngle)*cos(ViewPitch),sin(ViewAngle)*cos(ViewPitch),-sin(ViewPitch)); while ( a = Actor(t.Next()) ) { - Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); + Vector3 tdir = camera.level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue; Vector3 wpos = ViewPos+tdir; - Vector3 spos = dt_CoordUtil.WorldToScreen(wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); + Vector3 spos = dt_CoordUtil.WorldToScreen(camera.level,wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); if ( spos.z > 1.0 ) continue; TargetActor te = new("TargetActor"); te.vpos = dt_CoordUtil.ToViewport(spos); @@ -513,7 +513,7 @@ Class RedeemerHUD : HUDMessageBase { if ( CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() ) { - if ( !t ) t = ThinkerIterator.Create("Actor"); + if ( !t ) t = camera.level.CreateThinkerIterator("Actor"); if ( !tr ) tr = new("MidTracer"); t.Reinit(); ta.Clear(); @@ -521,10 +521,10 @@ Class RedeemerHUD : HUDMessageBase Vector3 vdir = (cos(ViewAngle)*cos(ViewPitch),sin(ViewAngle)*cos(ViewPitch),-sin(ViewPitch)); while ( a = Actor(t.Next()) ) { - Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); + Vector3 tdir = camera.level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue; Vector3 wpos = ViewPos+tdir; - Vector3 spos = dt_CoordUtil.WorldToScreen(wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); + Vector3 spos = dt_CoordUtil.WorldToScreen(camera.level,wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); if ( spos.z > 1.0 ) continue; TargetActor te = new("TargetActor"); te.vpos = dt_CoordUtil.ToViewport(spos); From b398a27919e68c445b85e83255973b0d59ec0faa Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Mon, 21 Jan 2019 02:12:59 +0100 Subject: [PATCH 2/6] Change blue health textures to something prettier. Add Heretic compatibility (WIP, needs testing and some tweaks). --- Readme.md | 1 + animdefs.txt | 15 --- filter/game-heretic/zmapinfo.txt | 14 +++ gldefs.txt | 75 +++++------- modeldef.misc | 45 ++++++- models/NewGreen.png | Bin 0 -> 44973 bytes shaders/glsl/FizzDistortX.fp | 18 +++ shaders/glsl/FizzDistortXY.fp | 18 +++ textures.misc | 121 +------------------ textures/fizzfull.png | Bin 0 -> 19151 bytes textures/fizzside.png | Bin 0 -> 3056 bytes textures/fizztop.png | Bin 0 -> 8360 bytes textures/warptex.png | Bin 0 -> 28936 bytes zscript/compat.zsc | 200 ++++++++++++++++++++++++++++++- zscript/utcommon.zsc | 175 ++++++++++++++++++++++----- 15 files changed, 470 insertions(+), 212 deletions(-) create mode 100644 filter/game-heretic/zmapinfo.txt create mode 100644 models/NewGreen.png create mode 100644 shaders/glsl/FizzDistortX.fp create mode 100644 shaders/glsl/FizzDistortXY.fp create mode 100644 textures/fizzfull.png create mode 100644 textures/fizzside.png create mode 100644 textures/fizztop.png create mode 100644 textures/warptex.png diff --git a/Readme.md b/Readme.md index 4476b4d..bb72607 100644 --- a/Readme.md +++ b/Readme.md @@ -56,6 +56,7 @@ This mod requires GZDoom 3.7.0 or later. - Add some more effects - Lava/Slime footstep sounds? - UT gore system (toggleable) + - Heretic compatibility ## Future plans diff --git a/animdefs.txt b/animdefs.txt index 1365cc2..dfd7600 100644 --- a/animdefs.txt +++ b/animdefs.txt @@ -5,21 +5,6 @@ texture static1 pic static2 tics 1 pic static3 tics 1 pic static4 tics 1 -texture FIZZHP00 - pic FIZZHP00 tics 8 - pic FIZZHP01 tics 8 - pic FIZZHP02 tics 8 - pic FIZZHP03 tics 8 -texture FIZZHP10 - pic FIZZHP10 tics 8 - pic FIZZHP11 tics 8 - pic FIZZHP12 tics 8 - pic FIZZHP13 tics 8 -texture FIZZHP20 - pic FIZZHP20 tics 8 - pic FIZZHP21 tics 8 - pic FIZZHP22 tics 8 - pic FIZZHP23 tics 8 texture invis00 pic invis00 tics 2 pic invis01 tics 2 diff --git a/filter/game-heretic/zmapinfo.txt b/filter/game-heretic/zmapinfo.txt new file mode 100644 index 0000000..cdbb4a4 --- /dev/null +++ b/filter/game-heretic/zmapinfo.txt @@ -0,0 +1,14 @@ +GameInfo +{ + AddEventHandlers = "RedeemerHUDHandler", "UTMainHandler" + PlayerClasses = "UTPlayerHereticCompatTMale1", "UTPlayerHereticCompatTMale2", "UTPlayerHereticCompatTFemale1", "UTPlayerHereticCompatTFemale2", "UTPlayerHereticCompatTBoss" + StatusBarClass = "UTHud" + BackpackType = "UTBackpack" + BorderFlat = "TEMPBG" + Border = 0,0,"","","","","","","","" +} + +// titlemaps need a mapinfo entry in devbuilds +map TITLEMAP "UT Logo Map" +{ +} diff --git a/gldefs.txt b/gldefs.txt index e2c887c..8f96065 100644 --- a/gldefs.txt +++ b/gldefs.txt @@ -2,53 +2,20 @@ HardwareShader Texture "models/Jgreen.png" { Shader "shaders/glsl/MeshEnviroMap.fp" } -Brightmap Texture "FIZZHP00" +HardwareShader Texture "fizzside" { - Map "brightmaps/fullbright.png" + Shader "shaders/glsl/FizzDistortX.fp" + Texture "warptex" "textures/warptex.png" } -Brightmap Texture "FIZZHP01" +HardwareShader Texture "fizztop" { - Map "brightmaps/fullbright.png" + Shader "shaders/glsl/FizzDistortXY.fp" + Texture "warptex" "textures/warptex.png" } -Brightmap Texture "FIZZHP02" +HardwareShader Texture "fizzfull" { - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP03" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP10" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP11" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP12" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP13" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP20" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP21" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP22" -{ - Map "brightmaps/fullbright.png" -} -Brightmap Texture "FIZZHP23" -{ - Map "brightmaps/fullbright.png" + Shader "shaders/glsl/FizzDistortXY.fp" + Texture "warptex" "textures/warptex.png" } HardwareShader Texture "models/jhbox1.png" { @@ -252,6 +219,10 @@ HardwareShader Texture "models/RedSkin2.png" { Shader "shaders/glsl/MeshEnviroMap_AmbientGlow.fp" } +HardwareShader Texture "models/NewGreen.png" +{ + Shader "shaders/glsl/MeshEnviroMap_AmbientGlow.fp" +} HardwareShader Texture "models/bpak.png" { Shader "shaders/glsl/AmbientGlow.fp" @@ -561,6 +532,14 @@ PulseLight "UTGoldKeyLight" Interval 2.0 Offset 0 16 0 } +PulseLight "UTGreenKeyLight" +{ + Color 0.0 1.0 0.0 + Size 15 + SecondarySize 20 + Interval 2.0 + Offset 0 16 0 +} Object "UTRedSkull" { Frame "USKL" { light "UTRedKeyLight" } @@ -585,6 +564,18 @@ Object "UTGoldKey" { Frame "UKEY" { light "UTGoldKeyLight" } } +Object "UTHereticYellowKey" +{ + Frame "UKEY" { light "UTGoldKeyLight" } +} +Object "UTHereticGreenKey" +{ + Frame "UKEY" { light "UTGreenKeyLight" } +} +Object "UTHereticBlueKey" +{ + Frame "UKEY" { light "UTBlueKeyLight" } +} HardwareShader PostProcess scene { Name "RedeemerView" diff --git a/modeldef.misc b/modeldef.misc index f4b9606..f00dcec 100644 --- a/modeldef.misc +++ b/modeldef.misc @@ -50,7 +50,7 @@ Model "UTHealthPack" Model 0 "hbox_d.3d" // indices start at 1 for this mesh SurfaceSkin 0 1 "jhbox1.png" - SurfaceSkin 0 2 "FIZZHP00" + SurfaceSkin 0 2 "fizzfull" Scale 0.2 0.24 0.2 RollOffset -90 ZOffset 16 @@ -64,8 +64,8 @@ Model "UTHealthBox" Model 0 "hboxbeta_d.3d" // indices start at 1 for this mesh SurfaceSkin 0 1 "jhboxbeta1.png" - SurfaceSkin 0 2 "FIZZHP10" - SurfaceSkin 0 3 "FIZZHP10" + SurfaceSkin 0 2 "fizzfull" + SurfaceSkin 0 3 "fizzfull" Scale 0.08 0.08 0.096 ZOffset 4 @@ -78,7 +78,7 @@ Model "UTMedBox" Model 0 "MedBox_d.3d" // indices start at 1 for this mesh SurfaceSkin 0 1 "JMedBox1.png" - SurfaceSkin 0 2 "FIZZHP10" + SurfaceSkin 0 2 "fizzfull" Scale 0.06 0.06 0.072 ZOffset 5 @@ -90,8 +90,8 @@ Model "UTHealthBonus" Path "models" Model 0 "Vial_d.3d" SurfaceSkin 0 0 "JVial0.png" - SurfaceSkin 0 1 "FIZZHP20" - SurfaceSkin 0 2 "FIZZHP20" + SurfaceSkin 0 1 "fizzside" + SurfaceSkin 0 2 "fizztop" Scale 0.04 0.04 0.048 ZOffset 8 DONTCULLBACKFACES @@ -228,6 +228,39 @@ Model "UTBlueKey" FrameIndex UKEY C 0 0 } +Model "UTHereticYellowKey" +{ + Path "models" + Model 0 "MercSymbol_d.3d" + Skin 0 "GoldSkin2.png" + Scale 0.08 0.08 0.096 + ZOffset 16 + ROTATING + + FrameIndex UKEY B 0 0 +} +Model "UTHereticGreenKey" +{ + Path "models" + Model 0 "UDamage_d.3d" + Skin 0 "NewGreen.png" + Scale 0.08 0.08 0.096 + ZOffset 16 + ROTATING + + FrameIndex UKEY D 0 0 +} +Model "UTHereticBlueKey" +{ + Path "models" + Model 0 "DomB_d.3d" + Skin 0 "BlueSkin2.png" + Scale 0.04 0.04 0.048 + ZOffset 16 + ROTATING + + FrameIndex UKEY C 0 0 +} Model "UTBackpack" { diff --git a/models/NewGreen.png b/models/NewGreen.png new file mode 100644 index 0000000000000000000000000000000000000000..58f1ae4abf9cf57e7caf8df3d117121552d7107a GIT binary patch literal 44973 zcmeAS@N?(olHy`uVBq!ia0y~yU}OMc4rT@hhU_&FAq)%*Ea{HEjtmSN`?>!lvNA9* zC?tCX`7$t6sWC7#v@kIIVqjosc)`F>YQVtoDuIE)Y6b&?c)^@qfi?^bj8_7DLR?u> zMVUkSm;!m2oH-bcSQyoq87yHm?QW(i{u4648$f`a^%af#0av)3UXH{ z^VVxf&2*5N<03lIf~!=KIh>EtnvGGKkx_+-QG=OLlbKPSnNgLAQIUyJj)_r{kx`71 zQIL_5kC9P?kx`V9QJ#rWpM}Ynn>|~KHCcouQJA|*MW9Vju+xCANt?4!j-x=9vqXWb zOpz^9oHC0c;HQkkn3mzD6z1VtIjfeW4y>)^u^!6cLVGY5o=+Mj=K<4n{^TW=35W zMq?I66IMoZRz_o1MjdA6Fg_+fZboiKMkOXjLl!1CPDXonMm-irM|O@JY4OR{f?b9Z z)9qyEx+*O2f!CE|GpS`S~7rv(nblfqmLE_$Sf{()SkS7uaxNhb!leKx#{T^_u?P4 zGMxX+Up_Ld0072>vPj_~Grv-P@0M&fS%sS9FQ>?EH+o z{^!p*{WoqnP`!TP)@|E@eLg&MYUqEQ|Nm#%8Z|lR%^QCtb@T>*TB*Xq%&MiS*O6|v z?aE5mU3UxG1HQh^QM;?H)pIIbwLA2|>Kca)6Z%wJJPWikxlYWm-&lICTU@?RFU;*| z|KF?syt;amH|YcyZo78ed6P;Yce`m%xk-AO-WdHF9((d_&h=^|*7(bp_cQ#+E-S05I`w*G{k}V%uXVTBHxxzuzuK;^ zzc1|952v+Zhd+LBdX;mNhyM=eW9=j(5i7CZPrI9q=1s9onc%(r_TD5pUJtP=DWXh_ zjhl@c8V;XgU8^=}d56Qswab;<-@n_%tr_UkJMBgV&*7wPD)-i2;b>gF>BlRkqxx_6 z{W-k4Q1}>6ZQi;3HTh?x%ZfWTEw!-Q|Fi5--WBQIV|lenMYo@RoO7n8D))q@Pu+#r zv6G+eSf_j~>)V4MyTApD_GEqRetIfWv~CNleGCT_tV|!<^O9+zyJ7q_3p*h+mk2u@g9D3^42NEeFZUG zy=~g!`h9UWVTW`MF071Se>d;@v=F_I9~x%(@U<^`^7;8u_Etqtk*z;A)~e1`b~e}F zw{FhOY}#3ZI~36~h^bNu~wsjI2Q6srf{`}lkLqn%2D7aQvGU(Dfm z-B)M->-lc}_xEIL+XIhloVms+FZW2(tnFxo;Jpv0+x2hNm*yC)S7JEywVAp0MeN;s z-{w{MZ{K?_^!K;SY|Z^G5vkS(pBQ!Qt-g@{^w7SWJvVc6+>e|V7q@79b~R#2_j0k+ zwDilihA#_knIGJoS8|^J{O-Hid-vowDD~#+zkcnvSa{XVRl9lDO`e&5IlEHrzVxlv zmLX~#FRkwWOH4WF=E`Yz;$^~TajPkPg%)e}?A#Kt^G9ZI?YW1A+p8Dt+j;Xw?%Qoq zYZHH%?zhalV7KMonR&`wp2??owSRefulcBq*TdCMy;LV9Y0lixIq~Y@4~26+TweZL zLYs;8-@i}aFWz>G6t&7Q6w7qdjAHjd-qx}}rKVhwlO+2qZrnP#~@{nFl@FX!DU`PJp@-?{W` z=J{jiLf75RUe4IqcH8vpv#qO_D@5;G6xSaSGU?jUf*785>o=QpECRTDH?E20o4{ux zXcH@@Jhip<^5o5-<~`S?XYXG7u=m-nkL`xVmHYQy%xZYn@aoRG+{l7BfmJ6@iq$~MSuIB&0ih=?IBcq^oB_9inLXx~shlHqc z%+wNjak+`lXQ9IB-)X-ii!3{4oN+iMq&k~ZEA91_T^n4@b$&k3Sn?}L!&1tqxFbKK zc3gs9-1kC0M+&?#2^yi+Pbx*4uK6Tu?es0ZnskWE-#=3hK>1(OE+DAMJ zaeSU`z3}m@ifuJrc|Sj?_`g40WO`yj$_4>@zV_+O-fw?j+mU$4!0=t3iTS(wn0Kk) z%QnrFKlb%mL3Z7C!#|eAS3f^pJE_l^eWy>_i(fW^EZemb=6cvG&C@+*;I)n`?AWP- zs}dFxArWg@4_EAu)|`I)lzsiQe7C$jKDT}MdU`_K>g2wKf8^K~c=89KZ{hP-p ze7`@=_|%hn-m2p1$E&Nm?mkgiJoi@Q9uupmMXTl*Nfg!Py~~=t;q9$&Rpt4Trz`mc zJ?8T}IwrDCb^P4CWn=1$zb4r(6O@v++Wp9@R&%@%n#!}eyf3onJpbF2>Z&==S+@|C<24a#pE*pC8w)y?JYGf4{lewfA$Y{eRW$v)FO! z>$=Zst6e`GKWDY5qGp+=c&Nad6_eaOJ^R{^M6DA3we-0F&yoHgiBF%OJ^J|W-EMLB zsJ*}b-M-yCvFLjNt3sEK%1sr!Z{OJVq%PgI;lsy*Cm&y!&k6E8d8RF=d+8L5Q^!m! zZ@zlF_V5BV_3icZ=N4Q2U?@5#%C$W0b7rH$pU^mkiE(LXZGXS~J7Lmw>k#cl_fOfX zs>tewA6%JJ=yW$~_Wj(y5>*^J#}}7`_H8R(=|`{cs4A&zn(#U%PJS8tx;N~GD(wfSBr>6FWKRE`R%QB{QMJV$SNFX8$;-4kOug-sWRuf)T)VP4tH|MUFRo{fl9K*cmFWS{-ckQ;j z6LxlE#+CQ+DTbVtyJVR-S(qxG+uUxe%04@j(NmVkglmbh+XT_;SK`(9N*Tx*b4&99PjAY#h2x2j^RjWkw$<(I1qSoh$eNOpJNtT%zT)Jm*YK7Y2b z*6^z5Cc{(lQ!TnfLoKf!;5(pb#&{behK zpFiJ*KKuMyNDp_{x z2FDuP=CbOS3-@X-JuvSkhoZ-ft9PD0J=cHDqGPp~G0%jp*XO?6#@4{*X!STI|Elfg z|Gz$;|3Bx-Z2PvV=A?}k`?i+;Evdb|``)G5I-#5AFBd=Bzt}J?K(%YF<9~7GsdW+3 zn|1kE52~@Q+<5!F)7ReN0J;874==_u=e`pP52l!o>F{mB-ux2voP zO57+G*?VOYgKCJ0R(Pq{W#|0kGrunEF=eQG^!@$s%%<3g7aQs>Re8->^!DL>|8FvC zt&Km{iX)&oLMNzk4@Jki*~wZ;ceg z&UA)7`ul5tnZ1tk=KsX8=#Q4m>ZR?f!5>QIUr*$oS~O#6h9#Sn9aH2EA;x)|bxQKN zmp-t2Rd)Jmv)~3dUj~zGpH_pNr;1fBuyrYhIyMNOxb`zba`z62?kRu73L3L?SpRk} zSU!Q@S?BaLhR#~M4!ay%8d>v{94U8T8(Z_ibjA6MV2t{%rfN4PYi@P+)YcJm9&EVuX= zm>C+b-%GpIuCd};l^oYPs~K~h4I`Obnc{iB%D;Czq$s`QMjh*|08#$!4ec=QO&kv0*+C%K5@RsPV^z_zj|KIGVU3*xx_ajMhox zE)6=Mu|s5<czWQUbw@z^x4D*kItSgbWqyx;9CE$59cmixGJ`2mD-f; z$yOfO2OZ-+Hg+o}q;PyGczec9WWDF!@Au!U?+xA@tbV~>WnS9no&Oivt*;fWeH(M_ zMotF9nH_VOS>(h{zW%@d6W6H)JzNjn*ZrET>>mH_R0XdL!*SD@n-AVFkeI{E_ryc~ z+5bEH!=xN{nF@IB)LOY;EGVz8(TX!tG1bF-YN1(pPYLoVY%&;eOb=- z$9%S3H|yii*A4Y%gGT;@iYL$shF}S10iA zn)sh_!BO!L=ZR{MWZ#BP^_V0SaAL!O|9-wc#}s7RtYjnfg&G^bm=tQg5^Q<0M604l zgOlsG&|zMoT@BjkMh3?a^TWkvN;SuLq_yZh;7o6b#p{p85j>@#a5 zrJ`T#EZY0``j;66FsU3>AQ1{3DARqQO+?x-8*FN?}$T_k2QmtD!A zhi$?>4*$jOp(p(>PGI<59{;ay&6P=o9t;jao!4ao)EF2q9C-IXoxzv&*Nz!AYz!_8 zUQ;u4SlUfyxOY4fxxZiq#|HkS<8F=(o@GuV>vb74L>EJjO-;j^g>yuX zN-UoK?dgjoi%TCTyWSTP=3$X!b<7N7|1NSYJ^EPB#>^RYf2*!tHd=Qz+AgU7$DPZU z_3zhI8yi0@dVh%fl0b!M+vU0{MpaIgt{=BwO>j%JaN9CNxbejuc4>yh_F$*W3~h>*^Eyfo z%_>phRJ?zBYq!tW$~QCKu>Wx~ob@Gj*4ePtoQf=52?c45D_vQxicLtGtjHs#;dj_} zQ+{;B+pZ}`6S=}N50=aeU$Wz!h36cv|EZU=s&8-GwB>|biO_ZiA}-dbe$N?6bQ)+dWWBO#8>JH;T*)O7F$AH1)nZ{%N^zZrdFu&g%=L z*p6E}U7N$*m{^eIx85M*HV3Qclj7T6mB~w9u2vA=+I@Qe-?uDVT({*|DV;hhH*p`o z{tWIYYetFGHS*_7Eqcw`$Lr#5oRKciFtPb9qlodW%NiX55%GmO zm&+E0+SFgOu#%dv_R_AX@|v&D)6Z}Fx3+D`*Tah+hu3VH6*}+#)5_GZUKKyzJ^l0N z%`6e!o@t4UQcoX$-h1ulO~>r?eIjS(xJUZd&bV$>s=xachh^Jqj)^CwBi1!vU*kHV zVS$LG2duzXc=4bxx8@?uAa(~h?vybbuf{!ro z?fS}3Z??Su+?Tq1PI~}Pm}9v?)7PU8=T;rLIDgIjXYvX z+vr`*=lhTUugd?l@|0)Y)7Q)W|Gwq_e`LOHS$s@<^Tp{WEcnEZL|Rv`t)1}ToYFRK zi=P)uHkp0cQMw{O`9i~&SK4;I2OD$hD<&id2r1l%Zuvd!=CZSU7_L6}B{D&iZSkdr zoEm?fI}}tG&ev3__xt1i+h3(8r}mnoPMzVgod+OvBF@3~%V zihA%X!JL_4S;mJsH}7OWv|8U5c207|jm*rc7xu2H&E~DB2vP2kyz^q&rm2UNL@MV^ zie!jqI66g=v9{~Vhq#rv&`2yqIy5V)l` z@%g9E=k?o#^-PPyXJtrzo5$UC#UyyDzfid8`ZMeN6%}}L0+e{)E?YF$Tl?_) zt?XY{hQGA?|7s(b|8x)0{7+NW>c0JZx?AJ+O?HOg)(i^578?>4zS;WCL*mJu*u?L( z{X6D|Rw#M(B%Nsf`Z{=0P2ko9r^Fc=%xG+J_}tZ#{p#(!^R|60$*T4I{z2n`wz=?7%%EgYeoS^ILf%Dpq2dg0+khhH9E5sj<0_9z^>duxHho)Yy3UqYL-bYCp<`OVkp z(h|0;Wy^BYwt(-Pr>4(oX|!TGX?RFw)#uttYyPo5d3XF0PuU9F4~I8jKE`q>|A)ud zk}8E=tCCN<6fxFL>-F%u;{U`y-kwRoeF?ARqi)sqQ+HU}S=iQleRbRY_Y1$r3b%j4 zQQMO$`u|+@zc^k0u}9^PM{Okn3_3w4q}1O`WYK%-^vN_=OLfiupDtgP8AwUZT5w%{ zUS6!M+}DXY%eB`vcogn%ylj~06>`HdK*|5z5#O-MQrrG!T)4bkb%Mz9oYRXQS`_=w z@vgO<`*q?BZ+C~_&4;^hanx0qyq;vx^!r0yAE%uIgN&S0y z|4k)k7N{X;@|Q@M=y(7BtxOI~j)jZ2H*Ra__YT7uj3?T@r43m3Ahg;a=?zo3fNC9#!Iz zoqdOFJSW-AJ#}BZ*HA`%l0>9lAPZB;HU@s5HPQiWoDBR`bvqY)*3a=>(b8T zvY%vmId|^)hCdG;Sly`S$Zn3PcFMk3!|du%9sexpPRb#v_G5`Eb9Gq0c-XeRdE;~a z@9u1-KK7PH(E)!Acpd+LkU3*=Pi`4^fEtTK)Az@g-(qv#-@V>Jw`ijS>=BJD7-46C3c>~0){jx)n`v4bC|eS*!Z%X zv=ZQWz`v`^8UH|(J(#7uC8a%st#%CN5@{j7yCTj$lLk( z*~*Uh7mQvsx>)SKDR{?ot+j7RxV)UH$prIVk=GxvS1WuolrB7%b=WU`Mem+YGheRg zZAEPi>o#S|3TvwJPMR8)6mb1oUfZ9b%D{%E+WA+cdh28*ST2ZItA1QPeVO!KN59o? zH1!TvKVDlob*EmMji$}|*L^Y^Hot1>+8LUadM>wcNw#h|c=ywBe>wYGQ?ypAKl*lT z_T5b4*Bmt67|b6(X*@mESY`TA_fKc{nzbHW$=L8A zc>A18^@s~b%I;B24DwCAda0dLnVWCvW;XOHPdd;tYbu9<+kx_loqwNuoUpgJzyIM< z_YW@jn3ZqZ)fM~y4079cSCwT2`=%_3jujR=x9;cJ;+Fqp*XEBq%)SO}zcT9wPtJ^o zhI!2{UUk1;MJ|6P94nQ_SIF!?)%+N%$Jv`P3pd|RWr?05&=A9CnqD@S@xi3MhsB=n zVf^eTaK-WW6(K2Uo&r~!`?l-d(he9h@Ju`5ecLx%u4MFW?#-s-Sso2+WKd~`dtD#HEbRU)2kRvGJ-gFbYE+l&-+U`@9MiP zTQz41M!O!IuD!hUjNp$8uQLCC_>^R(Xt_k?=#&NpgGmf?T-YavS}kWccMW^zbj~-U zoNL?SmHvmOE@LxgTI$N=rd*OPwbi~gUB%nl`u_d;6%no83|85=%xI^JRLWZpl| zt1HKX`I=xX`&4(+f_8?fiBdam-@bi3-`Cpy9t%T%SkflhBk^aFSEn3|eZ_boVMP~X z{*qHR7jE(1pV4E@{H86iPR(Jtga4J@-7OxSCs)*0-E#K0nmNgt^(0S&2Ls1x%e8V{ zEl+}2uPr-uSl7V$Jlp&WTooA^JKlK<=8Ftxm%LsQ|7eT(o7el?=FRlDsWDf0 z*2PY-3D z8`o290x1G3r&oyVy)@^%^Xdm2OeK4?+8^#>6H{e+a3p_ofXDr3=cH2@Q}(DIKlyR? znq6C1CN)~C9?|bo;ovz}D$x9#cgl67fo{em*1V<%;=P$vi3`y@8zo4_@?7Z zb>b@p8ub_!e7)SvrRcao=h2m=tJJrjS+V;~^weW-uf(pY;z;MRk74SU)h~-SzkYq~ zD$zTP4l4!N48kqB?y;D@TJo#l|ARLRO4l7}P~fas5@o$B+T4;ksp;vbd)BY7GUxvm zO%M6gx&NfBy8JYbS{3GMhJ^O12Vy#7`Ia29X5*da=fAGa_AW<=UsQkVuDkc$lvTrh zcWteDpW!j9lSe{;Nu>K?=jT zIm+x8|MzpQa8B87QRh{Ew$|<6bg+2+<5zR`Jm9ls-Lg1Q=Os*@FWoZjTsXIE(3Dxt;8&U)tUnhPuw6%y_znQjOUm{eEjxv&0?am>Zf*I)l zRupx)ZidAAzRI0e;!i5>-MOjEGE4HRbLhqgt3o}cE>1Ry4xhWP{lvQSr@ofkYckA8 zzVYzz+O?}!U+(_4;5qxIMJ}z1t0w$1Y5L+?uH4Nr+p@pdrDadT%;&-kOH3IAJfqD5 z9UEir-dvd$!rcAr=fSUM*M%}Ee9|n+?8*qF*13)HOwz_zST=7Jj&jxY$j)6lePVJ^E(ZJY2Hiv8Em6Cx}4axO?FRs=^|Pa z+;Dh8=?z0J=Y}W;lNtM$t}e(~6liLdKR0}4!v)VTXTLf(9@l1Q$U3I-N$-g zicVkF#J!5Xy+LuT3-KGqe1gKGy-0f>qy-w|}{D zIc&D=SECg_WB8Ki{R;w1qeqPAjsl3{er#;_l z8L!eV@w&?QOLec!v-|a7+ozjme;htFXy@E3rGT29wu-6mHUCQ{yG-`| zsr|p1O``Y9J;CaCuU{<+^XsnO#iHEAuYVvyi|63olZLF-frsh^7@jVesTiibs4imZs)YcwQ_Cf%3a z@_W|_$vL^|o?MBow^KH09eJPoul-|uSlCnJ&t`$~lE-du-#*PLR46^5$<~a|y>9EH zGiG}lmaAv(`fGLQ=ac`;30;R)#Fhjwsh_vv-Lr$d(VsW2rbpkgbFwo;Y*=yb>4EmI zj{=r%u6zFJ(+1^i&8|E^&U)82p2?yl9Is zcb6B6&k|gAm=C^fApg6Uw8$Z1nX#slfU85s8U zEZgT4kvsRT1p`BwLGN=BgQ=BM)~9`)_;8_n=~_qiOp`GCrGcrn*LGX%UD59*7r!Q} zH*UIZ34=h~-zPO`d*||5zdhCZ?Sy>c(Ty|qKRmlr=#4Dv~CPNQ!0IblkSc z-0tAo9+F{qXhPKllf@iKyK5HAlibd8tt-}dTv z%QwpIR?SIBIL~wP_ub=`-{-Ba_E1#*@$TSX>HRw|Zr^FTfs)Zdg zcpSUXNkW17(&ZyO67!_KQFhgZ&=9Z z5X|<#<@!l>2k!Us!SAwK)#ST&$?llSd2I6A`|84{TM<~%ofJ3Gv2p0Xl`)~7-z z^>c?sPqJpn<*Z6wc}mILS?x(imz~Pf#`A1%9;-DUJ;T6r&y4;3zlYcJ<>mWUoacK} z{{PrqyW?vQN?vEb^3EkmTPM;~9I1)bq@xJ6%2e|)ZJ*^4d@W*4z3GH0(F3%`4CYNoB!q;+i~Ydi`U8wOUm z@k^>K(BXJ=ws7<5|DRr;RzJ+@>dttioT=d8+J`oe|J|)tXJ4#$Z+}SXMa`-2EV_#$ z!&~REGd~a)SsAyk!KZV{VJWSXMLcB*iaQT(eRMV;e};|gm*&;~wl3=LDzEwfuD~Sa zmcyhr*||Jo7VSLzZ)Vi3zVj?dFm3%6hf|C?$FHtbJ*CI{yYSZ&)}=aXi6?GaZCboc z%k073TkD0LQ`t1qrZ7EVV7{>UadY5lwO3oxe)ezO_TlZ1wvQjz-`icxu|RrBq6Ayn z_Wm6Be@QGXLQnQ~hz zitp%PPHU*;@d%Qg^x~-IX^EW)uCJNeG|kvOnkrRKWD0*Nz3Ah5yp%C;7S9Wl-5hTg zpT7QHwrnQ%1&6nX80>Cx8y5UL_IIX!E0^(ZA;H~}{Oxru4N4zn{+xX1>pyw%%|kcm z91C3gA@ahTp!Ex0v(IF&IyHTxg|zDmLED>7L5m6_r0jwU#Ck2*nt$Fr+<#=&>f_CY zZ-ax=44HWL9nLyq_#kTHta&{C&wl+$%UgIarl9fp^c8P(53uA;J8{~tv#Fu!O!d_% z?w#9=P0Nom$mCv|6fmpdqR#&MgWvr6PF(rkc19*=$&1bJ)V{KC@Z7hx%DF0*e~Rz# z90`%KSRJ?4qtCSGJ#Va@`BCfo&b)_n=T`?A2k96w_{z0+A1bnmG*tJl+>_DPr?5iI zob5}Rp{b%)qX@4mh5d3RCCW{G>YYBy@0&p0GJFXU0~k4STS z(N{`AaT^(4rmiTLJh@)I<+}@y zcKvpv2l(bz##<=3Jx2@kL9AuL^AKm6c0z%91JUSZ+IDmSr&w+pXTTx37a zJYUBB$|R*s%`;gVig$W1w0KzZcKV*J4n1?-HNkKDXPexho=IZeYW@dq#-v1U%YSq3 zc52)62fVgl-PP6O>n^U6-oBYlm*>L!!vC=blLE2|XZpOhF=>X(Rr19Tcjk{ZrJ;bm8G*V{7{vq@0Fd?RJL#b+?f{jhHIk6A)bBRvrLt5dKMQ} z_y~S@9>4edw~uQkbiM28J$Dcj-m;;tIUo$_Zf zdoP&xd0lpzNzdzZ0_?}t+ZUHIM#S#gB`N)S=AO9`F$tP2oSVa)8PyKjem7sbZX(lj z|5(T9t=ggCD|&fe<#rl0%qjePaM6Q5|6)TvzYZz6Z!0zFN|u|@_PrO1e3aE*tuEAD zKWPHbf@POdv^O?!yz^-GToUDY*=A};^0dua*&bXroii%Zn5vWxZO9cM#l^ za{gkdzvR!KK^zmOc)s=D8~Ast_nr>ESHhZ!BC|HW{xVHCe7i)4O6}A)3pjY#UpGlB zGiBrz%Z7gcb#m5bPtFrO4#M$MP8^P$%(>&SXoKt3(}IlCruO|_YhqmREoxu*)q@{q zE<8JZR^qdrS&#I7b!(m7*Hr&$-#@5%o{CE5RH}!%q$NuZM#sB|y_x_(l z`pYdhg|$7=>S_=(nYn7`wOJ;1F1Lf1@H>~E&JfASHSe8}5#X;sr{TZ)bjRLJJP9$~ zrO8`kEoZVed1)o?&?|b7;PJ87rFhT#u)VcESpLct#=Dzsk-sP9?wMzPzowf-+_0lBF)A79YjyRjHyj4!2QGZIpSB5Fn-uU(A z-0l4~zg{~o{=Me+OY`~vKh9lzDEgr7B&$*{sq)WU1vM(7Dvk~pH#ARJ?iFBl)Jm{Q z?eM*a*}D#2*Poj=J6t<5@b+z)5Y~OJQjRwtGPk96eSNt1@#E&h4-cN)YkgglcharA zEpo>E3>q^1zhbRJjV3*oSeD83^4R2a%h=EHKXH9)-~BR7IIwT|>~mql%6rY{e`nxL zVEBC0byC}=sB?P_R+|Zby?E7peQj}*^}mm&-Tr?*Z@>S`(H9?5W@I&;ls-9Ya&pkB zi61nV25MaVuBPtF!4zuZwfLsU;~DN6%02-fr_>uXY}`MC`P4dt%;$?1X{^R zuT7`>+Y5mY40FDlVqpYvDh8hUjI&|_r>A#c%6AQS0~&% zu=e+SUj4Jb+GAV!d(QdEY|q-cT=QSYlbM2---@enhdjCTwDIJ`e+}vZvqPIp48@8W zAFH$N;IP>y6OnZ}^Zdb$J6EzC=HhD#?m5P+#T4=-$|6(5uj1B>O}d;u9a2rvoeuqx zY*LqGU9MKDZ@1W=+5CXBY4w%HrQfDKzyI&YdEI#J@Tf5+cn}l2V{U1M0{;>*?c|wy_cF=IPfLS zY*@Cpv}L(trNh?nfOD11YmT|B^O;hg*SMG4Vjf%Fs|;a%EhYA?VwTPm#hM?^S~jyH zb(-6RAmzR)hnUs%1~QXHqzY~s8ZEiE<~F~&zqu4=Kt;J}{5DhB9tFdh!Zqi8K78Ll znep7V;P8n%4#ecnv%BkK5_PufC{v;7eE-(O!tdNz$zv=eF-{DKMb9|&V zC%rE*o0Y_DYJIArplC-z;)d(*4u6fknY3!cgphcaAB~p6Omgd^9=OW2@ULh|suI@! zknMch_t24}ISv}v(`QKtwhI3A@yrdfGf8j%D>l*oT9nw;Jv`CL`}Sr&Ulo-#`R>b~ zFM}os?_Qy6IbW~*xd_Mo{~wfF4@9P~vlP==@V(4`e%T5s3wutcnGsT+pX%*vyS1I3 z3UVYeAKU-wLEw#w`D=Yu7ljtcty$9MAmw&RDj=;Yvr!=AoJaOH4rZRS8vPtDM;=_; z_h#Rxe}Cju6n^_Zi@UPvr$w2|(XKxi3)uc=_x-gJ;1X;c1yQUY0T~JXt{p*Tg_!l`^6?7?v`(vy2z5NBX`>Q^MN{H z^L`oe=s9q#pI(2v?!!X)SV4K46H?PYJvf+q>lR<6-Q%wpwk0LDUUHq+n^P-37n?eD@JjbeQ zW@|GQ)9=Xt)Vz0J^~8g3EWufAhA&!pmK?rUA6;1!)iZO}iZj)#Gplzt3wjjP-MZ;p zrFUb#?5fG`OjTvu?s@Jw1(Mfpl&UL{A){NIP>~veNyuE2BXyYEQzuZl7RrsX$eys_Hepe!% z>i+nZbM0wXr*_UI=C`~GmxZ>pFzscqeE2cHBEfRK$>MFgyzEIcZ>8+M`R19ZtWiT# zyzwpBVCkZJX}f-3_DkQb(pVV5zGvH;085iducYc(Av0Z7Gg|-uo__qUdSa3Bj#~`X zd(+}`ZFc$2_UZCiAZV~anVOLA8GAnuP{J5x_i`9Znz2tGsYv0x1#OfMEF5c8#zH!b1KcDFwOve>M&cw|> zVZ1)N?DEh4df$M$H`%U>Z!f(%b2g`=*Q5_0mELnqUO8vQXWJ^(P>xmphpOyU?j2mM z&MMI4B>iB^U)}ervDfag{nB31@E}^_r*HDVlGXZbz7wU&67Qxk%~+sT=XdViuGE(o z|3#nr^}jDx#m??(qp|U%B|rEUQQXwg(wL>QX$Pb}l$oFd;ZGQy16uK!^*Y3 zs{*3ta79j*5P!Lz(L~s&WQ)Arg1RG34`zBzn)>!`NFPU6he_ww+GVpc8diTAXC&ps&U15>Xm@UF9Hg=~RU+4GA!mRSbO{>T?Pc^oLsjV;DJyqtG zjC*GX@5CE?(H`Ag4OuD1msd~Q{kBHy$vp1Gm)h6**oGw7`K*1j$aaCs#Jf5o+iSdc zdbSH_^xE{DKK^Vidqtjt)wDgajbX8^I!0O_PKOj$YuvMWyXxU_&&|3^y$+Rr7uz5q zvaDSVCthav+>yetL}~r4jla@eJzRg>^@-KLB*l61(rb}v zOTIdV`*_CBFqk(-LyPNp-qI~yCe9yKpFZO7_|5z8<74f>+=)N-PjvaRQuoJikHlJ) zdDjwF-Ia_y;Bg@F&H|56g@{?{7F8OB3-Vm9I7tOwQgKMM>oyU&{O@_4`K&X&r#$sN z^#rc0+!N(@b<5Td%-z11b-vkqxpmfAEiLm`JyO)B-XFxp%^0`vt-1D#-J*8|pBXqx z*F;^@w4cRyv1W(3jKZPc)e5oy{jYxgzb#iiGB7uG`jit!22qPG7j*BAeQ=~LDYH(~ z`Q)?{o4ORAdIdJfvOi!9E55dNB5P3X%H6+~Mkq{Z+`9e5{+jo^FHM%upLHzki{!cV zXJ^mMUas4)!D%JeF$LQhOdED=-o2gMKd@L^+xp4Ww{QRYf8Ol$yKa~MlmBe&dXb-0 zgbU6)IIf-b_UzZ&@%QiM_}WJG{wZ@j zpKeCulr51(%eYqGVtQy3W;M01XSt@30>=^OH6_!}Wj#w@vi?+lM{WX#O>VmP+m35% zR%uVVxNM7tnbTw)R>hx5Oz#9A8Q#Ail>O|1)Ut>$>g5835W{V9H(*rioJiTJ!G1FC1Jk0)$lcjI6 zUVF3dvZ?N+=pLV@#VH&zUDfJ8Uf!G(eRSH?w|-@A?+!8bRRpDkPi@MPh+J_j?e^u_ zx3iVvm;JshTElp}{`b4GJKBft`fbd)>GJIO&2=)nIsBhhWk1UnUcP+w?8Dvt`ucwV zc3#`J_Qe0*XZ8R8{m%byvahmPL@lY-?sa%k?5&uNsBdB0ulto5onI8;tn+A>(P4(I zj7OM?8JM=+6FeIo!%((utIUb8YmGalEgzcg=-xip_1CT^e-E}UZsODDG=CUxP1MW!{+wapZq_T_r3ep1>gN1A(yfO3f;@Lp1U{q zYeM;5yV~#9JfDAd`TRkeV~@k8!->xiGR?J|#2Cz>wQsFVP3Zm%rpT^mp{23&C$UGZ z;>+GtncHwkc{1aFF;3Za>9==ySa@1uLxmZ{!1*1pbh>L}d3cUFPe zS>A33E@A&H`%WM4>mCzU{keJSQP`iub=+yz<~oxl7Bl zANB6M(i)Msa81x1bI8zIG^pIejCmOUTbW(YWKg_w{yX@q$LFw%nwrq zc$MB6skg|81#O8pG}O8IA*8tXl$7_Jre({Uyz^Z5UR{~I{MGyaKi*z;$-esJ|1poh zZsup7>%Cfc^e&Sh|N6;gs|_?IK3z@NWHDESBi1oYh+$K0=)Ua@Oxz59kCQJjeSQ5u zl0i=)tE#~(&2Z|&hgP1*%?Rq38N6m!{^nzmhsKVZ*}$@PBSx4q}|c?;D_lXWNm z_X=$P_w%AC^BzgxZ5pfJi!DFLvOlEg7U^X=QFSKUWT<}NMi^W1(Z zq$0yq>Gmb@BRtWocqw!bK52{&ZZNmXK^u2yMOCj!HN0v zXI^}LbCueEbGv+z^Yhv z664~_^R=@h6s|7ryc4?dfc(M<^Uq9PkjhoR-poPq^KB({!sB@+di zk9e}3(EFr3{iSW+hS#3qxopd3oV?_srYPH|lv1E_I)m@<#fJ`=^JKo42N|*EEj%L{ zGVdQxgs|zM%|C8m>$eYk^51QeobC0l)k#(^t#@B4tbBP|_tLAkr<8k671^-4W&XII z@{(0!&y}-<`%liDdvO9+VQ|9s%KGEg6Ipd~!{qmElb2vHRo-ovV;Ig>ao_oYgt$gJ zE5k3b=>=P#UfaU+XTtlaJJ-JcsX7v9YIZ}X!8M`N!&!lsY3;jJGmh@stbO|5$rZ(g z|B}}G7v;J8PWFxWy|(hcbK>lG^@7UFu08pG%;bjst>dLn7CS^dl<+wD=i1x#`QkE0 zPtM#IYG5o3GiEsGqO(AP^W}=91_j0Y#~uDUix^eG+|ajuqqI zyBY64-t0a+`QOQp_X>{(`2Tun<@48K)3TQrH{YzUjh_5pI{44y@M&LdIi07ZXc_S_ zJJ*(e$h){XsQV0~yNF!HqR#2-uD>o)2+kI1OXZA6XFZv*A@Ifng~S;<3w|H$-eDn@ z^XT)sV*WX-vnTjPZrWJntkJVO`J2u9_qPuun0H@w(P1drSR^3wVfPu<_wk!*-fp}d z()E5~nbPkYJFWIx=mnPXv8T_Uvwz8!1NWY$#!Jecb9O%a_r{iG`Foyj@0SaG^4~4% z?R#dHP4l)*ci6PTBjDvXcF#Neq}_K(Z9 zz*#GEL*5lpnYd1-z2*l#9b~X;WpI&St``~EzWLI|^vBk7{@<;Y-fs}MU=w43n?!>A z2GQz8_L0&KRvxzB z8NUp)`u;DkX9_R3%jTVHnz7mRW#x%`PoMpHJw0`&wAS(T z^ywkj6`23MSz>AbM&Zx1XRp)u?cXxLYT|_d(vF2&>ZeNC*UU7O+Q`e!k(Yh)oy$eR zkgY4aCzvF@pULx}(1tqZvT>6=@sHzI_EpviVzpc11Sgf zR$lXa{aJj)7VVP{n~!qMkU085^U_C&2h11dRYwR1uWnJd-@)8c8MZ@GgF!WGl{a&k z`$nt%e{NrwzIJ!_>EoMLZguDE-CVc1-lB=MV5R!r{Q7Tuo;&?p&iG|@+pp8pgTpPt zl?vEii1Apn9h&0zbiVHV3~`Oc1&dYxC_hn^Xj$|6rhS8^Z>?6YWTc$)wG`|AR~}m# z6M{Y;WC-bY*|S81zdDI!!<&EG@+BEGwzcvzIy7zio|gUEWro?xz-3#s>9{kO-Y&7>jj;@3+BC4YXLpI&t3JESrHHJ_3YpIPZOtprPqz*}jY^JVuwY2qf120k zSj*ABwY#}px?%fuFh zfBQ7Y$w)kXe$2ZgOrBvC{#zfs0wq3!?-%P9|9LKKb6aaiSZSyHObx{~cVfMG58h)b zIy0rTYK`w?9U0Tj_I0ik_Pk|3$sF&bC#2u_*^W!dn=5wq-OnpObT66OR#dTdM=Hyn z-0d2Z+zU<|WoJ2bdFC`G^NlB+g_w}1aS|NPWV z!H@Vj7+?SS6QuKDQS+CpB3#KImVEr&@84T`K)d12$4pDr&s(-nQ8E%r$=l>E`yzDa zeW5NfnLP#*?YcC-KXnakFaP-Pp3BZfDy`>Bj@X~u#UJRfXn};o;r?qpZh^m@tJ0af zCOyu-AJ{+lu5zTsObectIn9$+3s-#6*ygJ;|4Q+38zBrhGoiL_u4^AA9p{&Iy4N^Q!lA}tb=9Fp zk4=pCe4^&OirrsbUSM9PA=D+`9Dia(cd#9Qg8QoEXBmNs)d5SNTq)%6Se3TJ{m_g_ zky|!8OW5$V%a(p&Qm=R9k`p|5I{Z0vsqL+T6;V&-uUh}#%J`JqjMwh&2g~n2O=7sc zPWQk!5x@1jr`?`BPnG+m>i>P$W7j6>{T11=L(NZf@A9zo=gW>e*EY>q>zQA8t?Gc& zlakJ+dC`+2T7wR}Vo=S?ZryTT?>X<%E7Jm7E-P#~#47g2n~85tsK~NA&Cy=L4fESN zr#c95+&PgFD^TyEa4GhZe%#-;tP2{9?pRkJ^$pE>6!(Tv@a@}6HcO1o&OTrF6MJqI3e=tj39z8`gW&P=!mzcN@D9rs7 zeZ_c-iT%2J*Cu**u4rlClF?z7EIa*S<=UKzPd{=*%G|vEzxl(Y_u=aNegB?ZJ^JzF z$A@xwuiJv?2|ufW3l4iW2Yw(Iu|DWf90kj zv}xseqmzlhrStZbR^1a({d%G_Pb^mWUF^on*Yh~E%eSv^UF@+sjo}K*J+BQZ;;Av5 z9dr9EnbUtr%n!;gWz={R?CGHzn5`w{w#e~hq0weu=DJB)gBA6FHgcQI+pm)lpr;I7!l$Zh|VU-hruIdxJ9v-!eRn+4g#MP&}Tt_WKC zZpQM+n=c+k=(6utOBMXKgX`zj@aa=nWm{Wit9N~0@%_!qFGnQqn|ajve^&Rumm&DI zGgYT^SJz&56=ezU^SYa_PfE3z{G;u3!j7-&s&w8~Z~LoV>Zx!fu{dPc+TXu(*92Oe z{khm#$HPJ8X|tE!CZ#{ZGLw$KDBjaD$!uBc%1ssZ`c|j6Udfx?+M&Cc@zuIQn-lB2 zZc3)^SZZ9vp%ECqa+;#@57$lBIc*(3{%$^gmF+{aOY`Kj9)?{UhEgBaiQE7EwEWRB z#V6(4F89wnW~(-{EAVjCazC7_Xmt zyN!+c)!6snTVTbd^~fXiu0L-cPvqWjhdOP8T;^)63pAYDC~&l;qQU3O>fL9G8pJqP zuaA56;qz*@L!P-RZ+Icz>67QpOMjvj!EliV z^z>c0LTAE?7|AtPKDo4HoZYw6yQ1|-u&Z-i=kMxQ=fi~F=xX)#OVhXhUFU)fN znKsYOHn@A2%>Ct8zF%rI3(YUxwbo7ZkDYAU*EJy`^2;ygxT$nVXmBr)nbcLIw`t}v zy$zvX8(ZWR%NGbtd}caPHB~fG&bdT2r6RyI^MThEhV$pI+q&NH7vKJV-EHr)E-m-` zW~c>S+M!{vOu=!c*qxk`AhwwYZDU+K;sPG}`5b=sez(8w+gCp?Wpn(rz4TST;et(( zdCJM^Q*~C0D$Gy0A5VPaV`4i?C-BV#-7MCbMrWoQ-!2O{a_3&}ZlO6#?puc#@xF{) zu3&I(k7_~h$)~p`F+T3x)?CuOdhO~(YC?fgf>+rUIZj`!Ivm+yP-(hWMK*}1prC+( z`vODx`#RejzoOoR6de)$*s}Px;O*br=C3m@z32JyV8!#0kJ^{AF1h@4uWv{adufoz z@$;|drfEL%Ev5w5#uCb?8rE0RXG>!j*sk4sy1C5qpsqBA)5ucVtOUVjRl{!S9+0mXUd;YE0q><@a%ZNnU8q=Cu3pA8D_? z9FyP+?oQL~xFlzk2ukAI$G zbq(k@oo-~~t@BOrOiR}P*m6bI|8uTxX=2#FzrXI^>;7pMDjTYDUs*Vbrmji59uTmEL{ zzkmBKZ|U}Fq6z-#2Ue|d6Q26%1_yJ7i1{M!#;x3!+U+v#@M}g*4ikuI#6e$RKQe8awy&rgyT%}lmhdhW~DYnRi{|4Y$5a;j<3g9=lb zg@wrsb6G0dUbs0Q6cc#(s=YL{>Vt;I3zijyTu-7toL;ZNc6!y0Qn}Qx`x-qgyh|!| zr>^%~7cD8!^kGQ~gGp}px`(eL*K7(p>auhL^EDky2a)>JsogAb%a6`ZFgXAG!2L7x z<@@`&-#JzXL^Z2Q1usf{{#E0VRE~n4^F%?TorhL5U2~}1Q5hTlGEhCGVSDuLJ-lCT zZhrgwxAfIBGQsmM9ZR~T(ImXZGM?FPeri--zh-2`2PN)FPQh2@-tMXJd-(tTfyDty z=`D7Tm4ej$VtzO(PZnQU>-x+Al-s9UBoe@SKMR0?u1-_9tbR&_-u@y>%E9Dn^*Jbdxga;_tH z57S(~27?3q_BMy-P1(AhiIL%s&l;Dlh7UZ~l+4`pX2m4CWzVZWH2v{9Xny8<-z3pl z=Y<1#i|#%6Fu%pbuXf)f-IbfnY<`AhT{LvBUuQEf*e@=B;UQL!uOFmdPRM2HkWK0j zh>S_yVY1PUIdbz3rbqv{nH!e*9XCwx_FS`L$}5KS?%fI9ezR0l=Iq@3V3E7pck5l= zKj&YK6MdVrar@S@+<`BDZl9mC_g&@0==s+#CiAQ8Ty@tg48-A2+3bIs1ZI@%=PbL?1{j<5K~l+RDLUD>9vinT;JKx>iwwTQfXdDEnH zSNNXo;>rKx6&QHbV)0eE#~WLZ$jw(*UHzia{_72U5wrh%ySr6ir(Kd++j~zXH8rx{p>Niw0LH>4 z?C0mW|6)E~$xzyOsPEsO-Sg`;TMqt?$Sy2)Hg$EHw=rYgG0DQS1=nQHOUcfy*>&v4 zB%^Jd%$2cTSHn*)o;+FEsxL(Myj09K?n#s8mTy>Dm*rofAD|?Z@Q$-l*I~bt`?Ae` zviV+Y5?{XG`{br=u;SpwB)>j~?t3$ZdQYA_!?z^sn#(Cx+vNI$;L%o=7tb2`fpY?!tE-y=gwhpG>k_rI-Q75ImH4{O?tj1AmR z_D67JaNlxzQu=G+RxaY2;pBHY%e?J# zM~>DrL!^9LyRwYz2%YdIxn_~=WnQDb*C)nT|d#&u}Tt+ z#~10!ZJfF0N~$E=3z;c`Jko1DUcGUal(k;CK{&thUijR14WaVaHlMr2nKk*Ok1G56 z&wY#A`x6-dZVdlW&voVf|NNNWdKpp^Syw4-X3S2Kow1{}p*w$>BS&@XrAw5ytcgMseuMdj@I&9y@Eg0?S5MZPTrXN=a2F)WzQ1#6%WgrUmR*q6{=QP zR(bhc)Vw^0z3k`tC9^gcb?=rko&a-2^^F-^frsCQK`HfjwXL2;G6E<3?I((B|u=)&NtJlM;9Y)F8 z?LUpQn#45>ZwQ`q;$C{x!E<@6hx4aIcuCRqvB|zVWleElW8OyZ5E} za{qqqUtD#TMaU@7bQ9B+yPB%ca?3@yncNODpUwHmpzu-D<9?vf9SfCu2T5@jDUH8k zzxj0+#wgr)+##fF_kZU$PHzEr-zEJ4jtS>hJga8bX!*LT`CMKdd)%f8!lyST`=9uC zd;14YC5NOWL2rhqN8Hv%p!bBYTa;{wNCbw^HnoTbFr??Op;ljs`uKNz2{9i zGey_<%GJY@Q?(cUG7~(_Rna|rve)!{vGl)(uD!Sam;3%rV6Gi|_IZYm?td%Tc0`IB z$G3!r)Gt@-)ybU zlw5xKYg6BBDeu4U+}0n~4u7%FVRJ`Py}{2C>rKgX=CpjY)HrxacBhr?i&F0WwSV^P z{+}Ga{%rV8))`0Tj%C(=S5^8XC%y3Y%kaHxJpEnnHToE=+l&Gv&=c>ZBU6TcP)k$--?cH&G8`>wpKheNyz4!lTKi=pqwqm77w5CC@$FwPq-$mCKR-auxN9)CE=Y!p^ zqXfmS=IlMEG1D`|qH4+kE%TiQJDT?~Nfego=sY;^x}xUY^J&kf9KUFprP!3b|4B;B zkpk_WuLnc;cz4BmbVN4Ic5Nu;evhFnp`@rhm z{am9p7c?36GVx7JYGPH`rT_BDW#PQWMLs(Z+ZlY%IJ3M-uj5rvi;nKfx+CvaScM9t zJU7Z?XLDC(3*WwS!h$6M=OQdz+NVk0WXNWWtFz{M!*PSjmgC%)UCdhQm9-MG3agxt z->~O=!#g!viN!C zypcXOq2W`acBka8qhGJ29Gd)Gbm`j=KaH`m;b(f8hvw3a8O{o!Au92@QneJ#LGX1F&#Ktz`vrQ#crjSOgEg>jUrzz>gCJdpF4M+-|pX!s=IS8ct@>G|7w_1zp#G4e`h%BVUDghr6Z_&GXt`$@>-m1U z+w3#x@VAE#3rsdL=($T9+1lCLua~Qye!TVZ?CQJv^IulU*WA4Owp~}PYD3SY$xMuE zL#nGEu{b0ZWoOrKcly|%`@qRZQ_)@>#AMV&{@d(;@Oi0K7lstf4x<%?vnczw_ZKip?T2` z?#R^*sVS8ryf#g$CC6Uao$lHyb?N<(5z@8yGB)s87kZzuR<1;~c|JhpKS35|J%Z{fEMN7O!-Um0&vm z=b!rF)r)VReeJCAmgy?fv!#pE8(y{QEO~9IxQj!VOGnqhdeXIuGY29L@;FAG4B8Ok z{jC0XOQ1{OeBK8p7rz|kbo$K}A=e-^Ge(Sc%8!(lI;O{;WO^^2nd%UAb7J55m0xaE z&RNFlZ}rdMZQY%}6}Mi8#=ZY)Ty4rCecV(gvS`UytI}(th3wk`3jgo?`y@BjDxgL| z*QaL|Yul28JP8huSkf~>)9o$UI2%r>R{b-R+T-fAgjp|H8HU~Pd zE?eE`8p(F-oK9Ey@hJknYAMs>TYoF1-&*~uYE`p-P?+HarnKdD!qw3;!}?jjg?#oj zOg$sg`CQlZlkDBfnw=IF$-MCy9dGtnzJB+2TluZGd2il+E#2*Se5=RSMt$cSnTks< z+lD;CYBwl@s2*bu+%L45YsfP(~-*CmaRW{H}H!` zYLV_!v0Q^hfr=BthDk>stEz=?MwYBoYd;-&mZj%m;~qN&?u5H?mP=&cpS@{)?{>_> z_~pBzWY+Cy7QOJ)@zBfC_`Qct?fZRW|Hn7y)py70tO;GXHtp6Ewq6J3_&4_3+!yOO zth(T^{mr*3juo~+@?4dBDkZd|H^xYQ_J1>xald`=nTN~IdcNT`xVKSK@>F`{->epE zZ3Fd9JTs##7mG`A9`%*J`E7;cR7O=vSBA(1TMzzTKIcGIf9&=hd!nvtBx&_8HUF;h zXYTsdtw$a9-I-_~5cTJstWLnowWS7c)E;ww3Ac59RnGSM`uE1|xA*V=`$qo4?02D; zb*@F_hAXf4J;-*pV1n1awdap921I`7(R1ir#mF1d6q#Jn!ONrOwAA5u#|EA|PIJ7{ zUS58?L5x!?%HCf*`NiwV7GEZwbxV}P^raIb8#2#NmY!#& z;LsC$b!oc39;yCh<&ioT{*mA#jn@_l!0r1^2>Q=MudA20BJ z-gWn2(*J+|*iNsrKlp~#>Ac9_m(wmkyqt8(f?@7K!4ry(yw^TwpIzT?cQ;PQ{mV5| zjSW-PrwI1!uwKP^((|HhOI>$b!ou5sekI*p5xBQ^ropp?Hd2q4o;mYuZ?eE91%bJR zjuK7lq#)}re~rO8c7e++EN&IzuaFi<#FB9)6>1Se|RUG zT7LZa@enEfbIa#)ZL{~-XEwWE>dV=+Ej({Zm#^Hj@%GzbzfJ9P&jtG*oN}(@;{@Z& z{mTE?+*&xq9j-1qWzQn^Qi-*xN}%KJ(My|JzI@QmFgt0Ta^v9h<+~z}yFIeJF|R4P z`=r)u6XQo>vxM#_ZEI2BIih^X;^fkf6A{S^0wUhtm(lM(@mtLG^*rg_CDG|iyANB1 z^6;0YFSlB19%o@)asBoE8jCjGdkOK+*`5j41uagv@Iba{p?>)i4Zp}YJ5Rl3)Hu+R zm=ZPZcHZhfzFYh<7c~B_`H_8+nc?55a;7W`L)KT4TVjtn-Ex0$yLbXep3CHNXMc_M zBdaP`&os1R*fFog^RH#5*oM>(sXC`t9a89c$@YZpfuez{YWm%mCkk^*N_7wM@7mt5 zQ?=1djl0J%r&i9%Ej`d7w8r7ygR>u>K2^=%zR>%D=FGr#&6?)3W&}<+S(LC_?9!&1 z&m{uR9O{=&yzR+V@16Nrf#goaB1O|13#>@ z0-xw_I~dROMoeFkYs6kM;A|Vt?=US3olm+3wtg7DHt|I zbz)+OV~%%_!y}dihSixS0?(M%xwx*&Yw%&{Wr=Wd(L&FU5~mmxG-JLq zxf~Kb?Rqn)Dk}U4p+xOkL#6~X=iQZun8Mat|2Xrm#QFUE-~-QO z)`)lqItJ$6)SbG*{lcfzXa)zRsl6GWZ!0e7cVpPJYSqDaf;XdV@SB7warNJ zP1%tszKGM2Sv@EG-R54c|Myd^>t29BrHZ)C&x4nXK3|W|*S$B-n6uASc+L}7>jdrU zkaH^pS#!^rtoX_~V^Y?sCqn$MT<<%o&-XL(VR*5%_FIG8R;7^hJJ|jvbM-&IRJC)? zxhzkC*NMwpOm|2#-^met@}&7(#N>kkGI@!I8^-j!H*|jPo8#tb0%%wx$l)1a;*2h z^5r?u&3q;BM37y=}JN+#qc$JoV#d_*Kx7+vd`zcKg$>&EacF6_Jx%7qO!v=vB z3mn_;HBZ(qd7{)_m1l0cIC#aYCz&aX$3zn%8g6ke^RyK&>#bTEdfa!zMXmK8X@cbTp(E&0Tw zd@6t6-*2=3TfRIlwY6_otbb_El~&_#U*_In@Fhl8LtKRG&08L~A?M zedwK2{I>1?^}_U}e|e|&2LOTIq%zKvwP2xe^auJiY&XEI&UOC zR(Yi_8F-aXC-#l}R!we?2^U`^9$X~F^}s@KOH`hAsQlS!hrgcb$+f<)lI!sDk{8u? z?W;~{rZ%c4F8y#{*>uP0y}v%Z6H9x!rr^v|dG){ln!H{F`ug8_sgtoS^&~Ir&dNVm z?=NuscK3f>>76fAv&*Hg>q%x9aV$a*s8vhNPD^|PGLT`8mW-6v%y&5(v|72g)NlAYzh>J3akdv1B`t2}ZJ$2-ujp14Ddp2lv$ONf zSluSwY*=_y)3NFhhtCVk{7Y-B+t^)F^cL(hyt$dBuyos8e`j0o)U9T5yx+r<&vey^ zxIX`qD8O;|kpBNw_v(KvxRdke{=K{})r)23tzOn_Gr^xNUG?&I+o`MkV;(M6`uFPQ zy+g)@jM86j+of4f*<)?}ZbIZ$QKi$9QboH9f4*jj(UtM{PFgF*w0Cm8Pt7)mx`koI zu2~E8w}%%rJr#+|f3hfWl4t3cB9DFpiT7>!Rco#IcoV92?_A}p+Zl2`%&|*dCBb0w zp{qB)UfuH~s!U4b>eqt(DpuRM`)fWwx35!D7OT^kQ6G@wZND%3&#cuCWfxjz7#=A* z7xjF#;Camp=?Anl4;#PPxbW}m>1P-gCT{IEe78%>vbf=dgq@a}?fiVh2zid9lHYlE za!%c4ob}yQRHVV0@7(#ofWQ^=CHcRd*IRdjY5M1fQZ;I`@)o}7I(g)-rq6~sMki`Y zZSKYgPPi7(P@<6S+}d|OakX@b(~J#X4sRejpLg3N>)Dnx6tZ7Be>Gv^r_}zgISZyywW$0wPM8Z4H1Y5LaM z8x?XkeL9lr(fGUcr(8_volYtO<-oOjY+o zBvxKI^eN8e{H?jq3JL{0F8-9;5t46kjjxPx`KrL*D|-FeZVSpwKP;*H`+WK7Qq_%> zr)2|NLMFWs*?xIhQN?WwAFl89|6_OSi~e~qQ9QlqR@0xt#XA$aE)=O5-`S@sURxOT zszV{OaZ4d{RQqxE$!7!#-%FnmYq@tUXLakYO@cR_u55_bF#M3;VV!(u+UqB04Naq( zUpkniY*SkNJ|d!5R;F?7IsWr{Wnu?R)m*^Gcho=End1`TXm$*A-KjAlIO_xFqYmdZH&@~l_tf~v|3 zu5G-Voe;a?kpq`f7-L?Nb+3@Zgq*W>W{wrs*M25RZSZ{@YunN#aJ%isk~F=B;0=lC zbuF1j{Vhs{XXZ%vxhYPq%u@<}&UI;{+||3Y7KEm=xxeQVQkY_^!MpDKI=jD>wL6P+ zY8qx!>tf1eaSbk6$wqxdWT$La6t8LGq=F?g_^STOx28@s`cPA&1~ z4c2}!9O7_Q+mTHilCwwG(^;oGmI9RpV!`1x9%y=MAqcvfPTr7nu0-J!#yx>f@)cpPwIhpL0rL^$7+}W;HE= zXB;nd9e)T;uhrE{c+~BnX{6K;xi#(N+N4=M=IPnyd0Qp^MO-h>op|J(&%p)0Y&YTz zm>&pq?AVslvPi)8yUi<}kjYks`%bVXl=MhGpCITu^|;){RSl|0!KB)dwu=QOL8Y-l{}p|e{e)atIE z$6ekp>96$t=Gj`W+^%$Z$@X^J>QyIPPra*Sd!;%>X&1lal1)9{rE10Oufm(TZg&YT z@Afo^IyYTp)`y=vCzRSrFAY!SDGejA7r?mzB=&C@4b$p?rk0KKK+?{`ALX)cx!$4vs{Cj z|36nx6l6#gS?Kg}m%rbECw2!mx_2H}7x;oxbgvEnUvDr@ zdg<%Ta_VC8&C{pOio_)HeBr9?aaoY%xaQ@}Co57*zBx|SPIk=NZpUh3zOU8kZ@!UG_HQea6%_2dEL}AR#zn-OR*pSBy;5Re7nCt zGk3=a=B~e1sB3?5t&Z+K+v&BZudi;scm5s!p@$1gJU+4~h%J+vRbdu>WR>J9rUc~> ztDV0RV!75btbShh`RM2C>g-1y793bv6{2%QAoR+Emqtq%XFO1Ay->FJ?Q>;$vu}wt z5h4ms>RR%;I@?WVG-|MZ-ys)0)#<@kVb*=!PZe~ICs;PcYR}?1v9EbUl-CW}fcmp6 z4x#sx?ZxgeZn}JV%Bh5UKmUD4uV4LYD)}JmvZ>9gJ6mV;@q`w4^FL)j_;RJb$QtKZ zU7KB#|KHQlQk0f@C2@25NzMRKogHU3ZCZ5yu8-!cBW=nl-FwCL`%i5D04ZbMBX{3vyPXj! z@XDDgwU+e;_XT@b>$dL=T1=~YmfN;Y40!j#Ebwp2ybHx^Qm(|tIaECS^=p=7gID80 zjYYe7yC$x>9%V9HKB|1NdSJ+ey}N5R+Wh?SG1u_u!BuC{u2@{QJUUk;BSTYa+DX<& zA@9ykk2-KN&A+>=^jGjUt2bFz_wy?y3%H~#7N2CWYYTC6Id|6d)k+?%N`uRa3mHNW zn61uc6Eo0pGuWm*DapW)k@I-j;o_)(3*5@5ug;hgG==}^2j)ZXiZ;L5@$77g>Hqqq zmA7_GN||`+?*0?0>K|P73O3pY>nMs?SZ~@?w)tc9|Ch?5hq&f_|55YtLm@4#4O&Yd-mD3|+H$wVRDJn`70D7lcW3m^eV4|~J%RfG`vi8UgKs3)ngl)l zwDx{o?eU*MpPp>_z;dhR>F4!tk6XmbY^^`AyZf%;)}0qtJ9}QxPg|9D@?@4=5%T1q6$+i3{v`o9}zCh1IQ{RrDQ{ccGLE=T~?m! z99jCHY(Zy&ScciFv#j!g>N4H43%hn7Ud1%ci*1Kv)$`Y-e$N(gz6jWK?o)NgMURa} zcQhN0zxjFco?yuK*|lz5`HXGT6VG(M*ui{0i8Z!BB9(iqS;*UI4U3Fb?BlnlB~Ef> zU=ZK9VZ)x54Hr)Q3A*YmFz3~;BIC&`KJkYa|M>TH+NPInTBn|Fxg8t&_==IzyT@zY z{%`!3{79Yk?ylQf`>TF^Z7zQCf7=PpoYOB2GyH{_%@$7FwNr$fediwX~7eCKG&0Q7oV!^Eg)4DgG zt4O)IGb?%jiLc(v~Ik%6S=iZv!Y_wI&j+?0`cb=hRn2AHK2LA`w zf|)WKR$o`<3FX&l{9$PRQarcdjd9)8IWcSx)OO!pe#e;cLh$MyP5vIkgu}L4^Mg-s z?p0hIerx}ZT`~R6$NzW-c^k@Zx4sj{H^-v&248FA>&<`pvV+_g$CYm`)a80q_v_!| z^HuG!T&-KHIjYUg9zx3o<=%__?+GxFlrRjcd%e*0VfGoWftB#XFX|VbgmeeB^_A67Cq%YW>lRkxQLrKd@vB^$L z*lJsBuY_%$bMmkF@#-_I35-SuHb1tSuBWhF)%dU6oIGmDXuQ*rCdcd@2RjXIfYOA&T zUiI-Xs_eV5_MnmS{TH|6#H6o8wC|N(!g5u3;mW9ecjkSVXmhigvqX5drR<(1Zb|uv zwn|q|n01sjVb2do!n|}weX*f;oe{0I)G^2_|;^WGbJ}>!8w>!5#$g$<#s(*FK z3)U%Zx4T8J<``YRqZPQ_%U#<$`fr>2%Fx-NJ??8CT|Spd|;G3EMgr~fYMVTucoi0^o^Rn7NQ%Su-93mTKJHA{WF zdLvKXW1;WT)qR zKfJl@@sWLDQRUe=jj@ZoPHkWL$*4Nn>K6aoHwzbtRIFa`w`BX*kB@gppJ=dIF>8s1 z@5u*NCVW#*`GhFdHAOAZeZ6>=O2{#%`bB+O3lFhH7&IhSMid3JZpeJsQ1w`n`Q(Z^ zmP5C0n47q#w@YQs+EHf{#n4=F!TnKdqQw7P?pK$)e+4EVgf->YB5^Tue5DWQY8$;;OoL zk@s&+n(UW0uPbJc`1iQ$`L*-SrDkaD^$UCZA+>!DM~XEg!e7h)$;WbHo)o;fCS*5O8PRH5vn(-R`+U$|<~bZFO=d0Q9`GAK@Z zV6okC?diouIUg%eHE7*+?Z3B7<*0A#rG>8>UvfL@`hMU$edfjjlOlVGuX}d%{Nxj; z`V#yq?A~m{4|x=Q}qLd6{R!>G3|ltW3so*YWjG}%xzOyyw=$J(t;s9G*#4JmHLr_#DO;b) zbN=`3ttW_eP=a)&W%gk3jhB~kqEn` zC)%g2^>(h4+Vpq&8=ojRCmSusGD4DFId+FlMsCm7be4Gm{RyAgqUU+f#Q(D?Y&dTCB;Y?py z=Kfq4b3fNw?ppc5O19i@Q%%aGj2@`C+Uv9)&|T-y-ql~Wd*AkdpA!DRU47Rol<$SL zLyD|Cdx*fQg$zulMvJ6G_g!vmQk`=?==6<RT3l7QXvvqQACJH64Kj>AQl+$Y^TDrI&#*ts zzf>;d}aSG)hGM`wrOiFDOadTUe~y? zTszgvgKwk7w+C;vISiWETYL;c478Y+-J7rLcWu>Q9lt*}H6j?_vpB@$JYzhv=BCx( z;s&Wek!3EWeP z#g%=xx9xnMaI#|Ox3f(dUrKuH%%W$^(MK zf=76X_XAhu=q8`-(QBXi&1Mo(Ikm)ShF*~R;$Iqk8W&fFrJoVwacS!1JX3nO$Z(S2 z1NX#}H*%-XJ;v$wB{O#p$3KD4V~v59ecIC}-DqgrAoBB)&Y~^nb@dq6EO7Za!QA!R z_xtVmGZbY<90jO}@of=9u$aL$O@Y?Jx?ZZ=bjBT{)|Y_zIwPQGg!&c50H zJ|~-@YVxO!rzfo<7hJCT`mJGm2md{}eaq%>awoY3vxJDLGQBO{>ec$%r`S4giTab> z-!%Gf-JP9q_I$vRZ_LXAQ!`T;HLvWgOUOTY?Yw{P=8}Ck?bns1Z`KMn|EAF{?eqNe zR?AJgi}}T5z0SPMTyln;*>u^8XRks8&6@=o#82-tm0a`wLgHbU2`v^)nu?uEy{x~c z-;Ly-U|SH_YnbO9@ZGrU_OT!{G5v{7iHBA%ej9o(I{&Kndr`kJ*|KSl4J->dWa%)2kI zUU9Ad^5wGjwrEGL{jc&l7qv)S41agI-*EP&_e<_{?p3JvIKY&Cd8_8mf{V@(S$s*` zg}tK}1Y11tJve>O&TZbTo<6Ng7oMGtjob22`Skm_b9}doh)769&6#YwYEQIq_}kh0 zx)fcFbK}DT-YtIJ7iy$ll=I& zT8aGMV?N=Y%GowA1$WLFCJNQb0XI{ARRt~-e{g5Ql7kFiN>ujjT;Lh{BB^tZS@Egh zK(jMd&09BjXYQZ5ao?Pk4O8!bVa(%FNLQ?}1qn%l*> z_wnWB^|hBm#IDb;`~Uay*F9anuMCzhpOjt2@ykT*pU?)iY1cn9_Ay1>XzN>_RayI? zXUanBZHwH6eFQcC7T!JayU3;Uz$2ztCnPFj^*JxD*d_fWOlI>0RwM6{btWIeC$L6M zE=qm=L9E!x!1rHOw-C#kXvZ6Z6GSfDwS4?(Nod}z#=BoMMK8*9-Bh?%64G^i;%&v} zFC~laEaO@1b8t`a1pTr{SHjprFaP_QcXE-{@7Wi_Z~pLmlDIe9@a@dDSx#FH@`>1- zGE!006ZIIUb3|5@ zn7I9YXU@POcIWm2HWz_a3R90|1=#*PlJ&Cw&-tUGksCCBS5BBXd(FZx%&R00PDm`6BIlB~G_ED_`8PYG z#_LJ-<>~#CTs!2stGG7AJ!_n{>x&}8%%qo!AH+ViEr@V`Xr9n|$zsZ_2v@@`OEydBx4ukqXI6d{VCD{_74%$sfx~_!V-+X`_J5 zq-3psOlzJ6|C`1z!^z%fPGn}S`0YiD*6umCg7t~CubR^{Cho(^?x$Z?Up;W7<(riL zgzYnvL*HC0I>gGv++P=LeRWFY|9j^HW3((k85f;$Q+k-+E79#z8kcXys>Bg-_3DdL zyA&PIDAeD4?Nr+E&uQtx2eL^CpIg}@=Fb1*cS`c$uUCttL-!_KJ)`%fD#nXR%DJ{j zvR;iPS9J!%qY~fSUK`pLE}xjXdh1C&H?G|&Og!2BGs0OMh%`l<~;H7A?N_`;z6Eo`)|kkhxdE;Jv3_tYFD{yBDlsuO`KQEI9IJ^1CdL{6iUM z+NyfK%|DT(_)au>%Dccrud5?%{B%#rr=BnCI>~3X>P}eRTN%z5UOc~CZgZ)JnCupc z+n}Dl=-tZow|YVjd35@lR!(c>^S{Ix8tDIWZ-&2o|M8{e5$Y1Mzu&)GtR9&+J^N-s zNvYBMU%uBGqck<{TbP+K{8hZ>B|7I~oS36oT4mj9|L4p5@0o68sq(P8@IF?6*<9mk z=}B$A>ctCBy~)&C{U|J8bKhLG&-0&G7T=LO?KXLn+~HNBdKW{F#YsmpI3Kf$=;)4; z5?vd1R5y67UPYr~s%qi;!c2y6Q}@Fvh3c*vER`3RuBbb+{p<1i%Ai|y{cZ<}b$2$O zE1A8g?|$@RFYAo1E6=-E9J^ECBzNYJm{8cWi+}QhUY?C<*UnpV{(F2gvjOkizgn+X z7oDE7&ZmQ=Gl_HCFWD1Hm)i>)uP*PFI4G_<%gE@E=S`_9t=O)#kdh52H^^+5$az9; z_Y~>UC8zX`Y>leUEs>hAN%2>c34aCmuliTLQeh&o?T)AoLq+g#t-Jc`RX_)qN%JzjG~4kNKSOmNQ3hmWuPX%|5ZeX~W$)@dA%0yMJ7`agF+#MgNZe zY-N=Bu%Xob&mHb#JB_?c_-`dtM(H+rWzTzegq~-L z-}Z+gdrs*tW`hG(1=6qA$G^L874beqP1tkS-@D)WE&n5ci3=wahcSOlA?|ymQt?t#{^XaO~oPNLE8N2E(d+VZE@pEHm zZqqW04riUPgL&q@s3H+B^H~y^?iZ&|47$O2qeA)k&y_PKM0^p5WjnaFH)irZmlW;0 z>u&zZVK`{@o{5XWVZ}T#*W#*+yyeYsyZa$hcQ4h~)ov{dwas6~bJ*wY z#jmC38Q6KOC#x==w}Z*td){eT^*Qyb&DE1NbxwYA+2rv&eTlXA5t9v@gWvW|xuYf? zaYZKC?1kbrt3}7WSdJ(8G8~*BbIkQ-RE$a2v?WhxJ>4k1L*&;(1IC>V?7!FREnO6> zmskJ)HNW(4_TMSYj-{8DeLp9%H7}x)6{GL?u=cDt=DA_;P zY`?t^dQ>xiUsw3vxF<#|Pa-D9Wh~sNwOjQ^!_nvBYz*5@M^?3lE_3$Pv82ZwBo(%VTWn$JD9$5 zRx{3#XR=~{-O=Fs^h3UV?e4 z7<*j&`0>sCs-Jf*vibg0$U)=#-4haL(xv>?7(MjSa{IR0_P&qk^5>jW&bFs6nxrq} zTDn#4@{2OjjL#Q;EKvdrc}$1=9{PS>+zCN_2N z+wmBB?d@&%UbpmcX~5i`P~IE0 zy?-VOuavvI{p-Tiw|ndBrE-`$uIu0ZZ1OlRtjekF|L?ihE3dEpCHZT$lVGpvK|AS& z#=A|Lyr#>KHWtoQTlZ+`3emQ-?N&}q8i5a!f=}8qSlaOzyq+ArM5005V8+ig+s?9G zn4FTy^eg=)!>Uv|53EA=}(IM_Yfyx5W2dpO;dcy4{In-?Z{MO&zrpn|0?Hd9q z&g}}JIqfy^FY|WJE#q+5aD2(MnOjT654_Q>Jgt>l{yy#fqYYm|>fI%;B=26hLPS?b zJvONHz`?aV8%q8+J)Ug3IWO+0@0OIw37eZg#m1C=s!zzA-{h9X>pNlQN=3FFGJ-nn)9qHzGu1<^QILh&(%Nq9e;QF+J*CXPCa?y&AeyUjwejF*4I^hzUyo- zC+CCy1+RToKUcBZKA9r)wqR2=%L!v=UCm@?&Ue3dCN68Z?NBccYw8o@7|t; z;vWi{c|Qmo3S$4wFMqen)UkDXYT@q7&rF3D1Uj0yt~?$8p;rF5YIXJPyu4i7>U-O_ zUjA->Yqqbam%;?zD_q)*cWf9PKlh~eihkev>*uff%!XwPOO`*F+qS;=glvd-_Vqun zQ}`xU#PoQ$O})atndSf2GtPT`9k z<(KvEa&ils&u{WNuAkQX{BQd5uKyu? z=YG#V{{C*+s($TKmCzeAqwX?HJz3l4?G!uBI$CJ`zu!Mo`|aLs$y(&ua?MHp%w+NO z^z?}Oh%W+Cs^1!~vc2F7V@r7d(8Bw!pczBKl+2rR=klme-?skLKCx};?gdOAnols7 z-wrwIWqm(TAm!i5ztJU(C&c*o*M5FIo83LtVZsuQ4;>4C(5&$g(W- z;%|-jozfPdF`}f`J zRfl1YGJgX5flpQuwhpfYX9%9(SI&^8r>M^Od|_GCvZ8iBhlw%` z^ZviRy?y^4)`cg`SRF&Retw(m@mlKLdbSRog0H68M~xaM)NfurEw*cVvB!!=AXM-b9s^6CP9}}jwkbG)#zLJ{`vmCe*fGb z-|ybN8}aD=w*Mw~@7n%2{J&y*jO}%spX==dr5F83^-@vTnKrS&_R_I)n`Gj5^=AR5fTGGk4UxzhMtoB`3-4{r2wQ?8%Q8J@QD{n)7~6{J*dHGg|*K zizUSRYW**I{B}|f%N~2lr5DOiaqs`TC~8%~rD-O$-ho{;#rzJuUz_&&RplpTE>tOr zUt9i5b6tORvtL!-&y2@cZ^^Z?ubQP+=RH5r=JlCqMlH40qWCFSleq)h7OExuS}h*8t48cxw9Y}3S0eTP_6Y*gPBWxtJxW*?&gYu7v%77ai-hno*a9yCVxus$|7e| z5lbtEvv2fH+ded!z$#Mr`_E>T1B-S>u5hi^?bs_5%w@BCNgMa2t-jM9KGCgSkuAP* z_r@hROD8?ro8G+od;cwsWR_of*XFUf&gn zvkM&;{88ZfeP*j3OSr7IbEgIOCHC0xq?2pc@BdfzXYHTD*T(NB-+A2B^EzwIx?E@D zC1KZmxOyLKXI{#FUwZ!j^oE<99S1C9*birxDzqvrSRJrp{{r)U9KRyY&0cfikjP^7 z_Vo4}e^@@{p0n8V zT?2>Xex>~nu9~komm@oWeym*1X&$L0txIRt%PuXNDj0c+PjAEK?2x}Hn~ywdtGu?2 z?ZhE5^`Hl{+vc1(FZJWVtdLzH;u9EMPF@L$ZOD1_K#Fg%;!3fgH4=9J{btqwc;Kl0 ztVSlA_4B2}?8nso^G?O<{#c_I?xQk8&Fp1jAIry+x;b0qf((z}TH&k4IMepOsD-Da zH+QB=*KQxl)7<>N8ysBz9iKQ)$KidNkzmiGb0<%h=t$rB#t?Qmw)NlZh@&$qcgEnx^r@)yzu@zO>=g-sL8k;eep8OM7uc=Ez6NYt9WZI$-D{f-CQM>sWaIn%^b+g( zPp39N`*6K6@yI<6lZj8%wkui{9%L50SNUxQBgcn>L5k0BW-X54oO@@+!Im>lXE?n4 z|6iSPZz|&fyA1DRCm&986Wn!DdKcU4pr?&jm+jiQRK+p$VYjgngh+7=6v0-H{@vChY6q9DjBxgOyUqze2{oraq6|H zMmi6kYF>QUHuqKKgi@w8eGCoCXQy-=n_4jE^}fsJj_}IQeR1g9quHOkGY?+Wx*AaW zIix*p^BHrgRHZjeFW9*EpIydVDU;YgHKRCOtYW<-Q@itq&wr0jd(5mnDdk>R!0}%0 zss|Nr4=of|CzWtNdbKNeY2UnarYeB}e{acM5VhUl=+u&;YWr$&(t)>9T(#9(_LRC^Uz5r@5HgwA1f54c=t>X+TqAHcfxb8MRl7>Hmuz)GtFl4 z|4E+{ZVH{^y**9%c=GKm69t=9X(>l#%D%t9s>0G}ASbD?w<^Cjxjy-AT-A|Rn?s&% z_DSQZa;j_IvoKI{=}Fh1g&cjwYJD4wPhOI+mA$fL({AhT5SHMWln|~LXKnV$HN@m8 zdCM}bZv3>w!`-cDvGtS{XD>!dGU`fl&)PcUo8@6Gmrpzw1UN5izMu5!41?b4l3?%k z)5J8_nN2?9BI)p%Yr~-pIYAbWR5?Ng8rn)qZi)uEOItAS%L@H|gW-zY8~fVQUHf<5 zx~cuRO}2dJm(NF?K2>#ksTKWYOz6C8aUn8w;-hJgn*O|1h)$TKe_)a1f^hZIT`BhZ z$E5;{3p3SzOK)Z^5)3g~>~h^!qO0-agi!a2<%;hu_p#YnJd^X1`?G-OJ=>fnY384` z+#h0>yqh)2scviWCW(_fZa!fApy43#I5XH!t!!B`tN0m_rrtSm^2^MpsW-%V9R6X= zJZIiKyIAX2-?Di-b}LnFi`rNeIa$S9SY@MClG5kARf(-vXRX+Er9(1$w|9EJm?0y> zWc9H5g+C=&_{y?`E_?WzaOGXjF*~^Kz><9uUxEb}b3HUzQpQuhNo(Cb#}f@9raHl; zZ6D=V@OSl;vbi!vsH~s#IyCmEiS(1VI}~qOEsJ_Ghfk?is5Y+5dUti5#aVUX8=G7X z2)V3Y_k>4r-?p3cTOH>xS~1P`pFeNjyY*|oIB>k$QXs0C6{RC5&$Vnp;PVh!#%Vik z%vW{PB^zy7A(t`J?_C9_mQ=v`BkXC)`X3Gmim!b2&TZ4C%jL&r1m*OJ{ax|S=&01z zkbVC3M`q5qNjhq#%fP5QZ}-Q#0LNoN-QnLInHRW-UHH2CbVgc2>DRJg^G{O}?)_`Z z4cL$!Bl9L^PHf)m);C*@D5T$6@0I7r+4l19Q~|vP0}s6m2Rky7|7PqA-@IY1M8M41 zi=GHb^Q=-5si~cq&_ba}>9{`FQT9r08dF52h1MksDltQv7AktF%hq zKKk2vY2lIYU9mF{h%4XGe^Tdc7yr`3YRPT+E|H8N(~0GdjZVpT#8W@pG-zeqFa3F4 zbE5cN>6D@?i?+(>a5aiNlCQ6>t}w`*zDfLerMc%`?$B&5jcqQcC#LSc7#;uqH`7iB ziHS_-*E+SPhj9K~kb3>E+tTZimb=RJuPt@X_lnYpxT^QR<>gMl815MMoUK*fI@evw zwY#Mrys3Wme8p7Vq}Jx0TQ=vWm0U`{&MLT3RpRhhAMY%l)6P{+j&v9e2C{o=i++ZeOn-hk z>D=N)TQ6`G-Q4!*23K}Tmj_E*NUWn;PQya{YXp z1@;Rk&79R*B!2jcp208Elc@z>MlZR(u)Pd1%zme5R{64U@`cL`AEv(iwRq-3>woDs z`;;@U#!Wx8*435GHReJw{|c4Yjs^`phAYf;cqbI(WKUjP;B~U${ih!lZzc(!e^Gj` z^u~_X%iYKG`<^mvXgbPWbmC~vB@U*=5k@Sg(=~SP^Smh}!Mti(itF4GbFo>(84BL zQzB%{;NiQS@tavi8SljNhu&OOo^<)+%pUaBj`wFXepN5dD-Tdy ze?d+7;`3fb23w7PhndbE?ank>usGX2^pVdxKDG(nyPx0SG>g^pR%GLU5NLb-9+!*h zObv@^nH73cNoR{nKHdFy>)(mxJ{nVZ7dMMAcMJSJ#7%X=wrE*(4ecGFJ3S#(W>k^&sJ&dTGXj!ULex9`LfRAC(4T++vLAdd)mPwSFQgv zq~4@_%g0w=N_1nzSi5-^1o6Cye`zv7`b&`T{JMaQUi&%U3X;3owSzkd>eGoK|11$n(D=yx6aLOnssu^imM{dh5;qfEA-wkckN33 zH-RT0`K+EzUDlRe+xBhbb2{Qz{w2^SwDtP5m(zo#{!S5{Hbs+vrJ|GOnhh7qg34d( zFunaaH+<#Etg1CCN5fNgD6t-3&-OR%P&DBDdF*od@9eo#+}IW{c=}D`^=DF>M z7FPzZ&gxscD3YyL;ikNo_=h5WCawp4hm4JCOxdDj=6ro|QFH%nrV6$Sb+K6Xwn_4N z|Ja|-@zZK~Vp`<5>i;>06K$riuGBOf3b{IG{`4i$pVfksD|9!{yKTEC#z#rQ&Cfu4 z!PAc)FI_5Rydkt;yYY?JhFzDpY5zJ^cG*~#-(`^mr*BR8`4x%pGfG#OWl33XXqnqy zwd9e>bx8(K!LBrc&2MKI=LbgTMA@6=NS>1Gc_cpL3|r^bytCJK#qJAzY&Pe-m0yl5 z)3UIVNZ0%sbE;WVXIPiNUoTg?6nWoyQ`Svs?%p5FVb2SeY5ab zsE7;0uNAKZz9^J#oHTFs%&1hQtCHo*+CJKb={pnyHd=o}jm7YU{l`Tw6%uleR>cN*A1&kJ`0?n^hc&I2cKY%jy>sf+t5@yc z?P4mw?RVy4GGJhBv$M9B+kd}*G1sB(+g_bx7W=0nTH+Ls_i_9$O zJI-9SZ)ZhCWq{L07g3RIyrGLHoY30$)NFI~mB0k9x7~-mR;6t%SZpHGqjrVIH%4QT z#^P8Kki_72N|G($*em3SG#>`)Sbn^yqvQFKv z`t?Z2RJ#@WD=uZfJz6|bQ%BnQ^lZ7fch7u3L>NYPtE=B;Z{MTc@m2Mtx_R!&rI{;T zJq>1SIBnu(Pw-e5CLA>{X?1T_SCYfhhl+iccE)d;&30N%lqq`9-^}_oOgZc)=k+st z=bz;f`r{)#?Q7&pk6gdT2f_trl?Kk+!mwEC{yvrN91kUuXA&)U*4XZ-n{?I zWBWe>@9RJ4)NcPgJ^TK~GtZ|ovNdZn2Y9i~30(5M;O}g)od3yaqNdU~3z^h?|V z-oJkyJ^X3*sqvJs>D~>sMU@qs=5Ch!>lT`3J2@x+Inzlw`QYyhn={Wyg?(fDyNYAZ zTv?O0MVfr7Tq>0}iy7pef9md%`L#ShQ~yx*)f?{ewFW!({;J%QX!B2Gweu{6ow@SPcTemeU$Jbo%w|M{1eyrcUtm`$=%E1S-nz!U1rnclO;)q zfBks!VZjTfu0=n+)cp7szTvzgDtvzT&!9z9IGHS~=j5KMs4L`Hce-vSkHf^-O}ped z#8QH1C*NH9YQB}heUGLL`P&>%^@H{X_T1Wk?k>Omp1;jA*F<2; z^Y5*M(&Encw%>7Km*{Kd`w1ts31-(LNFx_i5|fYa}X$FILSek}Z6`nM+eFuNVL zzh1H~b(i0JKA-2pdIjEux*t!}A|Gf=+X;B|Z%KT6ywgq4Yk88`!Usv28!tG?lu=hAobANZuhT@X_%04Ow67_?wxjD z(bAIm^b|vL#{YIJMY9GS`;)bkG7~NCu4lT`a=APuf89L4 z@r;Tz--4Ix;xh8Zr%uxij*U3AB4UsK#)!oAS(b8}c61*UJI(y4(Iqs`*{E#e-0dqP zbi?a!c(4Db_pLtryZ!$E&#O<%|M|ExsL8;MPsU?rgOkmTso4=P#7@oqdO7^{>f(&4 z3=R>jyTAPUf4%f+d}d1Ij)*B|MIMx}Bnv4V(-84ku;7Nv0*!8ygswwk(?tS9V)|~q zaZ8=0)_r->wI!41y|Xi}e|sld?efc)^G;d*dt$jUZg2Vf?{~}h|MvB>J0fbaEuTks zwf^}~aUn(t-Rmb3PK!S@^SnO&eA+XSPb(I3`%GRPugB1@%|gbB}TOarc0uP z1(<{MESGLv@s?qh22()t;q83?etv$vJzZ|o(w05E8}pBC`!earhdYVehtQqA3m)7W_QDM`$_59{=Nr)+qZ~XwDA^{+uoae=cUb_ ze+w0TMIyFMbG!Q@A+N&y(AM^nJ>RZ#3m9ZXf&QONZP=S{V;nTyP~y}1|RGPQi+18uWJW`j>pSVg4$6L>OC9y7L^uAlm(pl;4- zo87-3O`jjX=j^i@O^bf*+eL4R_tf|uI44(bW3kVE{)TP7Y%;$(UH#_2(dc|v^x@y( z@&|vH_vL(e`_`TBN4wbdPfQOuCEA${jPnJRHYU9*So7_->4A(l2Jr#YbQiKNZwfq? z@9<&1*n#J(uQf#(t(~kA%vdlp@Z!!DTPiK~y6yEjp*ZFD9`^PBFX|jCIvR6EIeSq? zamkXItXy-14&8e*vwd%5L+A;w1AnwOSvu&j-DJ71AaTOh^2gKd@dY2IIVSu#;>CIP zx576|xql8d-xEJo)V#V;7P@Z5k7@kh7Q1X%2)gA4AnSS}=QwxQ`2Y^FgueZqj5$(M zquD-7Omn(3$8YkRvy4fZ$$NSJUS?WkGTor6Y`>Lb_Qefn?3fa-SlnTXIJ3oNj&6P$ z02`T#tH-@YQ=?{&=|iIsXL9sb2H<8eHVLT$bFvGjX%; zoY$W>-*o*ve?8-&EvJ{Hn}}w+&b;B~{=j}hqu4UXj$BHVpWLC%baV2u_B|^X%s$+E=fvd6lLdq3=Umh%VNUAMZgAEJ@L3e{Y0~-E ztnU^*XWG2`eSPb7dq?N9PG0MCqRrL&rm4kSCAeEJvlBQ!eVUxF@4qhvhj%Tw{MqY_ z6mRi`6OVlqZ5OXtb7Q%j)w?Mls?JL7&pfmtD%`$t*4wAm-(D`fYP6^13IBD53AaD} zbT}eo$e|hQZP+e+)$F2>gnUb%_U9RF5B;|qEE91Le3bDybM91?F9)RJLi6*Z8V|5s zWVj}?G00N*)}791IIX)f z|L>2h+#)MonT=w@KQ#Eilk?wKV_~{C(R$V|4mhQ4b%x_Q_CFUQyW z&pNyL&A-_>It_boESr!T5H|Nb&rSI~Ee~q{?>oECrH6S+am}CK?W(`I;!SrfiOWCO zp=G9%xwwmSMS#$cg?CJ6K1#V=6mrR1Xj9`)+1H_q)-2C@slT34Lwv4fjtSq>W6Ybw zL>R*#)+GAq+9Z73dbYFk?GEAB>=p-SJKmZo7Bh2ix$D|zRnKc;_i|2Hr7s%rrz=i* z-hw0B&lGK&&OXg-&rNxLzIiMS{LZiV3f#0}Q}4P(%C4J!+)~fX|MSGV*VQeVXZG94 z@lH0?Yi&8bsN~z)+23<6OYHJ~-O$+iTe#e;&#vyrv!9E9KVR!{c){)&vtJvY(A^j* zrhd0`{?-Tct<9U5zUeN=U%X|3kC8}%{Acm&47Rr3&oV8TD)--CzV?xW+8mV!TrSdy zQYX|JE?5*Wsxn-*T*GO&P%K>8bK0eA#ih9`_7>aa^se3|EBlN6Vnk!l&nU0G2Y0_# z4V>GxPI`Cz{)+o15|VvuuDg0K+MD3Buv|#F+k7iq@#8IWEDa)}J#N#!WV3o*=W6Xy zv#r_o@7k?jXVN_P{?od*ZVkU+*4NF}ee)HBWb)VW|Ji&`;$(@Q&YT}Bn}t``K9m;D z-0ARAz5Y7u0<&3RyxUkS^m>8q~2|2%o$9u99!hcwYb5w2ejY=tHY z%9hVJ3iBKKd$4OO1pNxQFh^3@$sx#UQk(bh2mhCCv$Fta$!<~m3@7(*h zU4P$MDFwH#O6J#lq9Skad{NR6%{S%blLePAUi`Y{=#%UxntPWd26(MvU$u6lM;GJ! zH|Nf-+!fnV$a8eXJi*VezrX35KKaF>?O|d?H*fnVH)d@(#+CG-;L9;7n}TBZVDIZ$ z2eYoKPO5XrZ>yPS_9H=iN$r+{|9?s`NW^|m5-{2sEb{Hip)|$UM6Q}U6J-KA@rOXb81{Xj6+9{exIREY0DL3`Gt4R9cra0v%W%E-w_Ns}> zbiaKo_vd%5@d2TOCbKui%!!YC8?tNayK~pBuKs%I!scRc1C6bfpEkNrsCt{7zC8Gy z<>?Ox`1i%gseIKnKgzkq{l(GFeN~74C1hs);ZWFeDD=+mziIX6(I(lExp!aJ@*Iri ze%Rc^d+pN8k~z{$WsLjscdZirTX#U;bYkC(;~rs`U!MQU-ov>x+^4%a{-EYR(?wS= z>D9d#)y_?jTCwG*qSuRDewMlOXCL2W&?j&x^QNwnN8}u?aGmPg((AbNoK=F?FHTRa z{dnc^rKK@D)o<=vuzgF`zZZ|*u8)`B)6LvN*ko91ye zttk6>#pbDhFwf)cch$kxdj#gWUXD%3{Iuh=B7INP9aJ=fvVgGS#gyLY@R*PiOKzy5BZ z#7-tfH>Ie_#`|jXe{R~nzsPevrg>ZzgP3w(`$_OvS;TWQ~GdFs$1FN*Vjo$k7OD5D{dF{ zG|Lt6J^5+F--~y*?!2ea=~~v}ylU<0t5><)-97sD?=h}Te{|1w!Rw{zw~aMaUw#ww zF%O#L(Rf)PjN#a~k1xOeJa?$HiPL=ZP7c|VDM}`DPrfx3w>=o}eAl9`T7kxiub@;XQA+lvs=fp122>IoxceZ8m&Z85PVz0au zoi<_jwDWK8-ZN(B+<)`@%hR{z>wm48@mhyLtf=gKc>0yxx!SSC@jBLhIc5rbA~yb< zJf-ES)sYXsPMwLJUHjYX;k7SQw%*x2(L<^<#zf)Pv+wW4c-8h5?c25K->ae@uRdMv zs!B`y`R>TyUf$icziuvlb%^Pr9|If9$MBaq-^GFsIw+gp>bUm0R7b9xX#qc%lJs3K zubc`N>+_4|yJd>^SopV1IGs4@lhs16KXF`=OZ@M@vF}}?*|*loAj3wkl52Om&f3c! zVvDV1GkV@!eHbz0bz9T2{NKODyLQUOzf)cF>e8#NoyFokA2T`L*Xyb-yrDJomGHT_ z6*Z|R_H9&SjjUyV=;n82slqmQKKD)e-#1UZcJx}-N|q;u#mlzTytfN$dc*gmx$ouM zxkt7-xpO+6x{|bY$?3J*U#w~jl;M)=y>`|_@=1>r_qBI!$1ObnPv;I;ps~ndtJAb4 zo5SC!OrAD7$RpC<{QG^A*O^UId22ps=~z8m^dzW5v3S>w4;$AcmP}cub8V%)#~S?yWDrePWZ& zjH?VB6BlV*lIpdwGe6fYz5AnClKr2$rM-8*-?Kgb?Zzb4E)my7+5caxdX;nHHAnyP zX)H{=?|x038mW5s>i?yex3GU;dBE_1MS=0eiv3m$*$n0kdf#m4Gek00>D||6X5kcY z5cObkXt0^fP_uo0B-1BJrIj^v>rz=m{u&D}uxHpa?fewkNwMJ*8Ee@tD3@kuu!VeQ zsAH(u_B)PQf^m)FCRP>!#z&vNmG5Ky`uhaKm;G<7R@NBj(t5Ge|SUD;PPjocNjYy@JJn;Rk!rt5esv)O0aj*u(yT>A~G=x9%UcRmf)G zj9p}U`uw(Sd+**CJaE6EZgqAiPeS7PNenv~H!y!-|Fvd=ywyckv2V^<^>I1HKaSQh z-eBIfWq*0Yw}6s{K87ldYugT}M{n7@_eQ$LwzJ=u-mqq_`rmK8`ya=~vms#~Z{yq? zu77)f^4(AW-%;CK8AJh)9I`W{L9YIwat&8FL?c162k+AtIQL^%l3PP z+uVG1*LmaSv-d7v{?<@(mQQE)?Rwp}o6mi#4Bojcjluhg%`vsMoCQ_0Y(3N29p2v6 zWr)0WeI4T;#sqH9@)xI<|9UNv`%sOczd`PA41>|FNAKPqV`IqwmiVv9{dS~v)r_3@ z+qcilGuk?oawf2zV0a-p=~TDa%Kk;0w5lU28vV9;vP#WP-M}7wDP8x})|aXEJM1Fm zKW3j~yKwx|pN7cEJPFz7Z5TGOmNa>=dpexEX=gn7=pMEw*Zk}m{+!l1urr6j*0Hqb z`Dq3h#;Knwn^La5o1VKY`0j+1y+^JsixL0!j^V^s+aDWq%u2p}m1g)pVN0Xdh3VWn zZyuGG-16TRmB*^aaG#-eBfrG!ORr}Cy{&#b_Gz|M+WU*^3~!b8eY1Su5XbECRPoPa zma`|HUY62l%)d~hC9TezcF#ZM+dPKa=0{?)!oO~~nZDx2q1mqkRa6)}g*NeRWAnD& z*=bh1sW-%LLmI=ctMfi)NT=npE1o^`e{t-4jt7#n%mXA3vaQRxkTTm&G26ZUUCy;K zZqKiMr`8+K{i9!YbbiB+zvbWZ{x#h=*z`}ls(14H<@fI%JXQC5(fqUKPm4Z%ow=rU z{=eFrDiRE_GrTJer*B*!T(xPwcVSY9|52j^osFz7LRP&kvW;BxDNXu?_ob`M>MgUL z?OE=7%5KBY=6^+7p4+GkJ&CRo|Nr7#8f^c{C|^a%3dygyrrG|NS>I zcxY$TEoVs0mcMqhx4-Q3`-T|Cs*U0WYTO^g`lgm_DX8Z5h&yxV_p7`&#d_cNuHSZG z-{J5E8wVA|bdh-JgU^$TFWGXe?moXiXy?8XnLMT)4i`n|^IM=Y}2`2Wyfsgw2?FX!TmrcC-ax$)#f|%6lz;uv2`&jy)H0S zYFP5=$*TBAahsVe?QegLd%NJ>#ozp*`=1HEkxKfvS%-@~Oxk*(euH1xDm5;F;9AdL zY3kon>g{Ldf7A9q>ho}}nbaxU7osNb-!S@Z;}G8za{5#BP1hT?vm%fF_g}Em=!k9y z>n}kTuk^f?>Zh+;DXJb0G(Qnw&Jej_m*C$c`)?KRzw!M(37|BY^RSFV#^;9j+H!GHT3yoEgPUQU}UvXk)x%h7XY&-pIA7b(fhS;$_c+u^Id z^6dL5cRYU{35nk&sVdqZsrI|);H5izBR8db9&QQpyw9>}lX#Pw=sLy+=DWZ1tXTha zwd=EOg(Vu2Q+~X(zj=Po&0jia=g!r*T(ND-y2TZ#k?-TLm;H6O&NyEdAsDu_-7lcz zg-}=g#}&8b{m!Sn+Wzdk@z0%;|JHgw`*XDH-OQT3S3*7{Gll&%6>BJKs9`Q?wplyz zQb$kq=FV>u+N_T#y_WQF-ZOvB+gB_1ZC+z+yt?7n=a)z0N-Pg1*_kFMckgrb%4M6l zWZAR@BG)coEBed4Hqw3fapUQRk2KD6DTN*pUCZy~uv~U&Tb3j%L#2AT;muP1C-dqj zzW$Ou=K}Nk2EP-#y4lzKW1qH6wTm6`!|1`%=5%^Bm6?D_w5fnw8DEcg~*e!6gfOtsLukyqleCS^w3hN5za425w=2!3l=hAJe|4NqbC+ty$E2F;x4t zdd$6C-TP;y_Fp_GeMtA~f&JbAQ>+zoAARxu)ZWhOk``4v-Ape@#UVM_{FeA;v6rX2 z_tq?}NLu83Mes$5)02oI))$hI$2oqqoZWrs%ok&k_*FBf8}2g{-?3reksAW`Z$7s< z@O7)6e%dnow^()BdABV$OTOK_%yA-?*Ch0;)I84F1rweH)$UkxNXxZlUZVb`&E3p1 za~U>i%yt$_@jSoz>;{9^AF^iWDPGsqS(y&FB99$b{{Cu_{TC;RA}}Wo)vZOm2I2>jnDQgZCI^; ze-lTnP#vRnD_iR0V9T$$d&FnQFcwdKmbYZ_f$uY$?(7z7;aX6YeSY`)nG+*EbhS6^ zc)gctmOA&G`!5Tg%(|FhWRS6DW5d4dy%(1(3vZZ{Gr8Cbzyif0> z8*jX?G$UwlYl7&s1ui$dt3BIKOrOkfA@>O5N#A|Z+am=e4PBT__@`LL-2SU#oyp#O z^sdo59+9X?PqiORKckcRbEf#GkL*?w+_yK>P2js)+7-XuTzlf`nc@AvTF?AHWT(7P z|NjTMcpU*1*RxzHb8{HKi?+LOsyeVWS4#g`grL*5Xg;hQDDqVLekdF;jf0`+11PNwGR8|&UoTJ)z+V4pqX&(lqx-haED@brd(t>Sdq zhb>O8Z^#|m_ve6!`c?lui+v_r_5C$xH3-q&!hYH^dKKHP-VGra|HLJHPPY~eKYHYJ z#=)hBS6tSqs9JpD+TT}gcInAK4ZRrMgk8!@nGF`rV7z+L%(b(O_2i~T+mN!fb84q~ z>Ri6A-!b9s@imL2Cw!I-sh^NqJil7_f#CAKNkKU~=KO82{Pg_#hZ!mS53W7h%-D5a zthYx0hohqZebCU7Tcivyi1vQ>lSO%XX#R%{j6^_uZgN( zlC$o5%cQ#@8!~3Ch}pS){y)!^C#_x2_OX?P?ECt^{LqQEn5WZfJ{XIxGKyr-(>u84 zLTk)f<-fIzFWM3wPn>smRp~Fk^D{XbJ{o<|R;U*)d$`d{vFk|4JnX~EId(~qXohD6Ok#SG@%kE48|Dy>TzHN*OtlXYmHjnjWZ}^tF3)B#ugP8&Rk}^_+Ey)f_S-S9XU%tew^t=CFzeNw((CEBh1j(! zxgNfsx$gCYljczY?H=M&*5!6-b7XAYe)i;4``cTzSQ__-n{bAk3JAA&U*5CD_nF6? z$*FAHk90;jF{@h!UAuC7|K4fSpPNd$cCUQFHp%Lc&9PsPa?h8X%;Krc)mY3}megvi zb8-4)(?}IQ>rB~$Q|c$&U%O!myMZR7W%;(mYfm2MpYYjr^8U@QcY4%~ik+F4W;N?p zv{(zRKI(hx*1MbKUqxA6{(UO{_CCj!t(r0Z@Yk!oGfza#jZRQt(zwtT9~}87VTa42 z$!GOmdxZLKS!TEH_(#DG{SB)c*EdG-T__ZLJiBVsf3GOV2WJ*W-}2D@^6`_h?dJt= z+io~yTbu4{-X+G%k~48XJt2`CaIk5p^_b*r~ikz`5`gc*2@v_N`P(dqA@kb1Y z)?Ds-#Q6QZ?Z&D;5$!n~$rb{A=L{S6|6zT4!&^ISXZEjDZbQbRl?w#krKLVd6gy!j zWb=CI!|>?ECwEMUHT~>ZvGMSN^pq>B(jEppJEU}|(d$yD!W-+&TRLtm($~LsNhg-! zlMnYFziA9%DxQJs#q>H))jqj!C}#T`YkkHxnQ3?DDD4wD_C1hu&Z_hj-LH99#jPr1 zyc51}S{huo#N^|wAKaY|D<@XeJGU;_nIY_-^(^k)o2ven`7^d&$eEV2>Gw`0?dO^6 zW|sfiRC@omcj1&PT0Wn64dU-Fs@8Yx)OJi!a_BjI{{6?ExE(^iM?;q^d-BC;S&@>` zqwgLUyCUW6#o|PK8BcDk?27JLV8C|kYJ))#xBoenu!4iCtREI#p8B(N|Ng1ESz0Xa zH(edoUPmx_qznGs`#RwCDnao%CtdDeO9-tO6n*Ei?7wj0m;G-});^xYV_mU*$MNK4 zHpS91{(D^2E=F~mGuSWOwYlr@Je}G9|8PJ2^SmuFwD}i1!|F|(LD4TZM?G?}%bS(> z`Dl%CqtV2h->2W5Vz0daoT|eaKI8opJ@+&{5{nErh_JiV(&+MLcK=r<&Y+GHdQ5I= z_0w9VIg9SPee_al{hRL=|9Hnk^;D)k53=4Y`>wJ4+Sgec6KYJ0|Alo$Mg%0>yxzM& z_-MFH`ktHLkFX-_gf&aT}yOLSr?%f_br0S~@%YPjs2eQnB0W3TX5 z+pO;H7~|yS5yhth^=nogoTk^wQ|a1xTkwLiNO?d{ubV?!p5i0Mrq$Y)wywI8-=t%4 zo=@2?idFAv8Rv|z7~P1#VTu5t_H6>*<~Vp@WoyCV6Ol3 zRtmYZ920nVX1o8FI}6^|&rUS;;#uvau=c>bNT$`zUsMlNFJ};7S$}W(f}A4xQq7BY zKLzI&TYvGG_C)*O&h$?^k5|nq4Rx3m`9|R20;!Vhz--;yalv0=0?lSl)OmdWXO-Xq z-U}`-h21_M-@8}fx2~IOcSWbcu+U+Y8q9ylkkP zxiZ%=F+!4mNzG!L1+R}uT2;0@%RQ1*>-e?CTsmC-Kko$nuzy=@%+5U6IOEsL;2+nf ztT5}hT^icICE5BE&$-P9o-I}lWDj79+qY3@)$h-mBA%s}-+LRn?&>gAcsgbJ>z~i< zZkM`0+0!V&uQZ!)!IF0FPw&rv`E$M{hbvJa_G{}V!)NDau9_pq9&>TN#>S?7fn8d; z2G3mt|MD06*5BS$mAFp5tv}ghJHtQbmA3;={)ztUbM?@6ABXtjC&jgqpO!9(mlWgq zI_0s@)kyO;J5`^X;-_k-iUzk>GVZh13r?s6;B+b6=*@hUzMV&3uT&;;?_ zW@Q?8*3MZu?ckK3yBE9=y|r6=+rF7gMT_;B8%wnr{_mYrQ|fa-d*}IyhMGn$!oM~} zuj|;dVKLMBa;`Wz&Voo5{Q#AlkN$62@#P}Z(s>Naj2q2%8g@G^>E=<-=V@6Kd%Ih1 z)+xE!-CpnIUM>y%vd*tU^{rx<;-roR6O;J2Ydzh}_T=Q_KGv(cLOU7GypmzwTO%N_ zP4VB8tusGN-1q+Cg3rG_vWuVGnP>KHWq{d*llq@5&hOHC{qiEyvGPTGZIzR|_cfWZ zolf#zcf!}8_{VwCHxrYrmcMk-ulJv|#hh8UYEzE3QpuMP(a%x!Y6j2reiUh*t*HGa zT^m0+s_a5TL95OMt2(Ei#3`INKKQhyrj&;Fib!u*?|bCLPE~;yGtEBDN}6$yVFSxi z@nZ4zSAIuM-;LGPNWHM@o6G-QOTTYod$L|jqO<9G%-ttTpX>f|+G%#JV@>q3+zS)_ zw64kc-Y@Xu<^Mz`f%}<0e|D^DnGkVgcGQ9ngIa^~;)R!<@xFY2$JAo^zhBHXclKy& z^1o2M&voE{&h=fNw5NJK582#*z;gbH`SB+veGzM@6nn7Y^WML;$=z?4eGe`WZ8hH{ zaWizj$DN=ryjMm2L%9{xt><(uNm!}*Wa`%{MZd-y_t(DZ?`3aXDQaZ0DYISgyU5CC z4FRG49!5^gM`vj~I=@8c)1I3hqL*g=ShA__lzjN+>^%+}x31r*^G9YY^TcTf4?FqW z-;|p1bK<+~+ZT>by<)7J@%Z0=_KBgtPfZb9?;mrM+iZbHjHGRZU|J-rc1fn<=g~Y(NBf%S z%^b@E_;zN0{jKq&Px;`{(~|!lZ1}NwW@egj`Idt^wb_rFKKJ~3nh?%iH}%2yi!*N3 zJMGfr%h<@2z3cPuOZkd|9^z{r2}dTEeGb0U&GceOPg}Uz5#M&xb7VI5MSV%TqDUwK@jL z_3tlUIlX2_(WJW#GK1ix$N$AlbeS=b1&FGq1Pj_|C!6hwHuR`81K3!&L#HuSfA*G3A(J! z?1#=>-+X25s-s>T%p)={bDO*mxa<7cipzhk$7heU>NTn9DaMW0w<)f;%lLNZG{?u0 zr>p}nU&xY(jgV5CC%A9oHKxGSDJCYZ>$#SxJ_=v+`tR8!*7eVPgG|H&XG|{pylqB@ z{LPD5vg)gX-W@9ax|XYH`t@L*E7P^Pttb9xT(JC}+58J9b|+8oUD9!q;h*{ff4ADW zTTW|qzV38VKk0X6BkLR=x7ei4EHiG|tmJEtd_EqJE%@5XbZ%!$_fdIXenpdB_FD;I zM%Q>mwXI(t^t*1{Xqz6zomD7&bhGfniN|lOX*DYgS1kNH<1WXmXBk@S>SBy<9gtY} zPAY5F<3~~4A-`uGx^w1|FrVCL$_lQzlYWnGmGKcmYj)F@(DYoJXnrC10_06yqdMx4l;7N(z zb%iOsAG-a*-9`7>rg?Jh+^)W@_6P2iFO=@1Va@wrYS*&$@9(QM4HQrfq`KIz& zttxS*+Eu?atrn~l&Y1uD`|4b|#PFnbA^dF)apCcv4x;U;PZK1WR__kWkZOOcwI+!1 z1K*40mtCO?y_<{AKVEa?g~N%ZmJ1*HU*?+?zU0Bj-U7$mNe`BIHG3XyUc3F0fMYpZ zYG3bpK9va;&8gz+b#7EIHTkr)MESDs<+F>6B-I@1BQLgx+7xr`+1wf?khy#6)bP6O z*}vzqsMt<)`{7clX(?P(uBk9n&iCe($=24FXVq$zPVdlN!zOIeXukDT_J-qLX{lCH z{rsnWlgRfl+EqaCh9E_i%sg01V(81wYV9hp2#m+Sfy3_O4P z8L29CGS5@H{_f(I^4XgeSd7oeeK9h6DZHa5*38G{byW0*6yJcD=zy)ux9*(q>_Nkn zYcrHe@7yw$?A#&>t+9CrGqw|Um} zN8MT#>DF(Ki9NFpToNXt8t-*^shZNgD+yi>QQw1)vZPommwl1vveCVn(&ThX?e_#e zJ&sAbg$>U_Q#LTZ?J5*t;yI-oXrxtWJ6B3SXs`JHHCuV+eZF;IwssNY`7Mg^6H0T# z-p*%f=si*C`(^Ds6E1ZtgX2-J)t`km9@#lPah2-#W2P}0&eBZ*THpTHKD>NaP;j$Y zXx95a(XDEctm|Tr&h2-!%XxW0_Uiuqfdw-vpi3b;$9-Sm2 zQhHXs?%-5)%c}w?wVW+{pz}dx9#A{|v^gkyWzG2Fy1Z|;&*-H*y`X2s8 z^KRtr4PN^K?yx^So&BV8k(byzu3+tpZtDS4gC)y`b_tX`pd*95JwvrA4t_~4yx z{l${W=4!~U>ZjGazxh{t%67`Niq*R}F3>KE^Rz0>jPKxCxJNhb^3S49uN&D+#bIHG zYEYx1TH2u@*jL(Gy%Gz@;ZehD} zui0<^sfKx7_os1jKi{L)bksO&c|gk>ouzso|DotZ zp>izwe~ej=E5Fnf`pCKdMRnws%_egmCm8IOpL9t?nRCKrwprd)_olC?Z+SGY=Ilg| z7VGX0=7BG=gSJjEwGCE@s`^*uw(yn7yLmw_=7s+y*ZR#~)WhIZ^z}q#D1ndhYj>+xAAv>{TzG?pnt^p}qLOiteSTJeyFH z^)FXG&&|_6midOK(mQ0Kbx=wj_to764y<+0w&^`{OX*cvxv@<3+8e2eU9SF{7gnno zOl4K8nKg_Ojlxg|coWg(d$ij)I zQr5M-O&8r6Gh2&2{r>Iab2@%JwEh>Mm0p?qYPNo8?PJ|bmJOGTGZ}=8^15eEy>%=0 zV8XdI=k4=Ow@o>x@HTd<)WvKG)6z@pmmZ!j!m)=VU}x~J`4g?umaVxxr=hZT;W;CN zM=ST7*IL~t@y&F?Rb`QS*Raq9nd`LYT=dh`jCAun+rBMw*|v8a30*ht*_}RhSw-S) zx20B-SLZ6B(v=66JI(iF{<`sV(KBtsb_bSA>$i0ONErV#I9f8!(XdCo5NyvSn6QpoV>;JVTU zMXHyldmouM=hKqUvwnSl#l3f{_AR|dU(dT75vdQHEoH;H*saGp;PM&WZE41!f?+Ty(0Fj`&X>p$KJo1ZBbZ?!hY60(T_Se zYSx6lwEHeFNA!cpi@lm6_Bl(1m%g~U_@{%Y-4*uEjYi&w4p05@qkoA{;lt*0S#M=+ zb67(U?a#EmD5W`nyZh(9sLhT6_nztP&PesQ*(Y=7@T+Tnf*CK_t1KV0Z7%y5m95-b z?_fJ+{y;c0u_g`-+RrJfSxnCB4pGuHG{F!ZC%JOJ)dtx>LYyy1j8(1f%=2|JO=STx;1R zI6Yuj%%jyTM|m0jkre}PBu0q+S(PVEe(5t_+=SxW663wVfHRXx?MJJ&knw1e1AcLAlXR*THq zZ6??2UOpYNZo$sJ#g7{Wtk!DGmE!bHmz;U|-1@cM*ALpwo^80WkhfA!#O+uSmyP4b zm77W;nRl(T6Ste|}slBr(TcU#zOn@QZQ5iwup&0tK$FQi01y0rRM<(8+M*QOsWGXB2z-(S(o1$IyO{{4MH zAU@*Dq8;pC;@5stTGbwFT%w((duZp=_?36=h-XF^PvY0f$*g$u(zN+B`@&4dTn>{$1y(D3E3v#O?hmp}TQi97tDly|FB$T|M7 zbF5y^1LUTB><-degeqq@e7Ll#tcQ-GLy|?ku6{lZrRi&?m*Q`&I4NGgguDJQrFDIAR zznUBRg{Nk)C*7H(`mu0Z+R>mdr;XhvgbMvlUA}C!C)<*3IsTIt{M27@_2g-{5BoU( zD_LH(E%Iyl=WqP=inm97*1Fi4pFrt+3-_bYXkVXjxE3te12$vWav z-zyDyxyNo=Gd8JjNL#SwV}Pio;GZAow(UH$@@-FW;V0vx3`@_~pE#&$ddYy-g+XGBH2He`G|(zBcZQNmsX{?H_rIJX5j&kxje7G82&mFnFBn}_-TR8iFJ6F)g_g!}z=GEA=aC(ZNgium?Og{~pw8a3eT#`~L+ItEL|1-g&TJs`J+TLZ`Q9^uBI* zX&jPy_=%`UsbApwU(#PRetoxE^i_COy3fzu}D3U=G{9sUMfDh-!>k8=diTZG7OCyp88x9KA2L zxAB5-+%DIZSFNw6+g!FqLU=s zE}RuhvCGy7zrQAb%MM}IZll!`9&T4oIi-~Qrux^av}t^YzEnQFXa9T_FYDn>RyB@B z&&d6^G+Q>$k4h>pIwc&na#y69@|1#rXs=VRXYI8t@~m)J#{B54<}ZmB5&imjmpKhf zYmT>-F4|=r@nhw_4-ftrJ3T+6z<;db%*~w(&87>NdGlLcYTKnYPa(f&;lWeds(;06 z-|J?rpPM{&fu;X>%P&iqc@DTu59Q3U>I|!`UNYs2$Gfb1pRP!F6*U`Ge$_MJ5KQQ* z~<`l`v*Buv}Pv!CY^GeepYReLj{26P~gRcHtvE0dg#pTVtQF3~V zl_%G2F|WD(<)OHz;#MyC`EAoaJ+19iz7{e2<)1dI(7n#LnGJ(CyjZtRV{Y=9+yf`h zyR@c9&0zM?{auAwTCdfx`zA9RHE!De=#`q#2eCT~S2TwzE3DFg#J=~4T}4?} zjF?ZglHDtxxkZbDO~WK3O=|x1TY@kCSYQgLDW}CU*TiRK3+1-l9x%p zyi4YELV|A2{K~}T^QOsIc{<*Xx%sihYk9qjNP*vR!+8C05oys|VLpc5OBYv(-itZQ zl_8w<`a<&p*($E{gr}zi~_B47>Sj zG@htkNQj+#!e+i^!p<`+oz@KhT{eAN$}#^tbLobr*wf2WJGKa0bE{aj{LH)Ie@f_0 z{1UGsK4;cg7WtFHQ!_r9i_{CU7szK{PV-fNq~N!I;-uo~0q-O$ba)j@6tl&|Qr(S7(b7{e*^0gJBtwzSroDMjCT)MQVbU}wq zi$mf6n)Vu5wtI{}?oZgYRWp0vIhN&dkIPnnUcDl-Bw7EC1D`--!0K1elfyq=mrOQe z{S#Tjty>ll|LXp<@VQ#f$NknWvAmd~Ah`U7=D8Ay7N&>6Q!hoPExKl`;ci;we3RdN zZi)GBb%{H--&{W~63G=<&`66dJObXp+ z_FTMqrpwZQ4bfA+E!D36d8hJ?hvgURw?7m+CYowjZOZ| zcRT1P_3?+LoV%~QJLv9K-OMim7K|Gk_eQ@Is@-;sRmpj-z;&Np3`^6sg(A3Ksq}E) zy7*K!^VT(ne~nYZrnD6Va4^MKX%$qspKbJ7)+u)2L56(p;^hm9Qvamhf1P}#%y;VA zYqA#p|FiVdovdGu5S?6W2#xDAX?t6}d*EVf8R@lzFTzQtuOYNe4&E^w=yalT#ewl5#bEa6*BBev7 zGbgeCepas4HHYKt=K~*&Rqh6#G75BjvGJJD#9W@7Ib3>K;2N&aoX2p`l%PyJN9yIS z`f4VUj61gn-<^4GQU8Oj36grj{=8dat*6dA`(=IaOqPt7LSa)k-{P?KGZs)YRXOEk z`0KP?N#iZ`<%_rEaVPlpi1!Nfu6+^pw&kOj^m>t*x3(2{cS)WI3V7_!FJdj$pCY9; z(Vu0b)!w&GOW#fmy0CCl&sXKYQCELubOx*e1+^jE2Bb}6(?3CKVAId z;epfX-IC{A`E-qK7j84!Fyqu*_EV)7H#B+Q|8ud5>8s#b|D9(KaI5@zKXbN%nsMB! z(#zpj=KY=fRrZC{zJznJ&6_-%ZR9ljEJ9N!^iTRNa8*CBT6RbG<0-d)3anear}x#O z&x``KjrVeGy$`GiQ`I@rZ@Tx1{Bn_2wzFZ@NrQ zE;Z*hchvCxswmfg^llZ;1Wt3kH8W1@DCs#%I?F9Pf25{1lS@~W#mjfqa;sS@KZ%FA z9bXkQvHni5;*pc{-?tskpZ#rR-lWy*|C>iDzMJt>Kc%y*>f6nPoP{ChG_F-`(fG^0 zKzl`wbD8S1;?oP-nU7dae|}$ULQk4p6SIC=9K5GHH}^^qGi8-xySb`v6JbWSnjy#Nfuna{yda>-;v!# zKU>a8uL#Mii2ZX_$NS~WFT1|(F|B=Sv`J}y`xK#x*xT~a z_C*XY4OYLOEHL>@`DN(^6Xz6fGrH7PvsgkkaDf)f)>|S0mCJVhUA83N@9IB;Nj;kQ- z$U^%Q*Yz{&@0u<@XRoo4FF(M7ZG*e)lOHC@-x?lV@Yem#cJ=n{%X=@@eLHYs-Am<& zH1&;h&dj~azU|x5`BVMY?T^wB%iqTMZ_)44^0dDV%*FYfq909+l&7B4__EdMXM)&< z{M%PH-EwE_ePMrAtApoYc}BIFi1wMQtY7jmCK%YC+z-_`bw!kB3y)FuJetHJx!`g z+E2RgcJn4)ThHQ?`8UV*X2A2eIg8Tfz6|zM-znffb;iZb!go%szjboy)6_N6GK+7z zJhO@FTEq#5dvD(E0kimmvBc{G?mHv@)SCper+iH>ci@EmdTizn+hJG?q_K!?>s`q6d$)t-mXtlMSHB~`k*_i>@Ip&eUu?YBg> zgjfv@qY_`YO$x7%nP+dQik{#{YP4GQ)X~w-3EB%fCZ(mWl_eN55^c;zE z7v8+N60pnU`n!xvCMQl^VR@8Zsh1hczJ20jKc&*Jhc2(w@&!yodlxQR(6vcT*U^8$ zLGbs}+e0^Usr46iU%Kcuwk zP9?Z&+%|4>-D{iTKJ$PQ3*RbfAESu%3*R}H1hU8YJxMZhy`peEXjiw$|40{=tBWeW z)NFWBn=xe@uX@0J9_GU9n>)7U_-;4Oo$b5j*Ku3NtK8X(%N4#|5^b;#c*dmX9DQTS zBICrKq-+U>rlL5$H_KwpSwER9{Qhp@(yA}|rY>(|IHGF|$p?!^ATOU+g=g+G(tmBx{_Okr#0riXcc{hNOr@6MO&mu37J!)2D0 zqbkW%v@UDado?p%VXy8|y=kY-ef#$LweR}4W!lwhmj}fvUY9q8t=p69U2~s*OVEo( z9X5^od$yIV?wdY)nNY0%qtCBTrwH^)ZvVZ_=Qe|~ej2Bh#;GmurMB#BzB}RP_sCt@ zRzH0b<+E4rn7P{e>VZpsb(6OJ576cRJj3=qL!D7awXfFJOH%&!AEX=ve@aZd7JcXG z9PNN5(vRhNp1s+>c-ymDWska+SIkA*HX8owK6T}ckDl0$^Nnt@C;lww`nW5=WXUlf zKFh^#zmzVBja7=7e{Sw)#smL5t{C}eJ8XL)WWZXscS*&=iFwyJMdqdHDQeDitx{&_ zTJ-Y9l;u)C-P)37G%QGZQnjt?=`P8`rU`%GLFB@ zV~^G^`<^3-HBA}T@2$E;BR#ukeo1(>IJH+_Y4PWe`|fk5{*`ucyYF_o)8JF7@5e7J zSF@L_Tl}Q^j*HEetZkQb{0i&@TzlfLXn!)9_ByMOJ+#OyNO@(piF1F!kuM8(zg#_+ z&7INKX}?+Kw5yzpewYNL8MzpQu^ajx)7SXee(T1xIomyq?sMF`*`4}k&D+C1FJ8@F zx1>SzP_6Enl)vVIS9e+c2)y^=?ww0zF+mP`U+m&vM*45z-0ji-JFCb)B`PmN{kg@} zRo}x-?VWk`&iRyiJeQxZ3@a3NTD4F!Zq74bg<7dOP0Y4;L<48e%zRzgz#mh$QT&_F z#jkT1l6q8cMjQxLeg3GF|2c2ldfTgKm!~g2R=m5St*|m!!rt-qkVvxuxW7L7d_vt6rMi(RZwSO@DqXf^B9?h{|?8S=4Le@g^k`#Vn0U90wfzqG5- ziPd>V5!;udC0gsJK2yDS_p)`is+2XmLisW2h=miIoVjMCyj*NxxghgY!IE3w9qzDr ze@?k77Hc3j<#L;@nDLuD!-eMz-o1G;ll5}+=gsPul;SQvpFNYmW7m3(`DCo2#>p(y#Rd zoG*J6*V7T;7d)vFOqo&R39nLWA070PMgnECX(eNfbK9f@gM zQkj;EiD;y)<}TS5S$pJ`d6%%?G3k)zH2W79Jnnpy&9&a6y|~qKTRm52tl`7$OQ#pM zUDkTZw=#@r@}D30iM=mj_~+m?^?1UZ1Lv4ln$El{{fJHPWR3Oe zZ#%o}OqG*`*T!Cz=4*+3qa{5xV9lDA*XFnOs9&+OlIxi_dz0tX#@=m`@gB3(LOzum zzA#+h7=+WJTJ=PNG;a!US_{`+UDw#OOLb$l?WEXqasP~eZZutBzvkE0 zC9Wr@G)ILs%#v3Zt9vFqHzoa+P}b6w*Um9Tcur&G*(`qL@}lq0M3yj_6>_T4&UG?&73A38FX~}~kh3k*f z!(SAi-~340coP4#tb2j{9o!4d>r~tw-oIH|wpC89`~J=E6JmTaPb|#IY|lISq(Ju` z$Gl%BD_E{1t6t^Eysno~ zi^xr$DCS?Rd;ZiUpWOa3h1Q87NuOiVwoZ(hue;_6@5O6#d;jEpZJcP;dGs7-r z`phk7WAECpkpF0@)mJNVX2!0MLABf7y>35VGQoCXgI&{6|5^G!)USwTsT+B&K2|$T z{KwQRhTk{OZ8I~ndr@$YLu)}wz|+@vnY8nwZce_G5xTk|v2;(5j`8=xWxSRbz4zU4 zd%5<|kD#9|f=3FU^OrTos@|^%4K@=~x7l`0neV=+XnRe;bKln9$HwjVFMJZr4sic* zWm3icDc@7mcmHuZcw7EkwZGS7+ljWqGvnPJ3gxz$JF}KgeE0Ol=J#r=mZ@D`@9ksy zpW(m;52F)&^WOVsv_&L(PSIZ#aXR7FZga2c^E4_RX)4c*I~Slk=Tiv3YNd4lzTI4^ z0#D{M{M)RtbZ=aM~u^_H*$Bu_aydtDpXGoZWtWQ%T9C^SU=4eSdv+ zrqi`=bItm$`QGJeunEemQ03GT%HO?rzRHVm?^yFrN@?}BDR){rIkn<=nuKk3t1Ds#`)=y^WNyc@PBk~x8B2LdLFNu{sg_eaX!Q^ z?y~odN$b-&%oo4ybb04DB`8op(wOmwjPRvdealXLW~z;Qcr)R?a%g&MgSpbPBgg)y zeE*U$?aex)S&xV|NhhGpKqMfU8~19FW~m!5|w2-`;0#FEw?-_rL)ZaN*vpt>{%Bd_KQXc zCW~mESGW?DKcSDyH~rM*+5?~Gn?3udE!ukS$fsJz+wzrjre0MqN>5)A7und+xSIRn zAG27U`AwhLnr>Upda2sMwZ8QG>xpi=ixL^PJ`Bv6r4+4K_tGL*oWFt3Otf2KPo{}q zT(4=(tg?AMOl|eIU)n|3{p0i%|1hCq^NnKu6YFwci*^5)n>3^IOGAE!w0*zXyKCy5 z;k|Vm+2;I=sE&MdCQ71a%{}?dZ2kJ|cR5OOPv^bct;}6LbLTYEtlQ!By?sAEGU!fN zQJN@S%iPJSlFRn?)GE8E9-r9_+}bA&u8dptr0qs-neZ-_l2A7NC#pZMo>aJFxMtP` z0gok(5!*HxYQ(?w|NQz>PItkAoQEDveW{1z|NPLtecI-n!mZM!vl^d^=jK{vJao#c zGtk`eQ1p{sb458zWb{LKn-714CvDpzZ6198k9p80zm zvuf@3Y7^CqJ-5V`gls-!JL}&L;ZCFaEmtk%br(k)TX$KdR9NBPjOGw=qL&CnP{w4Xi~lMn@ji6LnpPBmP(oBGbBIL16}$ELE-NUN;JCoe^uI(o4^H}v?t9}$~x zbjG#(tY1^n`<;P-s}6K7fcEJK|FsJOTf{g+RzLWnZ~nDnX~uRRwY$N~HY}_57iqlj zG^z08vf|pCzxa+a2T4u%%p7Xg|HRH~>c$<0?-Pm)Pl`#^CjOo&zD4$OMB>^nP5x_N zn0oA)_G(q4%p{Et(V~;dx9=ImoanHtdR9N7_Tz`+8@EY!ODDZ^$mO5EoPBoE&XpO` zrGGA^?YkfTIZ^+}b?Y+{)^_n3(V0(_S`G+qzQ(RmtY7=%jv`ajhvPn)JX7>m^i8c_ ze(O*7!oGN);^W`9b11Gn(e>o>9pwa9UJFUG%)jaqyv15Vh(;3|=tM(Bny!dHGm@KcV2{TKR0bbsD^%3%8tPdKes`SNHL&;AQs449ghVO?7Ha zr@Hv23b+}zPmgT<>hkU;%TgtmJ%3jR+>v6`)?OO)#qPyTyBBAKp1fq++Inl|qS*J` z8X4(K@jbu)Ghc`eIUC|GU9yQw#5;)nYTvChA9EIzA9}bxhc%v~Ch?be`KwRCE}I#G zG*_;ACpERtD*U`(R_p@Xoz|;@qCUScnpNj|p+s=jDIZ}C-%GalQ#yZCF(>|uJC`=W zM}zG_VvP5_+z^JUh9$CBt^JOCv~iPpD!pxf`GGI&Q`K@SXMQ~6ClVR#)96QhsTHrgRnS+0b9_^c$s(&DJ@YxmDU;YYe$H_p``+4}f$uk$d#|}BS&MRs2 zpH{wKaQD*rh6(;9TrC1y8XsINH@a!NG-~PX&PR3E?y5xA?n*i5Bkf$K-0eB~DzS^bw)=~`Ff7elC0K4^`f1~v zm95pSza@5LEn|zfkygLB@oG%G-SL{qv%j*a^vw8_u{3`Ex3>YW%pKM*+_o_40ng@= zFZ>-j+5*dF1fD!$a$08r`+`Kx8HF`VoG#AWBqDy;PU>=2;J+SAj`d>MGxeO@wk=&f zDJj$6df%Djnj6%%#%8lwaxG0cvvac6GY-4kVoP7UrTfU7D}J7HFM5^9tWD+_SA|8r z);ye2qqp|OOOs^2x)+is+w?wrUzXTer6N%ixuIzbSI>fNC7=GXHJxx9ABoeL=XqGP4}dL7T436*yD&C^1pz6mG)$~T=*_U+u0t-p)c3Pvnm z)@Jd#w0XgW{S)qQzgBKH$7@}>#Gy*Ih4VY}_RmR8V-6AibxZKd>#MIN|JS*;w0!p2 z%Ju2u&UZ$Y22Acznid(;Z7+)4!=021=7IjR`c#f!ifOE^$ z!ukFyx5Z>ct*-xT967!6RL7)kr=^pAt%y_DfYZL zWS7??@mk=LQIO2b+XCnII^@c--(t9S!0^oNTPn%riL+k2)ogN&X13Z=+ww+C{qaNZ zPY?1}B&Qg%9o6z*YF%Y8TX><+soAG?PN}=ab9y>cOsLp92hDqjei`joe!Y!x)f7RW zkBR-OCFgzMo*@72u3Wrsr*`F{|KFQ4mnMD``FBerF_ZaheZ;Kr<&9e$e3i^6oVd^N z^UvuXgPW|nHy=K|rF8b<8eN4ii$vN4e=Pg$@=}81gGQ^!*-oqS@(i~v0p;fog@1X} z*&QX%arHB&^!gQdx2}!q;9l^T=clzow|36n>zkMz-#^(kkMXW}T}zHGZ;AJ3p%1H< zh;^lJ4!)LeB2tul)lW~BKSi`(WbxcI23eo9X<50h?5~BytWOsu%vG|`yt>*x;~eiy zOWRrUug-?=m40Jsl4hIjmUZTjgd<b?qwz>yZaVf2ZR+bv7fwh`QGpUck^a^>YU52^{(ND-BS6+GpCs@MQ(m8 z}@Uc{)qaA^v^pI{Ld$RoOvr|g~X%U=wB??JmqVje7~o-c|-L- z;jMpv?sVGxsP%zzGA`Ci00S4WiA(Nx9>XoKz84CT@~etc`6n%|K;DvFzgTe~ HDWM4fOf%d3 literal 0 HcmV?d00001 diff --git a/textures/fizzside.png b/textures/fizzside.png new file mode 100644 index 0000000000000000000000000000000000000000..b25eb0f6a71505c425fe140e892d6e2702f1a51c GIT binary patch literal 3056 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 D_1@Nl literal 0 HcmV?d00001 diff --git a/textures/fizztop.png b/textures/fizztop.png new file mode 100644 index 0000000000000000000000000000000000000000..51fed753db8f6a3e6aac527b95b03bd36fefd0c5 GIT binary patch literal 8360 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 Z=-%c-f$yIiF)%PNc)I$ztaD0e0svjPAv*v7 literal 0 HcmV?d00001 diff --git a/textures/warptex.png b/textures/warptex.png new file mode 100644 index 0000000000000000000000000000000000000000..de45a9d0d93f75b2c005fc774edb804486fc9a74 GIT binary patch literal 28936 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 literal 0 HcmV?d00001 diff --git a/zscript/compat.zsc b/zscript/compat.zsc index 4f6ea5f..412b609 100644 --- a/zscript/compat.zsc +++ b/zscript/compat.zsc @@ -1,3 +1,199 @@ -// TODO Heretic keys +// Heretic keys +Class UTHereticYellowKey : KeyYellow +{ + Default + { + Tag "Red Key"; + Species "KeyYellow"; + Inventory.PickupMessage "You got the Yellow Key."; + } + States + { + Spawn: + UKEY B -1; + Stop; + } +} -// TODO Alternative player classes used for compatibility with Heretic, Hexen, Strife and Chex +Class UTHereticGreenKey : KeyGreen +{ + Default + { + Tag "Green Key"; + Species "KeyGreen"; + Inventory.PickupMessage "You got the Green Key."; + } + States + { + Spawn: + UKEY D -1; + Stop; + } +} + +Class UTHereticBlueKey : KeyBlue +{ + Default + { + Tag "Blue Key"; + Species "KeyBlue"; + Inventory.PickupMessage "You got the Blue Key."; + } + States + { + Spawn: + UKEY C -1; + Stop; + } +} + +// Alternative player classes for compatibility with Heretic sprites +Class UTPlayerHereticCompat : UTPlayer +{ + Default + { + Player.ColorRange 225, 240; + Player.Colorset 0, "Green", 225, 240, 238; + Player.Colorset 1, "Yellow", 114, 129, 127; + Player.Colorset 2, "Red", 145, 160, 158; + Player.Colorset 3, "Blue", 190, 205, 203; + Player.Colorset 4, "Brown", 67, 82, 80; + Player.Colorset 5, "Light Gray", 9, 24, 22; + Player.Colorset 6, "Light Brown", 74, 89, 87; + Player.Colorset 7, "Light Red", 150, 165, 163; + Player.Colorset 8, "Light Blue", 192, 207, 205; + Player.Colorset 9, "Beige", 95, 110, 108; + } + States + { + Spawn: + PLAY A -1; + Stop; + See: + PLAY ABCD 4; + Loop; + Melee: + Missile: + PLAY F 6 BRIGHT; + PLAY E 12; + Goto Spawn; + Pain: + PLAY G 4; + PLAY G 4 A_Pain; + Goto Spawn; + Death: + PLAY H 6 A_PlayerSkinCheck("AltSkinDeath"); + PLAY I 6 A_PlayerScream; + PLAY JK 6; + PLAY L 6 A_NoBlocking; + PLAY MNO 6; + PLAY P -1; + Stop; + XDeath: + PLAY Q 0 A_PlayerSkinCheck("AltSkinXDeath"); + PLAY Q 5 A_PlayerScream; + PLAY R 0 A_NoBlocking; + PLAY R 5 A_SkullPop; + PLAY STUVWX 5; + PLAY Y -1; + Stop; + Burn: + FDTH A 5 BRIGHT A_PlaySound("*burndeath"); + FDTH B 4 BRIGHT; + FDTH C 5 BRIGHT; + FDTH D 4 BRIGHT A_PlayerScream; + FDTH E 5 BRIGHT; + FDTH F 4 BRIGHT; + FDTH G 5 BRIGHT A_PlaySound("*burndeath"); + FDTH H 4 BRIGHT; + FDTH I 5 BRIGHT; + FDTH J 4 BRIGHT; + FDTH K 5 BRIGHT; + FDTH L 4 BRIGHT; + FDTH M 5 BRIGHT; + FDTH N 4 BRIGHT; + FDTH O 5 BRIGHT A_NoBlocking; + FDTH P 4 BRIGHT; + FDTH Q 5 BRIGHT; + FDTH R 4 BRIGHT; + ACLO E 35 A_CheckPlayerDone; + Wait; + AltSkinDeath: + PLAY H 10; + PLAY I 10 A_PlayerScream; + PLAY J 10 A_NoBlocking; + PLAY KLM 10; + PLAY N -1; + Stop; + AltSkinXDeath: + PLAY O 5; + PLAY P 5 A_XScream; + PLAY Q 5 A_NoBlocking; + PLAY RSTUV 5; + PLAY W -1; + Stop; + } +} + +Class UTPlayerHereticCompatTMale1 : UTPlayerHereticCompat +{ + Default + { + Player.SoundClass "tmale1"; + Player.DisplayName "M Commando"; + Player.Portrait "Blake"; + -NOMENU; + } +} +Class UTPlayerHereticCompatTMale2 : UTPlayerHereticCompat +{ + Default + { + Player.SoundClass "tmale2"; + Player.DisplayName "M Soldier"; + Player.Portrait "Brock"; + -NOMENU; + } +} +Class UTPlayerHereticCompatTFemale1 : UTPlayerHereticCompat +{ + Default + { + Player.SoundClass "tfemale"; + Player.DisplayName "F Commando"; + Player.Portrait "Ivana"; + UTPlayer.DollType DOLL_Female; + -NOMENU; + } +} +Class UTPlayerHereticCompatTFemale2 : UTPlayerHereticCompat +{ + Default + { + Player.SoundClass "tfemale"; + Player.DisplayName "F Soldier"; + Player.Portrait "Lauren"; + UTPlayer.DollType DOLL_Female; + -NOMENU; + } +} +Class UTPlayerHereticCompatTBoss : UTPlayerHereticCompat +{ + transient CVar bossfootsteps; + Default + { + Player.SoundClass "tboss"; + Player.DisplayName "Boss"; + Player.Portrait "Xan"; + UTPlayer.DollType DOLL_Boss; + // should have NOBLOOD, but Xan did bleed in vanilla UT so... + // (this is what gave birth to the theory that Xan was actually Jerl Liandri himself) + -NOMENU; + } + override void PlayFootstep( double vol ) + { + if ( !bossfootsteps ) bossfootsteps = CVar.GetCVar('flak_bossfootsteps',players[consoleplayer]); + if ( bossfootsteps.GetBool() ) A_PlaySound("ut/bossfootstep",CHAN_5,vol); + else Super.PlayFootstep(vol); + } +} \ No newline at end of file diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index c039703..d65c938 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -1411,54 +1411,64 @@ Class UTMainHandler : StaticEventHandler override void CheckReplacement( ReplaceEvent e ) { - if ( e.Replacee == 'Chainsaw' ) + if ( (e.Replacee == 'Chainsaw') || (e.Replacee == 'Gauntlets') ) { if ( Random[Replacements](0,1) ) e.Replacement = 'UTChainsaw'; else e.Replacement = 'Enforcer'; } - else if ( e.Replacee == 'Fist' ) e.Replacement = 'ImpactHammer'; - else if ( e.Replacee == 'Pistol' ) e.Replacement = 'Enforcer'; - else if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') ) + else if ( (e.Replacee == 'Fist') || (e.Replacee == 'Staff') ) e.Replacement = 'ImpactHammer'; + else if ( (e.Replacee == 'Pistol') || (e.Replacee == 'GoldWand') ) e.Replacement = 'Enforcer'; + else if ( (e.Replacee == 'Shotgun') || (e.Replacee == 'SuperShotgun') || (e.Replacee == 'Crossbow') ) { if ( !Random[Replacements](0,3) ) e.Replacement = 'Enforcer'; else if ( Random[Replacements](0,1) ) e.Replacement = 'BioRifle'; else e.Replacement = 'ShockRifle'; } - else if ( e.Replacee == 'Chaingun' ) + else if ( (e.Replacee == 'Chaingun') || (e.Replacee == 'Blaster') ) { if ( Random[Replacements](0,2) ) e.Replacement = 'PulseGun'; else e.Replacement = 'Ripper2'; } - else if ( e.Replacee == 'RocketLauncher' ) + else if ( (e.Replacee == 'RocketLauncher') || (e.Replacee == 'PhoenixRod') ) { if ( Random[Replacements](0,1) ) e.Replacement = 'FlakCannon'; else e.Replacement = 'UTRocketLauncher'; } - else if ( e.Replacee == 'PlasmaRifle' ) + else if ( (e.Replacee == 'PlasmaRifle') || (e.Replacee == 'SkullRod') ) { if ( Random[Replacements](0,1) ) e.Replacement = 'Minigun'; else e.Replacement = 'SniperRifle'; } else if ( e.Replacee == 'BFG9000' ) e.Replacement = 'WarheadLauncher'; - else if ( e.Replacee == 'Clip' ) e.Replacement = 'EClip'; - else if ( e.Replacee == 'ClipBox' ) + else if ( e.Replacee == 'Mace' ) + { + if ( !Random[Replacements](0,6) ) e.Replacement = 'EnhancedShockRifle'; + else e.Replacement = 'WarheadLauncher'; + } + else if ( (e.Replacee == 'Clip') || (e.Replacee == 'GoldWandAmmo') || (e.Replacee == 'GoldWandHefty') ) e.Replacement = 'EClip'; + else if ( (e.Replacee == 'ClipBox') ) { if ( !Random[Replacements](0,2) ) e.Replacement = 'EClip'; else if ( Random[Replacements](0,2) ) e.Replacement = 'PulseAmmo'; else e.Replacement = 'RipperAmmo'; } - else if ( e.Replacee == 'Shell' ) + else if ( (e.Replacee == 'BlasterAmmo') || (e.Replacee == 'BlasterHefty') ) + { + if ( Random[Replacements](0,2) ) e.Replacement = 'PulseAmmo'; + else e.Replacement = 'RipperAmmo'; + } + else if ( (e.Replacee == 'Shell') || (e.Replacee == 'CrossbowAmmo') ) { if ( !Random[Replacements](0,2) ) e.Replacement = 'EClip'; else if ( Random[Replacements](0,1) ) e.Replacement = 'BioAmmo2'; else e.Replacement = 'ShockAmmo2'; } - else if ( e.Replacee == 'ShellBox' ) + else if ( (e.Replacee == 'ShellBox') || (e.Replacee == 'CrossbowHefty') ) { if ( Random[Replacements](0,1) ) e.Replacement = 'BioAmmo'; else e.Replacement = 'ShockAmmo'; } - else if ( e.Replacee == 'RocketAmmo' ) + else if ( (e.Replacee == 'RocketAmmo') || (e.Replacee == 'PhoenixRodAmmo') || (e.Replacee == 'MaceAmmo') ) { if ( Random[Replacements](0,1) ) { @@ -1471,38 +1481,51 @@ Class UTMainHandler : StaticEventHandler else e.Replacement = 'UTRocketAmmo2'; } } - else if ( e.Replacee == 'RocketBox' ) + else if ( (e.Replacee == 'RocketBox') || (e.Replacee == 'PhoenixRodHefty') || (e.Replacee == 'MaceHefty') ) { if ( Random[Replacements](0,1) ) e.Replacement = 'FlakAmmo'; else e.Replacement = 'UTRocketAmmo'; } - else if ( e.Replacee == 'Cell' ) + else if ( (e.Replacee == 'Cell') || (e.Replacee == 'SkullRodAmmo') ) { if ( Random[Replacements](0,1) ) e.Replacement = 'EClip'; else if ( !Random[Replacements](0,3) ) e.Replacement = 'RifleAmmo'; else e.Replacement = 'RifleAmmo2'; } - else if ( e.Replacee == 'CellPack' ) + else if ( (e.Replacee == 'CellPack') || (e.Replacee == 'SkullRodHefty') ) { if ( !Random[Replacements](0,6) ) e.Replacement = 'WarheadAmmo'; else if ( Random[Replacements](0,1) ) e.Replacement = 'MiniAmmo'; else e.Replacement = 'RifleAmmo'; } else if ( e.Replacee == 'InvulnerabilitySphere' ) e.Replacement = 'EnhancedShockRifle'; - else if ( e.Replacee == 'Berserk' ) e.Replacement = 'UDamage'; - else if ( e.Replacee == 'Soulsphere' ) e.Replacement = 'UTHealthPack'; - else if ( e.Replacee == 'Megasphere' ) e.Replacement = 'UTShieldBelt'; - else if ( e.Replacee == 'Allmap' ) e.Replacement = 'UTMapRevealer'; - else if ( e.Replacee == 'BlurSphere' ) e.Replacement = 'UTInvisibility'; - else if ( e.Replacee == 'Infrared' ) e.Replacement = 'Searchlight'; - else if ( e.Replacee == 'RadSuit' ) e.Replacement = 'UTJumpBoots'; - else if ( e.Replacee == 'Backpack' ) e.Replacement = 'UTBackpack'; - else if ( e.Replacee == 'ArmorBonus' ) e.Replacement = 'UTArmorBonus'; - else if ( e.Replacee == 'HealthBonus' ) e.Replacement = 'UTHealthBonus'; - else if ( e.Replacee == 'GreenArmor' ) e.Replacement = 'UTThighPads'; - else if ( e.Replacee == 'BlueArmor' ) e.Replacement = 'UTBodyArmor'; + else if ( (e.Replacee == 'Berserk') || (e.Replacee == 'ArtiTomeOfPower') || (e.Replacee == 'ArtiEgg') ) e.Replacement = 'UDamage'; + else if ( (e.Replacee == 'Soulsphere') || (e.Replacee == 'ArtiSuperHealth') ) e.Replacement = 'UTHealthPack'; + else if ( (e.Replacee == 'Megasphere') || (e.Replacee == 'ArtiInvulnerability') ) e.Replacement = 'UTShieldBelt'; + else if ( (e.Replacee == 'Allmap') || (e.Replacee == 'SuperMap') ) e.Replacement = 'UTMapRevealer'; + else if ( (e.Replacee == 'BlurSphere') || (e.Replacee == 'ArtiInvisibility') ) e.Replacement = 'UTInvisibility'; + else if ( (e.Replacee == 'Infrared') || (e.Replacee == 'ArtiTorch') ) e.Replacement = 'Searchlight'; + else if ( (e.Replacee == 'RadSuit') || (e.Replacee == 'ArtiFly') ) e.Replacement = 'UTJumpBoots'; + else if ( (e.Replacee == 'Backpack') || (e.Replacee == 'BagOfHolding') ) e.Replacement = 'UTBackpack'; + else if ( (e.Replacee == 'ArmorBonus') || (e.Replacee == 'ArtiTimeBomb') ) e.Replacement = 'UTArmorBonus'; + else if ( (e.Replacee == 'HealthBonus') || (e.Replacee == 'CrystalVial') ) e.Replacement = 'UTHealthBonus'; + else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'Silvershield') ) e.Replacement = 'UTThighPads'; + else if ( (e.Replacee == 'BlueArmor') || (e.Replacee == 'EnchantedShield') ) e.Replacement = 'UTBodyArmor'; else if ( e.Replacee == 'Stimpack' ) e.Replacement = 'UTMedBox'; else if ( e.Replacee == 'Medikit' ) e.Replacement = 'UTHealthBox'; + else if ( e.Replacee == 'ArtiHealth' ) + { + if ( !Random[Replacements](0,3) ) e.Replacement = 'UTHealthBox'; + else e.Replacement = 'UTMedBox'; + } + else if ( e.Replacee == 'ArtiTeleport' ) + { + // I have no idea what to replace this with, so just have some random stuff + if ( Random[Replacements](0,1) ) e.Replacement = 'UTBackpack'; + else if ( Random[Replacements](0,1) ) e.Replacement = 'UTShieldBelt'; + else if ( Random[Replacements](0,1) ) e.Replacement = 'UTHealthPack'; + else e.Replacement = 'UDamage'; + } else if ( e.Replacee == 'RedCard' ) e.Replacement = 'UTRedKey'; else if ( e.Replacee == 'BlueCard' ) e.Replacement = 'UTBlueKey'; else if ( e.Replacee == 'YellowCard' ) e.Replacement = 'UTGoldKey'; @@ -1512,6 +1535,9 @@ Class UTMainHandler : StaticEventHandler else if ( e.Replacee == 'TeleportFog' ) e.Replacement = 'UTTeleportFog'; else if ( e.Replacee == 'ItemFog' ) e.Replacement = 'UTItemFog'; else if ( flak_blood && (e.Replacee == 'Blood') ) e.Replacement = 'UTBlood'; + else if ( e.Replacee == 'KeyYellow' ) e.Replacement = 'UTHereticYellowKey'; + else if ( e.Replacee == 'KeyGreen' ) e.Replacement = 'UTHereticGreenKey'; + else if ( e.Replacee == 'KeyBlue' ) e.Replacement = 'UTHereticBlueKey'; } private Actor AddLight( Vector3 pos, Color col, int radius ) @@ -1635,6 +1661,101 @@ Class UTMainHandler : StaticEventHandler AddAmbient((3584,736,64),"testamb/slime",0.4,2.4); AddAmbient((3584,512,64),"testamb/lava",0.8,2.4); } + else if ( level.GetChecksum() ~== "D8206A3414DA967F2159473B5791139E" ) + { + TextureID deftex = TexMan.CheckForTexture("-noflat-",TexMan.Type_Any); + TextureID skytx = TexMan.CheckForTexture("BlueSky",TexMan.Type_Any); + TextureID baseflor = TexMan.CheckForTexture("rClfFlr0",TexMan.Type_Any); + TextureID baseceil = TexMan.CheckForTexture("rClfBas0",TexMan.Type_Any); + TextureID basewall = TexMan.CheckForTexture("uAlnWl2b",TexMan.Type_Any); + TextureID xbasewall = TexMan.CheckForTexture("xAlnWl2b",TexMan.Type_Any); + TextureID glasstex = TexMan.CheckForTexture("Glassg",TexMan.Type_Any); + level.ChangeSky(skytx,skytx); + for ( int i=0; i Date: Mon, 21 Jan 2019 22:57:56 +0100 Subject: [PATCH 3/6] Assorted changes, including some code cleanup and more accurate UT physics for various projectiles. I also made the Kinsie's Test Map tweaks toggleable because someone didn't like them. --- cvarinfo.txt | 1 + menudef.txt | 1 + textures.misc | 7 ++ zscript/biorifle.zsc | 134 +++++++++++++++++++-------------------- zscript/eightball.zsc | 31 +++++++-- zscript/enforcer.zsc | 12 +++- zscript/flakcannon.zsc | 9 ++- zscript/ripper.zsc | 3 +- zscript/translocator.zsc | 22 +++++-- zscript/utcommon.zsc | 20 +++++- zscript/utgore.zsc | 37 ++++++++--- 11 files changed, 174 insertions(+), 103 deletions(-) diff --git a/cvarinfo.txt b/cvarinfo.txt index 9818139..e769b3d 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -38,3 +38,4 @@ server float flak_swingerstrength = 0.5; // strength of visual recoil server bool flak_radboots = true; // jump boots protect against damaging floors (this is to account for the lack of a radsuit) server bool flak_blood = true; // [WIP] use doom tournament blood (disable if using another gore mod) server bool flak_gibs = false; // [WIP/UNSTABLE] use doom tournament gibbing (disable if using another gore mod) +server bool flak_doomtest = false; // made toggleable due to loud complaints diff --git a/menudef.txt b/menudef.txt index cadc6e9..fb10856 100644 --- a/menudef.txt +++ b/menudef.txt @@ -66,6 +66,7 @@ OptionMenu "UTOptionMenu" Option "UT Blood", "flak_blood", "YesNo" Option "[WIP] UT Gibbing", "flak_gibs", "YesNo" Option "[WIP] Corpses Take Damage", "flak_corpsedamage", "YesNo" + Option "Edit Kinsie's Test Map", "flak_doomtest", "YesNo" } AddOptionMenu "OptionsMenu" diff --git a/textures.misc b/textures.misc index 1022a10..fa15ada 100644 --- a/textures.misc +++ b/textures.misc @@ -1,3 +1,10 @@ +Texture "DefTex",128,128 +{ + XScale 4 + YScale 4 + WorldPanning + Patch "-noflat-", 0, 0 +} Sprite "HBOXA0",1,1{} Sprite "HBOXB0",1,1{} Sprite "HBOXC0",1,1{} diff --git a/zscript/biorifle.zsc b/zscript/biorifle.zsc index b82e595..51e84b7 100644 --- a/zscript/biorifle.zsc +++ b/zscript/biorifle.zsc @@ -198,8 +198,6 @@ Class BioGel : Actor deadtimer = -1; l = Spawn("BioLight",pos); l.target = self; - b = Spawn("BioHitbox",pos); - b.target = self; rollvel = FRandom[GES](10,30)*RandomPick[GES](-1,1); pitchvel = FRandom[GES](10,30)*RandomPick[GES](-1,1); yawvel = FRandom[GES](10,30)*RandomPick[GES](-1,1); @@ -297,72 +295,8 @@ Class BioGel : Actor SetStateLabel("XDeath"); return; } - FLineTraceData d; A_SetSize(0.1,0); - if ( BlockingLine ) - { - atline = BlockingLine; - normal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit(); - atside = 1; - if ( !BlockingLine.sidedef[1] || (CurSector == BlockingLine.frontsector) ) - { - atside = 0; - normal *= -1; - } - Vector3 orig = (BlockingLine.v1.p.x,BlockingLine.v1.p.y,0); - Vector3 onwall = pos-(normal dot (pos-orig))*normal; - SetOrigin(onwall+normal*0.5,false); - // attempt to guess line part (upper/mid/lower) - if ( !atline.sidedef[1] ) atpart = 0; // mid - else if ( atline.sidedef[atside?0:1].sector.ceilingplane.ZAtPoint(pos.xy) < pos.z ) atpart = 1; // upper - else if ( atline.sidedef[atside?0:1].sector.floorplane.ZAtPoint(pos.xy) > pos.z ) atpart = -1; // lower - else atpart = 0; - if ( atpart == 1 ) - { - if ( atline.flags&Line.ML_DONTPEGTOP ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1); - else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(1); - } - else if ( atpart == -1 ) - { - if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0); - else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(0); - } - else if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0); - else atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1); - angle = atan2(normal.y,normal.x); - pitch = 0; - roll = 180; // otherwise it slides upwards (UT changes roll like this too) - if ( waterlevel > 0 ) hittype = HIT_FLOOR; - else hittype = HIT_WALL; - } - else if ( pos.z <= floorz+4 ) - { - atsector = cursector; - atplane = 0; - normal = cursector.floorplane.Normal; - pitch = asin(-normal.z); - angle = atan2(normal.y,normal.x); - roll = FRandom[GES](0,360); - SetOrigin((pos.x,pos.y,floorz)+normal*0.5,false); - atz = pos.z-cursector.GetPlaneTexZ(0); - hittype = HIT_FLOOR; - } - else if ( pos.z >= ceilingz-8 ) - { - atsector = cursector; - atplane = 1; - normal = cursector.ceilingplane.Normal; - pitch = asin(-normal.z); - angle = atan2(normal.y,normal.x); - roll = FRandom[GES](0,360); - SetOrigin((pos.x,pos.y,ceilingz)+normal*0.5,false); - atz = pos.z-cursector.GetPlaneTexZ(1); - if ( waterlevel > 0 ) hittype = HIT_FLOOR; - else if ( normal dot (0,0,-1) > 0.7 ) - hittype = HIT_CEILING; - else hittype = HIT_FLOOR; - } - else if ( tracer && tracer.bACTLIKEBRIDGE ) + if ( tracer && tracer.bACTLIKEBRIDGE ) { atbridge = tracer; onbridge = true; @@ -461,11 +395,77 @@ Class BioGel : Actor } } } + else if ( BlockingFloor ) + { + atsector = BlockingFloor; + atplane = 0; + normal = BlockingFloor.floorplane.Normal; + pitch = asin(-normal.z); + angle = atan2(normal.y,normal.x); + roll = FRandom[GES](0,360); + SetOrigin((pos.x,pos.y,floorz)+normal*0.5,false); + atz = pos.z-BlockingFloor.GetPlaneTexZ(0); + hittype = HIT_FLOOR; + } + else if ( BlockingCeiling ) + { + atsector = BlockingCeiling; + atplane = 1; + normal = BlockingCeiling.ceilingplane.Normal; + pitch = asin(-normal.z); + angle = atan2(normal.y,normal.x); + roll = FRandom[GES](0,360); + SetOrigin((pos.x,pos.y,ceilingz)+normal*0.5,false); + atz = pos.z-BlockingCeiling.GetPlaneTexZ(1); + if ( waterlevel > 0 ) hittype = HIT_FLOOR; + else if ( normal dot (0,0,-1) > 0.7 ) + hittype = HIT_CEILING; + else hittype = HIT_FLOOR; + } + else + if ( BlockingLine ) + { + atline = BlockingLine; + normal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit(); + atside = 1; + if ( !BlockingLine.sidedef[1] || (CurSector == BlockingLine.frontsector) ) + { + atside = 0; + normal *= -1; + } + Vector3 orig = (BlockingLine.v1.p.x,BlockingLine.v1.p.y,0); + Vector3 onwall = pos-(normal dot (pos-orig))*normal; + SetOrigin(onwall+normal*0.5,false); + // attempt to guess line part (upper/mid/lower) + if ( !atline.sidedef[1] ) atpart = 0; // mid + else if ( atline.sidedef[atside?0:1].sector.ceilingplane.ZAtPoint(pos.xy) < pos.z ) atpart = 1; // upper + else if ( atline.sidedef[atside?0:1].sector.floorplane.ZAtPoint(pos.xy) > pos.z ) atpart = -1; // lower + else atpart = 0; + if ( atpart == 1 ) + { + if ( atline.flags&Line.ML_DONTPEGTOP ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1); + else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(1); + } + else if ( atpart == -1 ) + { + if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0); + else atz = pos.z-atline.sidedef[atside?0:1].sector.GetPlaneTexZ(0); + } + else if ( atline.flags&Line.ML_DONTPEGBOTTOM ) atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(0); + else atz = pos.z-atline.sidedef[atside].sector.GetPlaneTexZ(1); + angle = atan2(normal.y,normal.x); + pitch = 0; + roll = 180; // otherwise it slides upwards (UT changes roll like this too) + if ( waterlevel > 0 ) hittype = HIT_FLOOR; + else hittype = HIT_WALL; + } else { SetStateLabel("XDeath"); return; } + b = Spawn("BioHitbox",pos); + b.target = self; A_PlaySound("ges/hit"); A_SprayDecal("BioSplat",-172); int numpt = Min(100,int(Scale.x*10))+Random[GES](-5,5); diff --git a/zscript/eightball.zsc b/zscript/eightball.zsc index 4a5fc89..a099255 100644 --- a/zscript/eightball.zsc +++ b/zscript/eightball.zsc @@ -221,11 +221,11 @@ Class UTGrenade : UTRocket DamageType 'GrenadeDeath'; -NOGRAVITY; +USEBOUNCESTATE; - -BOUNCEAUTOOFF; - +BOUNCEAUTOOFFFLOORONLY; -EXPLODEONWATER; +CANBOUNCEWATER; - BounceType "Doom"; + +NOEXPLODEFLOOR; + BounceType "Hexen"; + WallBounceFactor 0.75; BounceFactor 0.75; ReactionTime 85; Speed 20; @@ -243,20 +243,37 @@ Class UTGrenade : UTRocket Spawn: RCKT A 1 { - angle += anglevel; - pitch += pitchvel; - roll += rollvel; + if ( !bNOGRAVITY ) + { + angle += anglevel; + pitch += pitchvel; + roll += rollvel; + } + let s = Spawn("UTSmoke",pos); + s.scale *= 2.0; + s.alpha *= 0.6; + s.vel = (FRandom[Eightball](-0.1,0.1),FRandom[Eightball](-0.1,0.1),FRandom[Eightball](-0.1,0.3)); + s.vel += vel*0.05; + s.SetShade("000000"); A_Countdown(); } Wait; Bounce: RCKT A 0 { + bHITOWNER = true; A_PlaySound("utrl/bounce"); rollvel = FRandom[Eightball](-16,16); pitchvel = FRandom[Eightball](-16,16); anglevel = FRandom[Eightball](-16,16); - bHITOWNER = true; + if ( vel.z > 10 ) vel.z = 0.5*(10+vel.z); + else if ( BlockingFloor && (vel.xy.length() < 0.5) ) + { + vel *= 0; + bNOGRAVITY = true; + bMOVEWITHSECTOR = true; + ClearBounce(); + } } Goto Spawn; Death: diff --git a/zscript/enforcer.zsc b/zscript/enforcer.zsc index f016fbb..dfea801 100644 --- a/zscript/enforcer.zsc +++ b/zscript/enforcer.zsc @@ -88,7 +88,7 @@ Class BulletImpact : Actor Class UTCasing : Actor { - int deadtimer; + int deadtimer, numbounces; double pitchvel, anglevel; double heat; @@ -102,7 +102,9 @@ Class UTCasing : Actor +THRUACTORS; +USEBOUNCESTATE; +INTERPOLATEANGLES; - BounceType "Doom"; + Mass 1; + BounceType "Hexen"; + WallBounceFactor 0.65; BounceFactor 0.65; BounceSound "bullet/casing"; } @@ -144,6 +146,12 @@ Class UTCasing : Actor pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1); vel = (vel.unit()+(FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2))).unit()*vel.length(); + if ( numbounces && ((numbounces > 3) || (Random[Junk](1,20) < 17) || (vel.z > -1.4)) ) + { + ClearBounce(); + ExplodeMissile(); + } + numbounces++; } Goto Spawn; Death: diff --git a/zscript/flakcannon.zsc b/zscript/flakcannon.zsc index fd2520e..1c43cbc 100644 --- a/zscript/flakcannon.zsc +++ b/zscript/flakcannon.zsc @@ -166,12 +166,11 @@ Class FlakChunk : Actor Speed 50; DamageFunction Random[Flak](15,20); DamageType 'Shredded'; - BounceType "Doom"; + BounceType "Hexen"; BounceFactor 0.8; WallBounceFactor 0.8; PROJECTILE; +USEBOUNCESTATE; - -BOUNCEAUTOOFF; +CANBOUNCEWATER; +SKYEXPLODE; +INTERPOLATEANGLES; @@ -232,9 +231,8 @@ Class FlakChunk : Actor action void A_HandleBounce() { bHITOWNER = true; - A_SprayDecal("WallCrack",-8); int numpt = Random[Flak](2,3); - if ( frame < 10 ) + if ( (frame < 10) && Random[Flak](0,1) ) { for ( int i=0; i 0) || target.InStateSequence(target.CurState,target.FindState("XDeath")) ) + if ( !flak_corpsedamage || !target || (target.Health > 0) || target.InStateSequence(target.CurState,target.FindState("XDeath")) ) { Destroy(); return; @@ -1300,6 +1302,7 @@ Class ShredCorpseHitbox : Actor { // force gib (cheap ATM) State gib = target.FindState("XDeath"); + if ( !gib ) gib = target.FindState("Death.Extreme"); if ( gib ) target.SetState(gib); Destroy(); } @@ -1562,8 +1565,15 @@ Class UTMainHandler : StaticEventHandler override void WorldLoaded( WorldEvent e ) { if ( gamestate != GS_LEVEL || e.IsSaveGame ) return; - // prettify Kinsie's test map for a more Unreal feel let level = currentSession.levelinfo[0]; + // just replace the -noflat- with a better scaled version + if ( !flak_doomtest ) + { + if ( (level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33") || (level.GetChecksum() ~== "D8206A3414DA967F2159473B5791139E") ) + level.ReplaceTextures("-noflat-","DefTex",0); + return; + } + // prettify Kinsie's test map for a more Unreal feel if ( level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33" ) { TextureID deftex = TexMan.CheckForTexture("-noflat-",TexMan.Type_Any); @@ -1838,6 +1848,9 @@ Class UTMainHandler : StaticEventHandler override void RenderOverlay( RenderEvent e ) { + // well this if sure is a long one + if ( players[consoleplayer].camera.player && players[consoleplayer].camera.player.ReadyWeapon && (players[consoleplayer].camera.player.ReadyWeapon is 'UTWeapon') ) + UTWeapon(players[consoleplayer].camera.player.ReadyWeapon).RenderOverlay(e); if ( !menuactive ) return; if ( tex.IsNull() || !tex.IsValid() ) return; if ( !CVar.GetCVar('flak_showmenu',players[consoleplayer]).GetBool() ) return; @@ -1849,11 +1862,12 @@ Class UTMainHandler : StaticEventHandler { if ( e.Thing.bDONTGIB ) return; // gibbers - if ( flak_gibs && !e.Thing.bNOBLOOD && ((e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.Thing.Health < e.Thing.GetGibHealth())) && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH) ) + if ( flak_gibs && !e.Thing.bNOBLOOD && (e.Thing.FindState("XDeath") || e.Thing.FindState("Death.Extreme")) && ((e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.Thing.Health < e.Thing.GetGibHealth())) && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH) ) { // players have special gibbing if ( e.Thing.player ) { + // TODO return; } // generic gibbing diff --git a/zscript/utgore.zsc b/zscript/utgore.zsc index 930c07c..18ba524 100644 --- a/zscript/utgore.zsc +++ b/zscript/utgore.zsc @@ -8,6 +8,7 @@ Class UTBlood : Actor +NOBLOCKMAP; +NOGRAVITY; +NOTELEPORT; + +DONTSPLASH; +FORCEXYBILLBOARD; +PUFFGETSOWNER; } @@ -61,6 +62,7 @@ Class UTBloodDrop : Actor Default { Scale 0.24; + Mass 1; Radius 2; Height 2; RenderStyle "Translucent"; @@ -99,6 +101,7 @@ Class UTBloodSpurt : Actor { +NOBLOCKMAP; +NOGRAVITY; + +DONTSPLASH; +NOTELEPORT; +THRUACTORS; } @@ -134,6 +137,7 @@ Class UTBloodTrail : Actor +NOBLOCKMAP; +NOGRAVITY; +NOTELEPORT; + +DONTSPLASH; +THRUACTORS; } override void PostBeginPlay() @@ -183,6 +187,7 @@ Class UTBloodPuff : Actor +NOBLOCKMAP; +NOGRAVITY; +NOTELEPORT; + +DONTSPLASH; +FORCEXYBILLBOARD; } States @@ -284,12 +289,13 @@ Class UTGib : Actor { Radius 4; Height 4; - BounceType "Doom"; - BounceFactor 0.7; - WallBounceFactor 0.7; + BounceType "Hexen"; + BounceFactor 0.8; + WallBounceFactor 0.8; +ROLLSPRITE; +ROLLCENTER; +INTERPOLATEANGLES; + +CANBOUNCEWATER; +MISSILE; +THRUACTORS; +USEBOUNCESTATE; @@ -297,19 +303,30 @@ Class UTGib : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - let t = Spawn("UTBloodTrail",pos); - t.target = self; - if ( bloodcolor ) t.SetShade(bloodcolor); - else t.SetShade(gameinfo.defaultbloodcolor); - t.translation = bloodtranslation; + tracer = Spawn("UTBloodTrail",pos); + tracer.target = self; + if ( bloodcolor ) tracer.SetShade(bloodcolor); + else tracer.SetShade(gameinfo.defaultbloodcolor); + tracer.translation = bloodtranslation; rollvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1); anglevel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1); pitchvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1); } void A_HandleBounce() { - if ( vel.length() > double.epsilon ) - vel = (vel.unit()+(FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2))).unit()*vel.length(); + double spd = vel.length(); + if ( spd > double.epsilon ) + vel = (vel.unit()+(FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2))).unit()*spd; + if ( BlockingFloor && (vel.xy.length() < 1) ) + { + ClearBounce(); + ExplodeMissile(); + } + if ( spd < 10 ) + { + if ( tracer ) tracer.Destroy(); + } + else if ( spd > 20 ) vel *= 0.8; A_PlaySound("misc/gibp"); double ang, pt; for ( int i=0; i<6; i++ ) From ee0cf53e9bd7d50dd1683e7abc12223ad0fdcead Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Thu, 24 Jan 2019 21:09:17 +0100 Subject: [PATCH 4/6] Revert all "global level removal" changes, as this concept is being discarded in GZDoom. Keep a couple changes from that commit, though, such as the switch to legacy render style tags in Screen API calls. --- zmapinfo.txt | 5 ----- zscript.txt | 2 +- zscript/biorifle.zsc | 6 +++--- zscript/eightball.zsc | 2 +- zscript/enforcer.zsc | 2 +- zscript/flakcannon.zsc | 16 ++++++++-------- zscript/impacthammer.zsc | 2 +- zscript/minigun.zsc | 2 +- zscript/mk_coordutil.zsc | 2 +- zscript/pulsegun.zsc | 10 +++++----- zscript/ripper.zsc | 2 +- zscript/shockrifle.zsc | 18 +++++++++--------- zscript/utcommon.zsc | 31 +++++++++++++++++-------------- zscript/utgore.zsc | 2 +- zscript/uthud.zsc | 12 ++++++------ zscript/warheadlauncher.zsc | 36 ++++++++++++++++++------------------ 16 files changed, 74 insertions(+), 76 deletions(-) diff --git a/zmapinfo.txt b/zmapinfo.txt index a7a49c4..958dc67 100644 --- a/zmapinfo.txt +++ b/zmapinfo.txt @@ -7,8 +7,3 @@ GameInfo BorderFlat = "TEMPBG" Border = 0,0,"","","","","","","","" } - -// titlemaps need a mapinfo entry in devbuilds -map TITLEMAP "UT Logo Map" -{ -} diff --git a/zscript.txt b/zscript.txt index 9147f59..e2ceb1f 100644 --- a/zscript.txt +++ b/zscript.txt @@ -1,4 +1,4 @@ -version "3.8" +version "3.7" #include "zscript/mk_matrix.zsc" #include "zscript/mk_coordutil.zsc" diff --git a/zscript/biorifle.zsc b/zscript/biorifle.zsc index 51e84b7..e78e576 100644 --- a/zscript/biorifle.zsc +++ b/zscript/biorifle.zsc @@ -158,7 +158,7 @@ Class BioXLight : DynamicLight override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(64*lifetime); args[LIGHT_GREEN] = int(255*lifetime); args[LIGHT_BLUE] = int(48*lifetime); @@ -211,7 +211,7 @@ Class BioGel : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( !bNOGRAVITY ) { roll += rollvel; @@ -608,7 +608,7 @@ Class BioGlob : BioGel override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; Vector3 ofs = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); for ( int i=0; i<2; i++ ) { diff --git a/zscript/eightball.zsc b/zscript/eightball.zsc index a099255..b5bbe21 100644 --- a/zscript/eightball.zsc +++ b/zscript/eightball.zsc @@ -428,7 +428,7 @@ Class UTRocketLauncher : UTWeapon // lock-on check action void A_CheckTarget() { - let t = level.CreateThinkerIterator("Actor"); + let t = ThinkerIterator.Create("Actor"); Actor a; double closest = double.max; invoker.LockedTarget = null; diff --git a/zscript/enforcer.zsc b/zscript/enforcer.zsc index dfea801..8610c82 100644 --- a/zscript/enforcer.zsc +++ b/zscript/enforcer.zsc @@ -119,7 +119,7 @@ Class UTCasing : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; if ( InStateSequence(CurState,ResolveState("Death")) ) { deadtimer++; diff --git a/zscript/flakcannon.zsc b/zscript/flakcannon.zsc index 1c43cbc..0b28847 100644 --- a/zscript/flakcannon.zsc +++ b/zscript/flakcannon.zsc @@ -55,7 +55,7 @@ Class ChunkLight : DynamicLight Destroy(); return; } - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(255*(10-target.frame)*0.1); args[LIGHT_GREEN] = int(224*(10-target.frame)*0.1); args[LIGHT_BLUE] = int(128*(10-target.frame)*0.1); @@ -84,7 +84,7 @@ Class ChunkTrail : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( InStateSequence(CurState,FindState("Death")) ) return; if ( !target ) { @@ -121,7 +121,7 @@ Class FlakAccumulator : Thinker static void Accumulate( Actor victim, int amount ) { - let ti = victim.level.CreateThinkerIterator("FlakAccumulator",STAT_USER); + let ti = ThinkerIterator.Create("FlakAccumulator",STAT_USER); FlakAccumulator a, match = null; while ( a = FlakAccumulator(ti.Next()) ) { @@ -131,7 +131,7 @@ Class FlakAccumulator : Thinker } if ( !match ) { - match = new("FlakAccumulator"); // another thinker created through new(), this all looks like a big catastrophe waiting to happen + match = new("FlakAccumulator"); match.ChangeStatNum(STAT_USER); match.victim = victim; } @@ -141,7 +141,7 @@ Class FlakAccumulator : Thinker static int GetAmount( Actor victim ) { - let ti = victim.level.CreateThinkerIterator("FlakAccumulator",STAT_USER); + let ti = ThinkerIterator.Create("FlakAccumulator",STAT_USER); FlakAccumulator a; while ( a = FlakAccumulator(ti.Next()) ) { @@ -193,7 +193,7 @@ Class FlakChunk : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( waterlevel > 0 ) { vel.xy *= 0.98; @@ -335,7 +335,7 @@ Class SlugSmoke : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; lifetime += lifespeed; let s = Spawn("UTSmoke",pos); s.vel = (FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5)); @@ -369,7 +369,7 @@ Class SlugLight : DynamicLight override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(224*lifetime); args[LIGHT_BLUE] = int(128*lifetime); diff --git a/zscript/impacthammer.zsc b/zscript/impacthammer.zsc index bbe1956..81461dd 100644 --- a/zscript/impacthammer.zsc +++ b/zscript/impacthammer.zsc @@ -152,7 +152,7 @@ Class ImpactHammer : UTWeapon if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4); } // push aside projectiles - let t = level.CreateThinkerIterator("Actor"); + let t = ThinkerIterator.Create("Actor"); Actor m; while ( m = Actor(t.Next()) ) { diff --git a/zscript/minigun.zsc b/zscript/minigun.zsc index 084d6a1..35b6110 100644 --- a/zscript/minigun.zsc +++ b/zscript/minigun.zsc @@ -47,7 +47,7 @@ Class MinigunTracer : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; Vector3 dir = level.Vec3Diff(pos,dest); if ( dir.length() < 160 ) { diff --git a/zscript/mk_coordutil.zsc b/zscript/mk_coordutil.zsc index f61f2c3..709a425 100644 --- a/zscript/mk_coordutil.zsc +++ b/zscript/mk_coordutil.zsc @@ -9,7 +9,7 @@ Class dt_CoordUtil { // projects a world point onto screen // view matrix setup mostly pulled from gutawer's code - static Vector3 WorldToScreen( LevelLocals level, Vector3 vect, Vector3 eye, double pitch, double yaw, double roll, double vfov ) + static Vector3 WorldToScreen( Vector3 vect, Vector3 eye, double pitch, double yaw, double roll, double vfov ) { double ar = Screen.getWidth()/double(Screen.getHeight()); double fovr = (ar>=1.3)?1.333333:ar; diff --git a/zscript/pulsegun.zsc b/zscript/pulsegun.zsc index dc85f95..78add62 100644 --- a/zscript/pulsegun.zsc +++ b/zscript/pulsegun.zsc @@ -91,7 +91,7 @@ Class ViewPulseSpark : PulseSpark Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; ofs += vvel; vvel *= 0.9; scale *= 0.8; @@ -149,7 +149,7 @@ Class PulseExplLight : DynamicLight override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(64*lifetime); args[LIGHT_GREEN] = int(255*lifetime); lifetime -= 1./ReactionTime; @@ -372,7 +372,7 @@ Class PulseBolt : Actor { if ( !damagedactor ) { - accdamage = min(0.5*(level.maptime-lasthit),0.1); + accdamage = min(0.5*(level.time-lasthit),0.1); t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](80,100)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x)); accdamage = 0; } @@ -381,7 +381,7 @@ Class PulseBolt : Actor t.Results.HitActor.DamageMobj(self,target,int(Random[Pulse](80,100)*accdamage),'zapped',DMG_USEANGLE,atan2(x.y,x.x)); accdamage = 0; } - lasthit = level.maptime; + lasthit = level.time; damagedactor = t.Results.HitActor; accdamage += 1./TICRATE; if ( accdamage > 0.17 ) @@ -506,7 +506,7 @@ Class StarterBolt : PulseBolt override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( !target ) { Destroy(); diff --git a/zscript/ripper.zsc b/zscript/ripper.zsc index 53c53fe..a33dcd2 100644 --- a/zscript/ripper.zsc +++ b/zscript/ripper.zsc @@ -170,7 +170,7 @@ Class Razor2AltLight : DynamicLight override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(240*lifetime); args[LIGHT_BLUE] = int(224*lifetime); diff --git a/zscript/shockrifle.zsc b/zscript/shockrifle.zsc index dee5336..1247e97 100644 --- a/zscript/shockrifle.zsc +++ b/zscript/shockrifle.zsc @@ -72,7 +72,7 @@ Class ShockRifleWave : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; alpha -= 1/50.; } States @@ -99,7 +99,7 @@ Class SuperShockRifleWave : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; alpha -= 1/50.; } States @@ -127,7 +127,7 @@ Class ShockBeamRing : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; alpha -= 1./ReactionTime; } States @@ -154,7 +154,7 @@ Class SuperShockBeamRing : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; alpha -= 1./ReactionTime; } States @@ -295,7 +295,7 @@ Class ShockBeam : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( !moving ) return; // step trace tracedir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); @@ -522,7 +522,7 @@ Class SuperShockBeam : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( !moving ) return; // step trace tracedir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); @@ -765,7 +765,7 @@ Class ShockExplLight : DynamicLight override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(160*lifetime); args[LIGHT_GREEN] = int(128*lifetime); args[LIGHT_BLUE] = int(255*lifetime); @@ -791,7 +791,7 @@ Class SuperShockExplLight : DynamicLight override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(160*lifetime); args[LIGHT_BLUE] = int(128*lifetime); @@ -982,7 +982,7 @@ Class ViewShockSpark : ShockSpark Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; ofs += vvel; vvel *= 0.9; scale *= 0.8; diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index bce107b..d69e941 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -213,7 +213,7 @@ Class UTPlayer : DoomPlayer } if ( !footsteps ) footsteps = CVar.GetCVar('flak_footsteps',players[consoleplayer]); if ( !footsteps.GetBool() ) return; - double ang = level.maptime/(20*TICRATE/35.)*360.; + double ang = level.time/(20*TICRATE/35.)*360.; bool forcefootstep = false; if ( player.onground && !bNoGravity && !lastground && (waterlevel < 2) ) { @@ -901,7 +901,7 @@ Class UTViewSpark : UTSpark Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; ofs += vvel; vvel.z -= 0.1; scale *= 0.8; @@ -943,7 +943,7 @@ Class UTChip : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; if ( InStateSequence(CurState,ResolveState("Death")) ) { deadtimer++; @@ -1006,7 +1006,7 @@ Class UTBubble : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; vel *= 0.96; vel.z += 0.05; if ( (waterlevel <= 0) || !Random[Puff](0,100) ) Destroy(); @@ -1054,7 +1054,7 @@ Class UTSmoke : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; vel *= 0.96; vel.z += 0.01; A_FadeOut(1/32.); @@ -1146,7 +1146,7 @@ Class UTViewSmoke : UTSmoke Vector3 origin = x*ofs.x+y*ofs.y+z*ofs.z+(0,0,target.player.viewz); SetOrigin(target.Vec2OffsetZ(origin.x,origin.y,origin.z),true); bInvisible = (players[consoleplayer].camera != target); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; ofs += vvel; vvel *= 0.96; vvel.z += 0.01; @@ -1545,7 +1545,7 @@ Class UTMainHandler : StaticEventHandler private Actor AddLight( Vector3 pos, Color col, int radius ) { - Actor l = currentSession.levelinfo[0].Spawn("PointLightAttenuated",pos); + Actor l = Actor.Spawn("PointLightAttenuated",pos); if ( !l ) return null; l.args[0] = col.r; l.args[1] = col.g; @@ -1556,7 +1556,7 @@ Class UTMainHandler : StaticEventHandler private Actor AddAmbient( Vector3 pos, String snd, double volume = 1., double attenuation = ATTN_NORM ) { - Actor a = currentSession.levelinfo[0].Spawn("MapSpot",pos); + Actor a = Actor.Spawn("MapSpot",pos); if ( !a ) return null; a.A_PlaySound(snd,CHAN_BODY,volume,true,attenuation); return a; @@ -1565,12 +1565,15 @@ Class UTMainHandler : StaticEventHandler override void WorldLoaded( WorldEvent e ) { if ( gamestate != GS_LEVEL || e.IsSaveGame ) return; - let level = currentSession.levelinfo[0]; - // just replace the -noflat- with a better scaled version + // just replace the -noflat- with a better scaled version and change the sky if ( !flak_doomtest ) { if ( (level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33") || (level.GetChecksum() ~== "D8206A3414DA967F2159473B5791139E") ) + { level.ReplaceTextures("-noflat-","DefTex",0); + TextureID skytx = TexMan.CheckForTexture("BlueSky",TexMan.Type_Any); + level.ChangeSky(skytx,skytx); + } return; } // prettify Kinsie's test map for a more Unreal feel @@ -1871,7 +1874,7 @@ Class UTMainHandler : StaticEventHandler return; } // generic gibbing - let a = e.Thing.level.Spawn("UTGibber",e.Thing.pos); + let a = Actor.Spawn("UTGibber",e.Thing.pos); a.vel = e.Thing.vel; a.Scale = e.Thing.Scale; a.Translation = e.Thing.BloodTranslation; @@ -1886,7 +1889,7 @@ Class UTMainHandler : StaticEventHandler } // attach damage accumulator for corpses if ( !flak_corpsedamage ) return; - let a = e.Thing.level.Spawn("ShredCorpseHitbox",e.Thing.pos); + let a = Actor.Spawn("ShredCorpseHitbox",e.Thing.pos); a.target = e.Thing; } @@ -1911,7 +1914,7 @@ Class UTMainHandler : StaticEventHandler if ( !a || !a.bSHOOTABLE || !Source.CheckSight(a,0xf) || (a == Source) || (Source.Distance3D(a) > ExplosionRadius) ) continue; Vector3 midpoint = a.Vec3Offset(0,0,a.height*0.5); - a.vel += Source.level.Vec3Diff(Source.pos,midpoint).unit()*(MomentumTransfer/(Thinker.TICRATE*a.mass)); + a.vel += Level.Vec3Diff(Source.pos,midpoint).unit()*(MomentumTransfer/(Thinker.TICRATE*a.mass)); } } @@ -1925,7 +1928,7 @@ Class UTMainHandler : StaticEventHandler static void DoSwing( Actor target, Vector2 dir, double initial, double inc, int steps, int mode = 0, int delay = 0, double rmul = 1.0 ) { if ( !flak_swingers ) return; - let s = new("Swinger"); // this looks unsafe, shouldn't there be a way to create thinkers in specifc level? + let s = new("Swinger"); s.ChangeStatNum(Thinker.STAT_USER); s.target = target; s.dir = dir; diff --git a/zscript/utgore.zsc b/zscript/utgore.zsc index 18ba524..41179fa 100644 --- a/zscript/utgore.zsc +++ b/zscript/utgore.zsc @@ -155,7 +155,7 @@ Class UTBloodTrail : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; if ( !target ) return; SetOrigin(target.pos,true); double ang, pt; diff --git a/zscript/uthud.zsc b/zscript/uthud.zsc index 23dd938..5282e09 100644 --- a/zscript/uthud.zsc +++ b/zscript/uthud.zsc @@ -401,7 +401,7 @@ Class UTHud : BaseStatusBar if ( CPlayer.mo.Health < CPlayer.mo.SpawnHealth()/2 ) { Color blinkcolor; - double blinky = ((currentsession.time+fractic)/Thinker.TICRATE)*1.5; + double blinky = ((level.time+fractic)/Thinker.TICRATE)*1.5; blinky = blinky-floor(blinky); blinkcolor = LerpColor(tintcolor,WhiteColor,blinky); UTDrawTintedTex(Boxes[2],hudsize,-1,blinkcolor); @@ -517,7 +517,7 @@ Class UTHud : BaseStatusBar CurY = Screen.GetHeight()-64*hudsize*HScale; if ( showweapons && ((weaponsize*hudsize)>=1.0) ) CurY -= 64*hudsize*HScale; DrawColor = tintcolor; - double whiten = ((currentsession.time+fractic)-lastfrag)/Thinker.TICRATE; + double whiten = ((level.time+fractic)-lastfrag)/Thinker.TICRATE; if ( whiten < 3.0 ) { if ( tintcolor == GoldColor ) @@ -539,7 +539,7 @@ Class UTHud : BaseStatusBar } private void DrawIdentifyInfo() { - double lalpha = 2.0-((currentsession.time+fractic)-lastseentic)/Thinker.TICRATE; + double lalpha = 2.0-((level.time+fractic)-lastseentic)/Thinker.TICRATE; if ( !lastseen || (lalpha <= 0) ) return; String cl1 = "Teal", cl2 = "Cyan"; if ( deathmatch && (lastseen.player.GetTeam() < teams.size()) ) @@ -613,19 +613,19 @@ Class UTHud : BaseStatusBar Super.Tick(); if ( deathmatch||teamplay ) { - if ( CPlayer.fragcount != lastfragcnt ) lastfrag = currentsession.time; + if ( CPlayer.fragcount != lastfragcnt ) lastfrag = level.time; lastfragcnt = CPlayer.fragcount; } else { - if ( CPlayer.killcount != lastfragcnt ) lastfrag = currentsession.time; + if ( CPlayer.killcount != lastfragcnt ) lastfrag = level.time; lastfragcnt = CPlayer.killcount; } vtracer.ignore = CPlayer.mo; vtracer.trace(CPlayer.mo.Vec2OffsetZ(0,0,CPlayer.viewz),CPlayer.mo.CurSector,(cos(CPlayer.mo.angle)*cos(CPlayer.mo.pitch),sin(CPlayer.mo.angle)*cos(CPlayer.mo.pitch),-sin(CPlayer.mo.pitch)),1000,0); if ( vtracer.Results.HitType != TRACE_HitActor ) return; lastseen = vtracer.Results.HitActor; - lastseentic = currentsession.time; + lastseentic = level.time; } private void DrawUTHUD() diff --git a/zscript/warheadlauncher.zsc b/zscript/warheadlauncher.zsc index 1968dc6..a851d23 100644 --- a/zscript/warheadlauncher.zsc +++ b/zscript/warheadlauncher.zsc @@ -48,9 +48,9 @@ Class ShockWave : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( alpha <= 0 ) return; - if ( !t ) t = level.CreateThinkerIterator("Actor"); + if ( !t ) t = ThinkerIterator.Create("Actor"); icount++; if ( icount == 4 ) Spawn("WarheadSubExplosion",pos); lifespan--; @@ -164,7 +164,7 @@ Class WarheadExplodLight : DynamicLight override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; args[LIGHT_RED] = int(255*lifetime); args[LIGHT_GREEN] = int(192*lifetime); args[LIGHT_BLUE] = int(128*lifetime); @@ -224,7 +224,7 @@ Class WarheadTrail : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( level.frozen || globalfreeze ) return; vel *= 0.99; A_FadeOut(0.1); } @@ -275,7 +275,7 @@ Class WarShell : Actor override void Tick() { Super.Tick(); - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( !bMISSILE ) return; if ( vel.length() > 0 ) { @@ -375,7 +375,7 @@ Class GuidedWarShell : WarShell justleft = false; bHITOWNER = true; } - if ( isFrozen() ) return; + if ( globalfreeze || level.frozen ) return; if ( !bMISSILE ) return; if ( !target || !target.player || (target.Health <= 0) ) { @@ -482,7 +482,7 @@ Class RedeemerHUD : HUDMessageBase // shootable targetting if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && !CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() ) { - if ( !t ) t = camera.level.CreateThinkerIterator("Actor"); + if ( !t ) t = ThinkerIterator.Create("Actor"); if ( !tr ) tr = new("MidTracer"); t.Reinit(); ta.Clear(); @@ -490,10 +490,10 @@ Class RedeemerHUD : HUDMessageBase Vector3 vdir = (cos(ViewAngle)*cos(ViewPitch),sin(ViewAngle)*cos(ViewPitch),-sin(ViewPitch)); while ( a = Actor(t.Next()) ) { - Vector3 tdir = camera.level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); + Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue; Vector3 wpos = ViewPos+tdir; - Vector3 spos = dt_CoordUtil.WorldToScreen(camera.level,wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); + Vector3 spos = dt_CoordUtil.WorldToScreen(wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); if ( spos.z > 1.0 ) continue; TargetActor te = new("TargetActor"); te.vpos = dt_CoordUtil.ToViewport(spos); @@ -513,7 +513,7 @@ Class RedeemerHUD : HUDMessageBase { if ( CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() ) { - if ( !t ) t = camera.level.CreateThinkerIterator("Actor"); + if ( !t ) t = ThinkerIterator.Create("Actor"); if ( !tr ) tr = new("MidTracer"); t.Reinit(); ta.Clear(); @@ -521,10 +521,10 @@ Class RedeemerHUD : HUDMessageBase Vector3 vdir = (cos(ViewAngle)*cos(ViewPitch),sin(ViewAngle)*cos(ViewPitch),-sin(ViewPitch)); while ( a = Actor(t.Next()) ) { - Vector3 tdir = camera.level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); + Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5)); if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue; Vector3 wpos = ViewPos+tdir; - Vector3 spos = dt_CoordUtil.WorldToScreen(camera.level,wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); + Vector3 spos = dt_CoordUtil.WorldToScreen(wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV); if ( spos.z > 1.0 ) continue; TargetActor te = new("TargetActor"); te.vpos = dt_CoordUtil.ToViewport(spos); @@ -535,8 +535,8 @@ Class RedeemerHUD : HUDMessageBase } for ( int i=0; i Date: Thu, 24 Jan 2019 21:11:13 +0100 Subject: [PATCH 5/6] Clean leftover mapinfo entry in heretic compat. --- filter/game-heretic/zmapinfo.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/filter/game-heretic/zmapinfo.txt b/filter/game-heretic/zmapinfo.txt index cdbb4a4..864ee9e 100644 --- a/filter/game-heretic/zmapinfo.txt +++ b/filter/game-heretic/zmapinfo.txt @@ -7,8 +7,3 @@ GameInfo BorderFlat = "TEMPBG" Border = 0,0,"","","","","","","","" } - -// titlemaps need a mapinfo entry in devbuilds -map TITLEMAP "UT Logo Map" -{ -} From 2a9eb0e1b1d72fc76c6386bd05b62ec10df9762c Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Thu, 24 Jan 2019 22:33:09 +0100 Subject: [PATCH 6/6] Various changes to feel closer to vanilla UT, mainly in terms of projectile gravity and velocity. Reduced the smoke on the minigun and casings for better performance. Corrected the number of chunks (was 6, should be 8) fired by the flak cannon. Reduced flak chunk spread (should be ~5.5 degrees, was double of that) on the weapon and slugs. Reduced the size of the shock rifle combo shockwave mesh to be closer to vanilla UT. Misc. tweaks to health item textures. Reduced the blur in the Redeemer view shader, it was too strong. Fix expiration messages on powerups appearing on level changes. Address complaints about how I change Kinsie's test map. Shouldn't be too dark now. --- gldefs.txt | 2 +- modeldef.misc | 2 +- modeldef.shock | 4 ++-- shaders/glsl/FizzDistortX.fp | 5 ++-- shaders/glsl/RedeemerView.fp | 6 ++--- zscript/biorifle.zsc | 4 ++-- zscript/eightball.zsc | 20 ++++++++-------- zscript/enforcer.zsc | 5 ++-- zscript/flakcannon.zsc | 45 +++++++++++++++++++++++++++--------- zscript/minigun.zsc | 4 ++-- zscript/powerups.zsc | 4 ++-- zscript/pulsegun.zsc | 2 +- zscript/ripper.zsc | 2 +- zscript/shockrifle.zsc | 2 +- zscript/sniperrifle.zsc | 2 +- zscript/translocator.zsc | 3 ++- zscript/utcommon.zsc | 10 ++++---- zscript/utgore.zsc | 6 +++-- zscript/warheadlauncher.zsc | 6 ++--- 19 files changed, 80 insertions(+), 54 deletions(-) diff --git a/gldefs.txt b/gldefs.txt index 8f96065..755eeea 100644 --- a/gldefs.txt +++ b/gldefs.txt @@ -583,7 +583,7 @@ HardwareShader PostProcess scene Texture StaticTexture "textures/static1.png" Uniform float Timer } -SkyBox "BlueSky" fliptop +SkyBox "KGDaySky" fliptop { "graphics/SkySetB_front.png" "graphics/SkySetB_right.png" diff --git a/modeldef.misc b/modeldef.misc index f00dcec..adcdfa1 100644 --- a/modeldef.misc +++ b/modeldef.misc @@ -64,7 +64,7 @@ Model "UTHealthBox" Model 0 "hboxbeta_d.3d" // indices start at 1 for this mesh SurfaceSkin 0 1 "jhboxbeta1.png" - SurfaceSkin 0 2 "fizzfull" + SurfaceSkin 0 2 "fizzside" SurfaceSkin 0 3 "fizzfull" Scale 0.08 0.08 0.096 ZOffset 4 diff --git a/modeldef.shock b/modeldef.shock index ddb8eef..56c84fd 100644 --- a/modeldef.shock +++ b/modeldef.shock @@ -35,7 +35,7 @@ Model "ShockRifleWave" Path "models" Model 0 "shockrwm_d.3d" Skin 0 "shocktt1.png" - Scale 1.2 1.0 1.0 + Scale 0.6 0.5 0.5 PitchOffset 90 FrameIndex SWAV A 0 0 @@ -47,7 +47,7 @@ Model "SuperShockRifleWave" Path "models" Model 0 "shockrwm_d.3d" Skin 0 "sshocktt1.png" - Scale 1.2 1.0 1.0 + Scale 0.6 0.5 1.5 PitchOffset 90 FrameIndex SWAV A 0 0 diff --git a/shaders/glsl/FizzDistortX.fp b/shaders/glsl/FizzDistortX.fp index 3e62195..2cf77af 100644 --- a/shaders/glsl/FizzDistortX.fp +++ b/shaders/glsl/FizzDistortX.fp @@ -7,12 +7,11 @@ vec4 ProcessTexel() { vec2 coord = vTexCoord.st; vec2 dist = 2.0*texture(warptex,vTexCoord.st).xy-1.0; - dist.x *= abs(mod(dist.y+timer*3.34536,4)-2)-1; - coord.x += dist.x*0.12; + dist.y *= abs(mod(dist.x+timer*3.34536,4)-2)-1; + coord.y += dist.y*0.12; dist = 2.0*texture(warptex,vTexCoord.st*2.0).xy-1.0; dist.y *= abs(mod(dist.x+timer*5.45363,4)-2)-1; coord.y -= dist.y*0.09; coord.y = clamp(coord.y,0.0,1.0); - coord.x += timer*0.5346; return getTexel(coord); } diff --git a/shaders/glsl/RedeemerView.fp b/shaders/glsl/RedeemerView.fp index d4137c3..78c0a10 100644 --- a/shaders/glsl/RedeemerView.fp +++ b/shaders/glsl/RedeemerView.fp @@ -5,14 +5,12 @@ void main() vec2 sz = textureSize(InputTexture,0); vec2 px = 1.0/vec2(1920.0); px.y *= sz.x/sz.y; - float cnt = 1.0; - for ( int j=-5; j<=5; j++ ) for ( int i=-5; i<=5; i++ ) + for ( int j=-1; j<=1; j++ ) for ( int i=-1; i<=1; i++ ) { nc = TexCoord+px*vec2(i,j); tinted += texture(InputTexture,nc); - cnt += 1.0; } - tinted /= cnt; + tinted /= 10.0; vec2 coord = TexCoord; coord *= 4.0; coord.y *= px.x/px.y; diff --git a/zscript/biorifle.zsc b/zscript/biorifle.zsc index e78e576..20ca347 100644 --- a/zscript/biorifle.zsc +++ b/zscript/biorifle.zsc @@ -528,8 +528,8 @@ Class BioGel : Actor Radius 3; Height 3; Scale 2; - Speed 18; - Gravity 0.5; + Speed 11; + Gravity 0.25; PROJECTILE; -NOGRAVITY; +SKYEXPLODE; diff --git a/zscript/eightball.zsc b/zscript/eightball.zsc index b5bbe21..404e13f 100644 --- a/zscript/eightball.zsc +++ b/zscript/eightball.zsc @@ -111,7 +111,7 @@ Class UTRocket : Actor DamageType 'RocketDeath'; Radius 2; Height 2; - Speed 20; + Speed 15; PROJECTILE; +SKYEXPLODE; +EXPLODEONWATER; @@ -145,21 +145,21 @@ Class UTRocket : Actor int numpt = Random[Eightball](15,30); for ( int i=0; i 45. ) vel = Vel.unit()*45.; + if ( vel.length() > 30. ) vel = Vel.unit()*30.; Vector3 dir = vel.unit(); - if ( waterlevel <= 0 ) vel = dir*min(vel.length()+1,32); + if ( waterlevel <= 0 ) vel = dir*min(vel.length()+1,24); angle = atan2(dir.y,dir.x); pitch = asin(-dir.z); for ( int i=0; i<3; i++ ) @@ -228,7 +228,8 @@ Class UTGrenade : UTRocket WallBounceFactor 0.75; BounceFactor 0.75; ReactionTime 85; - Speed 20; + Speed 15; + Gravity 0.35; } override void PostBeginPlay() { @@ -309,7 +310,8 @@ Class UTRocketLauncher : UTWeapon { LockedTarget = null; LockedOn = false; - Owner.A_PlaySound("utrl/seeklost",CHAN_WEAPON); + if ( Owner.player.ReadyWeapon == self ) + Owner.A_PlaySound("utrl/seeklost",CHAN_WEAPON); } if ( LockedTarget ) crosshair = 99; else crosshair = 0; @@ -368,7 +370,7 @@ Class UTRocketLauncher : UTWeapon Vector3 dir = (x2+cos(a)*y2*s*0.004+sin(a)*z2*s*0.004).unit(); p = Spawn("UTGrenade",origin+cos(a)*y*s+sin(a)*z*s); p.vel = x*(vel dot x)*0.4 + dir*p.speed*FRandom[Eightball](1.0,1.2); - p.vel.z += 6; + p.vel.z += 3.5; p.target = self; } } diff --git a/zscript/enforcer.zsc b/zscript/enforcer.zsc index 8610c82..b825b25 100644 --- a/zscript/enforcer.zsc +++ b/zscript/enforcer.zsc @@ -103,6 +103,7 @@ Class UTCasing : Actor +USEBOUNCESTATE; +INTERPOLATEANGLES; Mass 1; + Gravity 0.35; BounceType "Hexen"; WallBounceFactor 0.65; BounceFactor 0.65; @@ -126,7 +127,7 @@ Class UTCasing : Actor if ( deadtimer > 300 ) A_FadeOut(0.05); return; } - heat -= 0.02; + heat -= 0.05; if ( heat <= 0 ) return; let s = Spawn("UTSmallSmoke",pos); s.alpha *= heat; @@ -376,7 +377,7 @@ Class Enforcer : UTWeapon } origin += x*8.0+ydir*y*6.0-z*2.0; let c = Spawn("UTCasing",origin); - c.vel = x*FRandom[Junk](-2,2)+y*ydir*FRandom[Junk](3,6)+z*FRandom[Junk](3,5); + c.vel = x*FRandom[Junk](-1.5,1.5)+y*ydir*FRandom[Junk](2,4)+z*FRandom[Junk](2,3); } override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack ) diff --git a/zscript/flakcannon.zsc b/zscript/flakcannon.zsc index 0b28847..fb1d066 100644 --- a/zscript/flakcannon.zsc +++ b/zscript/flakcannon.zsc @@ -163,7 +163,7 @@ Class FlakChunk : Actor Obituary "%o was ripped to shreds by %k's Flak Cannon."; Radius 2; Height 2; - Speed 50; + Speed 32; DamageFunction Random[Flak](15,20); DamageType 'Shredded'; BounceType "Hexen"; @@ -243,13 +243,16 @@ Class FlakChunk : Actor } else A_SprayDecal("WallCrack",-8); A_Gravity(); + gravity = 0.35; invoker.rollvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed); invoker.pitchvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed); invoker.yawvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed); vel = (vel.unit()+(FRandom[Flak](-0.2,0.2),FRandom[Flak](-0.2,0.2),FRandom[Flak](-0.2,0.2))).unit()*vel.length(); + // TODO chunks in vanilla have a special variation on the standard reflect formula that causes them to bounce differently when hitting a surface head-on + // (0.5 to 0.8 reduction perpendicular to the surface normal, to be specific) + // I have no idea how I'll even implement this reduction reliably A_PlaySound("flak/bounce",volume:0.3); A_AlertMonsters(); - bBOUNCEAUTOOFFFLOORONLY = true; if ( vel.length() < 5.0 ) ExplodeMissile(); } override int DoSpecialDamage( Actor target, int damage, Name damagetype ) @@ -386,7 +389,8 @@ Class FlakSlug : Actor DamageType 'FlakDeath'; Radius 2; Height 2; - Speed 40; + Gravity 0.35; + Speed 20; PROJECTILE; -NOGRAVITY; +SKYEXPLODE; @@ -398,7 +402,7 @@ Class FlakSlug : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - vel.z += 4; + vel.z += 3; } override void Tick() { @@ -423,16 +427,26 @@ Class FlakSlug : Actor double a, s; [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Actor p; + Vector3 spawnofs; + if ( BlockingMobj ) spawnofs = level.Vec3Diff(pos,BlockingMobj.Vec3Offset(0,0,BlockingMobj.height/2)).unit()*8; + else if ( BlockingFloor ) spawnofs = BlockingFloor.floorplane.Normal*8; + else if ( BlockingCeiling ) spawnofs = BlockingCeiling.ceilingplane.Normal*8; + else if ( BlockingLine ) + { + spawnofs = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit()*8; + if ( !BlockingLine.sidedef[1] || (CurSector == BlockingLine.frontsector) ) + spawnofs *= -1; + } for ( int i=0; i<5; i++ ) { - p = Spawn("FlakChunk",pos); + p = Spawn("FlakChunk",Vec3Offset(spawnofs.x,spawnofs.y,spawnofs.z)); p.bHITOWNER = true; a = FRandom[Flak](0,360); - s = FRandom[Flak](0,0.2); + s = FRandom[Flak](0,0.1); Vector3 dir = (x+y*cos(a)*s+z*sin(a)*s).unit(); p.angle = atan2(dir.y,dir.x); p.pitch = -asin(dir.z); - p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed*FRandom[Flak](0.5,1.5); + p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*(p.speed+FRandom[Flak](-3,3)); p.target = target; } int numpt = Random[Flak](8,12); @@ -521,16 +535,25 @@ Class FlakCannon : UTWeapon A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true); A_OverlayRenderstyle(-2,STYLE_Add); [x, y, z] = dt_Matrix4.GetAxes(BulletSlope(),angle,roll); + Vector3 offsets[8]; // vanilla adds these to each chunk + offsets[0] = (0,0,0); + offsets[1] = -z; + offsets[2] = 2*y+z; + offsets[3] = -y; + offsets[4] = 2*y-z; + offsets[5] = (0,0,0); + offsets[6] = y-z; + offsets[7] = 2*y+z; Actor p; - for ( int i=0; i<6; i++ ) + for ( int i=0; i<8; i++ ) { - p = Spawn("FlakChunk",origin); + p = Spawn("FlakChunk",level.Vec3Offset(origin,offsets[i])); a = FRandom[Flak](0,360); - s = FRandom[Flak](0,0.2); + s = FRandom[Flak](0,0.1); Vector3 dir = (x+y*cos(a)*s+z*sin(a)*s).unit(); p.angle = atan2(dir.y,dir.x); p.pitch = -asin(dir.z); - p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed; + p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*(p.speed+FRandom[Flak](-3,3)); p.target = self; } int numpt = Random[Flak](20,30); diff --git a/zscript/minigun.zsc b/zscript/minigun.zsc index 35b6110..f58e761 100644 --- a/zscript/minigun.zsc +++ b/zscript/minigun.zsc @@ -151,7 +151,7 @@ Class Minigun : UTWeapon t.pitch = asin(-dir.z); MinigunTracer(t).dest = d.HitLocation; } - for ( int i=0; i<4; i++ ) + for ( int i=0; i<2; i++ ) { let s = Spawn("UTViewSmoke",origin); UTViewSmoke(s).ofs = (10,2,-2); @@ -162,7 +162,7 @@ Class Minigun : UTWeapon } origin += x*8.0+y*5.0-z*5.0; let c = Spawn("UTCasing",origin); - c.vel = x*FRandom[Junk](-2,2)+y*FRandom[Junk](3,6)+z*FRandom[Junk](3,5); + c.vel = x*FRandom[Junk](-1.5,1.5)+y*FRandom[Junk](2,4)+z*FRandom[Junk](2,3); c.Scale *= 0.5; } diff --git a/zscript/powerups.zsc b/zscript/powerups.zsc index d6518a8..0180e57 100644 --- a/zscript/powerups.zsc +++ b/zscript/powerups.zsc @@ -78,7 +78,7 @@ Class DamageAmplifier : Powerup override void EndEffect() { Super.EndEffect(); - PrintPickupMessage(true,"Damage Amplifier has worn off."); + if ( EffectTics <= 0 ) PrintPickupMessage(true,"Damage Amplifier has worn off."); } override bool isBlinking() @@ -217,7 +217,7 @@ Class PowerUTInvisibility : PowerInvisibility override void EndEffect() { Super.EndEffect(); - PrintPickupMessage(true,"Invisibility has worn off."); + if ( EffectTics <= 0 ) PrintPickupMessage(true,"Invisibility has worn off."); } } diff --git a/zscript/pulsegun.zsc b/zscript/pulsegun.zsc index 78add62..16db2db 100644 --- a/zscript/pulsegun.zsc +++ b/zscript/pulsegun.zsc @@ -170,7 +170,7 @@ Class PulseBall : Actor +SKYEXPLODE; +FORCEXYBILLBOARD; Scale 0.19; - Speed 29; + Speed 22; Radius 2; Height 2; } diff --git a/zscript/ripper.zsc b/zscript/ripper.zsc index a33dcd2..1ff11a5 100644 --- a/zscript/ripper.zsc +++ b/zscript/ripper.zsc @@ -56,7 +56,7 @@ Class Razor2 : Actor { Radius 2; Height 2; - Speed 27; + Speed 25; DamageFunction (Random[Ripper](20,25)*((DamageType=='Decapitated')?3:1.0)); DamageType 'Shredded'; Obituary "%k ripped a chunk of meat out of %o with the Ripper."; diff --git a/zscript/shockrifle.zsc b/zscript/shockrifle.zsc index 1247e97..e931e46 100644 --- a/zscript/shockrifle.zsc +++ b/zscript/shockrifle.zsc @@ -934,7 +934,7 @@ Class SuperShockBall : Actor Radius 2; Height 2; Scale 0.5; - Speed 25; + Speed 24; PROJECTILE; +FORCEXYBILLBOARD; +SKYEXPLODE; diff --git a/zscript/sniperrifle.zsc b/zscript/sniperrifle.zsc index 34c2185..77c1e5c 100644 --- a/zscript/sniperrifle.zsc +++ b/zscript/sniperrifle.zsc @@ -154,7 +154,7 @@ Class SniperRifle : UTWeapon origin += x*8.0+y*6.0-z*9.0; let c = Spawn("UTCasing",origin); c.scale *= 1.25; - c.vel = x*FRandom[Junk](-2,2)+y*FRandom[Junk](3,6)+z*FRandom[Junk](3,5); + c.vel = x*FRandom[Junk](-1.5,1.5)+y*FRandom[Junk](2,4)+z*FRandom[Junk](2,3); } override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack ) { diff --git a/zscript/translocator.zsc b/zscript/translocator.zsc index 2f61cc8..8b40114 100644 --- a/zscript/translocator.zsc +++ b/zscript/translocator.zsc @@ -121,7 +121,7 @@ Class TranslocatorModule : Actor { Radius 2; Height 2; - Speed 25; + Speed 16; PROJECTILE; -NOGRAVITY; +USEBOUNCESTATE; @@ -133,6 +133,7 @@ Class TranslocatorModule : Actor BounceType "Hexen"; BounceFactor 0.3; WallBounceFactor 0.3; + Gravity 0.35; } override void PostBeginPlay() diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index d69e941..ddb327d 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -853,7 +853,7 @@ Class UTSpark : Actor +DONTSPLASH; BounceType "Doom"; BounceFactor 0.4; - Gravity 0.5; + Gravity 0.2; Scale 0.05; } override void Tick() @@ -927,7 +927,7 @@ Class UTChip : Actor +INTERPOLATEANGLES; BounceType "Doom"; BounceFactor 0.3; - Gravity 0.7; + Gravity 0.35; Scale 0.2; } override void PostBeginPlay() @@ -1570,7 +1570,7 @@ Class UTMainHandler : StaticEventHandler { if ( (level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33") || (level.GetChecksum() ~== "D8206A3414DA967F2159473B5791139E") ) { - level.ReplaceTextures("-noflat-","DefTex",0); + TexMan.ReplaceTextures("-noflat-","DefTex",0); TextureID skytx = TexMan.CheckForTexture("BlueSky",TexMan.Type_Any); level.ChangeSky(skytx,skytx); } @@ -1580,7 +1580,7 @@ Class UTMainHandler : StaticEventHandler if ( level.GetChecksum() ~== "FBC3B6622A8B74AE06DE01E70007AC33" ) { TextureID deftex = TexMan.CheckForTexture("-noflat-",TexMan.Type_Any); - TextureID skytx = TexMan.CheckForTexture("BlueSky",TexMan.Type_Any); + TextureID skytx = TexMan.CheckForTexture("KGDaySky",TexMan.Type_Any); TextureID baseflor = TexMan.CheckForTexture("rClfFlr0",TexMan.Type_Any); TextureID baseceil = TexMan.CheckForTexture("rClfBas0",TexMan.Type_Any); TextureID basewall = TexMan.CheckForTexture("uAlnWl2b",TexMan.Type_Any); @@ -1589,7 +1589,7 @@ Class UTMainHandler : StaticEventHandler level.ChangeSky(skytx,skytx); for ( int i=0; i 0 ) { vel *= 0.98; - if ( vel.length() < 12 ) vel += vel.unit(); + if ( vel.length() < 6 ) vel += vel.unit()*0.35; } - else if ( vel.length() < 40 ) vel += vel.unit(); + else if ( vel.length() < 20 ) vel += vel.unit()*0.35; } } action void A_Trail()