diff --git a/modeldef.eightball b/modeldef.eightball index 7cb37ea..c29badd 100644 --- a/modeldef.eightball +++ b/modeldef.eightball @@ -22,6 +22,31 @@ Model "UTRocketAmmo2" FrameIndex RCKT A 0 0 } +Model "UTGrenade" +{ + Path "models" + Model 0 "UTRocket_d.3d" + Skin 0 "JuRocket1.png" + Scale 0.07 0.0822 0.09864 + USEACTORPITCH + USEACTORROLL + AngleOffset -90 + + FrameIndex RCKT A 0 0 +} +Model "UTRocket" +{ + Path "models" + Model 0 "UTRocket_d.3d" + Skin 0 "JuRocket1.png" + Scale 0.07 0.0822 0.09864 + USEACTORPITCH + USEACTORROLL + AngleOffset -90 + + FrameIndex RCKT B 0 1 +} + Model "UTRocketLauncher" { Path "models" diff --git a/modeldef.enforcer b/modeldef.enforcer index 8e07c80..2c1c31d 100644 --- a/modeldef.enforcer +++ b/modeldef.enforcer @@ -27,6 +27,67 @@ Model "UTCasing" FrameIndex PCAS A 0 0 } +Model "BulletImpact" +{ + Path "models" + Model 0 "BulletImpact_d.3d" + Skin 0 "Impact_a00.png" + Scale 0.32 0.268 0.24 + PitchOffset -90 + USEACTORPITCH + USEACTORROLL + DONTCULLBACKFACES + FrameIndex BIMP A 0 0 +} +Model "BulletImpact" +{ + Path "models" + Model 0 "BulletImpact_d.3d" + Skin 0 "Impact_a01.png" + Scale 0.32 0.268 0.24 + PitchOffset -90 + USEACTORPITCH + USEACTORROLL + DONTCULLBACKFACES + FrameIndex BIMP B 0 0 +} +Model "BulletImpact" +{ + Path "models" + Model 0 "BulletImpact_d.3d" + Skin 0 "Impact_a02.png" + Scale 0.32 0.268 0.24 + PitchOffset -90 + USEACTORPITCH + USEACTORROLL + DONTCULLBACKFACES + FrameIndex BIMP C 0 0 +} +Model "BulletImpact" +{ + Path "models" + Model 0 "BulletImpact_d.3d" + Skin 0 "Impact_a03.png" + Scale 0.32 0.268 0.24 + PitchOffset -90 + USEACTORPITCH + USEACTORROLL + DONTCULLBACKFACES + FrameIndex BIMP D 0 0 +} +Model "BulletImpact" +{ + Path "models" + Model 0 "BulletImpact_d.3d" + Skin 0 "Impact_a04.png" + Scale 0.32 0.268 0.24 + PitchOffset -90 + USEACTORPITCH + USEACTORROLL + DONTCULLBACKFACES + FrameIndex BIMP E 0 0 +} + Model "Enforcer" { Path "models" diff --git a/modeldef.rifle b/modeldef.rifle index 61a79f5..47497e6 100644 --- a/modeldef.rifle +++ b/modeldef.rifle @@ -43,6 +43,18 @@ Model "SniperRifle" FrameIndex SRFP B 1 0 } +Model "SniperRifle" +{ + Path "models" + Model 2 "Flat_d.3d" + Skin 2 "MuzzleFlash2.png" + AngleOffset 90 + PitchOffset 90 + Scale 0.12 0.12 0.12 + Offset 6.0 -40.0 -6.0 + + FrameIndex SMUZ A 2 0 +} Model "SniperRifle" { diff --git a/models/BulletImpact_a.3d b/models/BulletImpact_a.3d new file mode 100644 index 0000000..8cceccf Binary files /dev/null and b/models/BulletImpact_a.3d differ diff --git a/models/BulletImpact_d.3d b/models/BulletImpact_d.3d new file mode 100644 index 0000000..f715e6d Binary files /dev/null and b/models/BulletImpact_d.3d differ diff --git a/models/Impact_a00.png b/models/Impact_a00.png new file mode 100644 index 0000000..28cfa45 Binary files /dev/null and b/models/Impact_a00.png differ diff --git a/models/Impact_a01.png b/models/Impact_a01.png new file mode 100644 index 0000000..b09c7e8 Binary files /dev/null and b/models/Impact_a01.png differ diff --git a/models/Impact_a02.png b/models/Impact_a02.png new file mode 100644 index 0000000..4014418 Binary files /dev/null and b/models/Impact_a02.png differ diff --git a/models/Impact_a03.png b/models/Impact_a03.png new file mode 100644 index 0000000..08104cd Binary files /dev/null and b/models/Impact_a03.png differ diff --git a/models/Impact_a04.png b/models/Impact_a04.png new file mode 100644 index 0000000..d661388 Binary files /dev/null and b/models/Impact_a04.png differ diff --git a/readme.txt b/readme.txt index e605b5f..21bff4a 100644 --- a/readme.txt +++ b/readme.txt @@ -37,11 +37,11 @@ Currently implemented: - Ripper (slot 6) - Jump Boots (radsuit, has "iron boots" powerup effect to compensate) - Minigun (slot 7) + - Sniper Rifle (slot 0) In progress: - Rocket Launcher (slot 9) - - Sniper Rifle (slot 0) Things to do eventually: diff --git a/textures.eightball b/textures.eightball index ec2f872..73c0c79 100644 --- a/textures.eightball +++ b/textures.eightball @@ -1,5 +1,6 @@ Sprite "RPAKA0",1,1{} Sprite "RCKTA0",1,1{} +Sprite "RCKTB0",1,1{} Sprite "EBLPA0",1,1{} Sprite "EBLPB0",1,1{} Sprite "EBLSA0",1,1{} @@ -178,4 +179,4 @@ Sprite "EBLDG0",1,1{} Sprite "EBLDH0",1,1{} Sprite "EBLDI0",1,1{} Sprite "EBLDJ0",1,1{} -Sprite "EBLDK0",1,1{} +Sprite "EBLDK0",1,1{} \ No newline at end of file diff --git a/textures.enforcer b/textures.enforcer index 8fe10fc..b8fbc9c 100644 --- a/textures.enforcer +++ b/textures.enforcer @@ -253,3 +253,8 @@ Sprite "EMUZA0",1,1{} Sprite "EMUZB0",1,1{} Sprite "EMUZC0",1,1{} Sprite "EMUZD0",1,1{} +Sprite "BIMPA0",1,1{} +Sprite "BIMPB0",1,1{} +Sprite "BIMPC0",1,1{} +Sprite "BIMPD0",1,1{} +Sprite "BIMPE0",1,1{} diff --git a/textures.sniper b/textures.sniper index f6c9539..0bd6f94 100644 --- a/textures.sniper +++ b/textures.sniper @@ -77,3 +77,4 @@ Sprite "SRFDD0",1,1{} Sprite "SRFDE0",1,1{} Sprite "SRFDF0",1,1{} Sprite "SRFDG0",1,1{} +Sprite "SMUZA0",1,1{} diff --git a/zscript/chainsaw.zsc b/zscript/chainsaw.zsc index b12a108..978e4f6 100644 --- a/zscript/chainsaw.zsc +++ b/zscript/chainsaw.zsc @@ -104,8 +104,10 @@ Class UTChainsaw : UTWeapon LineTrace(angle,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); if ( d.HitType == TRACE_HitActor ) { - int dmg = Random[Chainsaw](100,110); - dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Decapitated'); + int dmg = Random[Chainsaw](50,55); + if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) ) + dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated'); + else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'slashed'); d.HitActor.vel = -y*(1200/d.HitActor.mass); vel += x*(100/mass); if ( d.HitActor.player ) d.HitActor.A_QuakeEx(5,5,5,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25); diff --git a/zscript/eightball.zsc b/zscript/eightball.zsc index b84d42c..773bda6 100644 --- a/zscript/eightball.zsc +++ b/zscript/eightball.zsc @@ -36,6 +36,26 @@ Class UTRocketAmmo2 : UTRocketAmmo } } +Class UTRocket : Actor +{ + States + { + Spawn: + RCKT B 1; + Wait; + } +} + +Class UTGrenade : Actor +{ + States + { + Spawn: + RCKT A 1; + Wait; + } +} + Class UTRocketLauncher : UTWeapon { int loaded; @@ -43,6 +63,7 @@ Class UTRocketLauncher : UTWeapon Default { Tag "Rocket Launcher"; + //Obituary "%o was smacked down by %k's Rocket Launcher."; Inventory.PickupMessage "You got the Rocket Launcher."; Weapon.UpSound "utrl/select"; Weapon.SlotNumber 9; diff --git a/zscript/enforcer.zsc b/zscript/enforcer.zsc index 0673633..7355619 100644 --- a/zscript/enforcer.zsc +++ b/zscript/enforcer.zsc @@ -41,41 +41,48 @@ Class BulletImpact : Actor { Default { + RenderStyle "Add"; Radius 0.1; Height 0; +NOGRAVITY; +NOCLIP; +DONTSPLASH; + Scale 0.25; } override void PostBeginPlay() { Super.PostBeginPlay(); - A_SprayDecal("Pock",20); - int numpt = Random[Enforcer](5,10); + A_SprayDecal("Pock",-20); + int numpt = Random[Enforcer](5,10)*scale.x*4; Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch)); for ( int i=0; i victim.pos.z+victim.height*0.8 ) DamageType = 'Decapitated'; + return -1; + } override int DoSpecialDamage( Actor target, int damage, Name damagetype ) { - if ( pos.z > target.pos.z+target.height*0.8 ) damage *= 3; + if ( pos.z > target.pos.z+target.height*0.8 ) damage *= 2; if ( !target.bNOBLOOD ) { target.SpawnBlood(pos,AngleTo(target),damage); diff --git a/zscript/sniperrifle.zsc b/zscript/sniperrifle.zsc index 43550c9..0d28a02 100644 --- a/zscript/sniperrifle.zsc +++ b/zscript/sniperrifle.zsc @@ -35,11 +35,100 @@ Class RifleAmmo2 : RifleAmmo } } -Class SniperRifle : UTWeapon +Class SniperLight : EnforcerLight { + Default + { + args 255,224,64,120; + } +} + +Class SniperRifle : UTWeapon +{ + double sniperzoom; + TextureID reticle; + + override void PostBeginPlay() + { + Super.PostBeginPlay(); + reticle = TexMan.CheckForTexture("RReticle",Texman.Type_Any); + } + override void PreRender() + { + if ( sniperzoom <= 1.0 ) return; + Screen.DrawTexture(reticle,false,320,240,DTA_VirtualWidth,640,DTA_VirtualHeight,480); + Screen.DrawText(confont,Font.CR_DARKGREEN,192,160,String.Format("X%.1f",sniperzoom),DTA_Clean,true); + } + action void A_SniperFire( bool zoomed = false ) + { + Weapon weap = Weapon(invoker); + if ( !weap ) return; + if ( weap.Ammo1.Amount <= 0 ) return; + if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return; + invoker.FireEffect(); + UTMainHandler.DoFlash(self,Color(32,0,0,255),1); + A_PlaySound("sniper/fire",CHAN_WEAPON); + A_AlertMonsters(); + if ( zoomed ) A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.09); + else + { + A_QuakeEx(3,3,3,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.12); + 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] = Matrix4.GetAxes(pitch,angle,roll); + Vector3 origin = Vec2OffsetZ(0,0,player.viewz)+10.0*x; + if ( !zoomed ) origin = origin+y*4.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 = Random[Sniper](40,50); + if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) ) + dmg = d.HitActor.DamageMobj(invoker,self,dmg+65,'Decapitated'); + else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot'); + 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 ) hitnormal = d.HitSector.floorplane.Normal; + else if ( d.HitType == TRACE_HitCeiling ) 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); + } + 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); + } Default { Tag "Sniper Rifle"; + Obituary "%k put a bullet through %o's head."; Inventory.PickupMessage "You got the Sniper Rifle."; Weapon.UpSound "sniper/select"; Weapon.SlotNumber 0; @@ -61,7 +150,7 @@ Class SniperRifle : UTWeapon SRFS A 1 A_Raise(int.max); Wait; Ready: - SRFS A 1; + SRFS A 1 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT); SRFS B 2; SRFS C 1; SRFS D 2; @@ -85,7 +174,21 @@ Class SniperRifle : UTWeapon A_WeaponReady(); } Wait; + ZoomedIdle: + TNT1 A 1 + { + A_CheckReload(); + A_WeaponReady(); + } + Wait; Fire: + SRFI A 0 A_JumpIf(invoker.sniperzoom>1.0,"ZoomedFire"); + SRFI A 0 + { + A_SniperFire(); + return A_Jump(256,1,11,21,31,41); + } + Goto Idle; SRF1 ABCDEFGHIJ 2; Goto Idle; SRF2 ABCDEFGHIJ 2; @@ -96,9 +199,31 @@ Class SniperRifle : UTWeapon Goto Idle; SRF5 ABCDEFGHIJ 2; Goto Idle; + ZoomedFire: + TNT1 A 20 A_SniperFire(true); + Goto ZoomedIdle; + AltFire: + SRFI A 0 A_JumpIf(invoker.sniperzoom>1.0,"AltHold2"); + AltHold: + 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_Refire("AltHold"); + Goto ZoomedIdle; + AltHold2: + SRFI A 1 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT); + SRFI A 0 A_Refire("AltHold2"); + Goto Idle; Deselect: + SRFD A 0 A_ZoomFactor(invoker.sniperzoom=1.0,ZOOM_INSTANT); SRFD ABCDEFG 2; SRFD G 1 A_Lower(int.max); Wait; + MuzzleFlash: + SMUZ A 3 Bright; + Stop; } } diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index b3c85b1..dabeb42 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -176,7 +176,9 @@ Class RandomSpawner2 : RandomSpawner Class UTWeapon : Weapon { + // Drawstuffs under HUD virtual ui void PreRender() {} + // Drawstuffs over HUD virtual ui void PostRender() {} override Inventory CreateTossable( int amt )