Various Sentry fixups and whatnot, plus a fancy explosion.

Sentry no longer causes a freeze if it runs out of ammo while still having a target.
Sentry now has to be recalled by using the item.
Hijacking a sentry now immediately assigns it to your inventory.
You can hijack rogue sentries (not owned by anyone).
Better placement check for forcefield and sentry spawning, no more "no room" messages when it can definitely fit.
Increased flak slug explosion sprite size, as it felt too small.
Eightball loads faster (slightly faster than vanilla but can't do anything about that).
ASMD combo no longer spawns amped explosions when it shouldn't.
Added a new flag to UnrealInventory, bDRAWSPECIAL, so the HUD displays the special1 as an amount. This is useful for items like the Sentry that use this variable to count ammo.
Increased rotation range for the Sentry so it's harder for enemies to sneak behind it from the sides.
Added debris to the explosions of flares and voice boxes.
This commit is contained in:
Marisa the Magician 2019-09-06 14:08:53 +02:00
commit 2d64db512f
14 changed files with 323 additions and 65 deletions

View file

@ -190,6 +190,7 @@ M_SENTRYDOWN = "Your Sentry has been destroyed.";
M_SENTRYDRY = "Your Sentry has run out of ammo."; M_SENTRYDRY = "Your Sentry has run out of ammo.";
M_SENTRYHIJACK = "Your Sentry has been hijacked."; M_SENTRYHIJACK = "Your Sentry has been hijacked.";
M_MSNOROOM = "No room to deploy Sentry."; M_MSNOROOM = "No room to deploy Sentry.";
M_NSTOOFAR = "Cannot recall Sentry from this distance.";
M_FFNOROOM = "No room to activate Force Field."; M_FFNOROOM = "No room to activate Force Field.";
S_MINHUD = "Health %d Score %d Ammo %d"; S_MINHUD = "Health %d Score %d Ammo %d";
S_MINHUD2 = "Health %d Score %d Ammo %d/%d"; S_MINHUD2 = "Health %d Score %d Ammo %d/%d";
@ -409,6 +410,7 @@ M_SENTRYDOWN = "Tu Torreta ha sido destruida.";
M_SENTRYDRY = "Tu Torreta se ha quedado sin munición."; M_SENTRYDRY = "Tu Torreta se ha quedado sin munición.";
M_SENTRYHIJACK = "Tu Torreta ha sido hackeada."; M_SENTRYHIJACK = "Tu Torreta ha sido hackeada.";
M_MSNOROOM = "No hay espacio para colocar la Torreta."; M_MSNOROOM = "No hay espacio para colocar la Torreta.";
M_NSTOOFAR = "No se puede retirar la Torreta desde esta distancia.";
M_FFNOROOM = "No hay espacio para activar el Campo de Fuerza."; M_FFNOROOM = "No hay espacio para activar el Campo de Fuerza.";
S_MINHUD = "Salud %d Puntuación %d Munición %d"; S_MINHUD = "Salud %d Puntuación %d Munición %d";
S_MINHUD2 = "Salud %d Puntuación %d Munición %d/%d"; S_MINHUD2 = "Salud %d Puntuación %d Munición %d/%d";

View file

@ -565,6 +565,23 @@ Model "MinigunSentryX"
FrameIndex SENF P 0 47 // shoot FrameIndex SENF P 0 47 // shoot
} }
Model "SentryFragment"
{
Path "models"
Model 0 "sfrag_d.3d"
Skin 0 "Minigun.png"
Scale 0.1 0.1 0.12
USEACTORPITCH
USEACTORROLL
FrameIndex CHIP A 0 0
FrameIndex CHIP B 0 1
FrameIndex CHIP C 0 2
FrameIndex CHIP D 0 3
FrameIndex CHIP E 0 4
FrameIndex CHIP F 0 5
}
Model "MinigunSentryBase" Model "MinigunSentryBase"
{ {
Path "models" Path "models"

BIN
models/sfrag_a.3d Normal file

Binary file not shown.

BIN
models/sfrag_d.3d Normal file

Binary file not shown.

View file

@ -225,3 +225,8 @@ sentry/raise sentup
sentry/wind sentwind sentry/wind sentwind
sentry/fire sentfire sentry/fire sentfire
sentry/unwind sentuwnd sentry/unwind sentuwnd
sentry/explode cannonex
vfrag/bounce1 glasstk1
vfrag/bounce2 glasstk2
$random vfrag/bounce { vfrag/bounce1 vfrag/bounce2 }

BIN
sounds/CannonEx.ogg Normal file

Binary file not shown.

BIN
sounds/GlassTk1.ogg Normal file

Binary file not shown.

BIN
sounds/GlassTk2.ogg Normal file

Binary file not shown.

View file

@ -532,7 +532,7 @@ Class ASMDBeam : Actor
Actor r; Actor r;
if ( t.Results.HitActor is 'ASMDHitbox' ) if ( t.Results.HitActor is 'ASMDHitbox' )
{ {
BeamExplode(true); BeamExplode(mult>1.5);
if ( target ) if ( target )
{ {
target.TakeInventory('ASMDAmmo',2); target.TakeInventory('ASMDAmmo',2);

View file

@ -431,6 +431,28 @@ Class VoiceBoxActive : Actor
bMOVEWITHSECTOR = false; bMOVEWITHSECTOR = false;
bFORCEXYBILLBOARD = true; bFORCEXYBILLBOARD = true;
A_SetScale(FRandomPick[ExploS](-1.5,1.5),FRandomPick[ExploS](-1.5,1.5)); A_SetScale(FRandomPick[ExploS](-1.5,1.5),FRandomPick[ExploS](-1.5,1.5));
int numpt = Random[ExploS](15,30);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,3);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
}
numpt = Random[ExploS](9,18);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[ExploS](18,28);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,12);
let s = Spawn("UTChip",pos);
s.vel = pvel;
s.scale *= FRandom[ExploS](0.9,2.7);
}
return A_Jump(256,"Explo1","Explo2","Explo3","Explo4","Explo5"); return A_Jump(256,"Explo1","Explo2","Explo3","Explo4","Explo5");
} }
Explo1: Explo1:
@ -616,6 +638,28 @@ Class FlareThrown : Actor
bMOVEWITHSECTOR = false; bMOVEWITHSECTOR = false;
bFORCEXYBILLBOARD = true; bFORCEXYBILLBOARD = true;
A_SetScale(FRandomPick[ExploS](-1.5,1.5),FRandomPick[ExploS](-1.5,1.5)); A_SetScale(FRandomPick[ExploS](-1.5,1.5),FRandomPick[ExploS](-1.5,1.5));
int numpt = Random[ExploS](10,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,3);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
}
numpt = Random[ExploS](6,15);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[ExploS](15,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,12);
let s = Spawn("UTChip",pos);
s.vel = pvel;
s.scale *= FRandom[ExploS](0.9,2.7);
}
return A_Jump(256,"Explo1","Explo2","Explo3","Explo4","Explo5"); return A_Jump(256,"Explo1","Explo2","Explo3","Explo4","Explo5");
} }
Explo1: Explo1:
@ -907,6 +951,28 @@ Class BetaFlareThrown : Actor
bMOVEWITHSECTOR = false; bMOVEWITHSECTOR = false;
bFORCEXYBILLBOARD = true; bFORCEXYBILLBOARD = true;
A_SetScale(FRandomPick[ExploS](-1.5,1.5),FRandomPick[ExploS](-1.5,1.5)); A_SetScale(FRandomPick[ExploS](-1.5,1.5),FRandomPick[ExploS](-1.5,1.5));
int numpt = Random[ExploS](10,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,3);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
}
numpt = Random[ExploS](6,15);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[ExploS](15,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,12);
let s = Spawn("UTChip",pos);
s.vel = pvel;
s.scale *= FRandom[ExploS](0.9,2.7);
}
return A_Jump(256,"Explo1","Explo2","Explo3","Explo4","Explo5"); return A_Jump(256,"Explo1","Explo2","Explo3","Explo4","Explo5");
} }
Explo1: Explo1:
@ -1056,15 +1122,13 @@ Class Forcefield : UnrealInventory
override bool Use( bool pickup ) override bool Use( bool pickup )
{ {
if ( pickup ) return false; if ( pickup ) return false;
Vector3 x, y, z; Vector3 origin = Owner.Vec2OffsetZ(0,0,Owner.player.viewz);
[x, y, z] = dt_CoordUtil.GetAxes(Owner.pitch,Owner.angle,Owner.roll); FLineTraceData d;
Vector3 origin = level.Vec3Offset(Owner.Vec2OffsetZ(0,0,Owner.player.viewz),x*90.); Owner.LineTrace(Owner.angle,90,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
origin = level.Vec3Offset(origin,(0,0,-GetDefaultByType("ForceFieldEffect").Height*.5)); if ( d.HitType != TRACE_HitNone ) origin = d.HitLocation-d.HitDir*(GetDefaultByType("ForceFieldEffect").radius+8);
if ( !level.IsPointInLevel(origin) ) else origin = d.HitLocation;
{ Owner.LineTrace(0,GetDefaultByType("ForceFieldEffect").height/2,90,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_FFNOROOM")); origin = d.HitLocation;
return false;
}
let a = Spawn("ForceFieldEffect",origin); let a = Spawn("ForceFieldEffect",origin);
if ( !a.TestMobjLocation() ) if ( !a.TestMobjLocation() )
{ {
@ -1365,26 +1429,55 @@ Class SentryItem : UnrealInventory
Inventory.MaxAmount 1; Inventory.MaxAmount 1;
Inventory.PickupMessage "$I_SENTRY"; Inventory.PickupMessage "$I_SENTRY";
Inventory.RespawnTics 1050; Inventory.RespawnTics 1050;
UnrealInventory.Charge 300; UnrealInventory.Charge MinigunSentryBase.sentryhealth;
+UNREALINVENTORY.DRAWSPECIAL;
}
static void TransferOwnership( Actor newowner, Actor sentry )
{
if ( sentry.master ) sentry.master.TakeInventory("SentryItem",200);
sentry.master = newowner;
sentry.SetTag(String.Format(StringTable.Localize("$T_OWNEDSENTRY"),newowner.player.GetUserName()));
sentry.tracer.A_ClearTarget();
sentry.tracer.SetFriendPlayer(newowner.player);
let si = SentryItem(newowner.FindInventory("SentryItem"));
if ( si )
{
si.bActive = true;
si.tracer = sentry;
}
else
{
newowner.GiveInventory("SentryItem",1);
let si = SentryItem(newowner.FindInventory("SentryItem"));
si.bActive = true;
si.tracer = sentry;
}
} }
override void AttachToOwner( Actor other ) override void AttachToOwner( Actor other )
{ {
Super.AttachToOwner(other);
special1 = MinigunSentryBase.sentryammo; special1 = MinigunSentryBase.sentryammo;
Super.AttachToOwner(other);
} }
override bool Use( bool pickup ) override bool Use( bool pickup )
{ {
if ( pickup ) return false; if ( pickup ) return false;
if ( bActive ) return false; if ( bActive )
Vector3 x, y, z;
[x, y, z] = dt_CoordUtil.GetAxes(Owner.pitch,Owner.angle,Owner.roll);
Vector3 origin = level.Vec3Offset(Owner.Vec2OffsetZ(0,0,Owner.player.viewz),x*90.);
origin = level.Vec3Offset(origin,(0,0,-GetDefaultByType("MinigunSentryBase").Height*.5));
if ( !level.IsPointInLevel(origin) )
{ {
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_MSNOROOM")); if ( Owner.Distance3D(tracer) > 80 )
{
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_NSTOOFAR"));
return false;
}
tracer.SetStateLabel("PackUp");
return false; return false;
} }
Vector3 origin = Owner.Vec2OffsetZ(0,0,Owner.player.viewz);
FLineTraceData d;
Owner.LineTrace(Owner.angle,90,Owner.pitch,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
if ( d.HitType != TRACE_HitNone ) origin = d.HitLocation-d.HitDir*20;
else origin = d.HitLocation;
Owner.LineTrace(0,56,90,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
origin = d.HitLocation;
let a = Spawn("MinigunSentryBase",origin); let a = Spawn("MinigunSentryBase",origin);
if ( !a.TestMobjLocation() ) if ( !a.TestMobjLocation() )
{ {
@ -1416,7 +1509,8 @@ Class SentryItem : UnrealInventory
return; return;
} }
Charge = tracer.Health; Charge = tracer.Health;
if ( Charge <= 0 ) DepleteOrDestroy(); special1 = tracer.special1;
if ( Charge <= 0 ) Destroy();
} }
override void Travelled() override void Travelled()
{ {
@ -1425,7 +1519,7 @@ Class SentryItem : UnrealInventory
{ {
bUNTOSSABLE = false; bUNTOSSABLE = false;
bUNDROPPABLE = false; bUNDROPPABLE = false;
DepleteOrDestroy(); Destroy();
} }
} }
States States
@ -1481,8 +1575,8 @@ Class MinigunSentryX : Actor
// The "head" of the sentry, attaches to the body // The "head" of the sentry, attaches to the body
Class MinigunSentry : Actor Class MinigunSentry : Actor
{ {
const maxangle = 60; const maxangle = 80;
const maxpitch = 30; const maxpitch = 40;
Default Default
{ {
@ -1545,7 +1639,7 @@ Class MinigunSentry : Actor
} }
void A_SentryAttack() void A_SentryAttack()
{ {
special1 = max(0,special1-1); master.special1 = special1 = max(0,special1-1);
if ( (special1 <= 0) && master.master && master.master.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_SENTRYDRY")); if ( (special1 <= 0) && master.master && master.master.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_SENTRYDRY"));
A_SentryFaceTarget(); A_SentryFaceTarget();
master.A_AlertMonsters(0,AMF_TARGETEMITTER); master.A_AlertMonsters(0,AMF_TARGETEMITTER);
@ -1553,7 +1647,7 @@ Class MinigunSentry : Actor
Vector3 x, y, z, origin; Vector3 x, y, z, origin;
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll); [x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
origin = level.Vec3Offset(pos,x*24+z*8); origin = level.Vec3Offset(pos,x*24+z*8);
double a = FRandom[Sentry](0,360), s = FRandom[Sentry](0,0.15); double a = FRandom[Sentry](0,360), s = FRandom[Sentry](0,0.04);
Vector3 dir = (x+y*cos(a)*s+z*sin(a)*s).unit(); Vector3 dir = (x+y*cos(a)*s+z*sin(a)*s).unit();
FLineTraceData d; FLineTraceData d;
master.LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d); master.LineTrace(atan2(dir.y,dir.x),10000,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
@ -1692,7 +1786,7 @@ Class MinigunSentry : Actor
SENU A 0 SENU A 0
{ {
A_LookEx(LOF_NOSOUNDCHECK|LOF_NOJUMP); A_LookEx(LOF_NOSOUNDCHECK|LOF_NOJUMP);
if ( TargetVisible() ) return ResolveState("MissileLoop"); if ( TargetVisible() && (special1>0) ) return ResolveState("MissileLoop");
A_PlaySound("sentry/unwind"); A_PlaySound("sentry/unwind");
master.SetStateLabel("MissileEnd"); master.SetStateLabel("MissileEnd");
return ResolveState(null); return ResolveState(null);
@ -1716,21 +1810,180 @@ Class MinigunSentry : Actor
Class SentryFragment : Actor Class SentryFragment : Actor
{ {
int deadtimer;
double rollvel, anglevel, pitchvel;
double heat;
Default
{
Radius 2;
Height 2;
+NOBLOCKMAP;
+MISSILE;
+MOVEWITHSECTOR;
+THRUACTORS;
+NOTELEPORT;
+DONTSPLASH;
+INTERPOLATEANGLES;
+USEBOUNCESTATE;
BounceType "Doom";
BounceFactor 0.3;
Gravity 0.35;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
frame = Random[Junk](0,5);
scale *= Frandom[Junk](0.8,1.2);
heat = 1.5;
}
override void Tick()
{
Super.Tick();
if ( isFrozen() ) return;
if ( heat > 0 )
{
heat -= FRandom[Junk](0.003,0.006);
let s = Spawn("UTSmoke",pos);
s.alpha *= min(1.,heat)*0.6*alpha;
}
if ( InStateSequence(CurState,ResolveState("Death")) )
{
deadtimer++;
if ( deadtimer > 300 ) A_FadeOut(0.05);
return;
}
}
States
{
Spawn:
CHIP # 1
{
angle += anglevel;
pitch += pitchvel;
roll += rollvel;
}
Loop;
Bounce:
CHIP # 0
{
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
vel = (vel.unit()+(FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2),FRandom[Junk](-.2,.2))).unit()*vel.length();
A_PlaySound("vfrag/bounce",CHAN_BODY,min(1.,vel.length()*0.1),pitch:FRandom[Junk](0.6,1.4));
}
Goto Spawn;
Death:
CHIP # -1
{
pitch = int(pitch/180)*180;
roll = int(roll/180)*180;
}
Stop;
Dummy:
CHIP ABCDEF -1;
Stop;
}
}
Class SentryXLight : PaletteLight
{
Default
{
ReactionTime 30;
Args 0,0,0,120;
}
} }
Class SentryBoom : Actor Class SentryBoom : Actor
{ {
Default
{
RenderStyle "Add";
Scale 3.2;
+NOGRAVITY;
+NOBLOCKMAP;
+NODAMAGETHRUST;
+FORCERADIUSDMG;
+FORCEXYBILLBOARD;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_Explode(80,250);
A_PlaySound("sentry/explode");
UTMainHandler.DoBlast(self,250,70000);
double ang, pt;
for ( int i=0; i<16; i++ )
{
let f = Spawn("SentryFragment",Vec3Offset(FRandom[EFrag](-8,8),FRandom[EFrag](-8,8),FRandom[EFrag](4,40)));
ang = FRandom[EFrag](0,360);
pt = FRandom[EFrag](-90,90);
f.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[EFrag](8,15);
}
Scale.x *= RandomPick[EFrag](-1,1);
Scale.y *= RandomPick[EFrag](-1,1);
int numpt = Random[ExploS](20,25);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,3);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
}
numpt = Random[ExploS](10,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[ExploS](20,30);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,12);
let s = Spawn("UTChip",pos);
s.vel = pvel;
s.scale *= FRandom[ExploS](0.9,2.7);
}
Spawn("FlareXLight",pos);
}
States
{
Spawn:
TNT1 A 0 NoDelay A_Jump(256,"Explo1","Explo2","Explo3","Explo4","Explo5");
Explo1:
EXP1 ABCDEFGH 3 Bright;
Stop;
Explo2:
EXP2 ABCDEFGH 3 Bright;
Stop;
Explo3:
EXP3 ABCDEFGH 3 Bright;
Stop;
Explo4:
EXP4 ABCDEFGH 3 Bright;
Stop;
Explo5:
EXP5 ABCDEFGH 3 Bright;
Stop;
}
} }
// The body of the sentry // The body of the sentry
Class MinigunSentryBase : Actor Class MinigunSentryBase : Actor
{ {
const sentryammo = 200; const sentryammo = 200;
const sentryhealth = 500;
int rememberedplayer; int rememberedplayer;
Default Default
{ {
Health 300; Health sentryhealth;
Mass int.max; Mass int.max;
Radius 12; Radius 12;
Height 48; Height 48;
@ -1740,22 +1993,6 @@ Class MinigunSentryBase : Actor
+DONTTHRUST; +DONTTHRUST;
+SPECIAL; +SPECIAL;
} }
override bool Used( Actor user )
{
Super.Used(user);
if ( !user.player || !bSPECIAL ) return false;
if ( deathmatch )
{
if ( master && (user != user) && user.CheckLocalView() )
Console.Printf(StringTable.Localize("$M_SENTRYHIJACK"));
SetTag(String.Format(StringTable.Localize("$T_OWNEDSENTRY"),user.player.GetUserName()));
}
master = user;
bSHOOTABLE = false;
bSPECIAL = false;
SetStateLabel("PackUp");
return true;
}
override void PostBeginPlay() override void PostBeginPlay()
{ {
Super.PostBeginPlay(); Super.PostBeginPlay();
@ -1770,7 +2007,7 @@ Class MinigunSentryBase : Actor
rememberedplayer = -1; rememberedplayer = -1;
} }
tracer = Spawn("MinigunSentry",pos); tracer = Spawn("MinigunSentry",pos);
tracer.special1 = sentryammo; tracer.special1 = special1;
tracer.master = self; tracer.master = self;
tracer.angle = angle; tracer.angle = angle;
tracer.pitch = pitch; tracer.pitch = pitch;
@ -1816,16 +2053,13 @@ Class MinigunSentryBase : Actor
{ {
if ( master && (toucher != master) && master.CheckLocalView() ) if ( master && (toucher != master) && master.CheckLocalView() )
Console.Printf(StringTable.Localize("$M_SENTRYHIJACK")); Console.Printf(StringTable.Localize("$M_SENTRYHIJACK"));
master = toucher; SentryItem.TransferOwnership(toucher,self);
SetTag(String.Format(StringTable.Localize("$T_OWNEDSENTRY"),toucher.player.GetUserName()));
tracer.A_ClearTarget();
tracer.SetFriendPlayer(toucher.player);
} }
let amo = toucher.FindInventory("UMiniAmmo"); let amo = toucher.FindInventory("UMiniAmmo");
if ( !amo || (amo.Amount <= 0) || (tracer.special1 >= sentryammo) ) return; if ( !amo || (amo.Amount <= 0) || (tracer.special1 >= sentryammo) ) return;
A_PlaySound("misc/i_pkup",CHAN_ITEM); A_PlaySound("misc/i_pkup",CHAN_ITEM);
int xammo = min(sentryammo-tracer.special1,amo.Amount); int xammo = min(sentryammo-tracer.special1,amo.Amount);
tracer.special1 += xammo; special1 = tracer.special1 += xammo;
amo.Amount -= xammo; amo.Amount -= xammo;
} }
override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle ) override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle )
@ -1841,10 +2075,6 @@ Class MinigunSentryBase : Actor
if ( tracer && !tracer.target ) tracer.target = target; if ( tracer && !tracer.target ) tracer.target = target;
return dmg; return dmg;
} }
override void Die( Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath )
{
Super.Die(source,inflictor,dmgflags,MeansOfDeath);
}
States States
{ {
Spawn: Spawn:
@ -1866,6 +2096,7 @@ Class MinigunSentryBase : Actor
PackUp: PackUp:
SENI A -1 SENI A -1
{ {
bSPECIAL = false;
tracer.SetStateLabel("PackUp"); tracer.SetStateLabel("PackUp");
} }
Stop; Stop;
@ -1891,7 +2122,7 @@ Class MinigunSentryBase : Actor
} }
Stop; Stop;
Death: Death:
TNT1 A 1 Spawn("SentryBoom",pos); TNT1 A 1 Spawn("SentryBoom",Vec3Offset(0,0,height/2));
Stop; Stop;
} }
} }

View file

@ -516,10 +516,10 @@ Class Eightball : UnrealWeapon
EBLS ABCDEFGHIJKLMNO 1 A_WeaponReady(WRF_NOFIRE); EBLS ABCDEFGHIJKLMNO 1 A_WeaponReady(WRF_NOFIRE);
Ready2: Ready2:
EBLS O 0 A_CheckReload(); EBLS O 0 A_CheckReload();
EBLL A 0 A_PlaySound("utrl/load",CHAN_ITEM,Dampener.Active(self)?.1:1.); EBLL A 0 A_PlaySound("utrl/load",CHAN_6,Dampener.Active(self)?.1:1.);
EBLL ABCDEFGHIJK 2; EBLL ABCDEFGHIJK 1 A_WeaponReady(WRF_NOFIRE);
EBLL L 0 A_PlaySound("utrl/rotate",CHAN_ITEM,Dampener.Active(self)?.01:.1); EBLL L 0 A_PlaySound("utrl/rotate",CHAN_ITEM,Dampener.Active(self)?.01:.1);
EBLL LMNOPQRSTUVWXYZ[ 1; EBLL LMNOPQRSTUVWXYZ[ 1 A_WeaponReady(WRF_NOFIRE);
EBLL Z 0; // force no tweening EBLL Z 0; // force no tweening
EBLI A 0; EBLI A 0;
Goto Idle; Goto Idle;
@ -571,8 +571,8 @@ Class Eightball : UnrealWeapon
Loading: Loading:
EBLI A 0; EBLI A 0;
EBLL A 0 A_LoadRocket(); EBLL A 0 A_LoadRocket();
EBLL A 0 A_PlaySound("utrl/load",CHAN_ITEM,Dampener.Active(self)?.1:1.); EBLL A 0 A_PlaySound("utrl/load",CHAN_6,Dampener.Active(self)?.1:1.);
EBLL ABCDEFGHIJK 2; EBLL ABCDEFGHIJK 1;
EBLL L 0 A_PlaySound("utrl/rotate",CHAN_ITEM,Dampener.Active(self)?.01:.1); EBLL L 0 A_PlaySound("utrl/rotate",CHAN_ITEM,Dampener.Active(self)?.01:.1);
EBLL LMNOPQRSTUVWXYZ[ 1; EBLL LMNOPQRSTUVWXYZ[ 1;
EBLL Z 0; EBLL Z 0;

View file

@ -117,7 +117,7 @@ Class UFlakSlug : FlakSlug
A_SetRenderStyle(1.0,STYLE_Add); A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("RocketBlast",50); A_SprayDecal("RocketBlast",50);
A_NoGravity(); A_NoGravity();
A_SetScale(1.2); A_SetScale(2.2);
UTMainHandler.DoBlast(self,120,75000); UTMainHandler.DoBlast(self,120,75000);
A_Explode(70,120); A_Explode(70,120);
A_QuakeEx(4,4,4,8,0,170,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,rollIntensity:0.2); A_QuakeEx(4,4,4,8,0,170,"",QF_RELATIVE|QF_SCALEDOWN,falloff:120,rollIntensity:0.2);

View file

@ -592,9 +592,12 @@ Class UnrealInventory : Inventory
bool bActive; // is currently activated bool bActive; // is currently activated
int Charge; // for timed items int Charge; // for timed items
int DefaultCharge; int DefaultCharge;
private int UItemFlags;
Property Charge : DefaultCharge; Property Charge : DefaultCharge;
FlagDef DrawSpecial : UItemFlags, 0; // hud draws special1 as amount
// Drawstuffs under HUD // Drawstuffs under HUD
virtual ui void PreRender( double lbottom ) {} virtual ui void PreRender( double lbottom ) {}
// Drawstuffs over HUD // Drawstuffs over HUD

View file

@ -190,9 +190,9 @@ Class UnrealHUD : BaseStatusBar
private void DrawNumberOf( Inventory i, double x, double y ) private void DrawNumberOf( Inventory i, double x, double y )
{ {
if ( i.Amount <= 1 ) return; if ( (i.Amount <= 1) && !((i is 'UnrealInventory') || !UnrealInventory(i).bDRAWSPECIAL) ) return;
double TempX = CurX, TempY = CurY; double TempX = CurX, TempY = CurY;
string itxt = String.Format("%d",i.Amount); string itxt = String.Format("%d",((i is 'UnrealInventory')&&UnrealInventory(i).bDRAWSPECIAL)?i.special1:i.Amount);
CurX += 30; CurX += 30;
CurY += 23; CurY += 23;
CurX -= TinyRedFont.StringWidth(itxt); CurX -= TinyRedFont.StringWidth(itxt);
@ -377,7 +377,7 @@ Class UnrealHUD : BaseStatusBar
{ {
bRed = ((Prev is 'UnrealInventory') && UnrealInventory(Prev).bActive) || (Prev is 'Powerup') || ((Prev is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4)))); bRed = ((Prev is 'UnrealInventory') && UnrealInventory(Prev).bActive) || (Prev is 'Powerup') || ((Prev is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4))));
DrawHudIcon(x,y,Prev,bRed); DrawHudIcon(x,y,Prev,bRed);
if ( Prev.MaxAmount > 1 ) DrawNumberOf(Prev,x,y); if ( (Prev.MaxAmount > 1) || ((Prev is 'UnrealInventory') && UnrealInventory(Prev).bDRAWSPECIAL) ) DrawNumberOf(Prev,x,y);
} }
bRed = ((SelectedItem is 'UnrealInventory') && UnrealInventory(SelectedItem).bActive) || (SelectedItem is 'Powerup') || ((SelectedItem is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4)))); bRed = ((SelectedItem is 'UnrealInventory') && UnrealInventory(SelectedItem).bActive) || (SelectedItem is 'Powerup') || ((SelectedItem is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4))));
if ( !Next && !Prev && !bDrawOne ) DrawHudIcon(x+64,y,SelectedItem,bRed); if ( !Next && !Prev && !bDrawOne ) DrawHudIcon(x+64,y,SelectedItem,bRed);
@ -386,12 +386,12 @@ Class UnrealHUD : BaseStatusBar
if ( !Next && !Prev && !bDrawOne ) CurX = x+64; if ( !Next && !Prev && !bDrawOne ) CurX = x+64;
CurY = y; CurY = y;
Screen.DrawTexture(IconSel,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,0.5); Screen.DrawTexture(IconSel,false,CurX,CurY,DTA_VirtualWidthF,ClipX,DTA_VirtualHeightF,ClipY,DTA_KeepRatio,true,DTA_Alpha,0.5);
if ( SelectedItem.MaxAmount > 1 ) DrawNumberOf(SelectedItem,CurX,y); if ( (SelectedItem.MaxAmount > 1) || ((SelectedItem is 'UnrealInventory') && UnrealInventory(SelectedItem).bDRAWSPECIAL) ) DrawNumberOf(SelectedItem,CurX,y);
if ( Next ) if ( Next )
{ {
bRed = ((Next is 'UnrealInventory') && UnrealInventory(Next).bActive) || (Next is 'Powerup') || ((Next is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4)))); bRed = ((Next is 'UnrealInventory') && UnrealInventory(Next).bActive) || (Next is 'Powerup') || ((Next is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4))));
DrawHudIcon(x+64,y,Next,bRed); DrawHudIcon(x+64,y,Next,bRed);
if ( Next.MaxAmount > 1 ) DrawNumberOf(Next,x+64,y); if ( (Next.MaxAmount > 1) || ((Next is 'UnrealInventory') && UnrealInventory(Next).bDRAWSPECIAL) ) DrawNumberOf(Next,x+64,y);
} }
} }