diff --git a/cvarinfo.txt b/cvarinfo.txt index cb46c05..f30080b 100644 --- a/cvarinfo.txt +++ b/cvarinfo.txt @@ -20,6 +20,7 @@ user float flak_weaponsize = 0.8; // 0.2 <-> 1.0 in steps of 0.2 (default 0.8) user float flak_statussize = 1.0; // 0.5 <-> 1.5 in steps of 0.1 (default 1.0) user bool flak_footsteps = true; // players make footstep sounds server bool flak_translocator = false; // translocator is enabled (hello, sequence breaking) +server bool flak_transloc2k4 = false; // translocator has recharging ammo like in UT2k4 and up user bool flak_noswitchdeemer = true; // don't switch to redeemer when out of ammo user bool flak_deemershader = false; // fancy blur/grain/tint shader server bool flak_classicsshock = false; // classic enhanced shock rifle (no altfire, beams don't have splash damage) @@ -27,10 +28,10 @@ server bool flak_utmovement = false; // emulate UE1's air/ground movement phys server bool flak_doomspeed = false; // keep Doomguy run speed when using UT movement server bool flak_doomaircontrol = false; // keep Doom's limited air control when using UT movement server bool flak_nobosstelefrag = false; // disable telefragging of boss monsters (useful when translocator is enabled) -server bool flak_nowalkdrop = false; // don't drop off ledges while holding walk key (glitchy) +server bool flak_nowalkdrop = false; // [GLITCHY] don't drop off ledges while holding walk key server bool flak_corpsedamage = false; // [WIP/EXPERIMENTAL] allow corpses to take damage and be gibbed, currently just causes a jump to XDeath until gore system is implemented server bool flak_swingers = true; // weapon recoil that affects player view 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; // use doom tournament blood (disable if using another gore mod) -server bool flak_gibs = true; // use doom tournament gibbing (disable if using another gore mod) +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) diff --git a/graphics/hud/IconTrn2.png b/graphics/hud/IconTrn2.png new file mode 100644 index 0000000..55e3fbc Binary files /dev/null and b/graphics/hud/IconTrn2.png differ diff --git a/graphics/hud/UseTrn2.png b/graphics/hud/UseTrn2.png new file mode 100644 index 0000000..dbb8868 Binary files /dev/null and b/graphics/hud/UseTrn2.png differ diff --git a/menudef.txt b/menudef.txt index 72313e1..c626275 100644 --- a/menudef.txt +++ b/menudef.txt @@ -35,6 +35,7 @@ OptionMenu "UTOptionMenu" StaticText " " StaticText "Translocator (Potentially Game-Breaking)", "Gold" Option "Prevent Boss Telefrag", "flak_nobosstelefrag", "YesNo" + Option "Translocator Has Ammo", "flak_transloc2k4", "YesNo" Option "Enable Translocator", "flak_translocator", "YesNo" Command "Apply Changes", "event refreshtrans" StaticText " " diff --git a/modeldef.enforcer b/modeldef.enforcer index 4164b1d..8e766b8 100644 --- a/modeldef.enforcer +++ b/modeldef.enforcer @@ -384,4 +384,4 @@ Model "Enforcer" FrameIndex 2NFA S 2 148 FrameIndex 2NFA T 2 149 FrameIndex 2NFA U 2 150 -} \ No newline at end of file +} diff --git a/zscript/biorifle.zsc b/zscript/biorifle.zsc index 38c70e7..8aa2475 100644 --- a/zscript/biorifle.zsc +++ b/zscript/biorifle.zsc @@ -657,7 +657,7 @@ Class BioRifle : UTWeapon else A_QuakeEx(1,1,1,5,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05); Vector3 x, y, z; double a, s; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+8.0*y-5.0*z; Actor p; if ( alt ) diff --git a/zscript/chainsaw.zsc b/zscript/chainsaw.zsc index a1cc12f..7652de3 100644 --- a/zscript/chainsaw.zsc +++ b/zscript/chainsaw.zsc @@ -53,7 +53,7 @@ Class UTChainsaw : UTWeapon invoker.FireEffect(); A_AlertMonsters(); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-4.0*z; FLineTraceData d; LineTrace(angle,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); @@ -91,7 +91,7 @@ Class UTChainsaw : UTWeapon if ( initial ) invoker.FireEffect(); A_AlertMonsters(); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-2.0*z; FLineTraceData d; double ang = (angle-60)+120*invoker.sawcnt; @@ -141,7 +141,7 @@ Class UTChainsaw : UTWeapon UTMainHandler.DoSwing(self,(FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)),0.25,-0.1,2,SWING_Spring); if ( bAlt || Random[Chainsaw](0,2) ) return; Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+5.0*x+1.0*y-3.0*z; for ( int i=0; i<5; i++ ) { diff --git a/zscript/eightball.zsc b/zscript/eightball.zsc index 9b4d168..316ffb5 100644 --- a/zscript/eightball.zsc +++ b/zscript/eightball.zsc @@ -337,9 +337,9 @@ Class UTRocketLauncher : UTWeapon UTMainHandler.DoSwing(self,(FRandom[Eightball](0.4,-0.8),FRandom[Eightball](-0.5,0.5)),1,-0.2,Random[Eightball](3,4),SWING_Spring,Random[Eightball](2,5),Random[Eightball](2,4)); Vector3 x, y, z, x2, y2, z2; double a, s; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-3.0*z; - [x2, y2, z2] = Matrix4.GetAxes(BulletSlope(),angle,roll); + [x2, y2, z2] = dt_Matrix4.GetAxes(BulletSlope(),angle,roll); Actor p; if ( weap.bAltFire ) { diff --git a/zscript/enforcer.zsc b/zscript/enforcer.zsc index 4e69a26..a9d4b87 100644 --- a/zscript/enforcer.zsc +++ b/zscript/enforcer.zsc @@ -303,14 +303,14 @@ Class Enforcer : UTWeapon UTMainHandler.DoSwing(self,(FRandom[Enforcer](-0.2,-0.5),FRandom[Enforcer](-0.3,0.2)),2,0,1,SWING_Spring,0,2); } Vector3 x, y, z, x2, y2, z2; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = pos+(0,0,player.viewheight)+10.0*x; int ydir = slave?-1:1; if ( alt ) origin = origin-z*3.0+ydir*y*1.0; else origin = origin-z*1.0+ydir*y*4.0; double a = FRandom[Enforcer](0,360), s = FRandom[Enforcer](0,alt?0.08:0.004); if ( invoker.SlaveActive ) s *= 3; - [x2, y2, z2] = Matrix4.GetAxes(BulletSlope(),angle,roll); + [x2, y2, z2] = dt_Matrix4.GetAxes(BulletSlope(),angle,roll); Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit(); FLineTraceData d; LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); diff --git a/zscript/flakcannon.zsc b/zscript/flakcannon.zsc index c005cc5..4432890 100644 --- a/zscript/flakcannon.zsc +++ b/zscript/flakcannon.zsc @@ -422,7 +422,7 @@ Class FlakSlug : Actor Spawn("SlugLight",pos); Vector3 x, y, z; double a, s; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Actor p; for ( int i=0; i<5; i++ ) { @@ -516,12 +516,12 @@ Class FlakCannon : UTWeapon A_QuakeEx(1,1,1,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.05); Vector3 x, y, z; double a, s; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+4.0*y-3.0*z; A_Overlay(-2,"MuzzleFlash"); A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true); A_OverlayRenderstyle(-2,STYLE_Add); - [x, y, z] = Matrix4.GetAxes(BulletSlope(),angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(BulletSlope(),angle,roll); Actor p; for ( int i=0; i<6; i++ ) { @@ -566,7 +566,7 @@ Class FlakCannon : UTWeapon A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1); Vector3 x, y, z; double a, s; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-3.0*z; A_Overlay(-2,"MuzzleFlash"); A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true); diff --git a/zscript/impacthammer.zsc b/zscript/impacthammer.zsc index e0343c1..81461dd 100644 --- a/zscript/impacthammer.zsc +++ b/zscript/impacthammer.zsc @@ -70,7 +70,7 @@ Class ImpactHammer : UTWeapon UTMainHandler.DoSwing(self,(FRandom[Impact](-0.3,-1.5),FRandom[Impact](-1.2,-0.4)),3,-0.8,3,SWING_Spring,3,2); A_AlertMonsters(); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*z; double realcharge = min(1.5,invoker.chargesize); FLineTraceData d; @@ -133,7 +133,7 @@ Class ImpactHammer : UTWeapon A_AlertMonsters(); A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*z; FLineTraceData d; LineTrace(angle,120,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); @@ -188,7 +188,7 @@ Class ImpactHammer : UTWeapon { FLineTraceData d; Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+3.0*y-4.0*z; LineTrace(angle,40,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); if ( (invoker.chargesize > 1) && (d.HitType == TRACE_HitActor) ) diff --git a/zscript/minigun.zsc b/zscript/minigun.zsc index b8e20ea..35b6110 100644 --- a/zscript/minigun.zsc +++ b/zscript/minigun.zsc @@ -101,10 +101,10 @@ Class Minigun : UTWeapon l.target = self; if ( !alt ) MinigunLight(l).cnt--; Vector3 x, y, z, x2, y2, z2; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = pos+(0,0,player.viewheight)+10.0*x+y*2.0-z*2.0; double a = FRandom[Minigun](0,360), s = FRandom[Minigun](0,alt?0.05:0.02); - [x2, y2, z2] = Matrix4.GetAxes(BulletSlope(),angle,roll); + [x2, y2, z2] = dt_Matrix4.GetAxes(BulletSlope(),angle,roll); Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit(); FLineTraceData d; LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); diff --git a/zscript/mk_coordutil.zsc b/zscript/mk_coordutil.zsc index 299feed..709a425 100644 --- a/zscript/mk_coordutil.zsc +++ b/zscript/mk_coordutil.zsc @@ -5,7 +5,7 @@ See https://www.gnu.org/licenses/lgpl-3.0.txt for its terms. */ -Class mkCoordUtil +Class dt_CoordUtil { // projects a world point onto screen // view matrix setup mostly pulled from gutawer's code @@ -21,32 +21,32 @@ Class mkCoordUtil double apitch = asin(angy/alen); double ayaw = yaw-90; // rotations - Matrix4 mRoll = Matrix4.rotate((0,0,1),roll); - Matrix4 mPitch = Matrix4.rotate((1,0,0),apitch); - Matrix4 mYaw = Matrix4.rotate((0,-1,0),ayaw); + dt_Matrix4 mRoll = dt_Matrix4.rotate((0,0,1),roll); + dt_Matrix4 mPitch = dt_Matrix4.rotate((1,0,0),apitch); + dt_Matrix4 mYaw = dt_Matrix4.rotate((0,-1,0),ayaw); // scaling - Matrix4 mScale = Matrix4.identity(); + dt_Matrix4 mScale = dt_Matrix4.identity(); mScale.set(1,1,pr); // YZ swap - Matrix4 mYZ = Matrix4.create(); + dt_Matrix4 mYZ = dt_Matrix4.create(); mYZ.set(0,0,1); mYZ.set(2,1,1); mYZ.set(1,2,-1); mYZ.set(3,3,1); // translation - Matrix4 mMove = Matrix4.identity(); + dt_Matrix4 mMove = dt_Matrix4.identity(); mMove.set(3,0,-eye.x); mMove.set(3,1,-eye.y); mMove.set(3,2,-eye.z); // perspective - Matrix4 mPerspective = Matrix4.perspective(fov,ar,5,65535); + dt_Matrix4 mPerspective = dt_Matrix4.perspective(fov,ar,5,65535); // full matrix - Matrix4 mView = mRoll.mul(mPitch); + dt_Matrix4 mView = mRoll.mul(mPitch); mView = mView.mul(mYaw); mView = mView.mul(mScale); mView = mView.mul(mYZ); mView = mView.mul(mMove); - Matrix4 mWorldToScreen = mPerspective.mul(mView); + dt_Matrix4 mWorldToScreen = mPerspective.mul(mView); return mWorldToScreen.vmat(vect); } diff --git a/zscript/mk_matrix.zsc b/zscript/mk_matrix.zsc index 37ddf69..7a15095 100644 --- a/zscript/mk_matrix.zsc +++ b/zscript/mk_matrix.zsc @@ -5,25 +5,25 @@ See https://www.gnu.org/licenses/lgpl-3.0.txt for its terms. */ -Class Matrix4 +Class dt_Matrix4 { private double m[16]; - Matrix4 init() + dt_Matrix4 init() { int i; for ( i=0; i<16; i++ ) m[i] = 0; return self; } - static Matrix4 create() + static dt_Matrix4 create() { - return new("Matrix4").init(); + return new("dt_Matrix4").init(); } - static Matrix4 identity() + static dt_Matrix4 identity() { - Matrix4 o = Matrix4.create(); + dt_Matrix4 o = dt_Matrix4.create(); for ( int i=0; i<4; i++ ) o.set(i,i,1); return o; } @@ -38,27 +38,27 @@ Class Matrix4 m[r*4+c] = v; } - Matrix4 add( Matrix4 o ) + dt_Matrix4 add( dt_Matrix4 o ) { - Matrix4 r = Matrix4.create(); + dt_Matrix4 r = dt_Matrix4.create(); int i, j; for ( i=0; i<4; i++ ) for ( j=0; j<4; j++ ) r.set(j,i,get(j,i)+o.get(j,i)); return r; } - Matrix4 scale( double s ) + dt_Matrix4 scale( double s ) { - Matrix4 r = Matrix4.create(); + dt_Matrix4 r = dt_Matrix4.create(); int i, j; for ( i=0; i<4; i++ ) for ( j=0; j<4; j++ ) r.set(j,i,get(j,i)*s); return r; } - Matrix4 mul( Matrix4 o ) + dt_Matrix4 mul( dt_Matrix4 o ) { - Matrix4 r = Matrix4.create(); + dt_Matrix4 r = dt_Matrix4.create(); int i, j; for ( i=0; i<4; i++ ) for ( j=0; j<4; j++ ) r.set(j,i,get(0,i)*o.get(j,0)+get(1,i)*o.get(j,1)+get(2,i)*o.get(j,2)+get(3,i)*o.get(j,3)); @@ -75,9 +75,9 @@ Class Matrix4 return (x,y,z)/w; } - static Matrix4 rotate( Vector3 axis, double theta ) + static dt_Matrix4 rotate( Vector3 axis, double theta ) { - Matrix4 r = Matrix4.identity(); + dt_Matrix4 r = dt_Matrix4.identity(); double s, c, oc; s = sin(theta); c = cos(theta); @@ -94,9 +94,9 @@ Class Matrix4 return r; } - static Matrix4 perspective( double fov, double ar, double znear, double zfar ) + static dt_Matrix4 perspective( double fov, double ar, double znear, double zfar ) { - Matrix4 r = Matrix4.create(); + dt_Matrix4 r = dt_Matrix4.create(); double f = 1/tan(fov*0.5); r.set(0,0,f/ar); r.set(1,1,f); @@ -110,10 +110,10 @@ Class Matrix4 static Vector3, Vector3, Vector3 getaxes( double pitch, double yaw, double roll ) { Vector3 x = (1,0,0), y = (0,-1,0), z = (0,0,1); // y inverted for left-handed result - Matrix4 mRoll = Matrix4.rotate((1,0,0),roll); - Matrix4 mPitch = Matrix4.rotate((0,1,0),pitch); - Matrix4 mYaw = Matrix4.rotate((0,0,1),yaw); - Matrix4 mRot = mRoll.mul(mYaw); + dt_Matrix4 mRoll = dt_Matrix4.rotate((1,0,0),roll); + dt_Matrix4 mPitch = dt_Matrix4.rotate((0,1,0),pitch); + dt_Matrix4 mYaw = dt_Matrix4.rotate((0,0,1),yaw); + dt_Matrix4 mRot = mRoll.mul(mYaw); mRot = mRot.mul(mPitch); x = mRot.vmat(x); y = mRot.vmat(y); diff --git a/zscript/mk_quaternion.zsc b/zscript/mk_quaternion.zsc index 24631a5..8a5770c 100644 --- a/zscript/mk_quaternion.zsc +++ b/zscript/mk_quaternion.zsc @@ -5,11 +5,11 @@ See https://www.gnu.org/licenses/lgpl-3.0.txt for its terms. */ -Class Quat +Class dt_Quat { protected double W, X, Y, Z; - Quat init( double w, double x, double y, double z ) + dt_Quat init( double w, double x, double y, double z ) { self.W = w; self.X = x; @@ -18,7 +18,7 @@ Class Quat return self; } - void copy( Quat q ) + void copy( dt_Quat q ) { W = q.W; X = q.X; @@ -26,26 +26,26 @@ Class Quat Z = q.Z; } - static Quat create( double w, double x, double y, double z ) + static dt_Quat create( double w, double x, double y, double z ) { - return new("Quat").init(w,x,y,z); + return new("dt_Quat").init(w,x,y,z); } - static Quat create_axis( Vector3 axis, double theta ) + static dt_Quat create_axis( Vector3 axis, double theta ) { double scale = axis dot axis; - if ( scale < double.epsilon ) return Quat.create(1,0,0,0); + if ( scale < double.epsilon ) return dt_Quat.create(1,0,0,0); theta *= 0.5; double f = sin(theta)/sqrt(scale); - return Quat.create(cos(theta),axis.x*f,axis.y*f,axis.z*f); + return dt_Quat.create(cos(theta),axis.x*f,axis.y*f,axis.z*f); } - static Quat create_euler( double pitch, double yaw, double roll ) + static dt_Quat create_euler( double pitch, double yaw, double roll ) { - Quat zrot = Quat.create_axis((0,0,1),yaw); - Quat yrot = Quat.create_axis((0,1,0),pitch); - Quat xrot = Quat.create_axis((1,0,0),roll); - Quat sum = zrot.qmul(yrot); + dt_Quat zrot = dt_Quat.create_axis((0,0,1),yaw); + dt_Quat yrot = dt_Quat.create_axis((0,1,0),pitch); + dt_Quat xrot = dt_Quat.create_axis((1,0,0),roll); + dt_Quat sum = zrot.qmul(yrot); sum = sum.qmul(xrot); return sum; } @@ -89,9 +89,9 @@ Class Quat return pitch, yaw, roll; } - Quat qmul( Quat q ) + dt_Quat qmul( dt_Quat q ) { - return Quat.create(w*q.w-x*q.x-y*q.y-z*q.z,w*q.x+x*q.w+y*q.z-z + return dt_Quat.create(w*q.w-x*q.x-y*q.y-z*q.z,w*q.x+x*q.w+y*q.z-z *q.y,w*q.y+y*q.w+z*q.x-x*q.z,w*q.z+z*q.w+x*q.y-y*q.x); } } diff --git a/zscript/pulsegun.zsc b/zscript/pulsegun.zsc index 9733d6b..78add62 100644 --- a/zscript/pulsegun.zsc +++ b/zscript/pulsegun.zsc @@ -87,7 +87,7 @@ Class ViewPulseSpark : PulseSpark return; } Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(target.pitch,target.angle,target.roll); + [x, y, z] = dt_Matrix4.GetAxes(target.pitch,target.angle,target.roll); 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); @@ -515,7 +515,7 @@ Class StarterBolt : PulseBolt Vector3 x, y, z, origin; if ( target.player ) { - [x, y, z] = Matrix4.GetAxes(target.pitch,target.angle,target.roll); + [x, y, z] = dt_Matrix4.GetAxes(target.pitch,target.angle,target.roll); origin = target.Vec2OffsetZ(0,0,target.player.viewz)+8.0*x+4.1*y-2.7*z; } else origin = target.Vec3Offset(0,0,target.missileheight); @@ -562,7 +562,7 @@ Class PulseGun : UTWeapon UTMainHandler.DoSwing(self,(FRandom[Pulse](-1,-1),FRandom[Pulse](-1,1)),0.1,-0.02,3,SWING_Spring,0,2); A_AlertMonsters(); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = Vec2OffsetZ(0,0,player.viewz)+10.0*x+4.1*y-2.7*z; for ( int i=0; i<4; i++ ) { @@ -628,7 +628,7 @@ Class PulseGun : UTWeapon A_OverlayRenderstyle(-2,STYLE_Add); Vector3 x, y, z; double a; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = Vec2OffsetZ(0,0,player.viewz)+10.0*x+3.0*y-1.8*z; origin += y*cos(invoker.sangle)*2.0+z*sin(invoker.sangle)*2.0; invoker.sangle += 100; @@ -660,7 +660,7 @@ Class PulseGun : UTWeapon { A_PlaySound("pulse/bolt",CHAN_WEAPON,1.0,true); Vector3 x, y, z, origin; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); origin = Vec2OffsetZ(0,0,player.viewz)+10.0*x+4.1*y-2.7*z; invoker.beam = Spawn("StarterBolt",origin); invoker.beam.angle = angle; diff --git a/zscript/ripper.zsc b/zscript/ripper.zsc index 3d2ebff..03aec45 100644 --- a/zscript/ripper.zsc +++ b/zscript/ripper.zsc @@ -283,7 +283,7 @@ Class Ripper2 : UTWeapon UTMainHandler.DoSwing(self,(FRandom[Ripper](-0.3,-0.6),FRandom[Ripper](0.2,0.6)),1,-0.3,2,SWING_Spring,2,2); } Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+6.0*y-4.0*z; Actor p; if ( alt ) p = Spawn("Razor2Alt",origin); diff --git a/zscript/shockrifle.zsc b/zscript/shockrifle.zsc index c33b560..1247e97 100644 --- a/zscript/shockrifle.zsc +++ b/zscript/shockrifle.zsc @@ -978,7 +978,7 @@ Class ViewShockSpark : ShockSpark return; } Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(target.pitch,target.angle,target.roll); + [x, y, z] = dt_Matrix4.GetAxes(target.pitch,target.angle,target.roll); 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); @@ -1012,7 +1012,7 @@ Class ShockRifle : UTWeapon A_AlertMonsters(); A_QuakeEx(2,2,2,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z; Actor p = Spawn("ShockBeam",origin); p.angle = angle; @@ -1050,7 +1050,7 @@ Class ShockRifle : UTWeapon A_AlertMonsters(); A_QuakeEx(2,2,2,8,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z; Actor p = Spawn("ShockBall",origin); p.angle = angle; @@ -1195,7 +1195,7 @@ Class EnhancedShockRifle : UTWeapon A_AlertMonsters(); A_QuakeEx(3,3,3,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.15); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z; Actor p = Spawn("SuperShockBeam",origin); p.angle = angle; @@ -1233,7 +1233,7 @@ Class EnhancedShockRifle : UTWeapon A_AlertMonsters(); A_QuakeEx(3,3,3,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.15); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-1.5*z; Actor p = Spawn("SuperShockBall",origin); p.angle = angle; diff --git a/zscript/sniperrifle.zsc b/zscript/sniperrifle.zsc index 73a031b..34c2185 100644 --- a/zscript/sniperrifle.zsc +++ b/zscript/sniperrifle.zsc @@ -95,7 +95,7 @@ Class SniperRifle : UTWeapon let l = Spawn("SniperLight",pos); l.target = self; Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_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; diff --git a/zscript/translocator.zsc b/zscript/translocator.zsc index f1652ba..ebde8a2 100644 --- a/zscript/translocator.zsc +++ b/zscript/translocator.zsc @@ -274,9 +274,43 @@ Class TranslocatorAfterimage : Actor } } +Class TranslocatorAmmo : Ammo +{ + Default + { + Tag "Translocator Ammo"; + Inventory.Amount 6; + Inventory.MaxAmount 6; + Ammo.BackpackAmount 0; + Ammo.BackpackMaxAmount 6; + } +} + Class Translocator : UTWeapon { Actor module; + double ammocharge; + + override void Tick() + { + Super.Tick(); + if ( !Owner ) return; + if ( flak_transloc2k4 ) + { + AmmoType1 = "TranslocatorAmmo"; + if ( !Ammo1 ) Ammo1 = NonIdioticAddAmmo(Owner,AmmoType1,6); + if ( Ammo1.Amount >= Ammo1.MaxAmount ) return; + if ( ammocharge >= 1. ) + { + ammocharge = 0.; + Ammo1.Amount = min(Ammo1.Amount+1,Ammo1.MaxAmount); + } + else ammocharge = min(1.,ammocharge+0.4/TICRATE); + return; + } + if ( Ammo1 ) Ammo1.Destroy(); + if ( AmmoType1 ) AmmoType1 = null; + } action void A_ThrowModule() { @@ -287,7 +321,7 @@ Class Translocator : UTWeapon UTMainHandler.DoSwing(self,(FRandom[Translocator](-0.2,0.4),FRandom[Translocator](-0.2,0.7)),2,-0.3,3,SWING_Spring,2,3); A_AlertMonsters(); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-8.0*y-12.0*z; let p = Spawn("TranslocatorModule",origin); p.target = self; @@ -328,6 +362,8 @@ Class Translocator : UTWeapon A_PlaySound("transloc/return",CHAN_WEAPON); return; } + // consume ammo if any + if ( weap.Ammo1 ) weap.Ammo1.Amount = max(0,weap.Ammo1.Amount-1); // check if there's enough space Vector3 oldpos = pos, newpos = invoker.module.pos; double modulefloorz = invoker.module.floorz, moduleceilingz = invoker.module.ceilingz; @@ -374,6 +410,8 @@ Class Translocator : UTWeapon Weapon.SelectionOrder 10; +WEAPON.NO_AUTO_SWITCH; +WEAPON.CHEATNOTWEAPON; + +WEAPON.AMMO_OPTIONAL; + +WEAPON.ALT_AMMO_OPTIONAL; } States { @@ -411,7 +449,7 @@ Class Translocator : UTWeapon TLI2 A 0; Goto Idle2; Fire: - TLCF A 0 A_JumpIf(invoker.module,"Return"); + TLCF A 0 A_JumpIf(invoker.module||(invoker.Ammo1&&invoker.Ammo1.Amount<=0),"Return"); TLCF A 0 A_ThrowModule(); TLCF ABCDEFGH 1; TLCF IJKLMNOPQRS 1 A_WeaponReady(WRF_NOPRIMARY); diff --git a/zscript/utcommon.zsc b/zscript/utcommon.zsc index 7ea2f03..27c6f97 100644 --- a/zscript/utcommon.zsc +++ b/zscript/utcommon.zsc @@ -574,7 +574,7 @@ Class UTWeapon : Weapon Vector2 hofs = RotateVector((dropper.radius,0),dropper.angle); SetOrigin(dropper.Vec3Offset(hofs.x,hofs.y,dropper.height*0.5),false); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(dropper.pitch,dropper.angle,dropper.roll); + [x, y, z] = dt_Matrix4.GetAxes(dropper.pitch,dropper.angle,dropper.roll); vel = x*12.0; vel.z += 4.0; angle = dropper.angle; @@ -745,7 +745,7 @@ Class UTViewSpark : UTSpark return; } Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(target.pitch,target.angle,target.roll); + [x, y, z] = dt_Matrix4.GetAxes(target.pitch,target.angle,target.roll); 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); @@ -990,7 +990,7 @@ Class UTViewSmoke : UTSmoke return; } Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(target.pitch,target.angle,target.roll); + [x, y, z] = dt_Matrix4.GetAxes(target.pitch,target.angle,target.roll); 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); diff --git a/zscript/uthud.zsc b/zscript/uthud.zsc index 6f80dc4..543b5e1 100644 --- a/zscript/uthud.zsc +++ b/zscript/uthud.zsc @@ -23,7 +23,7 @@ Class ViewTracer : LineTracer Class UTHud : BaseStatusBar { - TextureID AmmoBar, Boxes[4], Keys[5], BigNum[12], Flash, Slots[10], Icons[14], Uses[14], Man[5], Woman[5], WeaponBox; + TextureID AmmoBar, Boxes[4], Keys[5], BigNum[12], Flash, Slots[10], Icons[14], Uses[14], Man[5], Woman[5], WeaponBox, IconTloc2, UseTloc2; Class IconClasses[14]; double HScale; Color tintcolor, bgcolor; @@ -148,6 +148,8 @@ Class UTHud : BaseStatusBar override void Draw( int state, double TicFrac ) { Super.Draw(state,TicFrac); + if ( IconTloc2.IsNull() ) IconTloc2 = TexMan.CheckForTexture("IconTrn2",TexMan.Type_Any); + if ( UseTLoc2.IsNull() ) UseTloc2 = TexMan.CheckForTexture("UseTrn2",TexMan.Type_Any); HScale = Screen.GetWidth()/1280.; switch ( CVar.GetCVar('flak_colorprefs',CPlayer).GetInt() ) { @@ -223,8 +225,18 @@ Class UTHud : BaseStatusBar { Color halftint = Color(tintcolor.a,tintcolor.r/2,tintcolor.g/2,tintcolor.b/2); if ( !(w is IconClasses[i]) ) continue; - if ( use ) UTDrawTintedTex(Uses[i],sx,opacity+7); - else UTDrawTintedTex(Icons[i],sx,opacity,halftint); + if ( use ) + { + if ( (i == 11) && flak_transloc2k4 ) + UTDrawTintedTex(UseTloc2,sx,opacity+7); + else UTDrawTintedTex(Uses[i],sx,opacity+7); + } + else + { + if ( (i == 11) && flak_transloc2k4 ) + UTDrawTintedTex(IconTloc2,sx,opacity+7); + else UTDrawTintedTex(Icons[i],sx,opacity,halftint); + } return true; } return false; @@ -265,11 +277,31 @@ Class UTHud : BaseStatusBar CurX = showweapons?(Screen.GetWidth()-128*hudsize*HScale):(Screen.GetWidth()*0.5+128*hudsize*HScale); CurY = Screen.GetHeight()-64*hudsize*HScale; if ( showweapons && ((weaponsize*hudsize)>=1.0) ) CurY -= 64*hudsize*HScale; + double BaseX = CurX; + double BaseY = CurY; UTDrawTintedTex(Boxes[0],hudsize); CurX += 8*hudsize*HScale; CurY += 14*hudsize*HScale; DrawColor = WhiteColor; - if ( ammotype1 ) UTDrawBigNum(ammotype1.Amount,hudsize); + if ( ammotype1 ) + { + UTDrawBigNum(ammotype1.Amount,hudsize); + let cw = CPlayer.ReadyWeapon; + if ( flak_transloc2k4 && (cw is 'Translocator') ) + { + // draw ammo charge bar + double ch = Translocator(cw).ammocharge; + CurX = BaseX+6*hudsize*HScale; + CurY = BaseY+53*hudsize*HScale; + Vector2 ss = (0.54,0.3)*hudsize*HScale; + double dw = (Screen.GetWidth()/ss.x), dh = (Screen.GetHeight()/ss.y); + double dx = CurX/ss.x, dy = CurY/ss.y; + Vector2 bs = TexMan.GetScaledSize(AmmoBar); + double ddw = bs.x*ch; + double alpha = clamp((opacity+7)/15.,0.0,1.0); + Screen.DrawTexture(AmmoBar,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_WindowRightF,ddw,DTA_Alpha,alpha); + } + } if ( ammotype2 && (ammotype2 != ammotype1) ) { CurX = showweapons?(Screen.GetWidth()-128*hudsize*HScale):((Screen.GetWidth()+256*hudsize*HScale)*0.5); @@ -352,7 +384,7 @@ Class UTHud : BaseStatusBar if ( CPlayer.mo.Health < CPlayer.mo.SpawnHealth()/2 ) { Color blinkcolor; - double blinky = ((gametic+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); @@ -378,8 +410,6 @@ Class UTHud : BaseStatusBar double WeaponOffset = 128*WeapScale; let cw = CPlayer.ReadyWeapon; int cwslot = -1; - let pw = CPlayer.PendingWeapon; - int pwslot = -1; if ( cw && (cw.SlotNumber != -1) ) { cwslot = cw.SlotNumber?(cw.SlotNumber-1):9; @@ -389,7 +419,9 @@ Class UTHud : BaseStatusBar CurX = BaseX+cwslot*WeaponOffset; CurY = BaseY; } - if ( pw && (pw.SlotNumber != -1) && (pw != WP_NOCHANGE) ) + let pw = CPlayer.PendingWeapon; + int pwslot = -1; + if ( pw && (pw != WP_NOCHANGE) && (pw.SlotNumber != -1) ) { pwslot = pw.SlotNumber?(pw.SlotNumber-1):9; CurX = BaseX+pwslot*WeaponOffset-64*WeapScale; @@ -468,7 +500,7 @@ Class UTHud : BaseStatusBar CurY = Screen.GetHeight()-64*hudsize*HScale; if ( showweapons && ((weaponsize*hudsize)>=1.0) ) CurY -= 64*hudsize*HScale; DrawColor = tintcolor; - double whiten = ((gametic+fractic)-lastfrag)/Thinker.TICRATE; + double whiten = ((level.time+fractic)-lastfrag)/Thinker.TICRATE; if ( whiten < 3.0 ) { if ( tintcolor == GoldColor ) @@ -490,7 +522,7 @@ Class UTHud : BaseStatusBar } private void DrawIdentifyInfo() { - double lalpha = 2.0-((gametic+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()) ) @@ -564,19 +596,19 @@ Class UTHud : BaseStatusBar Super.Tick(); if ( deathmatch||teamplay ) { - if ( CPlayer.fragcount != lastfragcnt ) lastfrag = gametic; + if ( CPlayer.fragcount != lastfragcnt ) lastfrag = level.time; lastfragcnt = CPlayer.fragcount; } else { - if ( CPlayer.killcount != lastfragcnt ) lastfrag = gametic; + 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 = gametic; + lastseentic = level.time; } private void DrawUTHUD() diff --git a/zscript/warheadlauncher.zsc b/zscript/warheadlauncher.zsc index c63074f..675925b 100644 --- a/zscript/warheadlauncher.zsc +++ b/zscript/warheadlauncher.zsc @@ -398,8 +398,8 @@ Class GuidedWarShell : WarShell guideangle = lagangle2*0.95+lagangle*0.05; guidepitch = lagpitch2*0.95+lagpitch*0.05; guideroll = lagroll2*0.95+lagroll*0.05; - Quat orient = Quat.create_euler(pitch,angle,roll); - Quat angles = Quat.create_euler(guidepitch,guideangle,guideroll); + dt_Quat orient = dt_Quat.create_euler(pitch,angle,roll); + dt_Quat angles = dt_Quat.create_euler(guidepitch,guideangle,guideroll); orient = orient.qmul(angles); double npitch, nangle, nroll; [npitch, nangle, nroll] = orient.to_euler(); @@ -477,8 +477,8 @@ Class RedeemerHUD : HUDMessageBase } override bool Tick() { - LagRoll = Quat.Normalize180(ViewRoll-LagRoll2); - LagRoll2 += Quat.Normalize180(LagRoll-LagRoll2)*0.1; + LagRoll = dt_Quat.Normalize180(ViewRoll-LagRoll2); + LagRoll2 += dt_Quat.Normalize180(LagRoll-LagRoll2)*0.1; // shootable targetting if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && !CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() ) { @@ -493,10 +493,10 @@ Class RedeemerHUD : HUDMessageBase 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 = mkCoordUtil.WorldToScreen(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 = mkCoordUtil.ToViewport(spos); + te.vpos = dt_CoordUtil.ToViewport(spos); te.diststr = String.Format("%f",tdir.length()); te.diststr.Replace(".",""); ta.Push(te); @@ -524,10 +524,10 @@ Class RedeemerHUD : HUDMessageBase 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 = mkCoordUtil.WorldToScreen(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 = mkCoordUtil.ToViewport(spos); + te.vpos = dt_CoordUtil.ToViewport(spos); te.diststr = String.Format("%f",tdir.length()); te.diststr.Replace(".",""); ta.Push(te); @@ -660,7 +660,7 @@ Class WarheadLauncher : UTWeapon A_AlertMonsters(); A_QuakeEx(6,6,6,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.2); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); vel -= x*10; Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-2.0*z; Actor p = Spawn("WarShell",origin); @@ -674,7 +674,7 @@ Class WarheadLauncher : UTWeapon Weapon weap = Weapon(invoker); if ( !weap ) return; Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); vel -= x*0.2; Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-2.0*z; int numpt = Random[Warhead](10,20); @@ -698,7 +698,7 @@ Class WarheadLauncher : UTWeapon A_AlertMonsters(); A_QuakeEx(6,6,6,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.2); Vector3 x, y, z; - [x, y, z] = Matrix4.GetAxes(pitch,angle,roll); + [x, y, z] = dt_Matrix4.GetAxes(pitch,angle,roll); vel -= x*10; Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x+2.0*y-2.0*z; Actor p = Spawn("GuidedWarShell",origin);