Corrected various backface culling issues on weapons (rifle, peacemaker, autocannon). Fixed crash with dispersion pistol powerups due to typo. Fixed razorclaw and impaler not temporarily disabling invisibility on melee attack. Fixed rifle being visible with low zoom.
210 lines
6 KiB
Text
210 lines
6 KiB
Text
Class Bonesaw : UnrealWeapon
|
|
{
|
|
override bool TryPickup( in out Actor toucher )
|
|
{
|
|
if ( !sting_dubious ) return false; // not allowed
|
|
return Super.TryPickup(toucher);
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( sting_dubious ) return;
|
|
if ( !Owner )
|
|
{
|
|
let r = Spawn("Chainsaw",pos,ALLOW_REPLACE);
|
|
r.spawnangle = spawnangle;
|
|
r.spawnpoint = spawnpoint;
|
|
r.angle = angle;
|
|
r.pitch = pitch;
|
|
r.roll = roll;
|
|
r.special = special;
|
|
r.args[0] = args[0];
|
|
r.args[1] = args[1];
|
|
r.args[2] = args[2];
|
|
r.args[3] = args[3];
|
|
r.args[4] = args[4];
|
|
r.ChangeTid(tid);
|
|
r.SpawnFlags = SpawnFlags&~MTF_SECRET;
|
|
r.HandleSpawnFlags();
|
|
r.SpawnFlags = SpawnFlags;
|
|
r.bCountSecret = SpawnFlags&MTF_SECRET;
|
|
r.vel = vel;
|
|
r.master = master;
|
|
r.target = target;
|
|
r.tracer = tracer;
|
|
r.bDropped = bDropped;
|
|
Destroy();
|
|
}
|
|
else
|
|
{
|
|
Owner.RemoveInventory(self);
|
|
Destroy();
|
|
}
|
|
}
|
|
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )
|
|
{
|
|
if ( !bAltFire )
|
|
return StringTable.Localize((mod=='Decapitated')?"$O_RAZORCLAWDECAP2":"$O_RAZORCLAW2");
|
|
return StringTable.Localize((mod=='Decapitated')?"$O_RAZORCLAWDECAP1":"$O_RAZORCLAW1");
|
|
}
|
|
private action bool TryHit( double angle, int dmg )
|
|
{
|
|
FTranslatedLineTarget t;
|
|
double slope = AimLineAttack(angle,DEFMELEERANGE,t,0.,ALF_CHECK3D);
|
|
FLineTraceData d;
|
|
Vector3 x, y, z, origin;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
|
origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),y*4-z*4);
|
|
LineTrace(angle,DEFMELEERANGE,slope,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
|
|
if ( d.HitType != TRACE_HitNone )
|
|
{
|
|
if ( d.HitType == TRACE_HitActor )
|
|
{
|
|
if ( d.HitLocation.z >= (d.HitActor.pos.z+d.HitActor.height*0.8) )
|
|
dmg = d.HitActor.DamageMobj(invoker,self,dmg*2,'Decapitated',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
|
|
else dmg = d.HitActor.DamageMobj(invoker,self,dmg,'slashed',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
|
|
UTMainHandler.DoKnockback(d.HitActor,d.HitDir,-7000);
|
|
UTMainHandler.DoKnockback(self,-d.HitDir,-2000);
|
|
if ( d.HitActor.player ) d.HitActor.A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
|
|
if ( !d.HitActor.bNOBLOOD )
|
|
{
|
|
d.HitActor.TraceBleed(dmg,invoker);
|
|
d.HitActor.SpawnBlood(d.HitLocation,atan2(d.HitDir.y,d.HitDir.x)+180,dmg);
|
|
}
|
|
}
|
|
else if ( d.HitType == TRACE_HitWall )
|
|
d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4);
|
|
A_QuakeEx(1,1,1,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.12);
|
|
if ( !d.HitActor || d.HitActor.bNOBLOOD )
|
|
{
|
|
A_PlaySound("ripper/hit",CHAN_6);
|
|
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
|
|
p.angle = atan2(d.HitDir.y,d.HitDir.x);
|
|
p.pitch = asin(-d.HitDir.z);
|
|
}
|
|
else A_PlaySound("ripper/flesh",CHAN_6);
|
|
A_AlertMonsters();
|
|
if ( invoker.bAltFire ) A_QuakeEx(3,3,3,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.13);
|
|
else A_QuakeEx(1,1,1,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.06);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
action void A_Slice()
|
|
{
|
|
UTMainHandler.DoSwing(self,(FRandom[Bonesaw](-1,1),FRandom[Bonesaw](-1,1)),0.3,-0.2,2,SWING_Spring,0,2);
|
|
invoker.special1++;
|
|
if ( invoker.special1 < 5 ) return;
|
|
invoker.special1 = 0;
|
|
invoker.FireEffect();
|
|
for ( int i=0; i<8; i++ ) if ( TryHit(angle+i*(45./16),5) || TryHit(angle-i*(45./16),5) ) return;
|
|
}
|
|
action void A_Clamp()
|
|
{
|
|
invoker.FireEffect();
|
|
for ( int i=0; i<8; i++ ) if ( TryHit(angle+i*(45./16),20) || TryHit(angle-i*(45./16),20) ) return;
|
|
}
|
|
Default
|
|
{
|
|
Tag "$T_RAZORCLAW";
|
|
Inventory.PickupMessage "$I_RAZORCLAW";
|
|
Weapon.UpSound "bonesaw/select";
|
|
Weapon.SlotNumber 1;
|
|
Weapon.SelectionOrder 9;
|
|
Weapon.SlotPriority 0.9;
|
|
+WEAPON.MELEEWEAPON;
|
|
+FORCEPAIN;
|
|
+NOEXTREMEDEATH;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
CSWP A -1;
|
|
Stop;
|
|
CSWP B -1;
|
|
Stop;
|
|
Select:
|
|
CSWS A 1 A_Raise(int.max);
|
|
Wait;
|
|
Ready:
|
|
CSWS ABCDEFGHI 2 A_WeaponReady(WRF_NOFIRE);
|
|
Goto Idle;
|
|
Dummy:
|
|
TNT1 A 1 A_WeaponReady();
|
|
Wait;
|
|
Idle:
|
|
#### # 2 A_Overlay(-9999,"Dummy");
|
|
CSWI ABCDE 15 A_Jump(32,"Twiddle");
|
|
Goto Idle+1;
|
|
Twiddle:
|
|
#### # 2;
|
|
CSWT ABCDEFGHIJKLM 3;
|
|
CSWI A 3;
|
|
Goto Idle;
|
|
Fire:
|
|
#### # 2
|
|
{
|
|
A_Overlay(-9999,"Null");
|
|
A_PlaySound("bonesaw/spin",CHAN_WEAPON,Dampener.Active(self)?.1:1.,true);
|
|
invoker.special2 = 0;
|
|
}
|
|
CSWF ABCDEFGHIJKLMNO 1
|
|
{
|
|
invoker.special2++;
|
|
A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE);
|
|
}
|
|
CSWF PQRSTUVWX 1
|
|
{
|
|
invoker.special2++;
|
|
A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE);
|
|
A_Slice();
|
|
}
|
|
Goto Hold;
|
|
Hold:
|
|
CSWH A 0 A_SoundVolume(CHAN_WEAPON,Dampener.Active(self)?.1:1.);
|
|
CSWH ABCDEFGHIJKLMNOPQR 1
|
|
{
|
|
A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE);
|
|
A_Slice();
|
|
}
|
|
CSWH A 0 A_Refire("Hold");
|
|
Goto Release;
|
|
Release:
|
|
CSWR A 0 A_PlaySound("bonesaw/spinend",CHAN_WEAPON,Dampener.Active(self)?.1:1.);
|
|
CSWR ABCDEFGHI 1
|
|
{
|
|
A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE);
|
|
invoker.special2--;
|
|
A_Slice();
|
|
}
|
|
CSWR JKLMNOPQRSTUVWX 1
|
|
{
|
|
A_WeaponOffset(0+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,32+FRandom[Bonesaw](-0.1,0.1)*invoker.special2,WOF_INTERPOLATE);
|
|
invoker.special2--;
|
|
}
|
|
Goto Idle;
|
|
AltFire:
|
|
#### # 1
|
|
{
|
|
A_Overlay(-9999,"Null");
|
|
A_PlaySound("bonesaw/claw",CHAN_WEAPON,Dampener.Active(self)?.1:1.);
|
|
UTMainHandler.DoSwing(self,(FRandom[Bonesaw](-0.1,0.1),FRandom[Bonesaw](-0.2,-0.3)),4,0,8,SWING_Spring,5,0.7);
|
|
}
|
|
CSWA ABC 2;
|
|
CSWA D 0
|
|
{
|
|
UTMainHandler.DoSwing(self,(FRandom[Bonesaw](-0.1,0.1),FRandom[Bonesaw](0.8,0.5)),2,0,8,SWING_Spring,2,1.2);
|
|
}
|
|
CSWA DEF 1;
|
|
CSWA G 0 A_Clamp();
|
|
CSWA GH 1;
|
|
CSWA IJLMN 3;
|
|
CSWI A 3;
|
|
Goto Idle;
|
|
Deselect:
|
|
CSWD A 1 A_Overlay(-9999,"Null");
|
|
CSWD ABCDEFGHI 1;
|
|
CSWD I 1 A_Lower(int.max);
|
|
Wait;
|
|
}
|
|
}
|