stinger_m/zscript/upowerups.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

633 lines
16 KiB
Text

Class UInvisibility : UnrealInventory
{
Default
{
Tag "$T_INVISIBILITY";
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
+INVENTORY.ALWAYSPICKUP;
Inventory.Icon "I_Invis";
Inventory.PickupMessage "$I_INVISIBILITY";
Inventory.RespawnTics 3500;
Inventory.MaxAmount 1;
UnrealInventory.Charge 100;
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
bActive = !bActive;
if ( bActive )
{
Owner.A_StartSound("uinvis/toggle",CHAN_ITEM);
Owner.GiveInventory("PowerUInvisibility",1);
}
else Owner.TakeInventory("PowerUInvisibility",1);
return false;
}
override void DoEffect()
{
Super.DoEffect();
if ( !bActive ) return;
if ( special1 == -1 )
{
Owner.TakeInventory("PowerUInvisibility",1);
special1 = 3;
}
else if ( special1 > 1 ) special1--;
else if ( special1 == 1 )
{
Owner.GiveInventory("PowerUInvisibility",1);
special1 = 0;
}
if ( !(level.maptime%35) && DrainCharge(1) )
{
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_INVISIBILITY"));
Owner.TakeInventory("PowerUInvisibility",1);
DepleteOrDestroy();
}
}
override void DetachFromOwner()
{
Owner.TakeInventory("PowerUInvisibility",1);
Super.DetachFromOwner();
}
override void OwnerDied()
{
Owner.TakeInventory("PowerUInvisibility",1);
Super.OwnerDied();
}
override void Travelled()
{
if ( bActive ) Owner.TakeInventory("PowerUInvisibility",1);
Super.Travelled();
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
tracer = Spawn("UInvisibilityX",pos);
tracer.angle = angle;
tracer.target = self;
}
States
{
Spawn:
INVS A -1;
Stop;
}
}
Class UInvisibilityX : AsmdAmmoX
{
States
{
Spawn:
INVS A -1 Bright;
Stop;
}
}
Class PowerUInvisibility : PowerInvisibility
{
Default
{
Powerup.Duration 0x7FFFFFFD;
Powerup.Strength 90;
Powerup.Mode "Additive";
}
}
Class Amplifier : UnrealInventory
{
Default
{
Tag "$T_AMPLIFIER";
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
+INVENTORY.ALWAYSPICKUP;
Inventory.Icon "I_Amp";
Inventory.PickupMessage "$I_AMPLIFIER";
Inventory.RespawnTics 3150;
Inventory.MaxAmount 1;
UnrealInventory.Charge 1000;
}
static double GetMult( Actor Owner, int val )
{
if ( !Owner ) return 1.;
let d = Amplifier(Owner.FindInventory("Amplifier"));
if ( !d || !d.bActive ) return 1.;
double Multiplier = max(1,4*(double(d.Charge-val)/d.DefaultCharge));
if ( d.DrainCharge(val) )
{
d.Owner.A_StartSound("amplifier/unset",CHAN_ITEM);
if ( d.Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_AMPLIFIER"));
if ( d.tracer ) d.tracer.Destroy();
if ( d.Amount <= 0 ) d.DepleteOrDestroy();
}
return Multiplier;
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
bActive = !bActive;
Owner.A_StartSound(bActive?"amplifier/set":"amplifier/unset",CHAN_ITEM);
return false;
}
override void DoEffect()
{
Super.DoEffect();
if ( bActive && !tracer )
{
tracer = Spawn("AmpSound",Owner.pos);
tracer.target = Owner;
tracer.master = self;
}
else if ( !bActive && tracer ) tracer.Destroy();
if ( !bActive ) return;
if ( !(level.maptime%35) && DrainCharge(2) )
{
Owner.A_StartSound("amplifier/unset",CHAN_ITEM);
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_AMPLIFIER"));
if ( tracer ) tracer.Destroy();
if ( Amount <= 0 ) DepleteOrDestroy();
}
}
States
{
Spawn:
AMPP A -1;
Stop;
}
}
Class AmpSound : Actor
{
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
}
override void Tick()
{
Super.Tick();
if ( !target || !master )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
if ( target.CheckLocalView() )
{
A_SoundVolume(CHAN_VOICE,0.0);
A_SoundVolume(CHAN_7,1.0);
}
else
{
A_SoundVolume(CHAN_VOICE,0.25);
A_SoundVolume(CHAN_7,0.0);
}
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_StartSound("amplifier/act",CHAN_VOICE,CHANF_LOOPING,.25,1.5);
A_StartSound("amplifier/act",CHAN_7,CHANF_LOOPING,1.,ATTN_NONE);
}
override void OnDestroy()
{
Super.OnDestroy();
A_StopSound(CHAN_VOICE);
A_StopSound(CHAN_7);
}
}
Class UJumpBoots : UnrealInventory
{
int draincnt;
Default
{
Tag "$T_LBOOTS";
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
+INVENTORY.ALWAYSPICKUP;
Inventory.Icon "I_Boots";
Inventory.PickupMessage "$I_LBOOTS";
Inventory.RespawnTics 1050;
Inventory.MaxAmount 1;
UnrealInventory.Charge 3;
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
bActive = !bActive;
Owner.A_StartSound("boot/pickup",CHAN_ITEM);
if ( bActive ) Owner.GiveInventory("PowerJumpBoots_HighJump",1);
else Owner.TakeInventory("PowerJumpBoots_HighJump",1);
return false;
}
override void DoEffect()
{
Super.DoEffect();
if ( !Owner || !Owner.player ) return;
draincnt++;
if ( (draincnt >= 700) || (bActive && (owner.player.jumptics == -1)) )
{
draincnt = 0;
charge--;
Owner.A_StartSound("boot/jump",CHAN_POWERUP3,CHANF_OVERLAP);
}
else if ( (charge <= 0) && owner.player.onground )
{
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_LBOOTS"));
Amount--;
Owner.TakeInventory("PowerJumpBoots_HighJump",1);
charge = defaultcharge;
bActive = false;
if ( Amount <= 0 ) DepleteOrDestroy();
}
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( (level.maptime > 0) || !InStateSequence(CurState,FindState("Spawn")) || (gameinfo.gametype&GAME_RAVEN) ) return;
// detect hurtfloors
// can't detect terraindef-based damage
// this is currently an engine limitation
bool foundslime = false;
bool foundlava = false;
bool foundswim = false;
for ( int i=0; i<level.Sectors.Size(); i++ )
{
Sector s = level.Sectors[i];
if ( s.MoreFlags&(Sector.SECMF_UNDERWATER|Sector.SECMF_FORCEDUNDERWATER) ) foundswim = true;
for ( int i=0; i<s.Get3DFloorCount(); i++ )
if ( s.Get3DFloor(i).flags&F3DFloor.FF_SWIMMABLE ) foundswim = true;
if ( !s.DamageInterval || !s.DamageAmount ) continue;
if ( s.DamageType == 'Slime' ) foundslime = true;
else if ( s.DamageType == 'Fire' ) foundlava = true;
}
// random chance to ignore if a replacement already was made
let ti = ThinkerIterator.Create("Inventory");
Inventory a;
while ( a = Inventory(ti.Next()) )
{
// exclude owned items
if ( a.Owner ) continue;
if ( (a is "ToxinSuit") && Random[LBootRep](0,2) )
foundslime = false;
if ( (a is "AsbestosSuit") && Random[LBootRep](0,2) )
foundlava = false;
if ( (a is "SCUBAGear") && Random[LBootRep](0,2) )
foundswim = false;
}
// replace self with asbestos/toxin suits or scuba
// this is extremely naive and doesn't check proximity to the
// hurtfloor/swimmable, but it's better than nothing
Array<String> replacements;
replacements.Clear();
if ( foundslime ) replacements.Push("ToxinSuit");
if ( foundlava ) replacements.Push("AsbestosSuit");
if ( foundswim ) replacements.Push("SCUBAGear");
if ( replacements.Size() > 0 )
{
int rslot = Random[LBootRep](0,replacements.Size()-1);
let r = Spawn(replacements[rslot],pos,ALLOW_REPLACE);
r.spawnangle = spawnangle;
r.spawnpoint = spawnpoint;
r.angle = angle;
r.pitch = pitch;
r.roll = roll;
r.special = special;
r.args[0] = args[0];
r.args[1] = args[1];
r.args[2] = args[2];
r.args[3] = args[3];
r.args[4] = args[4];
r.ChangeTid(tid);
r.SpawnFlags = SpawnFlags&~MTF_SECRET;
r.HandleSpawnFlags();
r.SpawnFlags = SpawnFlags;
r.bCountSecret = SpawnFlags&MTF_SECRET;
r.vel = vel;
r.master = master;
r.target = target;
r.tracer = tracer;
r.bDropped = bDropped;
Destroy();
}
}
override void AttachToOwner( Actor Other )
{
Super.AttachToOwner(Other);
Other.GiveInventory("PowerJumpBoots_IronFeet",1);
}
override void DetachFromOwner()
{
Super.DetachFromOwner();
Owner.TakeInventory("PowerJumpBoots_HighJump",1);
Owner.TakeInventory("PowerJumpBoots_IronFeet",1);
}
States
{
Spawn:
JBUT A -1;
Stop;
}
}
// cheap replacement when proto content disabled
Class UAllMap : MapRevealer
{
Default
{
Tag "$T_ALLMAP";
+COUNTITEM;
+INVENTORY.ALWAYSPICKUP;
Inventory.MaxAmount 0;
Inventory.Icon "I_Detect";
Inventory.PickupSound "misc/p_pkup";
Inventory.PickupMessage "$I_ALLMAP";
Inventory.RespawnTics 1050;
}
States
{
Spawn:
TRNS ABCDCB 6;
Loop;
}
}
Class MotionDetector : UnrealInventory
{
ui TextureID DetHud, DetSpot[2];
Array<Actor> nearscan;
Default
{
Tag "$T_DETECTOR";
+COUNTITEM;
+INVENTORY.ALWAYSPICKUP;
Inventory.MaxAmount 1;
Inventory.Icon "I_Detect";
Inventory.PickupMessage "$I_DETECTOR";
Inventory.RespawnTics 1050;
UnrealInventory.Charge 7000;
}
override bool TryPickup( in out Actor toucher )
{
if ( !sting_proto ) return false; // not allowed
bool valid = Super.TryPickup(toucher);
if ( valid ) level.allmap = true;
return valid;
}
override void Tick()
{
Super.Tick();
if ( sting_proto ) return;
if ( !Owner )
{
let r = Spawn("AllMap",pos,ALLOW_REPLACE);
r.spawnangle = spawnangle;
r.spawnpoint = spawnpoint;
r.angle = angle;
r.pitch = pitch;
r.roll = roll;
r.special = special;
r.args[0] = args[0];
r.args[1] = args[1];
r.args[2] = args[2];
r.args[3] = args[3];
r.args[4] = args[4];
r.ChangeTid(tid);
r.SpawnFlags = SpawnFlags&~MTF_SECRET;
r.HandleSpawnFlags();
r.SpawnFlags = SpawnFlags;
r.bCountSecret = SpawnFlags&MTF_SECRET;
r.vel = vel;
r.master = master;
r.target = target;
r.tracer = tracer;
r.bDropped = bDropped;
r.bNeverRespawn = bNeverRespawn;
}
else Owner.RemoveInventory(self);
Destroy();
}
override void PostRender( double lbottom )
{
if ( !bActive ) return;
double xpos = UnrealHUD(StatusBar).ClipX-96;
double ypos = 0;
// offset if inventory display present on top right
if ( UnrealHUD(StatusBar).HudMode < 2 ) ypos += 32;
if ( DetHud.IsNull() ) DetHud = TexMan.CheckForTexture("DetHud",TexMan.Type_Any);
if ( DetSpot[0].IsNull() ) DetSpot[0] = TexMan.CheckForTexture("DetSpot0",TexMan.Type_Any);
if ( DetSpot[1].IsNull() ) DetSpot[1] = TexMan.CheckForTexture("DetSpot1",TexMan.Type_Any);
Screen.DrawTexture(DetHud,false,xpos,ypos,DTA_VirtualWidthF,UnrealHUD(StatusBar).ClipX,DTA_VirtualHeightF,UnrealHUD(StatusBar).ClipY,DTA_KeepRatio,true);
double alph = max(0.,0.25+0.75*sin((gametic+UnrealHUD(StatusBar).fractic)*6.));
Screen.Dim(Color("FF 40 00"),alph*.25,int((xpos+3)*UnrealHUD(StatusBar).scalev.x),int((ypos+3)*UnrealHUD(StatusBar).scalev.y),int(90*UnrealHUD(StatusBar).scalev.x),int(90*UnrealHUD(StatusBar).scalev.y));
Screen.DrawTexture(DetSpot[0],false,xpos+48,ypos+48,DTA_VirtualWidthF,UnrealHUD(StatusBar).ClipX,DTA_VirtualHeightF,UnrealHUD(StatusBar).ClipY,DTA_KeepRatio,true);
alph = max(0.,0.5+0.5*sin((gametic+UnrealHUD(StatusBar).fractic-10)*6.));
for ( int i=0; i<nearscan.Size(); i++ )
{
Vector2 absofs = level.Vec2Diff(Owner.pos.xy,nearscan[i].pos.xy);
absofs *= (96./1024.);
double ang = Owner.angle-90;
Vector2 relofs = (absofs.x*cos(ang)+absofs.y*sin(ang),-absofs.y*cos(ang)+absofs.x*sin(ang));
if ( max(abs(relofs.x),abs(relofs.y)) > 48. ) continue;
// this is a long line, but it's not the longest I've ever seen
// oh I have seen things... php code that would make you want to stab your eyes with forks...
Screen.DrawTexture(DetSpot[1],false,xpos+48+relofs.x,ypos+48+relofs.y,DTA_VirtualWidthF,UnrealHUD(StatusBar).ClipX,DTA_VirtualHeightF,UnrealHUD(StatusBar).ClipY,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_ClipLeft,int((xpos+3)*UnrealHUD(StatusBar).scalev.x),DTA_ClipTop,int((ypos+3)*UnrealHUD(StatusBar).scalev.y),DTA_ClipRight,int((xpos+93)*UnrealHUD(StatusBar).scalev.x),DTA_ClipBottom,int((ypos+93)*UnrealHUD(StatusBar).scalev.y));
}
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
bActive = !bActive;
if ( bActive ) Owner.A_StartSound("detector/start",CHAN_ITEM);
else Owner.A_StartSound("detector/stop",CHAN_ITEM,volume:.1,attenuation:3.);
return false;
}
override void DoEffect()
{
Super.DoEffect();
if ( bActive && !tracer )
{
tracer = Spawn("DetectorSound",Owner.pos);
tracer.target = Owner;
tracer.master = self;
}
else if ( !bActive && tracer ) tracer.Destroy();
if ( !bActive ) return;
nearscan.Clear();
let bi = BlockThingsIterator.Create(Owner,1024);
while ( bi.Next() )
{
if ( !bi.Thing || (bi.Thing == Owner) || !bi.Thing.bISMONSTER || bi.Thing.Health <= 0 ) continue;
nearscan.Push(bi.Thing);
}
if ( (Charge <= 0) || DrainCharge(1) )
{
Owner.A_StartSound("detector/stop",CHAN_ITEM,volume:.1,attenuation:3.);
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_DETECTOR"));
if ( tracer ) tracer.Destroy();
DepleteOrDestroy();
}
}
States
{
Spawn:
MDET A -1;
Stop;
}
}
Class DetectorSound : Actor
{
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
}
override void Tick()
{
Super.Tick();
if ( !target || !master )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
A_SoundVolume(CHAN_VOICE,target.CheckLocalView()?0.1:0.0);
A_SoundVolume(CHAN_7,!target.CheckLocalView()?0.1:0.0);
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_StartSound("detector/active",CHAN_VOICE,CHANF_LOOPING,.1,ATTN_NONE);
A_StartSound("detector/active",CHAN_7,CHANF_LOOPING,.1,3.);
}
override void OnDestroy()
{
Super.OnDestroy();
A_StopSound(CHAN_VOICE);
A_StopSound(CHAN_7);
}
}
Class SCUBAGear : UnrealInventory
{
int oldwaterlevel;
Default
{
Tag "$T_SCUBA";
Inventory.MaxAmount 1;
Inventory.Icon "I_Scuba";
Inventory.PickupMessage "$I_SCUBA";
Inventory.RespawnTics 700;
UnrealInventory.Charge 4200;
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
bActive = !bActive;
if ( !bActive ) Owner.A_StartSound("scuba/stop",CHAN_ITEM);
return false;
}
override void AttachToOwner( Actor other )
{
Super.AttachToOwner(other);
oldwaterlevel = other.waterlevel;
}
override void AbsorbDamage( int damage, Name damageType, out int newdamage )
{
if ( bActive && (damageType == 'Drowning') )
newdamage = 0;
}
override void DoEffect()
{
Super.DoEffect();
if ( (oldwaterlevel < 2) && (owner.waterlevel > 2) )
{
if ( sting_autoscuba && !bActive ) Use(false);
oldwaterlevel = owner.waterlevel;
}
else if ( (oldwaterlevel > 2) && (owner.waterlevel < 2) )
{
if ( sting_autoscuba && bActive ) Use(false);
oldwaterlevel = owner.waterlevel;
}
if ( bActive && !tracer )
{
tracer = Spawn("SCUBASound",Owner.pos);
tracer.target = Owner;
tracer.master = self;
}
else if ( !bActive && tracer ) tracer.Destroy();
if ( !bActive ) return;
if ( PlayerPawn(Owner) ) PlayerPawn(Owner).ResetAirSupply();
if ( (Charge <= 0) || DrainCharge(1) )
{
Owner.A_StartSound("scuba/stop",CHAN_ITEM);
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_SCUBA"));
if ( tracer ) tracer.Destroy();
DepleteOrDestroy();
}
}
States
{
Spawn:
SCUB A -1;
Stop;
}
}
Class SCUBASound : Actor
{
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
}
override void Tick()
{
Super.Tick();
if ( !target || !master )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
if ( target.CheckLocalView() )
{
A_SoundVolume(CHAN_VOICE,0.0);
A_SoundVolume(CHAN_5,0.0);
A_SoundVolume(CHAN_6,(target.waterlevel<3)?1.0:0.0);
A_SoundVolume(CHAN_7,(target.waterlevel>=3)?1.0:0.0);
}
else
{
A_SoundVolume(CHAN_VOICE,(target.waterlevel<3)?0.25:0.0);
A_SoundVolume(CHAN_5,(target.waterlevel>=3)?0.25:0.0);
A_SoundVolume(CHAN_6,0.0);
A_SoundVolume(CHAN_7,0.0);
}
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_StartSound("scuba/air",CHAN_VOICE,CHANF_LOOPING,.25,1.5);
A_StartSound("scuba/water",CHAN_5,CHANF_LOOPING,.25,1.5);
A_StartSound("scuba/air",CHAN_6,CHANF_LOOPING,1.,ATTN_NONE);
A_StartSound("scuba/water",CHAN_7,CHANF_LOOPING,1.,ATTN_NONE);
}
override void OnDestroy()
{
Super.OnDestroy();
A_StopSound(CHAN_VOICE);
A_StopSound(CHAN_5);
A_StopSound(CHAN_6);
A_StopSound(CHAN_7);
}
}