flak_m/zscript/powerups.zsc
Marisa Kirisame a3449b5c5b This branch is a staging area for changes that will make it to devel once they are fully implemented.
Everything in here is highly unstable and may not work.
Current commit contains various new features for the HUD, some cleanup, and additional changes for compatibility with Doomreal as it is developed.
The diff is kinda fucky on the font restructure due to flaky rename detection.
2019-08-31 03:12:46 +02:00

548 lines
13 KiB
Text

Class UDamage : PowerupGiver
{
Default
{
Tag "$T_UDAMAGE";
Inventory.PickupMessage "$I_UDAMAGE";
+COUNTITEM;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.ALWAYSPICKUP;
+INVENTORY.BIGPOWERUP;
Inventory.MaxAmount 0;
Powerup.Type "DamageAmplifier";
Inventory.PickupSound "udamage/pickup";
Inventory.RespawnTics 4200;
}
States
{
Spawn:
UDAM A -1;
Stop;
}
}
Class DamageAmpLight : DynamicLight
{
Default
{
DynamicLight.Type "Point";
Args 238,0,255,80;
}
override void Tick()
{
Super.Tick();
if ( !target || !master )
{
Destroy();
return;
}
if ( target.player )
SetOrigin(target.Vec2OffsetZ(0,0,target.player.viewz),true);
else SetOrigin(target.Vec3Offset(0,0,target.height/2),true);
args[LIGHT_INTENSITY] = Random[UDamage](10,12)*8;
bDORMANT = Powerup(master).isBlinking();
}
}
Class DamageAmplifier : Powerup
{
Actor l;
Default
{
Powerup.Duration -60;
Powerup.Color "EE00FF", 0.05;
}
override void BeginPlay()
{
Super.BeginPlay();
if ( deathmatch ) EffectTics /= 2;
}
override void InitEffect()
{
Super.InitEffect();
l = Spawn("DamageAmpLight",Owner.pos);
l.target = Owner;
l.master = self;
}
override void DoEffect()
{
Super.DoEffect();
if ( (EffectTics == 175) || (EffectTics == 140) || (EffectTics == 105) || (EffectTics == 70) || (EffectTics == 35) )
Owner.A_PlaySound("udamage/drain",CHAN_7,1.0,false,0.25);
}
override void EndEffect()
{
Super.EndEffect();
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_UDAMAGE"));
}
override bool isBlinking()
{
return ((EffectTics <= 175) && (EffectTics%35 >= 30));
}
void FireEffect()
{
if ( EffectTics < 350 ) Owner.A_PlaySound("udamage/fire2",CHAN_7,1.0,false,0.25);
else Owner.A_PlaySound("udamage/fire1",CHAN_7,1.0,false,0.25);
UTMainHandler.DoFlash(Owner,Color(96,238,0,255),10);
}
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive )
{
if ( passive || (damage <= 0) ) return;
newdamage = max(1,ApplyDamageFactors(GetClass(),damageType,damage,damage*3));
if ( !(Owner.player.ReadyWeapon is 'UTWeapon') ) FireEffect();
}
}
// Backpack that only gives ammo for valid weapons
Class UTBackpack : BackpackItem
{
override Inventory CreateCopy( Actor other )
{
// Find every unique type of ammoitem. Give it to the player if
// he doesn't have it already, and double its maximum capacity.
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
let type = (class<Ammo>)(AllActorClasses[i]);
if ( !type || (type.GetParentClass() != 'Ammo') ) continue;
// check that it's for a valid weapon
bool isvalid = false;
for ( int j=0; j<AllActorClasses.Size(); j++ )
{
let type2 = (class<Weapon>)(AllActorClasses[j]);
if ( !type2 ) continue;
let rep = GetReplacement(type2);
if ( (rep != type2) && !(rep is "DehackedPickup") ) continue;
readonly<Weapon> weap = GetDefaultByType(type2);
if ( !other.player || !other.player.weapons.LocateWeapon(type2) || weap.bCheatNotWeapon ) continue;
if ( (weap.AmmoType1 == type) || (weap.AmmoType2 == type) )
{
isvalid = true;
break;
}
}
// sneaky fix for chainsaw ammo
if ( (type is 'ChainsawAmmo') && flak_sawammo ) isvalid = true;
if ( !isvalid ) continue;
let ammoitem = Ammo(other.FindInventory(type));
int amount = GetDefaultByType(type).BackpackAmount;
// extra ammo in baby mode and nightmare mode
if ( !bIgnoreSkill ) amount = int(amount*G_SkillPropertyFloat(SKILLP_AmmoFactor));
if ( amount < 0 ) amount = 0;
if ( !ammoitem )
{
// The player did not have the ammoitem. Add it.
ammoitem = Ammo(Spawn(type));
ammoitem.Amount = bDepleted?0:amount;
if ( ammoitem.BackpackMaxAmount > ammoitem.MaxAmount )
ammoitem.MaxAmount = ammoitem.BackpackMaxAmount;
if ( ammoitem.Amount > ammoitem.MaxAmount )
ammoitem.Amount = ammoitem.MaxAmount;
ammoitem.AttachToOwner(other);
}
else
{
// The player had the ammoitem. Give some more.
if ( ammoitem.MaxAmount < ammoitem.BackpackMaxAmount )
ammoitem.MaxAmount = ammoitem.BackpackMaxAmount;
if ( !bDepleted && (ammoitem.Amount < ammoitem.MaxAmount) )
{
ammoitem.Amount += amount;
if ( ammoitem.Amount > ammoitem.MaxAmount )
ammoitem.Amount = ammoitem.MaxAmount;
}
}
}
return Inventory.CreateCopy(other);
}
override bool HandlePickup (Inventory item)
{
// Since you already have a backpack, that means you already have every
// kind of ammo in your inventory, so we don't need to look at the
// entire PClass list to discover what kinds of ammo exist, and we don't
// have to alter the MaxAmount either.
if ( item is 'BackpackItem' )
{
for ( let probe = Owner.Inv; probe; probe = probe.Inv )
{
if ( probe.GetParentClass() != 'Ammo' ) continue;
if ( probe.Amount >= probe.MaxAmount && !sv_unlimited_pickup ) continue;
int amount = Ammo(probe).Default.BackpackAmount;
// extra ammo in baby mode and nightmare mode
if ( !bIgnoreSkill )
amount = int(amount*G_SkillPropertyFloat(SKILLP_AmmoFactor));
probe.Amount += amount;
if ( (probe.Amount > probe.MaxAmount) && !sv_unlimited_pickup )
probe.Amount = probe.MaxAmount;
}
// The pickup always succeeds, even if you didn't get anything
item.bPickupGood = true;
return true;
}
return false;
}
Default
{
Tag "$T_BACKPACK";
Inventory.PickupMessage "$I_BACKPACK";
Inventory.RespawnTics 2100;
}
States
{
Spawn:
BPAK A -1;
Stop;
}
}
Class PowerUTInvisibility : PowerInvisibility
{
Default
{
Powerup.Duration -100;
Powerup.Strength 90;
Powerup.Mode "Additive";
Powerup.Color "FFFFFF", 0.1;
}
override void BeginPlay()
{
Super.BeginPlay();
if ( deathmatch ) EffectTics /= 2;
}
override void EndEffect()
{
Super.EndEffect();
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_INVISIBILITY"));
}
}
Class UTInvisibility : PowerupGiver
{
Default
{
Tag "$T_INVISIBILITY";
+COUNTITEM;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.ALWAYSPICKUP;
+INVENTORY.BIGPOWERUP;
Inventory.MaxAmount 0;
Powerup.Type "PowerUTInvisibility";
Inventory.PickupMessage "$I_INVISIBILITY";
Inventory.PickupSound "invis/pickup";
Inventory.RespawnTics 4200;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
tracer = Spawn("UTInvisibilityX",pos);
tracer.angle = angle;
tracer.target = self;
}
States
{
Spawn:
INVS A -1;
Stop;
}
}
Class UTInvisibilityX : Actor
{
Default
{
RenderStyle "Add";
+NOGRAVITY;
+NOCLIP;
+DONTSPLASH;
Radius 0.1;
Height 0;
}
override void Tick()
{
Super.Tick();
if ( !target )
{
Destroy();
return;
}
Warp(target,flags:WARPF_COPYINTERPOLATION|WARPF_NOCHECKPOSITION);
bInvisible = target.bInvisible;
}
States
{
Spawn:
INVS A -1 Bright;
Stop;
}
}
Class UTMapRevealer : MapRevealer
{
Default
{
+COUNTITEM;
+INVENTORY.FANCYPICKUPSOUND;
+INVENTORY.ALWAYSPICKUP;
Inventory.MaxAmount 0;
Inventory.PickupSound "trans/pickup";
Inventory.PickupMessage "$I_MAPREVEALER";
}
States
{
Spawn:
TRNS A -1;
Stop;
}
}
Class UTJumpBoots : Inventory
{
Default
{
Tag "$T_JUMPBOOTS";
+INVENTORY.AUTOACTIVATE;
+INVENTORY.ALWAYSPICKUP;
Inventory.Amount 2100;
Inventory.MaxAmount 2100;
Inventory.InterHubAmount 2100;
Inventory.PickupMessage "$I_JUMPBOOTS";
Inventory.PickupSound "boot/pickup";
Inventory.RespawnTics 1050;
}
override bool Use( bool pickup )
{
if ( pickup )
{
Owner.GiveInventory("PowerJumpBoots_HighJump",1);
if ( flak_radboots )
Owner.GiveInventory("PowerJumpBoots_IronFeet",1);
}
return false;
}
override void Tick()
{
Super.Tick();
if ( !Owner || !Owner.player ) return;
if ( flak_radboots )
amount--;
if ( (amount > 0) && (owner.player.jumptics == -1) )
{
Amount = max(0,Amount-700);
Owner.A_PlaySound("boot/jump",CHAN_BODY);
}
else if ( (Amount <= 0) && owner.player.onground )
{
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_JUMPBOOTS"));
DepleteOrDestroy();
}
}
override void DetachFromOwner()
{
Super.DetachFromOwner();
Owner.TakeInventory("PowerJumpBoots_HighJump",1);
Owner.TakeInventory("PowerJumpBoots_IronFeet",1);
}
override void OwnerDied()
{
Super.OwnerDied();
DepleteOrDestroy();
}
States
{
Spawn:
JBUT A -1;
Stop;
}
}
Class PowerJumpBoots_HighJump : PowerHighJump
{
Default
{
Powerup.Strength 3;
Powerup.Duration int.max;
+INVENTORY.PERSISTENTPOWER;
}
}
Class PowerJumpBoots_IronFeet : PowerIronFeet
{
Default
{
Powerup.Duration int.max;
Powerup.Color "00 00 00", 0.0;
+INVENTORY.PERSISTENTPOWER;
}
override void AbsorbDamage( int damage, Name damageType, out int newdamage )
{
}
override void DoEffect()
{
Powerup.DoEffect();
if ( !flak_radboots )
DepleteOrDestroy();
}
}
Class Searchlight : Inventory
{
Actor lt[3];
int ticcnt;
Default
{
Tag "$T_SEARCHLIGHT";
+COUNTITEM;
+INVENTORY.UNTOSSABLE;
+INVENTORY.FANCYPICKUPSOUND;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.ALWAYSPICKUP;
Inventory.Amount 200;
Inventory.MaxAmount 200;
Inventory.InterHubAmount 0;
Inventory.PickupMessage "$I_SEARCHLIGHT";
Inventory.PickupSound "lite/pickup";
Inventory.RespawnTics 1050;
}
override bool Use( bool pickup )
{
if ( !lt[0] ) lt[0] = Spawn("mkLight");
lt[0].target = owner;
lt[0].master = self;
if ( !lt[1] ) lt[1] = Spawn("mkLight2");
lt[1].target = owner;
lt[1].master = self;
if ( !lt[2] ) lt[2] = Spawn("mkLight3");
lt[2].target = owner;
lt[2].master = self;
return Super.Use(pickup);
}
override void DetachFromOwner()
{
Super.DetachFromOwner();
if ( lt[0] ) lt[0].Destroy();
if ( lt[1] ) lt[1].Destroy();
if ( lt[2] ) lt[2].Destroy();
}
override void DoEffect()
{
Super.DoEffect();
if ( !Owner ) return;
if ( ticcnt++ < TICRATE ) return;
ticcnt = 0;
if ( --Amount <= 0 )
{
if ( Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_SEARCHLIGHT"));
DepleteOrDestroy();
}
}
States
{
Spawn:
SLIT A -1;
Stop;
}
}
/* hello, Soundless Mound copypasted lights */
Class mkLight : DynamicLight
{
int basecolor[3];
Default
{
DynamicLight.Type "Point";
+DynamicLight.SPOT;
+DynamicLight.ATTENUATE;
+DynamicLight.DONTLIGHTSELF;
args 255,224,160,300;
DynamicLight.SpotInnerAngle 20;
DynamicLight.SpotOuterAngle 35;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
basecolor[0] = args[LIGHT_RED];
basecolor[1] = args[LIGHT_GREEN];
basecolor[2] = args[LIGHT_BLUE];
}
override void Tick()
{
Super.Tick();
if ( !target || !Inventory(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(Inventory(master).amount/40.,0.,1.));
args[LIGHT_GREEN] = int(basecolor[1]*clamp(Inventory(master).amount/40.,0.,1.));
args[LIGHT_BLUE] = int(basecolor[2]*clamp(Inventory(master).amount/40.,0.,1.));
bDORMANT = (target.health <= 0);
if ( Inventory(target) && target.bInvisible ) bDORMANT = true;
// alert monsters hit by the light
if ( GetClass() != "mkLight" ) 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 mkLight2 : mkLight
{
Default
{
args 128,112,96,300;
DynamicLight.SpotInnerAngle 0;
DynamicLight.SpotOuterAngle 50;
}
}
Class mkLight3 : DynamicLight
{
int basecolor[3];
Default
{
DynamicLight.Type "Point";
+DynamicLight.ATTENUATE;
args 32,28,24,0;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
basecolor[0] = args[LIGHT_RED];
basecolor[1] = args[LIGHT_GREEN];
basecolor[2] = args[LIGHT_BLUE];
}
override void Tick()
{
Super.Tick();
if ( !target || Inventory(target) || !Inventory(master) )
{
Destroy();
return;
}
args[LIGHT_RED] = int(basecolor[0]*clamp(Inventory(master).amount/40.,0.,1.));
args[LIGHT_GREEN] = int(basecolor[1]*clamp(Inventory(master).amount/40.,0.,1.));
args[LIGHT_BLUE] = int(basecolor[2]*clamp(Inventory(master).amount/40.,0.,1.));
SetOrigin(target.vec3Offset(0,0,target.height*0.5),true);
}
}