Peacemaker implemented, with some minor model adjustments.
Fixed ammo bars in hud being positioned incorrectly if a weapon in the slot has no ammo. Sentries now will also complain if the terrain is too steep or you're trying to deploy them in mid-air. Adjusted protomag spin animation. Still not perfect but I tried my best. Guess what: more PNG optimization.
This commit is contained in:
parent
6950bb48a1
commit
e562754f00
43 changed files with 760 additions and 17 deletions
|
|
@ -1527,9 +1527,28 @@ Class SentryItem : UnrealInventory
|
|||
}
|
||||
Vector3 origin = Owner.Vec2OffsetZ(0,0,Owner.player.viewz);
|
||||
FLineTraceData d;
|
||||
Owner.LineTrace(Owner.angle,90,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
|
||||
if ( d.HitType != TRACE_HitNone ) origin = d.HitLocation-d.HitDir*20;
|
||||
else origin = d.HitLocation;
|
||||
Owner.LineTrace(Owner.angle,80,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
|
||||
if ( d.HitType != TRACE_HitNone )
|
||||
{
|
||||
Vector3 normal = -d.HitDir;
|
||||
if ( d.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.top.Normal;
|
||||
else normal = d.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.bottom.Normal;
|
||||
else normal = d.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitWall )
|
||||
{
|
||||
normal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
||||
if ( !d.LineSide ) normal *= -1;
|
||||
}
|
||||
origin = d.HitLocation+normal*20;
|
||||
}
|
||||
else origin = d.HitLocation-d.HitDir*20;
|
||||
Owner.LineTrace(0,56,90,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
|
||||
origin = d.HitLocation;
|
||||
let a = Spawn("MinigunSentryBase",origin);
|
||||
|
|
@ -1539,6 +1558,28 @@ Class SentryItem : UnrealInventory
|
|||
a.Destroy();
|
||||
return false;
|
||||
}
|
||||
if ( a.pos.z-a.floorz > 50 )
|
||||
{
|
||||
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLOOR"));
|
||||
a.Destroy();
|
||||
return false;
|
||||
}
|
||||
F3DFloor ff = null;
|
||||
for ( int i=0; i<a.floorsector.Get3DFloorCount(); i++ )
|
||||
{
|
||||
if ( a.floorsector.Get3DFloor(i).top.ZAtPoint(pos.xy) > floorz ) continue;
|
||||
ff = a.floorsector.Get3DFLoor(i);
|
||||
break;
|
||||
}
|
||||
Vector3 normal;
|
||||
if ( ff ) normal = -ff.top.Normal;
|
||||
else normal = a.floorsector.floorplane.Normal;
|
||||
if ( normal.z < 0.9 )
|
||||
{
|
||||
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLAT"));
|
||||
a.Destroy();
|
||||
return false;
|
||||
}
|
||||
bActive = true;
|
||||
bUNTOSSABLE = true;
|
||||
bUNDROPPABLE = true;
|
||||
|
|
@ -2213,9 +2254,28 @@ Class SentryGunItem : UnrealInventory
|
|||
if ( pickup ) return false;
|
||||
Vector3 origin = Owner.Vec2OffsetZ(0,0,Owner.player.viewz);
|
||||
FLineTraceData d;
|
||||
Owner.LineTrace(Owner.angle,90,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
|
||||
if ( d.HitType != TRACE_HitNone ) origin = d.HitLocation-d.HitDir*20;
|
||||
else origin = d.HitLocation;
|
||||
Owner.LineTrace(Owner.angle,60,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
|
||||
if ( d.HitType != TRACE_HitNone )
|
||||
{
|
||||
Vector3 normal = -d.HitDir;
|
||||
if ( d.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.top.Normal;
|
||||
else normal = d.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( d.Hit3DFloor ) normal = -d.Hit3DFloor.bottom.Normal;
|
||||
else normal = d.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitWall )
|
||||
{
|
||||
normal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
||||
if ( !d.LineSide ) normal *= -1;
|
||||
}
|
||||
origin = d.HitLocation+normal*20;
|
||||
}
|
||||
else origin = d.HitLocation-d.HitDir*20;
|
||||
Owner.LineTrace(0,56,90,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
|
||||
origin = d.HitLocation;
|
||||
let a = Spawn("SentryGun",origin);
|
||||
|
|
@ -2225,6 +2285,28 @@ Class SentryGunItem : UnrealInventory
|
|||
a.Destroy();
|
||||
return false;
|
||||
}
|
||||
if ( a.pos.z-a.floorz > 50 )
|
||||
{
|
||||
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLOOR"));
|
||||
a.Destroy();
|
||||
return false;
|
||||
}
|
||||
F3DFloor ff = null;
|
||||
for ( int i=0; i<a.floorsector.Get3DFloorCount(); i++ )
|
||||
{
|
||||
if ( a.floorsector.Get3DFloor(i).top.ZAtPoint(pos.xy) > floorz ) continue;
|
||||
ff = a.floorsector.Get3DFLoor(i);
|
||||
break;
|
||||
}
|
||||
Vector3 normal;
|
||||
if ( ff ) normal = -ff.top.Normal;
|
||||
else normal = a.floorsector.floorplane.Normal;
|
||||
if ( normal.z < 0.9 )
|
||||
{
|
||||
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOFLAT"));
|
||||
a.Destroy();
|
||||
return false;
|
||||
}
|
||||
tracer = a;
|
||||
a.master = Owner;
|
||||
a.angle = Owner.angle;
|
||||
|
|
|
|||
|
|
@ -4,22 +4,434 @@ Class PeaceAmmo : Ammo
|
|||
{
|
||||
Inventory.Icon "I_Peace";
|
||||
Inventory.Amount 1;
|
||||
Inventory.MaxAmount 8;
|
||||
Inventory.MaxAmount 1;
|
||||
Ammo.BackpackAmount 0;
|
||||
Ammo.BackpackMaxAmount 16;
|
||||
Ammo.BackpackMaxAmount 2;
|
||||
}
|
||||
}
|
||||
|
||||
Class PeaceTrail : Actor
|
||||
{
|
||||
Default
|
||||
{
|
||||
RenderStyle "Add";
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
+NOBLOCKMAP;
|
||||
+NOGRAVITY;
|
||||
+DONTSPLASH;
|
||||
+FORCEXYBILLBOARD;
|
||||
+NOTELEPORT;
|
||||
Scale 0.25;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
A_AttachLight('RocketLight',DynamicLight.PointLight,Color(255,128,112),32,32);
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !target || !target.bMISSILE )
|
||||
{
|
||||
A_RemoveLight('RocketLight');
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
Vector3 dir = (cos(target.angle)*cos(target.pitch),sin(target.angle)*cos(target.pitch),-sin(target.pitch));
|
||||
SetOrigin(level.Vec3Offset(target.pos,-dir*3),true);
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
PFLA A -1 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class PeaceRocket : Actor
|
||||
{
|
||||
Vector3 Acceleration;
|
||||
int ticcnt;
|
||||
Default
|
||||
{
|
||||
Obituary "$O_PEACE";
|
||||
DamageType 'PeaceDeath';
|
||||
Radius 2;
|
||||
Height 2;
|
||||
Speed 3.5;
|
||||
PROJECTILE;
|
||||
+SKYEXPLODE;
|
||||
+EXPLODEONWATER;
|
||||
+SEEKERMISSILE;
|
||||
+FORCERADIUSDMG;
|
||||
+NODAMAGETHRUST;
|
||||
+INTERPOLATEANGLES;
|
||||
+HITOWNER;
|
||||
ReactionTime 9;
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
let l = Spawn("PeaceTrail",pos);
|
||||
l.target = self;
|
||||
A_PlaySound("peace/fly",CHAN_VOICE,1.0,true,2.5,pitch:0.8);
|
||||
Acceleration = vel*1.67;
|
||||
}
|
||||
action void A_CheckForTargets()
|
||||
{
|
||||
let bi = BlockThingsIterator.Create(self,500);
|
||||
while ( bi.Next() )
|
||||
{
|
||||
if ( !bi.Thing || (!bi.Thing.bISMONSTER && !bi.Thing.player) || (bi.Thing.Health <= 0) || (Distance3D(bi.Thing) > 500) || !CheckSight(bi.Thing) ) continue;
|
||||
tracer = bi.Thing;
|
||||
return;
|
||||
}
|
||||
}
|
||||
action void A_SeekTargets()
|
||||
{
|
||||
if ( !tracer || (tracer.Health <= 0) ) return;
|
||||
double mag = vel.length();
|
||||
vel = mag*(level.Vec3Diff(pos,tracer.Vec3Offset(0,0,tracer.height/2)).unit()*mag*6./TICRATE+vel).unit();
|
||||
}
|
||||
action void A_PeaceExplode()
|
||||
{
|
||||
bFORCEXYBILLBOARD = true;
|
||||
A_SetRenderStyle(1.0,STYLE_Add);
|
||||
A_SprayDecal("RocketBlast",50);
|
||||
A_NoGravity();
|
||||
A_SetScale(1.1);
|
||||
UTMainHandler.DoBlast(self,200,70000);
|
||||
A_Explode(100,200);
|
||||
A_QuakeEx(3,3,3,8,0,250,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollIntensity:0.2);
|
||||
A_PlaySound("utrl/explode",CHAN_VOICE);
|
||||
A_AlertMonsters();
|
||||
Spawn("RocketExplLight",pos);
|
||||
int numpt = Random[Peace](15,30);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Peace](-1,1),FRandom[Peace](-1,1),FRandom[Peace](-1,1)).unit()*FRandom[Peace](1,3);
|
||||
let s = Spawn("UTSmoke",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[Peace](10,20);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Peace](-1,1),FRandom[Peace](-1,1),FRandom[Peace](-1,1)).unit()*FRandom[Peace](2,6);
|
||||
let s = Spawn("UTSpark",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[Peace](35,70);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[Peace](-1,1),FRandom[Peace](-1,1),FRandom[Peace](-1,1)).unit()*FRandom[Peace](2,12);
|
||||
let s = Spawn("UTChip",pos);
|
||||
s.vel = pvel;
|
||||
s.scale *= FRandom[Peace](0.9,2.7);
|
||||
}
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
PEAR A 1
|
||||
{
|
||||
roll += 5.;
|
||||
A_SeekTargets();
|
||||
vel += Acceleration/TICRATE;
|
||||
double mag = vel.length();
|
||||
if ( mag > 0. )
|
||||
{
|
||||
Vector3 dir = vel/mag;
|
||||
if ( mag > 16 ) vel = vel.unit()*16;
|
||||
angle = atan2(dir.y,dir.x);
|
||||
pitch = asin(-dir.z);
|
||||
mag = Acceleration.length();
|
||||
Acceleration = dir*mag;
|
||||
}
|
||||
for ( int i=0; i<3; i++ )
|
||||
{
|
||||
let s = Spawn("UTSmoke",pos);
|
||||
s.vel = (FRandom[Peace](-0.2,0.2),FRandom[Peace](-0.2,0.2),FRandom[Peace](-0.2,0.2));
|
||||
s.vel += vel*0.1;
|
||||
s.SetShade(Color(1,1,1)*Random[Peace](32,48));
|
||||
}
|
||||
special1++;
|
||||
if ( special1 > 35 )
|
||||
{
|
||||
special1 = 0;
|
||||
A_CheckForTargets();
|
||||
A_CountDown();
|
||||
}
|
||||
}
|
||||
Wait;
|
||||
Death:
|
||||
TNT1 A 0 A_PeaceExplode();
|
||||
SSMX ABCDEFGHIJ 2 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class PeaceProj : Actor
|
||||
Class PeaceFragment : SentryFragment
|
||||
{
|
||||
Default
|
||||
{
|
||||
Scale 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
Class PeaceBarrel : Actor
|
||||
{
|
||||
action void A_AlignSelf()
|
||||
{
|
||||
// find closest 3d floor for its normal
|
||||
F3DFloor ff = null;
|
||||
for ( int i=0; i<floorsector.Get3DFloorCount(); i++ )
|
||||
{
|
||||
if ( !(floorsector.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
|
||||
ff = floorsector.Get3DFLoor(i);
|
||||
break;
|
||||
}
|
||||
Vector3 normal;
|
||||
if ( ff ) normal = -ff.top.Normal;
|
||||
else normal = floorsector.floorplane.Normal;
|
||||
// bless Gutawer
|
||||
Vector2 angv = (cos(angle),sin(angle));
|
||||
Vector3 x;
|
||||
if ( ff ) x = (angv,ff.top.ZAtPoint(pos.xy+angv)-pos.z).unit();
|
||||
else x = (angv,floorsector.floorplane.ZAtPoint(pos.xy+angv)-pos.z).unit();
|
||||
pitch = -asin(x.z);
|
||||
roll = asin(normal.x*angv.y-normal.y*angv.x);
|
||||
}
|
||||
action void A_FireRocket( int n )
|
||||
{
|
||||
A_PlaySound("flak/altfire",CHAN_AUTO);
|
||||
A_AlertMonsters();
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 dir = z*1.3;
|
||||
Vector3 origin;
|
||||
switch ( n )
|
||||
{
|
||||
case 0:
|
||||
// front right
|
||||
dir = (dir+x+y).unit();
|
||||
origin = level.Vec3Offset(pos,z*4+x*4+y*4);
|
||||
break;
|
||||
case 1:
|
||||
// front left
|
||||
dir = (dir-x+y).unit();
|
||||
origin = level.Vec3Offset(pos,z*4-x*4+y*4);
|
||||
break;
|
||||
case 2:
|
||||
// back right
|
||||
dir = (dir+x-y).unit();
|
||||
origin = level.Vec3Offset(pos,z*4+x*4-y*4);
|
||||
break;
|
||||
case 3:
|
||||
// back left
|
||||
dir = (dir-x-y).unit();
|
||||
origin = level.Vec3Offset(pos,z*4-x*4-y*4);
|
||||
break;
|
||||
}
|
||||
let r = Spawn("PeaceRocket",origin);
|
||||
r.angle = atan2(dir.y,dir.x);
|
||||
r.pitch = asin(-dir.z);
|
||||
r.vel = dir*r.speed;
|
||||
r.target = target;
|
||||
}
|
||||
action void A_BlowUp()
|
||||
{
|
||||
bFORCEXYBILLBOARD = true;
|
||||
SetOrigin(Vec3Offset(0,0,16),false);
|
||||
A_SetRenderStyle(1.0,STYLE_Add);
|
||||
A_SprayDecal("RocketBlast",50);
|
||||
A_NoGravity();
|
||||
A_SetScale(bAMBUSH?1.8:1.2);
|
||||
A_Explode(bAMBUSH?500:125,bAMBUSH?200:100);
|
||||
A_PlaySound("sentry/explode",CHAN_BODY,pitch:0.6);
|
||||
A_PlaySound("utrl/explode",CHAN_VOICE,pitch:0.8);
|
||||
A_AlertMonsters();
|
||||
A_QuakeEx(4,4,4,10,0,400,"",QF_RELATIVE|QF_SCALEDOWN,falloff:300,rollIntensity:0.2);
|
||||
UTMainHandler.DoBlast(self,bAMBUSH?200:100,50000);
|
||||
double ang, pt;
|
||||
for ( int i=0; i<16; i++ )
|
||||
{
|
||||
let f = Spawn("PeaceFragment",Vec3Offset(FRandom[EFrag](-8,8),FRandom[EFrag](-8,8),FRandom[EFrag](4,12)));
|
||||
ang = FRandom[EFrag](0,360);
|
||||
pt = FRandom[EFrag](-90,90);
|
||||
f.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[EFrag](4,20);
|
||||
f.vel.z += 3.;
|
||||
}
|
||||
int numpt = Random[ExploS](20,35);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,9);
|
||||
let s = Spawn("UTSmoke",pos);
|
||||
s.vel = pvel;
|
||||
s.scale *= 2.;
|
||||
}
|
||||
numpt = Random[ExploS](10,20);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
|
||||
let s = Spawn("UTSpark",pos);
|
||||
s.vel = pvel;
|
||||
}
|
||||
numpt = Random[ExploS](20,30);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
{
|
||||
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,12);
|
||||
let s = Spawn("UTChip",pos);
|
||||
s.vel = pvel;
|
||||
s.scale *= FRandom[ExploS](0.9,2.7);
|
||||
}
|
||||
Spawn("FlareXLight",pos);
|
||||
}
|
||||
Default
|
||||
{
|
||||
Obituary "$O_PEACEMK";
|
||||
Radius 6;
|
||||
Height 9;
|
||||
DamageType 'PeaceBarrelDeath';
|
||||
PROJECTILE;
|
||||
-NOGRAVITY;
|
||||
+SKYEXPLODE;
|
||||
+FORCERADIUSDMG;
|
||||
+NODAMAGETHRUST;
|
||||
+MOVEWITHSECTOR;
|
||||
+CANBOUNCEWATER;
|
||||
+BOUNCEAUTOOFF;
|
||||
+BOUNCEAUTOOFFFLOORONLY;
|
||||
+USEBOUNCESTATE;
|
||||
+INTERPOLATEANGLES;
|
||||
Speed 8;
|
||||
BounceType "Hexen";
|
||||
BounceFactor 0.3; // otherwise it's too damn bouncy
|
||||
BounceSound "transloc/bounce";
|
||||
WallBounceFactor 0.8;
|
||||
Gravity 0.35;
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
PEAM A -1;
|
||||
Stop;
|
||||
Bounce:
|
||||
PEAM A 0
|
||||
{
|
||||
if ( BlockingFloor ) A_AlignSelf();
|
||||
else pitch = roll = 0;
|
||||
if ( vel.length() < 2. ) ClearBounce();
|
||||
}
|
||||
Goto Spawn;
|
||||
Death:
|
||||
PEAM A 1 A_CheckFloor(1);
|
||||
Wait;
|
||||
PEAM A 4 A_AlignSelf();
|
||||
PEAM A 35
|
||||
{
|
||||
A_PlaySound((special1<=0)?"utrl/seeklost":"utrl/seeklock",CHAN_AUTO);
|
||||
A_AlertMonsters();
|
||||
return A_JumpIf(--special1<0,1);
|
||||
}
|
||||
Wait;
|
||||
PEAM A 0 A_JumpIf(bAMBUSH,"Detonate");
|
||||
PEAM A 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
PEAM B 3;
|
||||
PEAM C 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
PEAM D 3 A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
PEAM E 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
PEAM F 3
|
||||
{
|
||||
A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
|
||||
}
|
||||
PEAM G 3 A_PlaySound("peace/open",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
PEAM H 3
|
||||
{
|
||||
A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
|
||||
}
|
||||
PEAM I 3;
|
||||
PEAM J 3
|
||||
{
|
||||
A_PlaySound("transloc/bounce",CHAN_AUTO,.8,pitch:FRandom[Peace](0.8,1.2));
|
||||
A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
|
||||
}
|
||||
PEAM K 3 A_PlaySound("utrl/rotate",CHAN_AUTO,.1);
|
||||
PEAM L 3 A_PlaySound("transloc/bounce",CHAN_AUTO,.5,pitch:FRandom[Peace](0.8,1.2));
|
||||
PEAM M 3;
|
||||
PEAM N 3 A_PlaySound("utrl/rotate",CHAN_AUTO,.1);
|
||||
PEAM OPQ 3;
|
||||
PEAM R 3 A_PlaySound("utrl/rotate",CHAN_AUTO,.1);
|
||||
PEAM STU 3;
|
||||
PEAM V 3 A_PlaySound("utrl/rotate",CHAN_AUTO,.1);
|
||||
PEAM XYZ[\] 3;
|
||||
PEAM ] 35;
|
||||
PEAM ] 0 A_FireRocket(0);
|
||||
PEAL A 20;
|
||||
PEAL A 0 A_FireRocket(1);
|
||||
PEAL B 20;
|
||||
PEAL B 0 A_FireRocket(2);
|
||||
PEAL C 20;
|
||||
PEAL C 0 A_FireRocket(3);
|
||||
PEAL D 20;
|
||||
Detonate:
|
||||
PEAM A 20;
|
||||
BlowUp:
|
||||
TNT1 A 0 A_BlowUp();
|
||||
SSMX ABCDEFGHIJ 2 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class Peacemaker : UnrealWeapon
|
||||
{
|
||||
action void A_PeacemakerThrow( bool bAlt = false )
|
||||
{
|
||||
let weap = Weapon(invoker);
|
||||
if ( weap.Ammo1.Amount <= 0 ) return;
|
||||
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
||||
invoker.FireEffect();
|
||||
A_PlaySound("peace/throw",CHAN_WEAPON);
|
||||
Vector3 x, y, z;
|
||||
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+y*5-z*3);
|
||||
let p = Spawn("PeaceBarrel",origin);
|
||||
if ( bAlt ) p.bAMBUSH = true;
|
||||
p.special1 = invoker.special2;
|
||||
p.angle = angle;
|
||||
p.pitch = BulletSlope();
|
||||
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
|
||||
p.vel.z += 2.;
|
||||
p.target = self;
|
||||
if ( weap.Ammo1.Amount <= 0 ) player.SetPSprite(PSP_WEAPON,invoker.FindState("EmptyIdle"));
|
||||
else player.SetPSprite(PSP_WEAPON,invoker.FindState("Ready"));
|
||||
}
|
||||
action void A_StartCount()
|
||||
{
|
||||
invoker.special1 = invoker.special2 = 0;
|
||||
A_PlaySound("peace/set",CHAN_ITEM,.4);
|
||||
}
|
||||
action void A_CountUp( Statelabel next )
|
||||
{
|
||||
invoker.special1++;
|
||||
if ( invoker.special1 > 20 )
|
||||
{
|
||||
invoker.special2++;
|
||||
if ( invoker.special2 <= 9 )
|
||||
{
|
||||
A_PlaySound("peace/set",CHAN_ITEM,.4);
|
||||
player.FindPSprite(PSP_WEAPON).frame = invoker.special2;
|
||||
}
|
||||
invoker.special1 = 0;
|
||||
}
|
||||
if ( (invoker.special2 >= 10) || !(player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK)) )
|
||||
{
|
||||
invoker.special2 = min(9,invoker.special2);
|
||||
player.SetPSprite(PSP_WEAPON,invoker.FindState(next));
|
||||
}
|
||||
}
|
||||
Default
|
||||
{
|
||||
Tag "$T_PEACE";
|
||||
|
|
@ -29,6 +441,8 @@ Class Peacemaker : UnrealWeapon
|
|||
Weapon.SelectionOrder 1;
|
||||
Weapon.AmmoType "PeaceAmmo";
|
||||
Weapon.AmmoUse 1;
|
||||
Weapon.AmmoType2 "PeaceAmmo";
|
||||
Weapon.AmmoUse2 1;
|
||||
Weapon.AmmoGive 1;
|
||||
UTWeapon.DropAmmo 1;
|
||||
}
|
||||
|
|
@ -39,5 +453,73 @@ Class Peacemaker : UnrealWeapon
|
|||
Stop;
|
||||
PEAP B -1;
|
||||
Stop;
|
||||
Select:
|
||||
PEAS A 1 A_Raise(int.max);
|
||||
Wait;
|
||||
Ready:
|
||||
PEAS ABCDEFGHIJ 2 A_WeaponReady(WRF_NOFIRE);
|
||||
PEAS K 0 A_PlaySound("peace/up",CHAN_ITEM,.4);
|
||||
PEAS KLMNOPQRST 2 A_WeaponReady(WRF_NOFIRE);
|
||||
Idle:
|
||||
PEAI A 1
|
||||
{
|
||||
A_CheckReload();
|
||||
A_WeaponReady();
|
||||
}
|
||||
Wait;
|
||||
EmptyIdle:
|
||||
TNT1 A 1
|
||||
{
|
||||
let weap = Weapon(invoker);
|
||||
if ( weap.Ammo1.Amount > 0 )
|
||||
return ResolveState("Ready");
|
||||
A_CheckReload();
|
||||
A_WeaponReady(WRF_NOFIRE);
|
||||
return ResolveState(null);
|
||||
}
|
||||
Wait;
|
||||
Fire:
|
||||
PEAC A 1 A_StartCount();
|
||||
PEAC # 1 A_CountUp(1);
|
||||
Wait;
|
||||
PEAF ABCD 2;
|
||||
PEAF E 0
|
||||
{
|
||||
A_PlaySound("peace/down",CHAN_ITEM,.4);
|
||||
UTMainHandler.DoSwing(self,(FRandom[Peace](-0.1,-0.04),FRandom[Peace](0.4,0.6)),3,0,7,SWING_Spring,3,0.8);
|
||||
}
|
||||
PEAF EFG 2;
|
||||
PEAF H 0
|
||||
{
|
||||
UTMainHandler.DoSwing(self,(FRandom[Peace](0.08,0.12),FRandom[Peace](-1.2,-0.9)),4,0,6,SWING_Spring,3,1.5);
|
||||
}
|
||||
PEAF HI 2; // hello
|
||||
PEAF I -1 A_PeacemakerThrow();
|
||||
Stop;
|
||||
AltFire:
|
||||
PEAC A 1 A_StartCount();
|
||||
PEAC # 1 A_CountUp(1);
|
||||
Wait;
|
||||
PEAF ABCD 2;
|
||||
PEAF E 0
|
||||
{
|
||||
A_PlaySound("peace/down",CHAN_ITEM,.4);
|
||||
UTMainHandler.DoSwing(self,(FRandom[Peace](-0.1,-0.04),FRandom[Peace](0.4,0.6)),3,0,7,SWING_Spring,3,0.8);
|
||||
}
|
||||
PEAF EFG 2;
|
||||
PEAF H 0
|
||||
{
|
||||
UTMainHandler.DoSwing(self,(FRandom[Peace](0.08,0.12),FRandom[Peace](-1.2,-0.9)),4,0,6,SWING_Spring,3,1.5);
|
||||
}
|
||||
PEAF HI 2; // howdy
|
||||
PEAF I -1 A_PeacemakerThrow(true);
|
||||
Stop;
|
||||
Deselect:
|
||||
PEAD A 0 A_JumpIfNoAmmo("EmptyDeselect");
|
||||
PEAD ABCDEFGHI 1;
|
||||
PEAD J 1 A_Lower(int.max);
|
||||
EmptyDeselect:
|
||||
TNT1 A 1 A_Lower(int.max);
|
||||
Wait;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ Class UnrealHUD : BaseStatusBar
|
|||
for ( int j=0; j<aslots[i].Size(); j++ )
|
||||
{
|
||||
let amo = aslots[i][j];
|
||||
if ( amo.Amount <= 0 ) continue;
|
||||
AmmoBarSize = 16*min(1.0,amo.Amount/double(amo.MaxAmount));
|
||||
CurX = HalfHUDX-3+realslot*6+(4./nammo)*cbar;
|
||||
CurY = HalfHUDY+29-AmmoBarSize;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue