Addition to HUD for showing clip counts (kinda cheap-looking, but still better than what Oldskool did). Charge for some weapons and loaded rockets for eightball also use the clipcount display, like in Doom Tournament. Small fixups for dual wielding logic.
295 lines
6.7 KiB
Text
295 lines
6.7 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_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;
|
|
}
|
|
}
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UTranslocator : UnrealWeapon
|
|
{
|
|
Actor module;
|
|
|
|
override bool TryPickup( in out Actor toucher )
|
|
{
|
|
if ( !sting_telegun ) return false; // not allowed
|
|
return Super.TryPickup(toucher);
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( 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 = (pos.x,pos.y,player.viewz)+10.0*x-8.0*y-12.0*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);
|
|
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);
|
|
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 1;
|
|
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 { invoker.special1 = Random[TeleHand](2,5); }
|
|
TLCT ABCDEFGHI 3 A_SetTics(invoker.special1);
|
|
Goto Idle+1;
|
|
Fire:
|
|
TLCF A 0 A_Overlay(-9999,"Null");
|
|
TLCF A 0 A_JumpIf(invoker.module,"Recall");
|
|
TLCF ABCDEF 2;
|
|
TLCF G 0 A_ThrowModule();
|
|
TLCF GHIJKLMNOPQRSTUVWXY 2;
|
|
Goto Idle;
|
|
Recall:
|
|
TLCR ABCDEF 2;
|
|
TLCR G 0 A_ReturnModule();
|
|
TLCR GHIJKLM 2;
|
|
Goto Idle;
|
|
AltFire:
|
|
TLCA A 0 A_Overlay(-9999,"Null");
|
|
TLCA A 0 A_JumpIf(!invoker.module,"Reload");
|
|
TLCA ABCDE 2;
|
|
TLCA A 0 A_Translocate();
|
|
TLCA FGHIJKL 2;
|
|
Goto Idle;
|
|
Reload:
|
|
TLCB A 0 A_Overlay(-9999,"Null");
|
|
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);
|
|
}
|
|
}
|