- Add option for vanilla style Power Shield to not drain over time (defaults to true). - Fix various weapons being able to fire after player dies while charging (Biorifle, Flamethrower). - Fix Minigun not firing bullets immediately at start of fire loop or on refire. - Fix Minigun playing unwind animation on death, this time for real. - Added interpolation to some Teleport Capsule states and made refire a bit quicker.
327 lines
7.5 KiB
Text
327 lines
7.5 KiB
Text
Class UTranslocatorAmmo : Ammo
|
|
{
|
|
Default
|
|
{
|
|
Inventory.Icon "I_Tele";
|
|
Inventory.Amount 1;
|
|
Inventory.MaxAmount 2;
|
|
Ammo.BackpackAmount 0;
|
|
Ammo.BackpackMaxAmount 2;
|
|
+INVENTORY.IGNORESKILL;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( sting_proto && sting_telegun ) return;
|
|
if ( Owner ) Owner.RemoveInventory(self);
|
|
Destroy();
|
|
}
|
|
}
|
|
|
|
Class UTranslocatorModule : Actor
|
|
{
|
|
Actor b;
|
|
bool alreadyhit;
|
|
double anglevel;
|
|
|
|
Default
|
|
{
|
|
Radius 2;
|
|
Height 2;
|
|
Speed 16;
|
|
PROJECTILE;
|
|
-NOGRAVITY;
|
|
+USEBOUNCESTATE;
|
|
+SKYEXPLODE;
|
|
+HITTRACER;
|
|
+MOVEWITHSECTOR;
|
|
+CANBOUNCEWATER;
|
|
+BLOCKASPLAYER;
|
|
-ALLOWBOUNCEONACTORS;
|
|
+DONTBOUNCEONSHOOTABLES;
|
|
+INTERPOLATEANGLES;
|
|
BounceType "Hexen";
|
|
BounceFactor 0.3;
|
|
WallBounceFactor 0.3;
|
|
Gravity 0.35;
|
|
}
|
|
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
if ( !target )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
b = Spawn("ModuleHitbox",pos);
|
|
b.A_SetSize(6,6);
|
|
b.master = self;
|
|
anglevel = FRandom[TeleHand](3,5)*RandomPick[TeleHand](-1,1);
|
|
}
|
|
|
|
override bool CanCollideWith( Actor other, bool passive )
|
|
{
|
|
return (other != tracer);
|
|
}
|
|
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( bAMBUSH && !Random[Transloc](0,40) )
|
|
{
|
|
A_PlaySound("transloc/spark");
|
|
int numpt = Random[Transloc](20,40);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Transloc](-1,1),FRandom[Transloc](-1,1),FRandom[Transloc](-1,1)).unit()*FRandom[Transloc](0.1,1.2);
|
|
let s = Spawn("UTSmoke",pos);
|
|
s.vel = pvel;
|
|
s.SetShade(Color(1,1,1)*Random[Transloc](128,192));
|
|
}
|
|
numpt = Random[Transloc](4,12);
|
|
for ( int i=0; i<numpt; i++ )
|
|
{
|
|
Vector3 pvel = (FRandom[Transloc](-1,1),FRandom[Transloc](-1,1),FRandom[Transloc](-1,1)).unit()*FRandom[Transloc](2,8);
|
|
let s = Spawn("UTSpark",pos);
|
|
s.vel = pvel;
|
|
}
|
|
}
|
|
}
|
|
|
|
States
|
|
{
|
|
Spawn:
|
|
TMOD A 1
|
|
{
|
|
angle += anglevel;
|
|
}
|
|
Wait;
|
|
Bounce:
|
|
TMOD A 0
|
|
{
|
|
if ( alreadyhit )
|
|
{
|
|
ClearBounce();
|
|
ExplodeMissile();
|
|
}
|
|
else
|
|
{
|
|
anglevel = FRandom[TeleHand](5,30)*RandomPick[TeleHand](-1,1);
|
|
A_PlaySound("transloc/bounce");
|
|
if ( BlockingFloor || (tracer && (pos.z >= tracer.pos.z+tracer.height) && tracer.bACTLIKEBRIDGE) ) alreadyhit = true;
|
|
}
|
|
}
|
|
Goto Spawn;
|
|
Death:
|
|
TMOD A -1
|
|
{
|
|
if ( tracer && !tracer.bACTLIKEBRIDGE )
|
|
{
|
|
SetOrigin(tracer.Vec2OffsetZ(0,0,pos.z),false);
|
|
vel.xy *= 0;
|
|
tracer = null;
|
|
bHITTRACER = false;
|
|
}
|
|
}
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UTranslocator : UnrealWeapon
|
|
{
|
|
Actor module;
|
|
|
|
override bool TryPickup( in out Actor toucher )
|
|
{
|
|
if ( !sting_proto || !sting_telegun ) return false; // not allowed
|
|
return Super.TryPickup(toucher);
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( sting_proto && sting_telegun ) return;
|
|
if ( Owner ) Owner.RemoveInventory(self);
|
|
Destroy();
|
|
}
|
|
override void DoEffect()
|
|
{
|
|
Super.DoEffect();
|
|
if ( Ammo1 ) Ammo1.Amount = module?1:2;
|
|
}
|
|
action void A_ThrowModule()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
A_PlaySound("telehand/throw",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoSwing(self,(FRandom[Translocator](0.2,-0.4),FRandom[Translocator](0.2,-0.7)),2,-0.3,3,SWING_Spring,2,3);
|
|
Vector3 x, y, z;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
|
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x-8*y-12*z);
|
|
let p = Spawn("UTranslocatorModule",origin);
|
|
p.target = self;
|
|
p.angle = angle;
|
|
p.pitch = BulletSlope();
|
|
p.A_SetSize(radius);
|
|
Vector3 dir = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch));
|
|
dir.z += 0.35*(1-abs(dir.z));
|
|
p.vel = dir*p.speed;
|
|
invoker.module = p;
|
|
}
|
|
action void A_ReturnModule()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
A_PlaySound("transloc/return",CHAN_WEAPON);
|
|
invoker.FireEffect();
|
|
UTMainHandler.DoSwing(self,(FRandom[Translocator](-0.2,-0.4),FRandom[Translocator](-0.2,0.7)),3,-1,2,SWING_Spring,2,2);
|
|
if ( invoker.module && invoker.module.bAMBUSH )
|
|
{
|
|
UTMainHandler.DoFlash(self,Color(255,255,255,255),50);
|
|
A_PlaySound("transloc/spark",CHAN_WEAPON);
|
|
DamageMobj(invoker,self,int.max,'Telefrag',DMG_THRUSTLESS);
|
|
}
|
|
if ( invoker.module ) invoker.module.Destroy();
|
|
}
|
|
action void A_Translocate()
|
|
{
|
|
Weapon weap = Weapon(invoker);
|
|
if ( !weap ) return;
|
|
if ( !invoker.module )
|
|
{
|
|
invoker.FireEffect();
|
|
A_PlaySound("transloc/return",CHAN_WEAPON);
|
|
return;
|
|
}
|
|
// check if there's enough space
|
|
Vector3 oldpos = pos, newpos = invoker.module.pos;
|
|
double modulefloorz = invoker.module.floorz, moduleceilingz = invoker.module.ceilingz;
|
|
bool bBroken = invoker.module.bAMBUSH;
|
|
invoker.module.Destroy();
|
|
invoker.FireEffect();
|
|
// squeeze down new z if ceiling is in the way
|
|
if ( (newpos.z+height > moduleceilingz) ) newpos.z = max(modulefloorz,moduleceilingz-height);
|
|
// temporarily disable telefragging for all allies
|
|
bool oldnotele[MAXPLAYERS];
|
|
for ( int i=0; i<MAXPLAYERS; i++ )
|
|
{
|
|
if ( !playeringame[i] || !players[i].mo ) continue;
|
|
oldnotele[i] = players[i].mo.bNOTELEFRAG;
|
|
if ( !IsFriend(players[i].mo) ) continue;
|
|
players[i].mo.bNOTELEFRAG = true;
|
|
}
|
|
if ( Warp(self,newpos.x,newpos.y,newpos.z,flags:WARPF_ABSOLUTEPOSITION|WARPF_TESTONLY) && TeleportMove(newpos,true) )
|
|
{
|
|
A_PlaySound("flak/click",CHAN_WEAPON);
|
|
SpawnTeleportFog(oldpos,true,false);
|
|
SpawnTeleportFog(newpos,false,false);
|
|
player.fov = min(175,player.desiredfov+60);
|
|
}
|
|
else A_PlaySound("transloc/return",CHAN_WEAPON);
|
|
for ( int i=0; i<MAXPLAYERS; i++ )
|
|
{
|
|
if ( !playeringame[i] || !players[i].mo ) continue;
|
|
players[i].mo.bNOTELEFRAG = oldnotele[i];
|
|
}
|
|
if ( bBroken )
|
|
{
|
|
UTMainHandler.DoFlash(self,Color(255,255,255,255),50);
|
|
A_PlaySound("transloc/spark",CHAN_WEAPON);
|
|
DamageMobj(invoker,self,int.max,'Telefrag',DMG_THRUSTLESS);
|
|
}
|
|
}
|
|
override void OnDestroy()
|
|
{
|
|
Super.OnDestroy();
|
|
if ( module ) module.Destroy();
|
|
}
|
|
|
|
Default
|
|
{
|
|
Tag "$T_TELEGUN";
|
|
Inventory.PickupMessage "$I_TELEGUN";
|
|
Weapon.SlotNumber 1;
|
|
Weapon.SelectionOrder 9000;
|
|
Weapon.SlotPriority 0.1;
|
|
Weapon.AmmoType1 "UTranslocatorAmmo";
|
|
Weapon.AmmoUse1 1;
|
|
Weapon.AmmoType2 "UTranslocatorAmmo";
|
|
Weapon.AmmoUse2 1;
|
|
Weapon.AmmoGive 2;
|
|
UTWeapon.DropAmmo 2;
|
|
+WEAPON.NO_AUTO_SWITCH;
|
|
+WEAPON.CHEATNOTWEAPON;
|
|
+INVENTORY.UNDROPPABLE;
|
|
+INVENTORY.UNTOSSABLE;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TLCP A -1;
|
|
Stop;
|
|
TLCP B -1;
|
|
Stop;
|
|
Select:
|
|
TLCS A 1 A_Raise(int.max);
|
|
Wait;
|
|
Ready:
|
|
TLCS ABCDEFGH 2 A_WeaponReady(WRF_NOFIRE);
|
|
Goto Idle;
|
|
Dummy:
|
|
TNT1 A 1 A_WeaponReady(WRF_ALLOWRELOAD);
|
|
Wait;
|
|
Idle:
|
|
TLCI A 0 A_Overlay(-9999,"Dummy");
|
|
TLCI ABCDEFG 20 A_Jump(16,"Twiddle");
|
|
Goto Idle+1;
|
|
Twiddle:
|
|
#### # 6;
|
|
TLCT A 0 A_Jump(256,"Twiddle2","Twiddle3","Twiddle4","Twiddle5");
|
|
Twiddle2:
|
|
TLCT ABCDEFGHI 2;
|
|
Goto Idle+1;
|
|
Twiddle3:
|
|
TLCT ABCDEFGHI 3;
|
|
Goto Idle+1;
|
|
Twiddle4:
|
|
TLCT ABCDEFGHI 4;
|
|
Goto Idle+1;
|
|
Twiddle5:
|
|
TLCT ABCDEFGHI 5;
|
|
Goto Idle+1;
|
|
Fire:
|
|
#### # 0 A_Overlay(-9999,"Null");
|
|
#### # 0 A_JumpIf(invoker.module,"Recall");
|
|
#### # 2;
|
|
TLCF ABCDEF 2;
|
|
TLCF G 0 A_ThrowModule();
|
|
TLCF GHIJKLMNOPQRSTUV 2;
|
|
TLCF WXY 2 A_WeaponReady();
|
|
Goto Idle;
|
|
Recall:
|
|
#### # 2;
|
|
TLCR ABCDEF 2;
|
|
TLCR G 0 A_ReturnModule();
|
|
TLCR GHIJKLM 2;
|
|
Goto Idle;
|
|
AltFire:
|
|
#### # 0 A_Overlay(-9999,"Null");
|
|
#### # 0 A_JumpIf(!invoker.module,"Reload");
|
|
#### # 2;
|
|
TLCA ABCDE 2;
|
|
TLCA A 0 A_Translocate();
|
|
TLCA FGHIJKL 2;
|
|
Goto Idle;
|
|
Reload:
|
|
#### # 0 A_Overlay(-9999,"Null");
|
|
#### # 2;
|
|
TLCB ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] 2;
|
|
TLB2 AB 2;
|
|
Goto Idle;
|
|
Deselect:
|
|
TLCD A 0 A_Overlay(-9999,"Null");
|
|
TLCD ABCDEF 1;
|
|
TLCD F 1 A_Lower(int.max);
|
|
}
|
|
}
|