Flashlight/Searchlight implemented.
Proper handling of charge redistribution on multi-copy items (fixes infinitely replenishable charge exploit). More preparation code for other items.
This commit is contained in:
parent
ee8e612f48
commit
b12c4a4112
17 changed files with 270 additions and 24 deletions
|
|
@ -49,6 +49,22 @@ Class BigAmmo3 : BigAmmo
|
|||
}
|
||||
}
|
||||
|
||||
Class BigBlast : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class HitListEntry
|
||||
{
|
||||
Actor hitactor;
|
||||
Vector3 hitlocation, x;
|
||||
}
|
||||
|
||||
Class BigTracer : LineTracer
|
||||
{
|
||||
Array<HitListEntry> hitlist;
|
||||
double penetration; // please don't laugh
|
||||
}
|
||||
|
||||
Class BigGun : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
Class UFireball : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class UFireball2 : UFireball
|
||||
{
|
||||
}
|
||||
|
||||
Class FlameGun : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ Class SMiniAmmo : Ammo
|
|||
}
|
||||
}
|
||||
|
||||
Class SMiniBlast : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class SMiniGun : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -269,19 +269,17 @@ Class VoiceBox : UnrealInventory
|
|||
Inventory.MaxAmount 3;
|
||||
UnrealInventory.Charge 600;
|
||||
}
|
||||
override void Tick()
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( bActive )
|
||||
Super.DoEffect();
|
||||
if ( !bActive ) return;
|
||||
if ( box ) Charge = box.ReactionTime;
|
||||
else
|
||||
{
|
||||
if ( box ) Charge = box.ReactionTime;
|
||||
else
|
||||
{
|
||||
Charge = DefaultCharge;
|
||||
bActive = false;
|
||||
Amount--;
|
||||
if ( Amount <= 0 ) DepleteOrDestroy();
|
||||
}
|
||||
Charge = DefaultCharge;
|
||||
bActive = false;
|
||||
Amount--;
|
||||
if ( Amount <= 0 ) DepleteOrDestroy();
|
||||
}
|
||||
}
|
||||
override bool Use( bool pickup )
|
||||
|
|
@ -742,6 +740,18 @@ Class DarkFlare : BetaFlare
|
|||
}
|
||||
}
|
||||
|
||||
Class BetaFlareThrown
|
||||
{
|
||||
}
|
||||
|
||||
Class LightFlareThrown : BetaFlareThrown
|
||||
{
|
||||
}
|
||||
|
||||
Class DarkFlareThrown : BetaFlareThrown
|
||||
{
|
||||
}
|
||||
|
||||
Class Dampener : UnrealInventory
|
||||
{
|
||||
static bool Active( Actor Owner )
|
||||
|
|
@ -757,9 +767,9 @@ Class Dampener : UnrealInventory
|
|||
Owner.A_PlaySound(bActive?"dampener/on":"dampener/off",CHAN_ITEM);
|
||||
return false;
|
||||
}
|
||||
override void Tick()
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.Tick();
|
||||
Super.DoEffect();
|
||||
if ( !bActive ) return;
|
||||
if ( DrainCharge(1) )
|
||||
{
|
||||
|
|
@ -929,9 +939,64 @@ Class ForcefieldEffect : Actor
|
|||
}
|
||||
}
|
||||
|
||||
Class UFlashLight1 : DynamicLight
|
||||
{
|
||||
int basecolor[3];
|
||||
Default
|
||||
{
|
||||
DynamicLight.Type "Point";
|
||||
+DynamicLight.SPOT;
|
||||
+DynamicLight.ATTENUATE;
|
||||
+DynamicLight.DONTLIGHTSELF;
|
||||
args 0,0,0,560;
|
||||
DynamicLight.SpotInnerAngle 3;
|
||||
DynamicLight.SpotOuterAngle 10;
|
||||
}
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
if ( !target || !UnrealInventory(master) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
if ( target.player ) SetOrigin((target.pos.x,target.pos.y,target.player.viewz),true);
|
||||
else SetOrigin(target.vec3Offset(0,0,target.height*0.75),true);
|
||||
A_SetAngle(target.angle,SPF_INTERPOLATE);
|
||||
A_SetPitch(target.pitch,SPF_INTERPOLATE);
|
||||
args[LIGHT_RED] = int(basecolor[0]*clamp(UnrealInventory(master).charge/1400.,0.,1.));
|
||||
args[LIGHT_GREEN] = int(basecolor[1]*clamp(UnrealInventory(master).charge/1400.,0.,1.));
|
||||
args[LIGHT_BLUE] = int(basecolor[2]*clamp(UnrealInventory(master).charge/1400.,0.,1.));
|
||||
bDORMANT = (target.health <= 0);
|
||||
if ( Inventory(target) && target.bInvisible ) bDORMANT = true;
|
||||
// alert monsters hit by the light
|
||||
if ( GetClass() != "UFlashLight1" ) return;
|
||||
if ( !bDORMANT && target.player && (target.health > 0) )
|
||||
{
|
||||
BlockThingsIterator bt = BlockThingsIterator.Create(target,args[LIGHT_INTENSITY]);
|
||||
while ( bt.Next() )
|
||||
{
|
||||
if ( !bt.Thing || (Distance3D(bt.Thing) > args[LIGHT_INTENSITY]) ) continue;
|
||||
Vector3 aimdir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
|
||||
Vector3 reldir = Vec3To(bt.Thing).unit();
|
||||
if ( (acos(aimdir dot reldir) < SpotOuterAngle+5) && bt.Thing.CheckSight(target) ) bt.Thing.LastHeard = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Class UFlashLight2 : UFlashLight1
|
||||
{
|
||||
Default
|
||||
{
|
||||
args 0,0,0,600;
|
||||
DynamicLight.SpotInnerAngle 0;
|
||||
DynamicLight.SpotOuterAngle 20;
|
||||
}
|
||||
}
|
||||
|
||||
Class UFlashlight : UnrealInventory
|
||||
{
|
||||
Actor lt[3];
|
||||
UFlashLight1 lt[2];
|
||||
|
||||
Default
|
||||
{
|
||||
|
|
@ -941,6 +1006,66 @@ Class UFlashlight : UnrealInventory
|
|||
Inventory.PickupMessage "$I_FLASHLIGHT";
|
||||
UnrealInventory.Charge 2800;
|
||||
}
|
||||
virtual void SetupLights()
|
||||
{
|
||||
lt[0].basecolor[0] = 255;
|
||||
lt[0].basecolor[1] = 240;
|
||||
lt[0].basecolor[2] = 224;
|
||||
lt[1].basecolor[0] = 128;
|
||||
lt[1].basecolor[1] = 120;
|
||||
lt[1].basecolor[2] = 112;
|
||||
}
|
||||
override bool Use( bool pickup )
|
||||
{
|
||||
if ( pickup ) return false;
|
||||
bActive = !bActive;
|
||||
Owner.A_PlaySound(bActive?"lite/pickup":"lite/off",CHAN_ITEM);
|
||||
if ( bActive )
|
||||
{
|
||||
if ( !lt[0] ) lt[0] = UFlashLight1(Spawn("UFlashLight1",owner.pos));
|
||||
lt[0].target = owner;
|
||||
lt[0].master = self;
|
||||
if ( !lt[1] ) lt[1] = UFlashLight1(Spawn("UFlashLight2",owner.pos));
|
||||
lt[1].target = owner;
|
||||
lt[1].master = self;
|
||||
SetupLights();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( lt[0] ) lt[0].Destroy();
|
||||
if ( lt[1] ) lt[1].Destroy();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.DoEffect();
|
||||
if ( !bActive ) return;
|
||||
if ( DrainCharge(1) )
|
||||
{
|
||||
Owner.A_PlaySound("lite/off",CHAN_ITEM);
|
||||
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_FLASHLIGHT"));
|
||||
if ( Amount <= 0 ) DepleteOrDestroy();
|
||||
}
|
||||
}
|
||||
override void DetachFromOwner()
|
||||
{
|
||||
Super.DetachFromOwner();
|
||||
if ( lt[0] ) lt[0].Destroy();
|
||||
if ( lt[1] ) lt[1].Destroy();
|
||||
}
|
||||
override void Travelled()
|
||||
{
|
||||
Super.Travelled();
|
||||
if ( !bActive ) return;
|
||||
if ( !lt[0] ) lt[0] = UFlashLight1(Spawn("UFlashLight1",owner.pos));
|
||||
lt[0].target = owner;
|
||||
lt[0].master = self;
|
||||
if ( !lt[1] ) lt[1] = UFlashLight1(Spawn("UFlashLight2",owner.pos));
|
||||
lt[1].target = owner;
|
||||
lt[1].master = self;
|
||||
SetupLights();
|
||||
}
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
@ -960,6 +1085,31 @@ Class USearchlight : UFlashlight
|
|||
Inventory.RespawnTics 1050;
|
||||
UnrealInventory.Charge 70000;
|
||||
}
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.DoEffect();
|
||||
if ( !bActive ) return;
|
||||
if ( DrainCharge(1) )
|
||||
{
|
||||
Owner.A_PlaySound("lite/off",CHAN_ITEM);
|
||||
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_SEARCHLIGHT"));
|
||||
if ( Amount <= 0 ) DepleteOrDestroy();
|
||||
}
|
||||
}
|
||||
override void SetupLights()
|
||||
{
|
||||
lt[0].basecolor[0] = 255;
|
||||
lt[0].basecolor[1] = 224;
|
||||
lt[0].basecolor[2] = 192;
|
||||
lt[0].SpotInnerAngle = 20;
|
||||
lt[0].SpotOuterAngle = 35;
|
||||
lt[0].args[3] = 750;
|
||||
lt[1].basecolor[0] = 128;
|
||||
lt[1].basecolor[1] = 112;
|
||||
lt[1].basecolor[2] = 96;
|
||||
lt[1].SpotOuterAngle = 50;
|
||||
lt[1].args[3] = 780;
|
||||
}
|
||||
}
|
||||
|
||||
Class SentryItem : UnrealInventory
|
||||
|
|
|
|||
|
|
@ -19,6 +19,14 @@ Class FlameAmmo : Ammo
|
|||
}
|
||||
}
|
||||
|
||||
Class UFlame : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class UNapalm : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class UFlamethrower : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@ Class PeaceAmmo : Ammo
|
|||
}
|
||||
}
|
||||
|
||||
Class PeaceRocket : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class PeaceProj : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class Peacemaker : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ Class UShells2 : UShells
|
|||
}
|
||||
}
|
||||
|
||||
Class QCasing : UCasing
|
||||
{
|
||||
}
|
||||
|
||||
Class QuadShot : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -24,6 +24,14 @@ Class RazorAmmo : Ammo
|
|||
}
|
||||
}
|
||||
|
||||
Class RazorBlade : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class RazorBladeAlt : RazorBlade
|
||||
{
|
||||
}
|
||||
|
||||
Class Razorjack : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ Class StunnerAmmo : Ammo
|
|||
}
|
||||
}
|
||||
|
||||
Class StunTrail : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class StunProj : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class Stunner : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -40,6 +40,18 @@ Class UBioAmmo2 : UBioAmmo
|
|||
}
|
||||
}
|
||||
|
||||
Class UBioGel : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class UBioGlob : UBioGel
|
||||
{
|
||||
}
|
||||
|
||||
Class UBioSplash : UBioGel
|
||||
{
|
||||
}
|
||||
|
||||
Class UBioRifle : UnrealWeapon
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
|
|
@ -616,14 +616,28 @@ Class UnrealInventory : Inventory
|
|||
override void AttachToOwner( Actor other )
|
||||
{
|
||||
Super.AttachToOwner(other);
|
||||
Charge = DefaultCharge;
|
||||
if ( !Charge ) Charge = DefaultCharge;
|
||||
InterHubAmount = MaxAmount; // it's annoying to set this per-subclass
|
||||
}
|
||||
override bool HandlePickup( Inventory item )
|
||||
{
|
||||
if ( (item.GetClass() == GetClass()) && ((MaxAmount > 1) || (DefaultCharge > 0)) )
|
||||
{
|
||||
if ( MaxAmount > 1 ) Amount = min(MaxAmount,Amount+item.Amount);
|
||||
if ( MaxAmount > 1 )
|
||||
{
|
||||
if ( UnrealInventory(item).Charge ) // redistribute charge among copies
|
||||
{
|
||||
int addcharge = Charge+UnrealInventory(item).Charge;
|
||||
charge = min(DefaultCharge,addcharge);
|
||||
// if there's charge to spare, increase amount
|
||||
if ( addcharge > charge )
|
||||
{
|
||||
Amount = min(MaxAmount,Amount+item.Amount);
|
||||
charge = addcharge-charge;
|
||||
}
|
||||
}
|
||||
else Amount = min(MaxAmount,Amount+item.Amount); // fully charged new copy, just increase
|
||||
}
|
||||
else Charge = DefaultCharge; // reset charge
|
||||
item.bPickupGood = true;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ Class UInvisibility : UnrealInventory
|
|||
else Owner.TakeInventory("PowerUInvisibility",1);
|
||||
return false;
|
||||
}
|
||||
override void Tick()
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.Tick();
|
||||
Super.DoEffect();
|
||||
if ( !bActive ) return;
|
||||
if ( special1 == -1 )
|
||||
{
|
||||
|
|
@ -116,9 +116,9 @@ Class Amplifier : UnrealInventory
|
|||
Owner.A_PlaySound("amplifier/set",CHAN_ITEM);
|
||||
return false;
|
||||
}
|
||||
override void Tick()
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.Tick();
|
||||
Super.DoEffect();
|
||||
if ( bActive && !tracer )
|
||||
{
|
||||
tracer = Spawn("AmpSound",Owner.pos);
|
||||
|
|
@ -208,9 +208,9 @@ Class UJumpBoots : UnrealInventory
|
|||
else Owner.TakeInventory("PowerJumpBoots_HighJump",1);
|
||||
return false;
|
||||
}
|
||||
override void Tick()
|
||||
override void DoEffect()
|
||||
{
|
||||
Super.Tick();
|
||||
Super.DoEffect();
|
||||
if ( !Owner || !Owner.player ) return;
|
||||
draincnt++;
|
||||
if ( (draincnt >= 700) || (bActive && (owner.player.jumptics == -1)) )
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ Class UTranslocatorAmmo : Ammo
|
|||
}
|
||||
}
|
||||
|
||||
Class UTranslocatorModule : Actor
|
||||
{
|
||||
}
|
||||
|
||||
Class UTranslocator : UnrealWeapon
|
||||
{
|
||||
override bool TryPickup( in out Actor toucher )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue