Rifle implemented.

Misc. adjustments to Biorifle and Razorjack.
This commit is contained in:
Marisa the Magician 2019-09-11 23:19:55 +02:00
commit 6984c2819d
11 changed files with 410 additions and 12 deletions

View file

@ -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)

View file

@ -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
}

BIN
graphics/UReticle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -35,3 +35,103 @@ Model "URifle"
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
}

View file

@ -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);
}

View file

@ -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

View file

@ -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);
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

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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");