- Changeable player skins. - Ammo LEDs are now 1:1 with UT by using canvas textures. - Integrate some add-ons, including reskins. - Various fixes (some backported from Demolitionist). - Migrated from libeye to Gutamatics.
620 lines
13 KiB
Text
620 lines
13 KiB
Text
Class UDamage : PowerupGiver
|
|
{
|
|
bool bOldSkin;
|
|
|
|
void A_CheckSkin()
|
|
{
|
|
if ( flak_oldudamage )
|
|
{
|
|
if ( !bOldSkin ) A_ChangeModel("",0,"models/220","UDamage_d.3d",0,"models/220","Judamage1.png");
|
|
bOldSkin = true;
|
|
}
|
|
else
|
|
{
|
|
if ( bOldSkin ) A_ChangeModel("",0,"models","UDamage_d.3d",0,"models","GoldSkin2.png");
|
|
bOldSkin = false;
|
|
}
|
|
}
|
|
|
|
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 A_CheckSkin();
|
|
Wait;
|
|
}
|
|
}
|
|
|
|
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;
|
|
int lasteffect;
|
|
|
|
Default
|
|
{
|
|
Powerup.Duration -60;
|
|
Powerup.Color "EE00FF", 0.05;
|
|
}
|
|
|
|
override void BeginPlay()
|
|
{
|
|
Super.BeginPlay();
|
|
if ( deathmatch ) EffectTics /= 2;
|
|
}
|
|
|
|
override void InitEffect()
|
|
{
|
|
Super.InitEffect();
|
|
lasteffect = int.min;
|
|
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_StartSound("udamage/drain",CHAN_POWERUP2,attenuation:.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 ( gametic < lasteffect ) return;
|
|
if ( EffectTics < 350 ) Owner.A_StartSound("udamage/fire2",CHAN_POWERUP,attenuation:.25);
|
|
else Owner.A_StartSound("udamage/fire1",CHAN_POWERUP,attenuation:.25);
|
|
UTMainHandler.DoFlash(Owner,Color(48,238,0,255),6);
|
|
lasteffect = gametic+5; // prevent excess flash
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
|
|
Class UTInvulnerability : PowerupGiver
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_UTINVUL";
|
|
Inventory.PickupMessage "$I_UTINVUL";
|
|
+COUNTITEM;
|
|
+INVENTORY.AUTOACTIVATE;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
+INVENTORY.BIGPOWERUP;
|
|
Inventory.MaxAmount 0;
|
|
Powerup.Type "UTInvulPower";
|
|
Inventory.PickupSound "uinvul/pickup";
|
|
Inventory.RespawnTics 4200;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
UKEY A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UTInvulLight : DynamicLight
|
|
{
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
Args 255,238,0,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[UInvuln](10,12)*8;
|
|
bDORMANT = Powerup(master).isBlinking();
|
|
}
|
|
}
|
|
|
|
Class UTInvulPower : Powerup
|
|
{
|
|
Actor l;
|
|
int lasteffect;
|
|
|
|
Default
|
|
{
|
|
Powerup.Duration -60;
|
|
Powerup.Color "FFEE00", 0.05;
|
|
}
|
|
|
|
override void BeginPlay()
|
|
{
|
|
Super.BeginPlay();
|
|
if ( deathmatch ) EffectTics /= 2;
|
|
}
|
|
|
|
override void InitEffect()
|
|
{
|
|
Super.InitEffect();
|
|
lasteffect = int.min;
|
|
l = Spawn("UTInvulLight",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_StartSound("uinvul/drain",CHAN_POWERUP2,attenuation:.25);
|
|
}
|
|
|
|
override void EndEffect()
|
|
{
|
|
Super.EndEffect();
|
|
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_UTINVUL"));
|
|
}
|
|
|
|
override bool isBlinking()
|
|
{
|
|
return ((EffectTics <= 175) && (EffectTics%35 >= 30));
|
|
}
|
|
|
|
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive )
|
|
{
|
|
if ( !passive || (damage <= 0) ) return;
|
|
newdamage = 0;
|
|
if ( gametic < lasteffect ) return;
|
|
Owner.A_StartSound("uinvul/hit",CHAN_POWERUP4,attenuation:.25);
|
|
UTMainHandler.DoFlash(Owner,Color(48,255,238,0),6);
|
|
lasteffect = gametic+5; // prevent excess flash
|
|
}
|
|
}
|
|
|
|
// 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 && (GetReplacement(type) == type) ) 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||!target.InStateSequence(target.CurState,target.FindState("Spawn"));
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
INVS A -1 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UTMapRevealer : MapRevealer
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_MAPREVEALER";
|
|
+COUNTITEM;
|
|
+INVENTORY.FANCYPICKUPSOUND;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
Inventory.MaxAmount 0;
|
|
Inventory.PickupSound "misc/p_pkup";
|
|
Inventory.PickupMessage "$I_MAPREVEALER";
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
TRNS ABCDCB 6;
|
|
Loop;
|
|
}
|
|
}
|
|
|
|
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_StartSound("boot/jump",CHAN_POWERUP3);
|
|
}
|
|
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 )
|
|
{
|
|
Inventory.AbsorbDamage(damage,damageType,newdamage);
|
|
}
|
|
override void DoEffect()
|
|
{
|
|
Powerup.DoEffect();
|
|
if ( !flak_radboots )
|
|
DepleteOrDestroy();
|
|
}
|
|
}
|
|
|
|
Class UTNightVision : PowerupGiver
|
|
{
|
|
Default
|
|
{
|
|
Tag "$T_UTVISION";
|
|
Inventory.PickupMessage "$I_UTVISION";
|
|
+COUNTITEM;
|
|
+INVENTORY.AUTOACTIVATE;
|
|
+INVENTORY.ALWAYSPICKUP;
|
|
+INVENTORY.BIGPOWERUP;
|
|
Inventory.MaxAmount 0;
|
|
Powerup.Type "UTVisionPower";
|
|
Inventory.PickupSound "uvision/pickup";
|
|
Inventory.RespawnTics 4200;
|
|
}
|
|
override void PostBeginPlay()
|
|
{
|
|
Super.PostBeginPlay();
|
|
tracer = Spawn("UTNightVisionX",pos);
|
|
tracer.angle = angle;
|
|
tracer.target = self;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
UKEY A -1;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UTNightVisionX : UTInvisibilityX
|
|
{
|
|
Default
|
|
{
|
|
Alpha 0.3;
|
|
}
|
|
States
|
|
{
|
|
Spawn:
|
|
UKEY A -1 Bright;
|
|
Stop;
|
|
}
|
|
}
|
|
|
|
Class UTVisionLight : DynamicLight
|
|
{
|
|
Default
|
|
{
|
|
DynamicLight.Type "Point";
|
|
+DYNAMICLIGHT.SPOT;
|
|
DynamicLight.SpotInnerAngle 60;
|
|
DynamicLight.SpotOuterAngle 90;
|
|
Args 224,238,255,800;
|
|
}
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
if ( !target || !master )
|
|
{
|
|
Destroy();
|
|
return;
|
|
}
|
|
Vector3 x, y, z, origin;
|
|
[x, y, z] = dt_CoordUtil.GetAxes(target.pitch,target.angle,target.roll);
|
|
if ( target.player )
|
|
origin = target.Vec2OffsetZ(0,0,target.player.viewz);
|
|
else origin = target.Vec3Offset(0,0,target.height/2);
|
|
SetOrigin(origin,true);
|
|
angle = target.angle;
|
|
pitch = target.pitch;
|
|
args[LIGHT_INTENSITY] = Random[UVision](40,48)*20;
|
|
bDORMANT = ((players[consoleplayer].Camera != target)||Powerup(master).isBlinking());
|
|
}
|
|
}
|
|
|
|
Class UTVisionPower : Powerup
|
|
{
|
|
Actor l;
|
|
|
|
Default
|
|
{
|
|
Powerup.Duration -90;
|
|
Powerup.Color "AAEEFF", 0.05;
|
|
}
|
|
|
|
override void BeginPlay()
|
|
{
|
|
Super.BeginPlay();
|
|
if ( deathmatch ) EffectTics /= 2;
|
|
}
|
|
|
|
override void InitEffect()
|
|
{
|
|
Super.InitEffect();
|
|
l = Spawn("UTVisionLight",Owner.pos);
|
|
l.target = Owner;
|
|
l.master = self;
|
|
}
|
|
|
|
override void EndEffect()
|
|
{
|
|
Super.EndEffect();
|
|
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_UTVISION"));
|
|
}
|
|
}
|