Proper handling of charge redistribution on multi-copy items (fixes infinitely replenishable charge exploit). More preparation code for other items.
310 lines
6.3 KiB
Text
310 lines
6.3 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 2;
|
|
UnrealInventory.Charge 100;
|
|
}
|
|
override bool Use( bool pickup )
|
|
{
|
|
if ( pickup ) return false;
|
|
bActive = !bActive;
|
|
if ( bActive )
|
|
{
|
|
Owner.A_PlaySound("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 OnDrop( Actor dropper )
|
|
{
|
|
Super.OnDrop(dropper);
|
|
dropper.TakeInventory("PowerUInvisibility",1);
|
|
}
|
|
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 2;
|
|
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));
|
|
d.DrainCharge(val);
|
|
return Multiplier;
|
|
}
|
|
override bool Use( bool pickup )
|
|
{
|
|
if ( pickup ) return false;
|
|
bActive = !bActive;
|
|
Owner.A_PlaySound("amplifier/set",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 ( (Charge <= 0) || (!(level.maptime%35) && DrainCharge(2)) )
|
|
{
|
|
Owner.A_PlaySound("amplifier/set",CHAN_ITEM);
|
|
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_AMPLIFIER"));
|
|
if ( tracer ) tracer.Destroy();
|
|
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_PlaySound("amplifier/act",CHAN_VOICE,0.25,true,1.5);
|
|
A_PlaySound("amplifier/act",CHAN_7,1.0,true,ATTN_NONE);
|
|
}
|
|
override void OnDestroy()
|
|
{
|
|
Super.OnDestroy();
|
|
A_StopSound(CHAN_VOICE);
|
|
A_StopSound(CHAN_7);
|
|
}
|
|
}
|
|
|
|
Class UJumpBoots : UnrealInventory
|
|
{
|
|
int draincnt;
|
|
Default
|
|
{
|
|
Tag "$T_JUMPBOOTS";
|
|
+COUNTITEM;
|
|
+INVENTORY.BIGPOWERUP;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
Inventory.MaxAmount 3;
|
|
Inventory.Icon "I_Boots";
|
|
Inventory.PickupMessage "$I_JUMPBOOTS";
|
|
Inventory.RespawnTics 1050;
|
|
UnrealInventory.Charge 3;
|
|
}
|
|
override bool Use( bool pickup )
|
|
{
|
|
if ( pickup ) return false;
|
|
bActive = !bActive;
|
|
Owner.A_PlaySound("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_PlaySound("boot/jump",CHAN_BODY);
|
|
}
|
|
else if ( (charge <= 0) && owner.player.onground )
|
|
{
|
|
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_JUMPBOOTS"));
|
|
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")) ) 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 ) foundswim = true;
|
|
if ( !s.DamageInterval || !s.DamageAmount ) continue;
|
|
if ( s.DamageType == 'Slime' ) foundslime = true;
|
|
else if ( s.DamageType == 'Fire' ) foundlava = true;
|
|
}
|
|
// TODO replace self with asbestos/toxin suits or scuba
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
Class MotionDetector : UnrealInventory
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_DETECTOR";
|
|
+COUNTITEM;
|
|
+INVENTORY.BIGPOWERUP;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
Inventory.MaxAmount 1;
|
|
Inventory.Icon "I_Detect";
|
|
Inventory.PickupMessage "$I_DETECTOR";
|
|
Inventory.RespawnTics 1050;
|
|
UnrealInventory.Charge 3500;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
MDET A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class SCUBAGear : UnrealInventory
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_SCUBA";
|
|
Inventory.MaxAmount 1;
|
|
Inventory.Icon "I_Scuba";
|
|
Inventory.PickupMessage "$I_SCUBA";
|
|
Inventory.RespawnTics 700;
|
|
UnrealInventory.Charge 4200;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
SCUB A -1;
|
|
Stop;
|
|
}
|
|
}
|