- Various fixes for the Combined Patch. - Some safeguards for force field and sentries so they don't bug the hell out if receiving crushing or ice damage.
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("telehand/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);
|
|
}
|
|
}
|