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_SENTRYHIJACK = "Your Sentry has been hijacked.";
M_MSNOROOM = "No room to deploy Sentry.";
M_NSTOOFAR = "Cannot recall Sentry from this distance.";
M_FFNOROOM = "No room to activate Force Field.";
S_MINHUD = "Health %d Score %d Ammo %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_SENTRYHIJACK = "Tu Torreta ha sido hackeada.";
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.";
S_MINHUD = "Salud %d Puntuación %d Munición %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
}
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"
{
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/fire sentfire
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;
if ( t.Results.HitActor is 'ASMDHitbox' )
{
BeamExplode(true);
BeamExplode(mult>1.5);
if ( target )
{
target.TakeInventory('ASMDAmmo',2);

View file

@ -431,6 +431,28 @@ Class VoiceBoxActive : Actor
bMOVEWITHSECTOR = false;
bFORCEXYBILLBOARD = true;
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");
}
Explo1:
@ -616,6 +638,28 @@ Class FlareThrown : Actor
bMOVEWITHSECTOR = false;
bFORCEXYBILLBOARD = true;
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");
}
Explo1:
@ -907,6 +951,28 @@ Class BetaFlareThrown : Actor
bMOVEWITHSECTOR = false;
bFORCEXYBILLBOARD = true;
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");
}
Explo1:
@ -1056,15 +1122,13 @@ Class Forcefield : UnrealInventory
override bool Use( bool pickup )
{
if ( pickup ) return false;
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("ForceFieldEffect").Height*.5));
if ( !level.IsPointInLevel(origin) )
{
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$M_FFNOROOM"));
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*(GetDefaultByType("ForceFieldEffect").radius+8);
else origin = d.HitLocation;
Owner.LineTrace(0,GetDefaultByType("ForceFieldEffect").height/2,90,TRF_ABSPOSITION,origin.z,origin.x,origin.y,data:d);
origin = d.HitLocation;
let a = Spawn("ForceFieldEffect",origin);
if ( !a.TestMobjLocation() )
{
@ -1365,26 +1429,55 @@ Class SentryItem : UnrealInventory
Inventory.MaxAmount 1;
Inventory.PickupMessage "$I_SENTRY";
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 )
{
Super.AttachToOwner(other);
special1 = MinigunSentryBase.sentryammo;
Super.AttachToOwner(other);
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
if ( bActive ) return false;
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 ( bActive )
{
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;
}
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);
if ( !a.TestMobjLocation() )
{
@ -1416,7 +1509,8 @@ Class SentryItem : UnrealInventory
return;
}
Charge = tracer.Health;
if ( Charge <= 0 ) DepleteOrDestroy();
special1 = tracer.special1;
if ( Charge <= 0 ) Destroy();
}
override void Travelled()
{
@ -1425,7 +1519,7 @@ Class SentryItem : UnrealInventory
{
bUNTOSSABLE = false;
bUNDROPPABLE = false;
DepleteOrDestroy();
Destroy();
}
}
States
@ -1481,8 +1575,8 @@ Class MinigunSentryX : Actor
// The "head" of the sentry, attaches to the body
Class MinigunSentry : Actor
{
const maxangle = 60;
const maxpitch = 30;
const maxangle = 80;
const maxpitch = 40;
Default
{
@ -1545,7 +1639,7 @@ Class MinigunSentry : Actor
}
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"));
A_SentryFaceTarget();
master.A_AlertMonsters(0,AMF_TARGETEMITTER);
@ -1553,7 +1647,7 @@ Class MinigunSentry : Actor
Vector3 x, y, z, origin;
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
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();
FLineTraceData 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
{
A_LookEx(LOF_NOSOUNDCHECK|LOF_NOJUMP);
if ( TargetVisible() ) return ResolveState("MissileLoop");
if ( TargetVisible() && (special1>0) ) return ResolveState("MissileLoop");
A_PlaySound("sentry/unwind");
master.SetStateLabel("MissileEnd");
return ResolveState(null);
@ -1716,21 +1810,180 @@ Class MinigunSentry : 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
{
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
Class MinigunSentryBase : Actor
{
const sentryammo = 200;
const sentryhealth = 500;
int rememberedplayer;
Default
{
Health 300;
Health sentryhealth;
Mass int.max;
Radius 12;
Height 48;
@ -1740,22 +1993,6 @@ Class MinigunSentryBase : Actor
+DONTTHRUST;
+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()
{
Super.PostBeginPlay();
@ -1770,7 +2007,7 @@ Class MinigunSentryBase : Actor
rememberedplayer = -1;
}
tracer = Spawn("MinigunSentry",pos);
tracer.special1 = sentryammo;
tracer.special1 = special1;
tracer.master = self;
tracer.angle = angle;
tracer.pitch = pitch;
@ -1816,16 +2053,13 @@ Class MinigunSentryBase : Actor
{
if ( master && (toucher != master) && master.CheckLocalView() )
Console.Printf(StringTable.Localize("$M_SENTRYHIJACK"));
master = toucher;
SetTag(String.Format(StringTable.Localize("$T_OWNEDSENTRY"),toucher.player.GetUserName()));
tracer.A_ClearTarget();
tracer.SetFriendPlayer(toucher.player);
SentryItem.TransferOwnership(toucher,self);
}
let amo = toucher.FindInventory("UMiniAmmo");
if ( !amo || (amo.Amount <= 0) || (tracer.special1 >= sentryammo) ) return;
A_PlaySound("misc/i_pkup",CHAN_ITEM);
int xammo = min(sentryammo-tracer.special1,amo.Amount);
tracer.special1 += xammo;
special1 = tracer.special1 += xammo;
amo.Amount -= xammo;
}
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;
return dmg;
}
override void Die( Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath )
{
Super.Die(source,inflictor,dmgflags,MeansOfDeath);
}
States
{
Spawn:
@ -1866,6 +2096,7 @@ Class MinigunSentryBase : Actor
PackUp:
SENI A -1
{
bSPECIAL = false;
tracer.SetStateLabel("PackUp");
}
Stop;
@ -1891,7 +2122,7 @@ Class MinigunSentryBase : Actor
}
Stop;
Death:
TNT1 A 1 Spawn("SentryBoom",pos);
TNT1 A 1 Spawn("SentryBoom",Vec3Offset(0,0,height/2));
Stop;
}
}

View file

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

View file

@ -117,7 +117,7 @@ Class UFlakSlug : FlakSlug
A_SetRenderStyle(1.0,STYLE_Add);
A_SprayDecal("RocketBlast",50);
A_NoGravity();
A_SetScale(1.2);
A_SetScale(2.2);
UTMainHandler.DoBlast(self,120,75000);
A_Explode(70,120);
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
int Charge; // for timed items
int DefaultCharge;
private int UItemFlags;
Property Charge : DefaultCharge;
FlagDef DrawSpecial : UItemFlags, 0; // hud draws special1 as amount
// Drawstuffs under HUD
virtual ui void PreRender( double lbottom ) {}
// Drawstuffs over HUD

View file

@ -190,9 +190,9 @@ Class UnrealHUD : BaseStatusBar
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;
string itxt = String.Format("%d",i.Amount);
string itxt = String.Format("%d",((i is 'UnrealInventory')&&UnrealInventory(i).bDRAWSPECIAL)?i.special1:i.Amount);
CurX += 30;
CurY += 23;
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))));
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))));
if ( !Next && !Prev && !bDrawOne ) DrawHudIcon(x+64,y,SelectedItem,bRed);
@ -386,12 +386,12 @@ Class UnrealHUD : BaseStatusBar
if ( !Next && !Prev && !bDrawOne ) CurX = x+64;
CurY = y;
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 )
{
bRed = ((Next is 'UnrealInventory') && UnrealInventory(Next).bActive) || (Next is 'Powerup') || ((Next is 'UTranslator') && ((bTranslatorActive) || (bFlashTranslator && ((gametic%8)<4))));
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);
}
}