stinger_m/zscript/stinger.zsc
Marisa Kirisame 6820c4deba 1.1.1 update (same as flak_m):
- Sound overhaul.
 - Added extended '95 theme from Unreal mac port.
2020-01-04 22:33:10 +01:00

754 lines
18 KiB
Text

Class StingerAmmo : Ammo
{
Default
{
Tag "$T_STINGERAMMO";
Inventory.Icon "I_Stingr";
Inventory.PickupMessage "";
Inventory.Amount 5;
Inventory.MaxAmount 200;
Ammo.BackpackAmount 20;
Ammo.BackpackMaxAmount 400;
Ammo.DropAmount 2;
}
override String PickupMessage()
{
return String.Format("%s%d%s",StringTable.Localize("$I_STINGERAMMOL"),Amount,StringTable.Localize("$I_STINGERAMMOR"));
}
States
{
Spawn:
SAMO A -1;
Stop;
}
}
Class StingerAmmo2 : StingerAmmo
{
Default
{
Tag "$T_STINGERAMMO2";
Inventory.Amount 40;
Ammo.DropAmount 15;
}
States
{
Spawn:
SAMO B -1;
Stop;
}
}
Class StingerBurstLight : PaletteLight
{
Default
{
Tag "Blue4";
Args 0,0,0,30;
ReactionTime 12;
}
}
Class StingerChunk : Actor
{
int deadtimer;
double rollvel, anglevel, pitchvel;
Default
{
Radius 2;
Height 2;
+NOBLOCKMAP;
+MISSILE;
+MOVEWITHSECTOR;
+THRUACTORS;
+NOTELEPORT;
+DONTSPLASH;
+INTERPOLATEANGLES;
BounceType "Doom";
BounceFactor 0.4;
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,8);
scale *= Frandom[Junk](0.4,0.8);
}
override void Tick()
{
Super.Tick();
if ( isFrozen() ) return;
if ( InStateSequence(CurState,ResolveState("Death")) )
{
deadtimer++;
if ( deadtimer > 60 ) 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);
}
Goto Spawn;
Death:
CHIP # -1;
Stop;
Dummy:
CHIP ABCDEFGHI -1;
Stop;
}
}
Class ViewStingerChunk : StingerChunk
{
Vector3 ofs, vvel;
Default
{
+NOCLIP;
+NOGRAVITY;
-MISSILE;
BounceType "None";
}
override void Tick()
{
Actor.Tick();
if ( !target || !target.player )
{
Destroy();
return;
}
Vector3 x, y, z;
[x, y, z] = dt_CoordUtil.GetAxes(target.pitch,target.angle,target.roll);
Vector3 origin = level.Vec3Offset(target.Vec2OffsetZ(0,0,target.player.viewz),x*ofs.x+y*ofs.y+z*ofs.z);
SetOrigin(origin,true);
bInvisible = (players[consoleplayer].camera != target);
if ( isFrozen() ) return;
ofs += vvel;
scale *= 0.75;
if ( scale.x <= 0.01 ) Destroy();
}
}
Class TarydiumExLight : PaletteLight
{
Default
{
Tag "Blue2";
Args 0,0,0,60;
ReactionTime 30;
}
}
Class TarydiumExplosion : Actor
{
Default
{
RenderStyle "Add";
+NOGRAVITY;
+NOBLOCKMAP;
+FORCEXYBILLBOARD;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
DamageType 'TarydiumCharge';
Obituary "$O_STINGERX";
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_Explode(max(10,special1),90+special1);
UTMainHandler.DoBlast(self,90+special1,900*special1);
UTMainHandler.DoBlast(self,200+special1,200*special1); // hurtless secondary blast, so stuff that's pretty close by gets pushed away
// (just going off the novels here, it's supposed to be pretty strong)
A_QuakeEx(clamp(special1/6,2,9),clamp(special1/6,2,9),clamp(special1/6,2,9),10,0,300+special1*2,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200+special1*2,rollIntensity:0.12);
SetOrigin(Vec3Offset(0,0,16),false);
A_StartSound("stinger/explode",CHAN_VOICE,pitch:FRandom[Stinger](0.8,1.5));
A_StartSound("stinger/explode",CHAN_ITEM,pitch:FRandom[Stinger](0.8,1.5));
let l = Spawn("TarydiumExLight",pos);
l.args[3] = int(60*scale.x);
scale.x *= RandomPick[Stinger](-1,1);
scale.y *= RandomPick[Stinger](-1,1);
double ang, pt;
int numpt = Random[Stinger](10,15)*min(3,special1/60);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = Spawn("UTSmoke",pos);
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](2,7);
c.SetShade(Color(1,3,4)*Random[Stinger](24,63));
c.scale *= 3.;
}
numpt = Random[Stinger](4,8)*min(8,special1/25);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = Spawn("StingerChunk",pos);
c.angle = ang;
c.pitch = pt;
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](6,12);
}
numpt = Random[Stinger](10,20)*min(4,special1/40);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = Spawn("UTChip",pos);
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](6,12);
c.scale *= FRandom[Stinger](0.9,1.5);
}
}
States
{
Spawn:
TNT1 A 0 NoDelay A_Jump(128,"Explo2");
Explo1:
TEX1 ABCDEFGHI 3 Bright;
Stop;
Explo2:
TEX2 ABCDEFGHIJK 3 Bright;
Stop;
}
}
Class TDebuffLight : PointLightAttenuated
{
TarydiumDebuff dbf;
override void Tick()
{
Super.Tick();
if ( !dbf || !dbf.victim )
{
Destroy();
return;
}
Args[0] = int(min(dbf.Amount,64));
Args[1] = int(min(dbf.Amount*3,192));
Args[2] = int(min(dbf.Amount*4,255));
Args[3] = int(max(dbf.victim.radius,dbf.victim.height)+60+min(dbf.amount/4,40));
SetOrigin(dbf.Victim.Vec3Offset(0,0,dbf.Victim.Height/2),true);
}
}
Class TarydiumDebuff : Thinker
{
Actor victim, instigator, lite;
double amount; // accumulated damage for the explosion
Vector3 oldvel;
bool wasonair, exploding;
int explodetimer;
void UpdateEffect()
{
if ( !victim ) return;
if ( !lite )
{
lite = Actor.Spawn("TDebuffLight",victim.pos);
TDebuffLight(lite).dbf = self;
lite.Args[0] = int(min(Amount,64));
lite.Args[1] = int(min(Amount*3,192));
lite.Args[2] = int(min(Amount*4,255));
lite.Args[3] = int(max(victim.radius,victim.height)+60+min(amount/4,40));
}
}
void BlowUp()
{
let b = victim.Spawn("TarydiumExplosion",victim.Vec3Offset(FRandom[Stinger](-victim.radius,victim.radius),FRandom[Stinger](-victim.radius,victim.radius),FRandom[Stinger](0,victim.height)));
b.target = instigator;
b.special1 = int(min(amount,100)); // in Unreal this was capped to 10, which would make it deal barely any damage
b.scale *= .8+min(1.,amount*0.01);
amount = amount*0.9-10; // in Unreal this falls off linearly 10 points at a time, which can take very long at full charge
}
override void OnDestroy()
{
if ( lite ) lite.Destroy();
Super.OnDestroy();
}
override void Tick()
{
if ( !sting_stinger || !victim || (amount <= .4) )
{
Destroy();
return;
}
if ( exploding )
{
explodetimer--;
if ( explodetimer > 0 ) return;
explodetimer = Random[Stinger](3,6);
BlowUp();
return;
}
if ( victim.Health <= 0 )
{
exploding = true;
return;
}
if ( victim.pos.z > victim.floorz ) wasonair = true;
else
{
if ( wasonair && (oldvel.z < -20) )
{
Amount += min(int(-oldvel.z),100);
exploding = true;
return;
}
wasonair = false;
}
oldvel = victim.vel;
amount *= 1.-.04/TICRATE;
UpdateEffect();
if ( amount <= .4 )
{
Destroy();
return;
}
if ( level.maptime%3 ) return;
int numpt = clamp(int(Random[Stinger](1,3)*amount*0.02),1,8);
for ( int i=0; i<numpt; i++ )
{
Vector3 pos = victim.Vec3Offset(FRandom[Stinger](-victim.radius,victim.radius),FRandom[Stinger](-victim.radius,victim.radius),FRandom[Stinger](0,victim.height));
let l = victim.Spawn("StingerBurstLight",pos);
l.Args[3] /= 2;
double ang, pt;
int numpt2 = Random[Stinger](2,5);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = victim.Spawn("UTSmoke",pos);
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](0.3,0.8);
c.SetShade(Color(1,3,4)*Random[Stinger](24,63));
c.scale *= 3.;
c.alpha *= 0.35;
}
}
}
static void Apply( Actor victim, Actor instigator, double amount )
{
if ( !victim || (victim.Health <= 0) || !victim.bISMONSTER ) return;
if ( !sting_stinger ) return;
let ti = ThinkerIterator.Create("TarydiumDebuff",STAT_USER);
TarydiumDebuff t;
while ( t = TarydiumDebuff(ti.Next()) )
{
if ( t.victim != victim ) continue;
if ( instigator ) t.instigator = instigator;
t.amount += amount;
t.UpdateEffect();
return;
}
t = new("TarydiumDebuff");
t.ChangeStatNum(STAT_USER);
t.victim = victim;
t.instigator = instigator;
t.amount = amount;
t.oldvel = victim.vel;
t.wasonair = (victim.pos.z>victim.floorz);
t.UpdateEffect();
}
}
Class StingerProjectile : Actor
{
Vector3 oldvel;
Default
{
Obituary "$O_STINGER";
DamageType 'Stinger';
DamageFunction 14;
Speed 40;
Radius 2;
Height 2;
PROJECTILE;
+SKYEXPLODE;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( sting_stingerb )
{
// set bounce stuff
bBOUNCEONWALLS = true;
bBOUNCEONFLOORS = true;
bBOUNCEONCEILINGS = true;
bALLOWBOUNCEONACTORS = true;
bCANBOUNCEWATER = true;
bUSEBOUNCESTATE = true;
BounceCount = 4;
BounceFactor = 1.;
WallBounceFactor = 1.;
}
}
override void Tick()
{
oldvel = vel;
Super.Tick();
}
void A_HandleBounce()
{
// cancel bounce based on "incidence"
if ( vel dot oldvel < 0.87 )
{
ClearBounce();
ExplodeMissile();
return;
}
if ( !Random[Stinger](0,2) ) A_StartSound("stinger/hit2",volume:.5,pitch:FRandom[Stinger](0.5,1.5));
else A_StartSound("stinger/hit",volume:.6);
A_SprayDecal("WallCrack",-20);
A_AlertMonsters();
let l = Spawn("StingerBurstLight",pos);
l.Args[3] /= 2;
double ang, pt;
int numpt = Random[Stinger](1,3);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = Spawn("StingerChunk",pos);
c.scale *= 0.5;
c.angle = ang;
c.pitch = pt;
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](3,9);
}
numpt = Random[Stinger](2,5);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = Spawn("UTSmoke",pos);
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](0.3,0.8);
c.SetShade(Color(1,3,4)*Random[Stinger](48,63));
c.alpha *= 0.35;
}
}
override int DoSpecialDamage( Actor target, int damage, Name damagetype )
{
if ( !target.bNOBLOOD )
{
target.SpawnBlood(pos,AngleTo(target),damage);
A_StartSound("stinger/flesh");
A_AlertMonsters();
if ( sting_stinger )
{
TarydiumDebuff.Apply(target,self.target,10);
damage = 2;
}
}
return damage;
}
action void A_StingerHit()
{
if ( !Random[Stinger](0,2) ) A_StartSound("stinger/hit2",volume:.5,pitch:FRandom[Stinger](0.5,1.5));
else A_StartSound("stinger/hit",volume:.6);
A_SprayDecal("WallCrack",20);
A_AlertMonsters();
Spawn("StingerBurstLight",pos);
double ang, pt;
int numpt = Random[Stinger](4,8);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = Spawn("StingerChunk",pos);
c.angle = ang;
c.pitch = pt;
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](3,9);
}
numpt = Random[Stinger](6,12);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[Stinger](0,360);
pt = FRandom[Stinger](-90,90);
let c = Spawn("UTSmoke",pos);
c.vel = (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[Stinger](0.3,0.8);
c.SetShade(Color(1,3,4)*Random[Stinger](48,63));
c.alpha *= 0.5;
}
}
States
{
Spawn:
TPRJ A 1 Bright
{
if ( waterlevel > 0 )
Spawn("UTBubble",pos);
}
Wait;
Bounce:
TPRJ A 0 Bright A_HandleBounce();
Goto Spawn;
Death:
Crash:
TNT1 A 1 A_StingerHit();
Stop;
XDeath:
TNT1 A 1;
Stop;
}
}
Class StingerLight : EnforcerLight
{
Default
{
args 64,128,255,80;
}
}
Class Stinger : UnrealWeapon
{
int flashnum;
Default
{
Tag "$T_STINGER";
Inventory.PickupMessage "$I_STINGER";
Weapon.UpSound "stinger/select";
Weapon.SlotNumber 3;
Weapon.SelectionOrder 2500;
Weapon.SlotPriority 1;
Weapon.AmmoType "StingerAmmo";
Weapon.AmmoUse 1;
Weapon.AmmoType2 "StingerAmmo";
Weapon.AmmoUse2 1;
Weapon.AmmoGive 40;
UTWeapon.DropAmmo 20;
}
action void A_StingerFire( bool hold = false )
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
if ( hold )
{
A_SoundVolume(CHAN_WEAPONMISC,Dampener.Active(self)?.1:1.);
A_Overlay(PSP_FLASH,"MFlashHold");
}
else
{
A_StartSound("stinger/fire",CHAN_WEAPON,CHANF_OVERLAP,Dampener.Active(self)?.1:1.);
A_Overlay(PSP_FLASH,"MFlash");
}
A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true);
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
invoker.FireEffect();
UTMainHandler.DoFlash(self,Color(16,0,64,255),1);
UTMainHandler.DoSwing(self,(FRandom[Stinger](-0.1,-0.2),FRandom[Stinger](-0.1,0.1)),4,-1.5,2,SWING_Spring,2,2);
if ( !Dampener.Active(self) ) A_AlertMonsters();
A_QuakeEx(1,1,1,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
Vector3 x, y, z;
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),5*x+8*y-8*z);
Actor p = Spawn("StingerProjectile",origin);
p.angle = angle;
p.pitch = BulletSlope();
p.roll = FRandom[Stinger](0,360);
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
p.target = self;
int numpt = Random[Stinger](5,9);
double ang;
for ( int i=0; i<numpt; i++ )
{
let s = Spawn("ViewStingerChunk",origin);
ViewStingerChunk(s).ofs = (8,2,-2);
ang = FRandom[Stinger](0,360);
ViewStingerChunk(s).vvel = (FRandom[Stinger](0.2,1.2),0,0)+(0,cos(ang),sin(ang))*FRandom[Stinger](0.3,0.9);
s.target = self;
}
for ( int i=0; i<12; i++ )
{
let s = Spawn("UTViewSmoke",origin);
UTViewSmoke(s).ofs = (16,4,-4);
ang = FRandom[Stinger](0,360);
UTViewSmoke(s).vvel = (FRandom[Stinger](0,0.4),0,0)+(0,cos(ang),sin(ang))*FRandom[Stinger](0.2,0.5);
s.target = self;
s.scale *= 1.5;
s.alpha *= 0.3;
s.SetShade(Color(1,3,4)*Random[Stinger](31,63));
}
}
action void A_StingerAltFire()
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( weap.Ammo1.Amount <= 0 ) return;
A_StartSound("stinger/altfire",CHAN_WEAPON,CHANF_OVERLAP,Dampener.Active(self)?.1:1.);
A_Overlay(PSP_FLASH,"MFlash");
A_OverlayFlags(PSP_FLASH,PSPF_RenderStyle,true);
A_OverlayRenderstyle(PSP_FLASH,STYLE_Add);
invoker.FireEffect();
UTMainHandler.DoFlash(self,Color(16,0,64,255),1);
UTMainHandler.DoSwing(self,(FRandom[Stinger](-0.3,-0.8),FRandom[Stinger](-0.4,0.4)),4,-1,3,SWING_Spring,3,5);
if ( !Dampener.Active(self) ) A_AlertMonsters();
A_QuakeEx(1,1,1,4,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
Vector3 x, y, z;
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),5*x+8*y-8*z);
[x, y, z] = dt_CoordUtil.GetAxes(BulletSlope(),angle,roll);
Actor p;
double a, s;
Vector3 dir;
for ( int i=0; i<5; i++ )
{
if ( weap.Ammo1.Amount <= 0 ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
a = FRandom[Stinger](0,360);
s = FRandom[Stinger](0,(i>0)?.08:0.); // first shot always accurate
dir = (x+y*cos(a)*s+z*sin(a)*s).unit();
p = Spawn("StingerProjectile",origin);
p.angle = atan2(dir.y,dir.x);
p.pitch = asin(-dir.z);
p.roll = FRandom[Stinger](0,360);
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
p.target = self;
int numpt = Random[Stinger](5,9);
double ang;
for ( int i=0; i<numpt; i++ )
{
let s = Spawn("ViewStingerChunk",origin);
ViewStingerChunk(s).ofs = (8,2,-2);
ang = FRandom[Stinger](0,360);
ViewStingerChunk(s).vvel = (FRandom[Stinger](0.2,1.2),0,0)+(0,cos(ang),sin(ang))*FRandom[Stinger](0.3,0.9);
s.target = self;
}
for ( int i=0; i<12; i++ )
{
let s = Spawn("UTViewSmoke",origin);
UTViewSmoke(s).ofs = (16,4,-4);
ang = FRandom[Stinger](0,360);
UTViewSmoke(s).vvel = (FRandom[Stinger](0,0.4),0,0)+(0,cos(ang),sin(ang))*FRandom[Stinger](0.2,0.5);
s.target = self;
s.scale *= 1.5;
s.alpha *= 0.3;
s.SetShade(Color(1,3,4)*Random[Stinger](48,63));
}
}
}
States
{
Spawn:
STNP A -1;
Stop;
STNP B -1;
Stop;
Select:
STNS A 1 A_Raise(int.max);
Wait;
Ready:
STNS ABCDEFGHIJKLMNOPQRSTU 1 A_WeaponReady(WRF_NOFIRE);
Idle:
STNI A 1
{
A_CheckReload();
A_WeaponReady();
}
Wait;
Fire:
STNF A 2 A_StingerFire();
STNF BC 2;
STNI A 3;
STNI A 0 A_Refire(1);
Goto Idle;
STNI A 0
{
A_StartSound("stinger/hold",CHAN_WEAPONMISC,CHANF_LOOPING,Dampener.Active(self)?.1:1.);
invoker.flashnum = Random[Stinger](0,3);
}
Hold:
STNH A 1
{
// need to make sure player does the repeat fire anim
if ( self is 'UPlayer' )
UPlayer(self).PlayAttacking();
A_StingerFire(true);
invoker.flashnum = (invoker.flashnum+1)%4;
}
STNH BCDEFG 1;
STNH A 0 A_JumpIfNoAmmo(1);
STNH A 0 A_Refire();
STNH A 2
{
A_StopSound(CHAN_WEAPONMISC);
A_StartSound("stinger/release",CHAN_WEAPON,volume:Dampener.Active(self)?.1:1.);
}
Goto Idle;
AltFire:
STNF A 2 A_StingerAltFire();
STNF BC 2;
STNI A 35; // yes, 1 second cooldown
Goto Idle;
Deselect:
STND ACEGIK 1;
STND K 1 A_Lower(int.max);
Wait;
MFlash:
STFF A 2 Bright
{
let l = Spawn("StingerLight",pos);
l.target = self;
}
Stop;
MFlashHold:
TNT1 A 0 A_JumpIf(invoker.flashnum==0,7);
TNT1 A 0 A_JumpIf(invoker.flashnum==1,4);
TNT1 A 0 A_JumpIf(invoker.flashnum==2,4);
TNT1 A 0 A_JumpIf(invoker.flashnum==3,1);
Stop;
STFF A 2 Bright
{
let l = Spawn("StingerLight",pos);
l.target = self;
}
Stop;
STFF B 2 Bright
{
let l = Spawn("StingerLight",pos);
l.target = self;
}
Stop;
STFF C 2 Bright
{
let l = Spawn("StingerLight",pos);
l.target = self;
}
Stop;
STFF D 2 Bright
{
let l = Spawn("StingerLight",pos);
l.target = self;
}
Stop;
/*MFlash:
STFF ABC 2 Bright;
Stop;
MFlashHold:
STFH ABCDEFG 1 Bright;
Stop;*/
}
}