diff --git a/Readme.md b/Readme.md index 80dfb66..a8fff77 100644 --- a/Readme.md +++ b/Readme.md @@ -25,6 +25,9 @@ Doom Tournament (currently the devel branch is required). - GES Bio Rifle (slot 8) (replaces plasma rifle) - "Hold up to 2 seconds" feature from Unreal Bible - Biorifle splashes like UT (toggleable) + - Rifle (slot 9) (replaces plasma rifle) + - Restored rapid fire + - Restored flashlight - SMP 7243 (slot 0) (replaces bfg9000) - Backpack (replaces backpack, identical to Doom Tournament version) - Unreal 1 HUD @@ -58,15 +61,10 @@ Doom Tournament (currently the devel branch is required). ## In progress - - Rifle (slot 9) (replaces plasma rifle) - Minigun (slot 0) (replaces chaingun) ## Planned - - Unreal Bible & prototype build behaviour restoration - - Rifle restored rapid fire - - Rifle restored flashlight - - Stunner (slot 4) (replaces chainsaw) - Razorclaw (slot 1) (replaces chainsaw) - Teleport Capsules (slot 1) diff --git a/gldefs.txt b/gldefs.txt index 2e89414..726b598 100644 --- a/gldefs.txt +++ b/gldefs.txt @@ -752,3 +752,9 @@ HardwareShader Texture "models/JSentry1_.png" { Shader "shaders/glsl/AmbientGlow.fp" } +// PP shaders +HardwareShader PostProcess scene +{ + Name "URifleScope" + Shader "shaders/glsl/URifleScope.fp" 330 +} \ No newline at end of file diff --git a/graphics/UReticle.png b/graphics/UReticle.png new file mode 100644 index 0000000..b53fce4 Binary files /dev/null and b/graphics/UReticle.png differ diff --git a/modeldef.rifle b/modeldef.rifle index 6b5bccb..45ec1ba 100644 --- a/modeldef.rifle +++ b/modeldef.rifle @@ -34,4 +34,104 @@ Model "URifle" ZOffset 12 ROTATING FrameIndex SRFP A 1 0 +} + +Model "URifle" +{ + Path "models" + Model 2 "Flat_d.3d" + Skin 2 "URifMuz.png" + AngleOffset 90 + PitchOffset 90 + Scale 0.12 0.12 0.12 + Offset 12 -50 -10 + + FrameIndex SMUZ A 2 0 +} + +Model "URifle" +{ + Path "models" + Model 0 "RifleM_d.3d" + SurfaceSkin 0 1 "JRifle1.png" + Scale 0.2 -0.16 0.2 + AngleOffset -90 + Offset 12 -32 -17 + + // Select + FrameIndex SRFS A 0 0 + FrameIndex SRFS B 0 1 + FrameIndex SRFS C 0 2 + FrameIndex SRFS D 0 3 + FrameIndex SRFS E 0 4 + FrameIndex SRFS F 0 5 + FrameIndex SRFS G 0 6 + FrameIndex SRFS H 0 7 + FrameIndex SRFS I 0 8 + FrameIndex SRFS J 0 9 + FrameIndex SRFS K 0 10 + FrameIndex SRFS L 0 11 + FrameIndex SRFS M 0 12 + FrameIndex SRFS N 0 13 + FrameIndex SRFS O 0 14 + FrameIndex SRFS P 0 15 + FrameIndex SRFS Q 0 16 + FrameIndex SRFS R 0 17 + FrameIndex SRFS S 0 18 + FrameIndex SRFS T 0 19 + // Idle + FrameIndex SRFI A 0 20 + // Fire + FrameIndex SRFF A 0 21 + FrameIndex SRFF B 0 22 + FrameIndex SRFF C 0 23 + FrameIndex SRFF D 0 24 + FrameIndex SRFF E 0 25 + FrameIndex SRFF F 0 26 + FrameIndex SRFF G 0 27 + FrameIndex SRFF H 0 28 + FrameIndex SRFF I 0 29 + FrameIndex SRFF J 0 30 + // Scope Up + FrameIndex SRSU A 0 41 + FrameIndex SRSU B 0 42 + FrameIndex SRSU C 0 43 + FrameIndex SRSU D 0 44 + FrameIndex SRSU E 0 45 + FrameIndex SRSU F 0 46 + FrameIndex SRSU G 0 47 + FrameIndex SRSU H 0 48 + FrameIndex SRSU I 0 49 + FrameIndex SRSU J 0 50 + FrameIndex SRSU K 0 51 + FrameIndex SRSU L 0 52 + FrameIndex SRSU M 0 53 + FrameIndex SRSU N 0 54 + // Scoped Idle + FrameIndex SRSI A 0 55 + // Scope Down + FrameIndex SRSD A 0 86 + FrameIndex SRSD B 0 87 + FrameIndex SRSD C 0 88 + FrameIndex SRSD D 0 89 + FrameIndex SRSD E 0 90 + FrameIndex SRSD F 0 91 + FrameIndex SRSD G 0 92 + FrameIndex SRSD H 0 93 + FrameIndex SRSD I 0 94 + FrameIndex SRSD J 0 95 + FrameIndex SRSD K 0 96 + FrameIndex SRSD L 0 97 + FrameIndex SRSD M 0 98 + FrameIndex SRSD N 0 99 + FrameIndex SRSD O 0 100 + // Down + FrameIndex SRFD A 0 71 + FrameIndex SRFD B 0 73 + FrameIndex SRFD C 0 75 + FrameIndex SRFD D 0 77 + FrameIndex SRFD E 0 79 + FrameIndex SRFD F 0 81 + FrameIndex SRFD G 0 83 + FrameIndex SRFD H 0 85 } \ No newline at end of file diff --git a/shaders/glsl/URifleScope.fp b/shaders/glsl/URifleScope.fp new file mode 100644 index 0000000..709278d --- /dev/null +++ b/shaders/glsl/URifleScope.fp @@ -0,0 +1,12 @@ +void main() +{ + vec2 uv = TexCoord.st; + vec2 p = vec2(0.5)-uv; + vec2 sz = textureSize(InputTexture,0); + if ( sz.x > sz.y ) p.x *= sz.x/sz.y; + else p.y *= sz.y/sz.x; + vec3 col = texture(InputTexture,uv+p*pow(length(p),8.)*40.).rgb; + col = max(col.r,max(col.g,col.b))*vec3(1.,0.2,.1); + col *= 1.-clamp(pow(length(p)*2.,16.),0.,1.); + FragColor = vec4(col,1.0); +} diff --git a/sndinfo.txt b/sndinfo.txt index 1023093..4677340 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -220,6 +220,10 @@ automag/fire shot automag/click click automag/reload reload +rifle/fire riflesht +rifle/scopeon rifllon +rifle/scopeoff riflloff + translator/event transa3 detector/start detact diff --git a/zscript/miscitems.zsc b/zscript/miscitems.zsc index 32580d2..5e35901 100644 --- a/zscript/miscitems.zsc +++ b/zscript/miscitems.zsc @@ -1263,7 +1263,7 @@ Class UFlashLight1 : DynamicLight override void Tick() { Super.Tick(); - if ( !target || !UnrealInventory(master) ) + if ( !target || !master ) { Destroy(); return; @@ -1272,9 +1272,18 @@ Class UFlashLight1 : DynamicLight else SetOrigin(target.vec3Offset(0,0,target.height*0.75),true); A_SetAngle(target.angle,SPF_INTERPOLATE); A_SetPitch(target.pitch,SPF_INTERPOLATE); - args[LIGHT_RED] = int(basecolor[0]*clamp(UnrealInventory(master).charge/1400.,0.,1.)); - args[LIGHT_GREEN] = int(basecolor[1]*clamp(UnrealInventory(master).charge/1400.,0.,1.)); - args[LIGHT_BLUE] = int(basecolor[2]*clamp(UnrealInventory(master).charge/1400.,0.,1.)); + if ( UnrealInventory(master) ) + { + args[LIGHT_RED] = int(basecolor[0]*clamp(UnrealInventory(master).charge/1400.,0.,1.)); + args[LIGHT_GREEN] = int(basecolor[1]*clamp(UnrealInventory(master).charge/1400.,0.,1.)); + args[LIGHT_BLUE] = int(basecolor[2]*clamp(UnrealInventory(master).charge/1400.,0.,1.)); + } + else + { + args[LIGHT_RED] = basecolor[0]; + args[LIGHT_GREEN] = basecolor[1]; + args[LIGHT_BLUE] = basecolor[2]; + } bDORMANT = (target.health <= 0); if ( Inventory(target) && target.bInvisible ) bDORMANT = true; // alert monsters hit by the light diff --git a/zscript/razorjack.zsc b/zscript/razorjack.zsc index 51ea4eb..1c87d7c 100644 --- a/zscript/razorjack.zsc +++ b/zscript/razorjack.zsc @@ -212,6 +212,8 @@ Class Razorjack : UnrealWeapon if ( !weap ) return; if ( weap.Ammo1.Amount <= 0 ) return; if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return; + if ( self is 'UTPlayer' ) + UTPlayer(self).PlayAttacking3(); A_PlaySound("ripper/fire",CHAN_WEAPON,pitch:bAlt?1.:(1.+invoker.special1*.1)); invoker.FireEffect(); UTMainHandler.DoFlash(self,Color(16,255,0,255),1); diff --git a/zscript/rifle.zsc b/zscript/rifle.zsc index dc11a33..898c871 100644 --- a/zscript/rifle.zsc +++ b/zscript/rifle.zsc @@ -3,6 +3,7 @@ Class URifleAmmo : Ammo Default { Tag "$T_RIFLEAMMO"; + Inventory.Icon "I_RifleA"; Inventory.PickupMessage ""; Inventory.Amount 8; Inventory.MaxAmount 50; @@ -44,11 +45,183 @@ Class URifleAmmo2 : URifleAmmo Class URifle : UnrealWeapon { + double sniperzoom; + ui TextureID reticle; + transient ui Font zfont; + bool bLightOn; + UFlashLight1 lt[2]; + + override void PreRender( double lbottom ) + { + if ( sniperzoom <= 1. ) return; + if ( reticle.IsNull() ) reticle = TexMan.CheckForTexture("UReticle",Texman.Type_Any); + Screen.DrawTexture(reticle,false,300,300,DTA_VirtualWidth,600,DTA_VirtualHeight,600,DTA_LegacyRenderStyle,STYLE_Stencil,DTA_FillColor,Color(0,0,0)); + if ( !zfont ) zfont = Font.GetFont('UTFont40'); + Screen.DrawText(zfont,Font.CR_UNTRANSLATED,700,700,String.Format("X%.1f",sniperzoom),DTA_VirtualWidth,1280,DTA_VirtualHeight,960,DTA_LegacyRenderStyle,STYLE_Stencil,DTA_FillColor,Color(0,0,0)); + } + override void DetachFromOwner() + { + Super.DetachFromOwner(); + PlayerInfo p = players[consoleplayer]; + if ( p.Camera == Owner ) Shader.SetEnabled(p,"URifleScope",false); + bLightOn = false; + if ( lt[0] ) lt[0].Destroy(); + if ( lt[1] ) lt[1].Destroy(); + } + override void RenderOverlay( RenderEvent e ) + { + PlayerInfo p = players[consoleplayer]; + if ( (p.Camera != Owner) || (sniperzoom <= 1.) ) Shader.SetEnabled(p,"URifleScope",false); + else Shader.SetEnabled(p,"URifleScope",true); + } + override void DoEffect() + { + Super.DoEffect(); + bALT_AMMO_OPTIONAL = !sting_rifle; + if ( sniperzoom > 1.0 ) crosshair = 99; + else crosshair = 0; + } + action void A_ToggleLight() + { + invoker.bLightOn = !invoker.bLightOn; + A_PlaySound(invoker.bLightOn?"lite/pickup":"lite/off",CHAN_ITEM); + if ( invoker.bLightOn ) + { + if ( !invoker.lt[0] ) invoker.lt[0] = UFlashLight1(Spawn("UFlashLight1",pos)); + invoker.lt[0].target = self; + invoker.lt[0].master = invoker; + invoker.lt[0].basecolor[0] = 255; + invoker.lt[0].basecolor[1] = 224; + invoker.lt[0].basecolor[2] = 192; + invoker.lt[0].args[3] = 480; + invoker.lt[0].SpotInnerAngle = 2; + invoker.lt[0].SpotOuterAngle = 9; + if ( !invoker.lt[1] ) invoker.lt[1] = UFlashLight1(Spawn("UFlashLight2",pos)); + invoker.lt[1].target = self; + invoker.lt[1].master = invoker; + invoker.lt[1].basecolor[0] = 128; + invoker.lt[1].basecolor[1] = 112; + invoker.lt[1].basecolor[2] = 96; + invoker.lt[1].args[3] = 500; + invoker.lt[1].SpotOuterAngle = 15; + } + else + { + if ( invoker.lt[0] ) invoker.lt[0].Destroy(); + if ( invoker.lt[1] ) invoker.lt[1].Destroy(); + } + } + action void A_RifleFire( bool zoomed = false, bool alt = false ) + { + Weapon weap = Weapon(invoker); + if ( !weap ) return; + if ( weap.Ammo1.Amount <= 0 ) return; + if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return; + if ( self is 'UTPlayer' ) + UTPlayer(self).PlayAttacking3(); + invoker.FireEffect(); + UTMainHandler.DoFlash(self,Color(32,0,0,255),1); + if ( alt ) A_PlaySound("rifle/fire",CHAN_WEAPON,Dampener.Active(self)?.3:1.,pitch:FRandom[Sniper](0.9,1.1)); + else A_PlaySound("rifle/fire",CHAN_WEAPON,Dampener.Active(self)?.3:1.); + if ( !Dampener.Active(self) ) A_AlertMonsters(); + if ( zoomed ) + { + A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.09); + for ( int i=0; i<3; i++ ) + UTMainHandler.DoSwing(self,(FRandom[Sniper](-0.3,0.05),FRandom[Sniper](-0.3,0.1)),2,-0.5,Random[Sniper](3,4),SWING_Spring,Random[Sniper](3,4),Random[Sniper](4,5)); + } + else + { + A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.12); + for ( int i=0; i<(alt?6:3); i++ ) + UTMainHandler.DoSwing(self,(FRandom[Sniper](-0.3,0.05),FRandom[Sniper](-0.3,0.1)),4,-1,Random[Sniper](3,4),SWING_Spring,Random[Sniper](3,4),Random[Sniper](4,5)); + A_Overlay(-2,"MuzzleFlash"); + A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true); + A_OverlayRenderstyle(-2,STYLE_Add); + } + let l = Spawn("SniperLight",pos); + l.target = self; + Vector3 x, y, z; + [x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll); + Vector3 origin = Vec2OffsetZ(0,0,player.viewz)+10.0*x; + if ( !zoomed ) origin = origin+y*3.0-z*2.0; + FLineTraceData d; + LineTrace(angle,10000,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); + if ( d.HitType == TRACE_HitActor ) + { + int dmg = 45; + if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.81) ) + { + dmg = d.HitActor.DamageMobj(invoker,self,100,'Decapitated',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x)); + UTMainHandler.DoKnockback(d.HitActor,d.HitDir,35000); + } + else + { + dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x)); + UTMainHandler.DoKnockback(d.HitActor,d.HitDir,30000); + } + if ( d.HitActor.bNOBLOOD ) + { + let p = Spawn("BulletImpact",d.HitLocation); + p.scale *= 1.5; + p.angle = atan2(d.HitDir.y,d.HitDir.x)+180; + p.pitch = asin(d.HitDir.z); + } + else + { + d.HitActor.TraceBleed(dmg,self); + d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg); + } + } + else if ( d.HitType != TRACE_HitNone ) + { + Vector3 hitnormal = -d.HitDir; + if ( d.HitType == TRACE_HitFloor ) + { + if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal; + else hitnormal = d.HitSector.floorplane.Normal; + } + else if ( d.HitType == TRACE_HitCeiling ) + { + if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal; + else hitnormal = d.HitSector.ceilingplane.Normal; + } + else if ( d.HitType == TRACE_HitWall ) + { + hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit(); + if ( !d.LineSide ) hitnormal *= -1; + } + let p = Spawn("BulletImpact",d.HitLocation+hitnormal*0.01); + p.scale *= 1.5; + p.angle = atan2(hitnormal.y,hitnormal.x); + p.pitch = asin(-hitnormal.z); + if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation); + } + for ( int i=0; i<24; i++ ) + { + let s = Spawn("UTStaticViewSmoke",origin); + UTViewSmoke(s).ofs = (10,3,-2); + UTViewSmoke(s).vvel += (FRandom[Sniper](-0.05,0.15),FRandom[Sniper](-1.2,1.2),FRandom[Sniper](-0.1,0.1)); + s.target = self; + s.scale *= 1.8; + s.alpha *= 0.3; + } + origin += x*4.0+y*6.0-z*10.0; + let c = Spawn("UCasing",origin); + c.scale *= 1.25; + 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 ) + { + if ( mod == 'Decapitated' ) return StringTable.Localize("$O_SNIPERDECAP"); + return Obituary; + } Default { Tag "$T_RIFLE"; + Obituary "$O_SNIPER"; Inventory.PickupMessage "$I_RIFLE"; - Weapon.UpSound "rifle/select"; + Weapon.UpSound "sniper/select"; Weapon.SlotNumber 9; Weapon.SelectionOrder 9; Weapon.AmmoType "URifleAmmo"; @@ -56,7 +229,9 @@ Class URifle : UnrealWeapon Weapon.AmmoType2 "URifleAmmo"; Weapon.AmmoUse2 1; Weapon.AmmoGive 8; + Weapon.Kickback 250; UTWeapon.DropAmmo 4; + +NOEXTREMEDEATH; } States { @@ -65,5 +240,96 @@ Class URifle : UnrealWeapon Stop; SRFP B -1; Stop; + Select: + SRFS A 1 A_Raise(int.max); + Wait; + Ready: + SRFS A 0 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT); + SRFS ABCDEFGHIJKLMNOPQRST 1 A_WeaponReady(WRF_NOFIRE); + Idle: + SRFI A 1 + { + A_CheckReload(); + A_WeaponReady(sting_riflel?(WRF_ALLOWZOOM|WRF_ALLOWRELOAD):WRF_ALLOWZOOM); + } + Wait; + ZoomedIdle: + TNT1 A 1 + { + A_CheckReload(); + A_WeaponReady(sting_riflel?(WRF_ALLOWZOOM|WRF_ALLOWRELOAD):WRF_ALLOWZOOM); + } + Wait; + Fire: + SRFF A 0 A_JumpIf(invoker.sniperzoom>1.0,"ZoomedFire"); + SRFF A 0 A_RifleFire(); + SRFF ABCDEFGHIJ 2; + Goto Idle; + ZoomedFire: + SRSI A 20 A_RifleFire(true); + Goto ZoomedIdle; + AltFire: + SRFF A 0 A_JumpIf(!sting_rifle,"Zoom"); + SRFF A 0 A_JumpIf(invoker.sniperzoom>1.0,"ZoomedAltFire"); + SRFF A 0 A_RifleFire(false,true); + SRFF ABCDEFG 1; + SRFF A 0 A_JumpIfNoAmmo("AltFireEnd"); + SRFF A 0 A_RifleFire(false,true); + SRFF ABCDEFG 1; + SRFF A 0 A_JumpIfNoAmmo("AltFireEnd"); + SRFF A 0 A_RifleFire(false,true); + SRFF ABCDEFG 1; + AltFireEnd: + SRFF HIJ 1; + SRFI A 3; + Goto Idle; + ZoomedAltFire: + SRSI A 7 A_RifleFire(true,true); + SRSI A 0 A_JumpIfNoAmmo("ZoomedAltFireEnd"); + SRSI A 7 A_RifleFire(true,true); + SRSI A 0 A_JumpIfNoAmmo("ZoomedAltFireEnd"); + SRSI A 7 A_RifleFire(true,true); + ZoomedAltFireEnd: + SRSI A 6; + Goto Idle; + Reload: + SRFI A 8 A_ToggleLight(); + Goto Idle; + Zoom: + SRSU A 0 A_JumpIf(invoker.sniperzoom>1.0,"ZoomOut"); + SRSU A 0 A_PlaySound("rifle/scopeon",CHAN_ITEM,.5); + SRSU ABCDEFGHIJKLMN 1; + Goto ZoomHold; + ZoomHold: + TNT1 A 1 + { + if ( invoker.sniperzoom <= 8.0 ) + A_ZoomFactor(invoker.sniperzoom*=1.1); + invoker.sniperzoom = min(invoker.sniperzoom,8.1); + } + TNT1 A 0 A_JumpIf(player.cmd.buttons&(BT_ALTATTACK|BT_ZOOM),"ZoomHold"); + Goto ZoomedIdle; + ZoomOut: + SRSD A 0 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT); + SRSD A 0 A_PlaySound("rifle/scopeoff",CHAN_ITEM,.5); + SRSD ABCDEFGHIJKLMNO 1; + Goto Idle; + Deselect: + SRFD A 0 A_JumpIf(invoker.sniperzoom<=1.0,"Deselect2"); + SRSD A 0 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT); + SRSD A 0 A_PlaySound("rifle/scopeoff",CHAN_ITEM,.5); + SRSD ABCDEFGHIJKLMNO 1; + Deselect2: + SRFD A 0 + { + A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT); + if ( invoker.bLightOn ) A_ToggleLight(); + } + SRFD ABCDEFG 1; + SRFD H 1 A_Lower(int.max); + Wait; + MuzzleFlash: + SMUZ A 3 Bright; + Stop; } } diff --git a/zscript/ubiorifle.zsc b/zscript/ubiorifle.zsc index f40f5b0..7ff7367 100644 --- a/zscript/ubiorifle.zsc +++ b/zscript/ubiorifle.zsc @@ -593,7 +593,7 @@ Class UBioRifle : UnrealWeapon else A_PlaySound("ges/fire",CHAN_WEAPON,Dampener.Active(self)?.17:1.); invoker.FireEffect(); UTMainHandler.DoFlash(self,Color(48,0,255,0),1); - A_AlertMonsters(); + if ( !Dampener.Active(self) ) A_AlertMonsters(); if ( bAlt ) A_QuakeEx(1+int(0.5*invoker.chargesize),1+int(0.5*invoker.chargesize),1+int(0.5*invoker.chargesize),5+int(1.2*invoker.chargesize),0,64,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05+0.01*invoker.chargesize); else A_QuakeEx(1,1,1,5,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05); Vector3 x, y, z; diff --git a/zscript/unrealcommon.zsc b/zscript/unrealcommon.zsc index 7b442eb..c7066d4 100644 --- a/zscript/unrealcommon.zsc +++ b/zscript/unrealcommon.zsc @@ -234,7 +234,8 @@ Class UPlayer : UTPlayer if ( ((player.ReadyWeapon is 'UBioRifle') && (player.buttons&BT_ALTATTACK)) || (player.ReadyWeapon is 'Eightball') || ((player.ReadyWeapon is 'DispersionPistol') && DispersionPistol(player.ReadyWeapon).bCharging) - || ((player.ReadyWeapon is 'UBioRifle') && UBioRifle(player.ReadyWeapon).bCharging) ) + || ((player.ReadyWeapon is 'UBioRifle') && UBioRifle(player.ReadyWeapon).bCharging) + || (player.ReadyWeapon is 'Razorjack') ) { if ( !InStateSequence(CurState,FindState("MissileRepStill")) ) SetStateLabel("MissileRepStill");