Minigun implemented. Some minor adjustments to weapon model offsets.
Allow armor/pads to replace shield belt when it's not at max capacity (emulating UT behavior).
This commit is contained in:
parent
def0e317f3
commit
4f0cb3e73f
24 changed files with 756 additions and 32 deletions
|
|
@ -31,8 +31,6 @@ Class UTArmorBonus : UTArmor replaces ArmorBonus
|
|||
{
|
||||
Tag "Armor Bonus";
|
||||
+COUNTITEM;
|
||||
+INVENTORY.AUTOACTIVATE;
|
||||
+INVENTORY.UNTOSSABLE;
|
||||
+INVENTORY.ALWAYSPICKUP;
|
||||
Inventory.Amount 5;
|
||||
Inventory.MaxAmount 50;
|
||||
|
|
@ -114,14 +112,21 @@ Class UTShieldBelt : UTArmor replaces Megasphere
|
|||
}
|
||||
override bool HandlePickup( Inventory item )
|
||||
{
|
||||
if ( (item is 'UTThighPads') || (item is 'UTBodyArmor') ) return true;
|
||||
if ( (item is 'UTThighPads') || (item is 'UTBodyArmor') )
|
||||
{
|
||||
if ( amount < maxamount )
|
||||
{
|
||||
DepleteOrDestroy();
|
||||
return Super.HandlePickup(item);
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
return Super.HandlePickup(item);
|
||||
}
|
||||
Default
|
||||
{
|
||||
Tag "Shield Belt";
|
||||
+COUNTITEM;
|
||||
+INVENTORY.ALWAYSPICKUP;
|
||||
+INVENTORY.BIGPOWERUP;
|
||||
Inventory.Amount 150;
|
||||
Inventory.MaxAmount 150;
|
||||
|
|
|
|||
|
|
@ -285,27 +285,17 @@ Class Enforcer : UTWeapon replaces Pistol
|
|||
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
|
||||
A_OverlayRenderstyle(-2,STYLE_Add);
|
||||
}
|
||||
Vector3 x, y, z;
|
||||
double a;
|
||||
Vector3 x, y, z, x2, y2, z2;
|
||||
[x, y, z] = 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*9.0+ydir*y*1.0;
|
||||
else origin = origin-z*2.0+ydir*y*6.0;
|
||||
double ang = angle;
|
||||
double pt = BulletSlope();
|
||||
if ( alt )
|
||||
{
|
||||
ang += FRandom[Enforcer](-3,3);
|
||||
pt += FRandom[Enforcer](-3,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
ang += FRandom[Enforcer](-0.4,0.4);
|
||||
pt += FRandom[Enforcer](-0.4,0.4);
|
||||
}
|
||||
double a = FRandom[Enforcer](0,360), s = FRandom[Enforcer](0,alt?0.08:0.004);
|
||||
[x2, y2, z2] = Matrix4.GetAxes(BulletSlope(),angle,roll);
|
||||
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
||||
FLineTraceData d;
|
||||
LineTrace(ang,10000,pt,TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
||||
LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
int dmg = Random[Enforcer](15,20);
|
||||
|
|
|
|||
|
|
@ -44,13 +44,137 @@ Class MiniAmmo : Ammo
|
|||
}
|
||||
}
|
||||
|
||||
Class MinigunLight : EnforcerLight
|
||||
{
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
args[LIGHT_INTENSITY] = Random[Minigun](120,180);
|
||||
}
|
||||
}
|
||||
|
||||
Class MinigunTracer : Actor
|
||||
{
|
||||
Vector3 dest;
|
||||
Default
|
||||
{
|
||||
RenderStyle "Add";
|
||||
Radius 0.1;
|
||||
Height 0;
|
||||
+NOCLIP;
|
||||
+NOGRAVITY;
|
||||
+DONTSPLASH;
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
Vector3 dir = level.Vec3Diff(pos,dest);
|
||||
if ( dir.length() < 200 )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
dir = dir.unit();
|
||||
SetOrigin(Vec3Offset(dir.x*200,dir.y*200,dir.z*200),true);
|
||||
A_SetAngle(atan2(dir.y,dir.x),SPF_INTERPOLATE);
|
||||
A_SetPitch(asin(-dir.z),SPF_INTERPOLATE);
|
||||
A_SetRoll(roll+60,SPF_INTERPOLATE);
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
TRAC A -1 Bright;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
||||
Class Minigun : UTWeapon
|
||||
{
|
||||
int bcnt;
|
||||
|
||||
action void A_FireBullet( bool alt = false )
|
||||
{
|
||||
Weapon weap = Weapon(invoker);
|
||||
if ( !weap ) return;
|
||||
if ( weap.Ammo1.Amount <= 0 ) return;
|
||||
A_Overlay(-2,"MuzzleFlash",true);
|
||||
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
|
||||
A_OverlayRenderstyle(-2,STYLE_Add);
|
||||
if ( alt ) invoker.bcnt = min(invoker.bcnt,3);
|
||||
if ( invoker.bcnt-- > 0 ) return;
|
||||
invoker.bcnt = alt?3:5;
|
||||
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
|
||||
invoker.FireEffect();
|
||||
UTMainHandler.DoFlash(self,Color(64,255,255,0),1);
|
||||
A_AlertMonsters();
|
||||
if ( alt ) A_QuakeEx(3,3,3,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.12);
|
||||
else A_QuakeEx(2,2,2,5,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.08);
|
||||
let l = Spawn("MinigunLight",pos);
|
||||
l.target = self;
|
||||
if ( !alt ) MinigunLight(l).cnt--;
|
||||
Vector3 x, y, z, x2, y2, z2;
|
||||
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
|
||||
Vector3 origin = pos+(0,0,player.viewheight)+10.0*x+y*4.0-z*6.0;
|
||||
double a = FRandom[Minigun](0,360), s = FRandom[Minigun](0,alt?0.05:0.02);
|
||||
[x2, y2, z2] = 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);
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
int dmg = Random[Minigun](9,15); // fun fact: the Minigun is one of the few weapons that has actual RNG damage in UT (and it's exactly this damage)
|
||||
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'shot');
|
||||
if ( d.HitActor.bNOBLOOD )
|
||||
{
|
||||
let p = Spawn("BulletImpact",d.HitLocation-d.HitDir*4);
|
||||
p.angle = atan2(d.HitDir.y,d.HitDir.x);
|
||||
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 )
|
||||
{
|
||||
let p = Spawn("BulletImpact",d.HitLocation-d.HitDir*4);
|
||||
p.angle = atan2(d.HitDir.y,d.HitDir.x);
|
||||
p.pitch = asin(-d.HitDir.z);
|
||||
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
||||
}
|
||||
if ( !Random[Minigun](0,1) )
|
||||
{
|
||||
let t = Spawn("MinigunTracer",origin+x*20.0);
|
||||
t.angle = atan2(dir.y,dir.x);
|
||||
t.pitch = asin(-dir.z);
|
||||
MinigunTracer(t).dest = d.HitLocation;
|
||||
}
|
||||
origin += x*8.0+y*4.0-z*2.0;
|
||||
let c = Spawn("UTCasing",origin);
|
||||
c.vel = x*FRandom[Junk](-2,2)+y*FRandom[Junk](3,6)+z*FRandom[Junk](3,5);
|
||||
c.Scale *= 0.5;
|
||||
}
|
||||
|
||||
action void A_MinigunRefire( statelabel flash = null )
|
||||
{
|
||||
Weapon weap = Weapon(invoker);
|
||||
if ( !weap || !player ) return;
|
||||
if ( weap.Ammo1.Amount <= 0 )
|
||||
{
|
||||
A_ClearRefire();
|
||||
player.setpsprite(PSP_WEAPON,weap.FindState("Unwind"));
|
||||
return;
|
||||
}
|
||||
A_Refire(flash);
|
||||
}
|
||||
|
||||
Default
|
||||
{
|
||||
Tag "Minigun";
|
||||
Obituary "%k's Minigun turned %o into a leaky piece of meat.";
|
||||
Inventory.PickupMessage "You got the Minigun.";
|
||||
Weapon.UpSound "";
|
||||
Weapon.UpSound "minigun/select";
|
||||
Weapon.SlotNumber 7;
|
||||
Weapon.SelectionOrder 3;
|
||||
Weapon.AmmoType "MiniAmmo";
|
||||
|
|
@ -66,5 +190,239 @@ Class Minigun : UTWeapon
|
|||
Stop;
|
||||
MGNP B -1;
|
||||
Stop;
|
||||
Select:
|
||||
MGNS A 1 A_Raise(int.max);
|
||||
Wait;
|
||||
Ready:
|
||||
MGNS ABCDEFGHIJKLMNOPQRST 1;
|
||||
Idle:
|
||||
MGNI ABCDEFGHIJKLMNOPQRS 5
|
||||
{
|
||||
A_CheckReload();
|
||||
A_WeaponReady();
|
||||
}
|
||||
Loop;
|
||||
Fire:
|
||||
AltFire:
|
||||
MGNI A 3 { invoker.bcnt = 5; }
|
||||
Hold:
|
||||
MGNF A 1
|
||||
{
|
||||
A_PlaySound("minigun/fire",CHAN_WEAPON,1.0,true);
|
||||
A_FireBullet();
|
||||
}
|
||||
MGNF B 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF B 1 A_FireBullet();
|
||||
MGNF C 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF C 1 A_FireBullet();
|
||||
MGNF D 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF D 1 A_FireBullet();
|
||||
MGNF E 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF E 1 A_FireBullet();
|
||||
MGNF F 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF F 1 A_FireBullet();
|
||||
MGNF G 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF G 1 A_FireBullet();
|
||||
MGNF H 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF H 1 A_FireBullet();
|
||||
MGNF I 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF I 1 A_FireBullet();
|
||||
MGNF J 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF J 1 A_FireBullet();
|
||||
MGNF K 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF K 1 A_FireBullet();
|
||||
MGNF L 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF L 1 A_FireBullet();
|
||||
MGNF M 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF M 1 A_FireBullet();
|
||||
MGNF N 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF N 1 A_FireBullet();
|
||||
MGNF O 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF O 1 A_FireBullet();
|
||||
MGNF P 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF P 1 A_FireBullet();
|
||||
MGNF Q 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF Q 1 A_FireBullet();
|
||||
MGNF R 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF R 1 A_FireBullet();
|
||||
MGNF S 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF S 1 A_FireBullet();
|
||||
MGNF A 0
|
||||
{
|
||||
if ( invoker.bAltFire ) A_MinigunRefire(1);
|
||||
else A_MinigunRefire("Hold");
|
||||
}
|
||||
Goto Unwind;
|
||||
AltFire2:
|
||||
MGNF A 1 A_FireBullet();
|
||||
MGNF B 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF B 1 A_FireBullet();
|
||||
MGNF C 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF C 1 A_FireBullet();
|
||||
MGNF D 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF D 1 A_FireBullet();
|
||||
MGNF E 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF E 1 A_FireBullet();
|
||||
MGNF F 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF F 1 A_FireBullet();
|
||||
MGNF G 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF G 1 A_FireBullet();
|
||||
MGNF H 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF H 1 A_FireBullet();
|
||||
MGNF I 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF I 1 A_FireBullet();
|
||||
MGNF J 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF J 1 A_FireBullet();
|
||||
MGNF K 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF K 1 A_FireBullet();
|
||||
MGNF L 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF L 1 A_FireBullet();
|
||||
MGNF M 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF M 1 A_FireBullet();
|
||||
MGNF N 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF N 1 A_FireBullet();
|
||||
MGNF O 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF O 1 A_FireBullet();
|
||||
MGNF P 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF P 1 A_FireBullet();
|
||||
MGNF Q 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF Q 1 A_FireBullet();
|
||||
MGNF R 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF R 1 A_FireBullet();
|
||||
MGNF S 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF S 1 A_FireBullet();
|
||||
MGNF A 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
AltHold:
|
||||
MGNF A 1
|
||||
{
|
||||
A_PlaySound("minigun/altfire",CHAN_WEAPON,1.0,true);
|
||||
A_FireBullet(true);
|
||||
}
|
||||
MGNF D 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF D 1 A_FireBullet(true);
|
||||
MGNF G 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF G 1 A_FireBullet(true);
|
||||
MGNF J 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF J 1 A_FireBullet(true);
|
||||
MGNF M 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF M 1 A_FireBullet(true);
|
||||
MGNF P 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF P 1 A_FireBullet(true);
|
||||
MGNF S 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF S 1 A_FireBullet(true);
|
||||
MGNF C 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF C 1 A_FireBullet(true);
|
||||
MGNF F 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF F 1 A_FireBullet(true);
|
||||
MGNF I 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF I 1 A_FireBullet(true);
|
||||
MGNF L 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF L 1 A_FireBullet(true);
|
||||
MGNF O 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF O 1 A_FireBullet(true);
|
||||
MGNF R 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF R 1 A_FireBullet(true);
|
||||
MGNF B 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF B 1 A_FireBullet(true);
|
||||
MGNF E 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF E 1 A_FireBullet(true);
|
||||
MGNF H 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF H 1 A_FireBullet(true);
|
||||
MGNF K 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF K 1 A_FireBullet(true);
|
||||
MGNF N 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF N 1 A_FireBullet(true);
|
||||
MGNF Q 0 A_MinigunRefire(1);
|
||||
Goto Unwind;
|
||||
MGNF Q 1 A_FireBullet(true);
|
||||
MGNF A 0 A_MinigunRefire("AltHold");
|
||||
Goto Unwind;
|
||||
Unwind:
|
||||
MGNU A 0 A_PlaySound("minigun/unwind",CHAN_WEAPON);
|
||||
MGNU ABCDEFGHIJKLMNOPQRSTUVWXYZ 1;
|
||||
MGU2 ABCDEFGHIJKLM 1;
|
||||
Goto Idle;
|
||||
Deselect:
|
||||
MGND ABCDEFGHIJ 2;
|
||||
MGND J 1 A_Lower(int.max);
|
||||
Wait;
|
||||
MuzzleFlash:
|
||||
TNT1 A 0 A_Jump(256,1,2,3,4,5,6,7,8,9);
|
||||
Stop;
|
||||
MMUZ A 2 Bright;
|
||||
Stop;
|
||||
MMUZ B 2 Bright;
|
||||
Stop;
|
||||
MMUZ C 2 Bright;
|
||||
Stop;
|
||||
MMUZ D 2 Bright;
|
||||
Stop;
|
||||
MMUZ E 2 Bright;
|
||||
Stop;
|
||||
MMUZ F 2 Bright;
|
||||
Stop;
|
||||
MMUZ G 2 Bright;
|
||||
Stop;
|
||||
MMUZ H 2 Bright;
|
||||
Stop;
|
||||
MMUZ I 2 Bright;
|
||||
Stop;
|
||||
Dummy:
|
||||
MMUZ ABCDEFGHI -1;
|
||||
Stop;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue