Some more progress here:

- Added all armor and health items.
 - Added Grilled Cheese Sandwich and Ghost Artifact.
 - Started work on Chanceboxes, just need to finish adding the drop lists.
 - Fixed Ammo division.
 - Reduced backpack amounts of some ammo types.
 - Added inventory box/bar to HUD, plus armor and powerup display.
 - Fix jumps still alerting monsters even if not boosting.
 - Added "future plans" document.
This commit is contained in:
Mari the Deer 2020-02-03 22:16:06 +01:00
commit 0fa6207cb6
41 changed files with 2031 additions and 52 deletions

View file

@ -7,7 +7,6 @@ Mixin Class SWWMAmmo
{
let copy = Inventory(Spawn(type,Owner.Pos,NO_REPLACE));
if ( !copy ) return null;
copy.MaxAmount = MaxAmount;
copy.DropTime = 30;
copy.bSpecial = copy.bSolid = false;
copy.SetOrigin(Owner.Vec3Offset(0,0,10.),false);
@ -137,8 +136,8 @@ Mixin Class SWWMAmmo
double ang = FRandom[Junk](0,360);
last = DoDrop(ammotypes[i]);
last.SetOrigin(item.pos,false);
last.vel.xy = (cos(ang),sin(ang))*FRandom[Junk](.2,.5);
excess -= 16;
last.vel.xy = (cos(ang),sin(ang))*FRandom[Junk](2,5);
excess -= def.Amount;
break;
}
}
@ -492,7 +491,7 @@ Class EvisceratorShell : Ammo
Stamina 2500;
Inventory.Amount 1;
Inventory.MaxAmount 30;
Ammo.BackpackAmount 6;
Ammo.BackpackAmount 3;
Ammo.DropAmount 3;
+FLOATBOB;
FloatBobStrength 0.25;
@ -529,7 +528,7 @@ Class HellblazerMissiles : Ammo
Stamina 6000;
Inventory.Amount 1;
Inventory.MaxAmount 60;
Ammo.BackpackAmount 18;
Ammo.BackpackAmount 3;
Ammo.DropAmount 3;
+FLOATBOB;
FloatBobStrength 0.25;
@ -561,7 +560,7 @@ Class HellblazerCrackshots : Ammo
Stamina 8000;
Inventory.Amount 1;
Inventory.MaxAmount 24;
Ammo.BackpackAmount 6;
Ammo.BackpackAmount 2;
Ammo.DropAmount 2;
+FLOATBOB;
FloatBobStrength 0.25;
@ -593,7 +592,7 @@ Class HellblazerRavagers : Ammo
Stamina 12000;
Inventory.Amount 1;
Inventory.MaxAmount 9;
Ammo.BackpackAmount 3;
Ammo.BackpackAmount 1;
Ammo.DropAmount 1;
+FLOATBOB;
FloatBobStrength 0.25;
@ -784,6 +783,8 @@ Class AmmoFabricator : Inventory abstract
{
+INVENTORY.INVBAR;
+FLOATBOB;
Inventory.MaxAmount 32;
Inventory.InterHubAmount 32;
FloatBobStrength 0.25;
}
States

View file

@ -1 +1,146 @@
// All the armor items go here
Class ArmorNugget : SWWMArmor
{
Default
{
Inventory.Icon "graphics/HUD/Icons/I_ArmorNugget.png";
Inventory.Amount 5;
Inventory.MaxAmount 200;
Inventory.InterHubAmount 200;
SWWMArmor.ArmorPriority 10;
SWWMArmor.DrainFactor .1;
SWWMArmor.GiverArmor "ArmorNuggetItem";
}
override int HandleDamage( int damage, Name damageType, int flags )
{
double factor = amount*.01;
return int(ceil(damage*factor));
}
}
Class ArmorNuggetItem : SWWMSpareArmor
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"Nugget");
return Super.CreateCopy(other);
}
Default
{
Tag "$T_NUGGETA";
Inventory.Icon "graphics/HUD/Icons/I_ArmorNugget.png";
Inventory.PickupMessage "$T_NUGGETA";
Inventory.MaxAmount int.max;
Inventory.InterHubAmount int.max;
Inventory.UseSound "misc/armor_pkup";
SWWMSpareArmor.GiveArmor "ArmorNugget";
+INVENTORY.ALWAYSPICKUP;
+COUNTITEM;
}
States
{
Spawn:
XZW1 # -1 NoDelay
{
frame = Random[Nugget](0,7);
}
Stop;
Dummy:
XZW1 ABCDEFGH -1;
Stop;
}
}
Class BlastSuit : SWWMArmor
{
Default
{
Inventory.Icon "graphics/HUD/Icons/I_BlastSuit.png";
Inventory.Amount 500;
Inventory.MaxAmount 500;
Inventory.InterHubAmount 500;
SWWMArmor.ArmorPriority 2;
SWWMArmor.DrainFactor 1.;
SWWMArmor.DrainMessage "$D_BLASTSUIT";
SWWMArmor.GiverArmor "BlastSuitItem";
}
override int HandleDamage( int damage, Name damageType, int flags )
{
double factor = .75;
if ( flags&DMG_EXPLOSION ) factor = 1.-(1.-factor)*.5;
return int(ceil(damage*factor));
}
}
Class BlastSuitItem : SWWMSpareArmor
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"BlastSuit");
return Super.CreateCopy(other);
}
Default
{
Tag "$T_BLASTSUIT";
Inventory.Icon "graphics/HUD/Icons/I_BlastSuit.png";
Inventory.PickupMessage "$T_BLASTSUIT";
Inventory.UseSound "armor/blastsuit";
SWWMSpareArmor.GiveArmor "BlastSuit";
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}
Class WarArmor : SWWMArmor
{
Default
{
Inventory.Icon "graphics/HUD/Icons/I_WarArmor.png";
Inventory.Amount 1000;
Inventory.MaxAmount 1000;
Inventory.InterHubAmount 1000;
SWWMArmor.ArmorPriority 6;
SWWMArmor.DrainFactor 1.0;
SWWMArmor.DrainMessage "$D_WARARMOR";
SWWMArmor.GiverArmor "WarArmorItem";
}
override int HandleDamage( int damage, Name damageType, int flags )
{
double factor;
// should be enough "elemental" damage types I guess
if ( (damageType == 'Fire') || (damageType == 'Ice') || (damageType == 'Slime') || (damageType == 'Lightning') || (damageType == 'Wind') || (damageType == 'Water') ) factor = .9;
else factor = .8;
if ( flags&DMG_EXPLOSION ) factor = 1.-(1.-factor)*.7;
return int(ceil(damage*factor));
}
}
Class WarArmorItem : SWWMSpareArmor
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"WarArmor");
return Super.CreateCopy(other);
}
Default
{
Tag "$T_WARARMOR";
Inventory.Icon "graphics/HUD/Icons/I_WarArmor.png";
Inventory.PickupMessage "$T_WARARMOR";
Inventory.UseSound "armor/wararmor";
SWWMSpareArmor.GiveArmor "WarArmor";
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}

516
zscript/swwm_chancebox.zsc Normal file
View file

@ -0,0 +1,516 @@
// gacha nonsense
Class Chancebox : Inventory abstract
{
Class<Actor> dropclass;
Property DropClass : dropclass;
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"Lootbox");
return Super.CreateCopy(other);
}
override bool Use( bool pickup )
{
if ( pickup ) return false;
Vector3 x, y, z;
[x, y, z] = swwm_CoordUtil.GetAxes(Owner.pitch,Owner.angle,Owner.roll);
Vector3 origin = level.Vec3Offset(Owner.Vec2OffsetZ(0,0,Owner.player.viewz),x*20-z*8);
if ( !level.IsPointInLevel(origin) ) return false;
let b = Spawn(dropclass,origin);
if ( !b ) return false;
if ( !b.TestMobjLocation() )
{
b.Destroy();
return false;
}
b.angle = Owner.angle-180;
b.vel = x*10;
b.vel.z += 2.;
return true;
}
Default
{
+INVENTORY.INVBAR;
+FLOATBOB;
Inventory.MaxAmount 32;
Inventory.InterHubAmount 32;
FloatBobStrength 0.25;
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}
// top side of chancebox, shoots upwards
Class ChanceTop : Actor abstract
{
Default
{
Radius 16;
Height 4;
+MISSILE;
+THRUACTORS;
+NOGRAVITY;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
vel = (0,0,20);
}
States
{
Spawn:
XZW1 A 1
{
double magvel = vel.length();
if ( magvel > 0. )
{
magvel = min(60,magvel*1.2);
vel = vel.unit()*magvel;
}
}
Wait;
Death:
TNT1 A 1 A_SpawnItemEx("ExplodiumBulletImpact");
Stop;
}
}
// left/right side of chancebox, shoots forward
Class ChanceSide : Actor abstract
{
Default
{
Radius 16;
Height 32;
+MISSILE;
+THRUACTORS;
+NOGRAVITY;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
vel = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch))*20;
}
States
{
Spawn:
XZW1 A 1
{
double magvel = vel.length();
if ( magvel > 0. )
{
magvel = min(60,magvel*1.2);
vel = vel.unit()*magvel;
}
}
Wait;
Death:
TNT1 A 1 A_SpawnItemEx("ExplodiumBulletImpact");
Stop;
}
}
Class ChanceTopTier1 : ChanceTop {}
Class ChanceTopTier2 : ChanceTop {}
Class ChanceTopTier3 : ChanceTop {}
Class ChanceTopTier4 : ChanceTop {}
Class ChanceSideTier1 : ChanceSide {}
Class ChanceSideTier2 : ChanceSide {}
Class ChanceSideTier3 : ChanceSide {}
Class ChanceSideTier4 : ChanceSide {}
Class DroppedChancebox : Actor abstract
{
Class<Actor> topclass, sideclass;
Property TopClass : topclass;
Property SideClass : sideclass;
double rang;
action void A_DropSomething()
{
int num = 0;
// first pass, count up the max rng number
for ( DropItem d=GetDropItems(); d; d=d.Next )
num += d.Probability;
// second pass, pick the item
int choice = Random[Chancebox](0,num);
int num2 = 0;
for ( DropItem d=GetDropItems(); d; d=d.Next )
{
num2 += d.Probability;
if ( num2 < choice ) continue;
let thedrop = Spawn(d.Name,pos);
thedrop.angle = angle;
break;
}
int numpt = Random[ExploS](16,32);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](.3,8);
let s = Spawn("SWWMSmoke",Vec3Offset(0,0,16));
s.vel = pvel;
s.SetShade(FillColor*Random[ExploS](64,85));
s.special1 = Random[ExploS](1,4);
s.alpha *= .4;
s.scale *= 2.4;
}
}
action void A_Confetti()
{
A_StartSound("chancebox/tada",CHAN_ITEM);
double ang, pt;
int numpt = Random[ExploS](64,128);
for ( int i=0; i<numpt; i++ )
{
ang = FRandom[ExploS](0,360);
pt = FRandom[ExploS](-90,30);
let c = Spawn("FancyConfetti",Vec3Offset(0,0,16));
c.vel = (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt))*FRandom[ExploS](2,8);
}
}
Default
{
Radius 16;
Height 32;
Gravity .7;
+CANNOTPUSH;
+MOVEWITHSECTOR;
+BLOCKASPLAYER;
+ROLLSPRITE;
}
States
{
Spawn:
XZW1 A 1 A_JumpIf(pos.z<=floorz,1);
Wait;
XZW1 A 35
{
A_Stop();
A_StartSound("chancebox/land",CHAN_BODY);
rang = angle;
}
XZW1 A 0 A_StartSound("chancebox/drumroll",CHAN_WEAPON);
XZW1 A 1
{
angle = rang+FRandom[Chancebox](-5,5);
pitch = FRandom[Chancebox](-5,5);
roll = FRandom[Chancebox](-5,5);
special1++;
return A_JumpIf(special1>40,"BlowUp");
}
Wait;
BlowUp:
XZW2 A 1
{
A_QuakeEx(2,2,2,9,0,500,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollIntensity:.2);
A_StartSound("chancebox/explode",CHAN_VOICE);
angle = rang;
pitch = roll = 0;
let t = Spawn(TopClass,Vec3Offset(0,0,32));
t.angle = angle;
let s1 = Spawn(SideClass,level.Vec3Offset(pos,(RotateVector((16,0),angle+90),0)));
s1.angle = angle+90;
let s2 = Spawn(SideClass,level.Vec3Offset(pos,(RotateVector((16,0),angle-90),0)));
s2.angle = angle-90;
A_DropSomething();
}
XZW2 BCDEFGHIJKLMNO 1;
XZW2 P -1 A_Confetti();
Stop;
Dummy:
XZW1 BCDEFG -1; // these won't actually be used, found a better way
Stop;
}
}
Class DroppedChanceboxTier1 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier1";
DroppedChancebox.SideClass "ChanceSideTier1";
StencilColor "01 01 03";
DropItem "ChanceDropShells1", 6;
DropItem "ChanceDropShells2", 6;
DropItem "ChanceDropShells3", 5;
DropItem "ChanceDropShells4", 4;
DropItem "ChanceDropShells5", 3;
DropItem "ChanceDropShells6", 2;
}
}
Class DroppedChanceboxTier2 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier2";
DroppedChancebox.SideClass "ChanceSideTier2";
StencilColor "01 03 01";
}
}
Class DroppedChanceboxTier3 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier3";
DroppedChancebox.SideClass "ChanceSideTier3";
StencilColor "03 01 01";
}
}
Class DroppedChanceboxTier4 : DroppedChancebox
{
Default
{
DroppedChancebox.TopClass "ChanceTopTier4";
DroppedChancebox.SideClass "ChanceSideTier4";
StencilColor "03 03 01";
}
}
Class ChanceboxTier1 : Chancebox
{
Default
{
Tag "$T_LOOTBOX1";
Inventory.PickupMessage "$T_LOOTBOX1";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox1.png";
Stamina 1000;
Chancebox.DropClass "DroppedChanceboxTier1";
}
}
Class ChanceboxTier2 : Chancebox
{
Default
{
Tag "$T_LOOTBOX2";
Inventory.PickupMessage "$T_LOOTBOX2";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox2.png";
Stamina 10000;
Chancebox.DropClass "DroppedChanceboxTier2";
}
}
Class ChanceboxTier3 : Chancebox
{
Default
{
Tag "$T_LOOTBOX3";
Inventory.PickupMessage "$T_LOOTBOX3";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox3.png";
Stamina 100000;
Chancebox.DropClass "DroppedChanceboxTier3";
}
}
Class ChanceboxTier4 : Chancebox
{
Default
{
Tag "$T_LOOTBOX4";
Inventory.PickupMessage "$T_LOOTBOX4";
Inventory.Icon "graphics/HUD/Icons/I_Chancebox4.png";
Stamina 1000000;
Chancebox.DropClass "DroppedChanceboxTier4";
}
}
Class FancyConfetti : Actor
{
int deadtimer;
double anglevel, pitchvel, rollvel;
Default
{
Radius 2;
Height 2;
+NOBLOCKMAP;
+MISSILE;
+MOVEWITHSECTOR;
+THRUACTORS;
+NOTELEPORT;
+DONTSPLASH;
+INTERPOLATEANGLES;
+ROLLSPRITE;
+ROLLCENTER;
Gravity 0.05;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
anglevel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
if ( bAMBUSH ) frame = 0;
else frame = Random[Junk](0,9);
scale *= Frandom[Junk](0.8,1.2);
}
override void Tick()
{
Super.Tick();
if ( isFrozen() ) return;
vel.xy *= 0.98;
if ( vel.z > 0 ) vel.z *= 0.98;
if ( InStateSequence(CurState,ResolveState("Death")) )
{
deadtimer++;
if ( deadtimer > 300 ) A_FadeOut(0.05);
return;
}
}
States
{
Spawn:
XZW1 # 1
{
angle += anglevel;
pitch += pitchvel;
roll += rollvel;
}
Loop;
Death:
XZW1 # -1
{
pitch = roll = 0;
}
Stop;
Dummy:
XZW1 ABCDEFGHIJ -1;
Stop;
}
}
// Chancebox drops
Class ChanceDrop : Actor abstract
{
Default
{
StencilColor "03 03 03";
+NOBLOCKMAP;
+NOGRAVITY;
}
action void A_DropTheGoods()
{
int num = 0;
for ( DropItem d=GetDropItems(); d; d=d.Next )
{
if ( Random[Chancebox](0,255) > d.Probability ) continue;
Actor i = Spawn(d.Name,pos);
i.bDROPPED = true;
i.bNOGRAVITY = false;
i.vel.z = FRandom[Chancebox](2,4);
switch ( num )
{
case 0:
i.vel.xy = (0,0);
break;
case 1:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle);
break;
case 2:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle+90);
break;
case 3:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle-90);
break;
case 4:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),angle+180);
break;
default:
i.vel.xy = RotateVector((FRandom[Chancebox](3,6),0),FRandom[Chancebox](0,360));
break;
}
num++;
if ( i is 'Inventory' ) Inventory(i).bTOSSED = true;
}
}
States
{
Spawn:
TNT1 A 1 NoDelay A_DropTheGoods();
Stop;
}
}
Class ChanceDropShells1 : ChanceDrop
{
Default
{
DropItem "RedShell2", 256;
DropItem "RedShell4", 224;
DropItem "RedShell4", 224;
DropItem "RedShell8", 192;
DropItem "RedShell8", 192;
}
}
Class ChanceDropShells2 : ChanceDrop
{
Default
{
DropItem "GreenShell2", 256;
DropItem "GreenShell4", 192;
DropItem "GreenShell4", 192;
DropItem "GreenShell8", 160;
DropItem "GreenShell8", 160;
}
}
Class ChanceDropShells3 : ChanceDrop
{
Default
{
DropItem "BlueShell2", 256;
DropItem "BlueShell4", 160;
DropItem "BlueShell4", 160;
DropItem "BlueShell8", 128;
DropItem "BlueShell8", 128;
}
}
Class ChanceDropShells4 : ChanceDrop
{
Default
{
DropItem "PurpleShell2", 256;
DropItem "PurpleShell2", 128;
DropItem "PurpleShell2", 128;
DropItem "PurpleShell4", 96;
DropItem "PurpleShell4", 96;
}
}
Class ChanceDropShells5 : ChanceDrop
{
Default
{
DropItem "WhiteShell", 256;
DropItem "WhiteShell", 128;
DropItem "WhiteShell", 128;
DropItem "WhiteShell2", 96;
DropItem "WhiteShell2", 96;
}
}
Class ChanceDropShells6 : ChanceDrop
{
Default
{
DropItem "BlackShell", 256;
DropItem "BlackShell", 64;
DropItem "BlackShell", 64;
}
}
Class ChanceDropShells7 : ChanceDrop
{
Default
{
DropItem "GoldShell", 256;
}
}

View file

@ -1277,7 +1277,8 @@ Class SWWMHandler : EventHandler
static const Class<Actor> purplepool[] = {"PurpleShell","PurpleShell2","PurpleShell4"};
static const Class<Actor> bluepool[] = {"BlueShell","BlueShell2","BlueShell4","BlueShell8"};
static const Class<Actor> blackpool[] = {"BlackShell","BlackShell2","BlackShell4"};
if ( (e.Replacee is 'ItemFog') ) e.Replacement = 'SWWMItemFog';
if ( e.Replacee is 'ItemFog' ) e.Replacement = 'SWWMItemFog';
if ( e.Replacee is 'TeleportFog' ) e.Replacement = 'SWWMTeleportFog';
else if ( (e.Replacee is 'Chainsaw') || (e.Replacee is 'Gauntlets') || (e.Replacee is 'FWeapAxe') ) e.Replacement = 'PusherWeapon';
else if ( (e.Replacee is 'Fist') || (e.Replacee is 'Staff') ) e.Replacement = 'DeepImpact';
else if ( (e.Replacee is 'Pistol') || (e.Replacee is 'GoldWand') || (e.Replacee is 'FWeapFist') || (e.Replacee is 'CWeapMace') || (e.Replacee is 'MWeapWand') ) e.Replacement = 'ExplodiumGun';
@ -1447,7 +1448,7 @@ Class SWWMHandler : EventHandler
if ( Random[Replacements](0,3) ) e.Replacement = 'SparkUnit';
else e.Replacement = 'SilverBulletAmmo';
}
else if ( e.Replacee == 'ArtiTeleport' )
else if ( (e.Replacee == 'ArtiTeleport') || (e.Replacee == 'ArtiTeleportOther') )
{
if ( Random[Replacements](0,2) ) e.Replacement = 'SWWMNothing';
else e.Replacement = 'GoldShell';
@ -1465,6 +1466,20 @@ Class SWWMHandler : EventHandler
else if ( (e.Replacee == 'FWeaponPiece1') || (e.Replacee == 'FWeaponPiece2')
|| (e.Replacee == 'CWeaponPiece1') || (e.Replacee == 'CWeaponPiece3')
|| (e.Replacee == 'MWeaponPiece2') || (e.Replacee == 'MWeaponPiece3') ) e.Replacement = 'SWWMNothing';
else if ( (e.Replacee == 'ArmorBonus') || (e.Replacee == 'ArtiTimeBomb') || (e.Replacee == 'ArtiBlastRadius') ) e.Replacement = 'ArmorNuggetItem';
else if ( (e.Replacee == 'HealthBonus') || (e.Replacee == 'CrystalVial') ) e.Replacement = 'HealthNuggetItem';
else if ( e.Replacee == 'Stimpack' ) e.Replacement = 'TetraHealthItem';
else if ( e.Replacee == 'Medikit' ) e.Replacement = 'CubeHealthItem';
else if ( e.Replacee == 'ArtiHealth' )
{
if ( Random[Replacements](0,1) ) e.Replacement = 'CubeHealthItem';
else e.Replacement = 'TetraHealthItem';
}
else if ( (e.Replacee == 'Soulsphere') || (e.Replacee == 'ArtiSuperHealth') ) e.Replacement = 'RefresherItem';
else if ( (e.Replacee == 'Megasphere') || (e.Replacee == 'ArtiEgg') || (e.Replacee == 'PlatinumHelm') ) e.Replacement = 'GrilledCheeseSandwich';
else if ( (e.Replacee == 'Blursphere') || (e.Replacee == 'ArtiInvisibility') || (e.Replacee == 'AmuletOfWarding') ) e.Replacement = 'GhostArtifact';
else if ( (e.Replacee == 'GreenArmor') || (e.Replacee == 'SilverShield') || (e.Replacee == 'MeshArmor') ) e.Replacement = 'BlastSuitItem';
else if ( (e.Replacee == 'BlueArmor') || (e.Replacee == 'FalconShield') || (e.Replacee == 'EnchantedShield') ) e.Replacement = 'WarArmorItem';
}
override void NetworkProcess( ConsoleEvent e )

View file

@ -1 +1,197 @@
// all the healing items go here
Class HealthNugget : Health
{
Default
{
Inventory.Amount 5;
Inventory.MaxAmount 200;
}
}
Class TetraHealth : Health
{
Default
{
Inventory.Amount 15;
Inventory.MaxAmount 100;
}
}
Class CubeHealth : Health
{
Default
{
Inventory.Amount 30;
Inventory.MaxAmount 100;
}
}
Class RefresherHealth : Health
{
Default
{
Inventory.Amount 500;
Inventory.MaxAmount 500;
}
override bool TryPickup( in out Actor other )
{
PrevHealth = other.player?other.player.health:other.health;
if ( other.GiveBody(Amount,MaxAmount) )
{
GoAwayAndDie();
let p = Powerup(other.FindInventory("RefresherRegen"));
if ( p ) p.EffectTics = p.default.EffectTics;
else other.GiveInventory("RefresherRegen",1);
return true;
}
return false;
}
}
Class RefresherRegen : Powerup
{
Default
{
Inventory.Icon "graphics/HUD/Icons/I_Refresher.png";
Powerup.Duration -60;
Powerup.Strength 10;
}
override void EndEffect()
{
Super.EndEffect();
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_REFRESHER"));
}
override void DoEffect()
{
Super.DoEffect();
if ( Owner && (Owner.health > 0) && !(EffectTics%175) )
{
if ( Owner.GiveBody(int(Strength),500) )
{
SWWMHandler.DoFlash(Owner,Color(32,224,128,255),10);
Owner.A_StartSound("powerup/refresher",CHAN_ITEM,CHANF_LOCAL,.4);
}
}
}
}
Class HealthNuggetItem : SWWMHealth
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"Nugget");
return Super.CreateCopy(other);
}
Default
{
Tag "$T_NUGGETH";
Inventory.Icon "graphics/HUD/Icons/I_HealthNugget.png";
Inventory.PickupMessage "$T_NUGGETH";
Inventory.MaxAmount int.max;
Inventory.InterHubAmount int.max;
SWWMHealth.GiveHealth "HealthNugget";
+INVENTORY.ALWAYSPICKUP;
+COUNTITEM;
}
States
{
Spawn:
XZW1 # -1 NoDelay
{
frame = Random[Nugget](0,7);
}
Stop;
Dummy:
XZW1 ABCDEFGH -1;
Stop;
}
}
Class TetraHealthItem : SWWMHealth
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"HealthGeom");
return Super.CreateCopy(other);
}
Default
{
Tag "$T_TETRAHEALTH";
Inventory.Icon "graphics/HUD/Icons/I_HealthTetra.png";
Inventory.PickupMessage "$T_TETRAHEALTH";
Inventory.MaxAmount 20;
Inventory.InterHubAmount 20;
SWWMHealth.GiveHealth "TetraHealth";
}
States
{
Spawn:
XZW1 # -1;
Stop;
}
}
Class CubeHealthItem : SWWMHealth
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"HealthGeom");
return Super.CreateCopy(other);
}
Default
{
Tag "$T_CUBEHEALTH";
Inventory.Icon "graphics/HUD/Icons/I_HealthCube.png";
Inventory.PickupMessage "$T_CUBEHEALTH";
Inventory.MaxAmount 10;
Inventory.InterHubAmount 10;
SWWMHealth.GiveHealth "CubeHealth";
}
States
{
Spawn:
XZW1 # -1;
Stop;
}
}
Class RefresherItem : SWWMHealth
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"Refresher");
return Super.CreateCopy(other);
}
override void AutoUseExtra()
{
let p = Powerup(Owner.FindInventory("RefresherRegen"));
if ( p ) p.EffectTics = p.default.EffectTics;
else Owner.GiveInventory("RefresherRegen",1);
}
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
return Super.Use(pickup);
}
Default
{
Tag "$T_REFRESHER";
Inventory.Icon "graphics/HUD/Icons/I_Refresher.png";
Inventory.PickupMessage "$T_REFRESHER";
Inventory.PickupSound "misc/p_pkup";
Inventory.MaxAmount 5;
Inventory.InterHubAmount 5;
SWWMHealth.GiveHealth "RefresherHealth";
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
}
States
{
Spawn:
XZW1 # -1;
Stop;
}
}

View file

@ -27,6 +27,8 @@ Class SWWMStatusBar : BaseStatusBar
double FracTic;
int chatopen;
bool justselected;
DynamicValueInterpolator HealthInter, ScoreInter, FuelInter, DashInter;
override void FlushNotify()
@ -100,10 +102,22 @@ Class SWWMStatusBar : BaseStatusBar
override void Tick()
{
Super.Tick();
if ( CPlayer.inventorytics >= (5*Thinker.TICRATE)-1 )
{
if ( CPlayer.mo.InvSel )
S_StartSound("menu/demoscroll",CHAN_BODY,CHANF_UI|CHANF_MAYBE_LOCAL);
}
if ( CPlayer.inventorytics > 0 ) justselected = false;
else
{
if ( !justselected && CPlayer.mo.InvSel )
S_StartSound("menu/democlose",CHAN_BODY,CHANF_UI|CHANF_MAYBE_LOCAL);
justselected = true;
}
if ( !chatduration ) chatduration = CVar.GetCVar('swwm_chatduration',players[consoleplayer]);
if ( !msgduration ) msgduration = CVar.GetCVar('swwm_msgduration',players[consoleplayer]);
if ( !pickduration ) pickduration = CVar.GetCVar('swwm_pickduration',players[consoleplayer]);
Super.Tick();
// prune old messages
for ( int i=0; i<PickupQueue.Size(); i++ )
{
@ -157,6 +171,7 @@ Class SWWMStatusBar : BaseStatusBar
ChatTex[3] = TexMan.CheckForTexture("graphics/HUD/ChatBoxTop_Smol.png",TexMan.Type_Any);
ChatTex[4] = TexMan.CheckForTexture("graphics/HUD/ChatBoxLine_Smol.png",TexMan.Type_Any);
ChatTex[5] = TexMan.CheckForTexture("graphics/HUD/ChatBoxBottom_Smol.png",TexMan.Type_Any);
InventoryTex = TexMan.CheckForTexture("graphics/HUD/InventoryBox.png",TexMan.Type_Any);
mTewiFont = HUDFont.Create("TewiShaded");
HealthInter = DynamicValueInterpolator.Create(100,.1,1,100);
ScoreInter = DynamicValueInterpolator.Create(0,.1,1,1000);
@ -178,10 +193,90 @@ Class SWWMStatusBar : BaseStatusBar
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,ss.x-(margin+58),margin+1,String.Format("%09d",clamp(ScoreInter.GetValue(),0,999999999)),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
private void DrawInvIcon( Inventory i, double xx, double yy, double alpha = 1., bool forceamt = false )
{
if ( !i ) return;
Vector2 scl = TexMan.GetScaledSize(i.Icon);
double mscl = 30./max(scl.x,scl.y);
double dw = (ss.x/mscl), dh = (ss.y/mscl);
double dx = (xx+(30-scl.x*mscl)/2)/mscl, dy = (yy+(30-scl.y*mscl)/2)/mscl;
if ( i is 'Powerup' )
{
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
String nstr = String.Format("%ds",Powerup(i).EffectTics/Thinker.TICRATE);
int len = mTewiFont.mFont.StringWidth(nstr);
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,Powerup(i).IsBlinking()?alpha*.5:alpha);
return;
}
Screen.DrawTexture(i.Icon,false,dx,dy,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha,DTA_TopOffset,0,DTA_LeftOffset,0);
if ( (i.Amount > 1) || forceamt )
{
String nstr;
if ( (i.Amount > 99999) && !forceamt ) nstr = "99999";
else nstr = String.Format("%d",i.Amount);
int len = mTewiFont.mFont.StringWidth(nstr);
Screen.DrawText(mTewiFont.mFont,Font.CR_FIRE,(xx+30)-len,(yy+30)-11,nstr,DTA_VirtualWidthF,dw,DTA_VirtualHeightF,dh,DTA_KeepRatio,true,DTA_Alpha,alpha);
}
}
private void DrawInventory()
{
// active items (armor / powerups)
double xx = margin;
double yy = ss.y-(margin+60);
if ( CPlayer.mo.InvSel && !isInventoryBarVisible() ) yy -= 34;
bool drewarmor = false;
for ( Inventory i=CPlayer.mo.Inv; i; i=i.Inv )
{
if ( (i.Amount <= 0) || (!(i is 'SWWMArmor') && !(i is 'BasicArmor')) ) continue;
DrawInvIcon(i,xx,yy,forceamt:true);
yy -= 34;
drewarmor = true;
}
yy = ss.y-(margin+60);
if ( drewarmor ) xx += 40;
else if ( CPlayer.mo.InvSel && !isInventoryBarVisible() ) yy -= 34;
for ( Inventory i=CPlayer.mo.Inv; i; i=i.Inv )
{
if ( !(i is 'Powerup') || (Powerup(i).EffectTics <= 0) || !(Powerup(i).Icon) ) continue;
DrawInvIcon(i,xx,yy);
yy -= 34;
}
// inventory box / bar
if ( !CPlayer.mo.InvSel ) return;
if ( isInventoryBarVisible() )
{
Array<Inventory> bar;
bar.Clear();
for ( Inventory i=CPlayer.mo.FirstInv(); i; i=i.NextInv() ) bar.Push(i);
int ps = bar.Find(CPlayer.mo.InvSel);
Inventory prev[2], next[2];
if ( bar.Size() > 1 )
{
if ( ps+1 >= bar.Size() ) next[0] = bar[0];
else next[0] = bar[ps+1];
if ( ps-1 < 0 ) prev[0] = bar[bar.Size()-1];
else prev[0] = bar[ps-1];
}
if ( bar.Size() > 2 )
{
if ( ps+2 >= bar.Size() ) next[1] = bar[(ps+2)-bar.Size()];
else next[1] = bar[ps+2];
if ( ps-2 < 0 ) prev[1] = bar[bar.Size()+(ps-2)];
else prev[1] = bar[ps-2];
}
xx = (ss.x-34)/2;
yy = (ss.y+64)/2;
Screen.DrawTexture(InventoryTex,false,xx,yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
DrawInvIcon(CPlayer.mo.InvSel,xx+2,yy+2);
DrawInvIcon(prev[0],xx-32,yy+2,2./3.);
DrawInvIcon(prev[1],xx-66,yy+2,1./3.);
DrawInvIcon(next[0],xx+36,yy+2,2./3.);
DrawInvIcon(next[1],xx+70,yy+2,1./3.);
return;
}
Screen.DrawTexture(InventoryTex,false,margin,ss.y-(margin+61),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
DrawInvIcon(CPlayer.mo.InvSel,margin+2,ss.y-(margin+59));
}
private void DrawWeapon()
@ -369,6 +464,11 @@ Class SWWMStatusBar : BaseStatusBar
return true;
}
override void DrawPowerups()
{
// don't do anything
}
override void Draw( int state, double TicFrac )
{
Super.Draw(state,TicFrac);

View file

@ -2,8 +2,14 @@
Class SWWMArmor : Armor abstract
{
int priority;
double reduction;
String drainmsg;
Class<SWWMSpareArmor> parent;
Property ArmorPriority : priority;
Property DrainFactor : reduction;
Property DrainMessage : drainmsg;
Property GiverArmor : parent;
Default
{
@ -31,24 +37,36 @@ Class SWWMArmor : Armor abstract
Inv = saved;
}
// for subclasses
virtual int HandleDamage( int damage, Name damageType )
virtual int HandleDamage( int damage, Name damageType, int flags )
{
return damage;
}
override void AbsorbDamage( int damage, Name damageType, out int newdamage )
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( !passive ) return;
int saved;
if ( (amount > 0) && !DamageTypeDefinition.IgnoreArmor(damageType) )
if ( (amount > 0) && !DamageTypeDefinition.IgnoreArmor(damageType) && (damage > 0) )
{
saved = HandleDamage(damage,damageType);
if ( amount <= saved ) saved = amount;
saved = HandleDamage(damage,damageType,flags);
if ( amount <= int(ceil(saved*reduction)) ) saved = amount;
newdamage -= saved;
amount -= saved;
if ( newdamage < 0 ) Owner.GiveBody(abs(newdamage));
amount -= int(ceil(saved*reduction));
damage = newdamage;
if ( amount <= 0 )
{
if ( damage > 0 ) newdamage = ApplyDamageFactors(GetClass(),damageType,damage,damage);
DepleteOrDestroy();
if ( Owner.CountInv(parent) > 0 )
{
Amount = default.Amount;
if ( GetDefaultByType(parent).UseSound ) Owner.A_StartSound(GetDefaultByType(parent).UseSound,CHAN_ITEM,CHANF_DEFAULT,.6);
Owner.TakeInventory(parent,1);
}
else
{
if ( Owner.CheckLocalView() && (drainmsg != "") ) Console.Printf(StringTable.Localize(drainmsg));
DepleteOrDestroy();
}
return;
}
}
@ -59,6 +77,83 @@ Class SWWMArmor : Armor abstract
// gives armor when used
Class SWWMSpareArmor : Inventory abstract
{
Class<SWWMArmor> giveme;
Property GiveArmor : giveme;
override bool Use( bool pickup )
{
let cur = Owner.FindInventory(giveme);
if ( !cur || (cur.Amount < cur.MaxAmount) )
{
Owner.GiveInventory(giveme,GetDefaultByType(giveme).Amount);
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEM,CHANF_DEFAULT,.6);
SWWMHandler.DoFlash(Owner,Color(48,96,255,64),5);
return true;
}
return false;
}
Default
{
+INVENTORY.INVBAR;
+INVENTORY.ISARMOR;
+INVENTORY.AUTOACTIVATE;
Inventory.MaxAmount 5;
Inventory.InterHubAmount 5;
+FLOATBOB;
FloatBobStrength 0.25;
}
}
Class SWWMHealth : Inventory abstract
{
// can't use the Health class for whatever reason
// nice parser you got there I guess?
Class<Inventory> giveme;
Property GiveHealth : giveme;
override bool Use( bool pickup )
{
if ( Owner.Health >= GetDefaultByType(giveme).MaxAmount ) return false;
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEM,CHANF_DEFAULT,.6);
SWWMHandler.DoFlash(Owner,Color(48,64,128,255),5);
Owner.GiveInventory(giveme,GetDefaultByType(giveme).Amount);
return true;
}
virtual void AutoUseExtra()
{
}
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( passive && (Owner.Health-damage <= 0) )
{
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEM,CHANF_DEFAULT,.6);
while ( (Amount > 0) && (newdamage > 0) )
{
newdamage = max(0,damage-GetDefaultByType(giveme).Amount);
AutoUseExtra();
Amount--;
if ( Amount <= 0 ) DepleteOrDestroy();
}
}
else newdamage = damage;
}
Default
{
+INVENTORY.INVBAR;
+INVENTORY.ISHEALTH;
+INVENTORY.AUTOACTIVATE;
Inventory.MaxAmount 5;
Inventory.InterHubAmount 5;
Inventory.UseSound "misc/health_pkup";
+FLOATBOB;
FloatBobStrength 0.25;
}
}
// Base casing classes

View file

@ -196,7 +196,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
invlist.Clear();
for ( Inventory inv=players[consoleplayer].mo.Inv; inv; inv=inv.Inv )
{
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') ) continue;
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') || (inv is 'SWWMArmor') ) continue;
String tag = inv.GetTag();
bool greater = false;
for ( int i=0; i<invlist.Size(); i++ )
@ -446,10 +446,10 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
int clscol = (i==sel0)?Font.CR_WHITE:Font.CR_DARKGRAY;
if ( invlist[i] is 'Weapon' ) clscol = (i==sel0)?Font.CR_YELLOW:Font.FindFontColor('DarkYellow');
else if ( invlist[i] is 'Ammo' ) clscol = (i==sel0)?Font.CR_ORANGE:Font.FindFontColor('DarkOrange');
else if ( (invlist[i] is 'Health') || (invlist[i] is 'HealthPickup') ) clscol = (i==sel0)?Font.CR_RED:Font.CR_DARKRED;
else if ( (invlist[i] is 'PowerupGiver') || invlist[i].bBIGPOWERUP ) clscol = (i==sel0)?Font.CR_PURPLE:Font.FindFontColor('DarkPurple');
else if ( (invlist[i] is 'Health') || (invlist[i] is 'HealthPickup') || (invlist[i] is 'SWWMHealth') ) clscol = (i==sel0)?Font.CR_RED:Font.CR_DARKRED;
else if ( (invlist[i] is 'Armor') || (invlist[i] is 'SWWMSpareArmor') ) clscol = (i==sel0)?Font.CR_GREEN:Font.CR_DARKGREEN;
else if ( invlist[i] is 'PuzzleItem' ) clscol = (i==sel0)?Font.CR_LIGHTBLUE:Font.CR_BLUE;
else if ( invlist[i] is 'PowerupGiver' ) clscol = (i==sel0)?Font.CR_PURPLE:Font.FindFontColor('DarkPurple');
Screen.DrawText(TewiFont,clscol,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += 16;
if ( yy >= 369 )

View file

@ -124,6 +124,19 @@ Class Demolitionist : PlayerPawn
if ( !item.CallTryPickup(self) ) item.Destroy();
}
}
// Also give spares
for ( int i=0; i<AllActorClasses.Size(); i++ )
{
let type = (Class<SWWMSpareArmor>)(AllActorClasses[i]);
if ( !type || (type == 'SWWMSpareArmor') ) continue;
if ( GetReplacement(type) == type )
{
let item = Inventory(Spawn(type));
item.ClearCounters(); // don't increase item counts
item.Amount = item.MaxAmount;
if ( !item.CallTryPickup(self) ) item.Destroy();
}
}
if ( !giveall ) return;
}
if ( giveall || (name ~== "keys") )
@ -225,11 +238,14 @@ Class Demolitionist : PlayerPawn
}
void A_Dash()
{
A_AlertMonsters(800);
vel += dashdir*dashboost;
player.vel = vel.xy;
if ( dashboost < 0.1 ) dashboost = 0.;
else dashboost *= .5;
else
{
A_AlertMonsters(800);
dashboost *= .5;
}
mystats.fuelusage += dashfuel-max(0.,dashfuel-dashboost);
dashfuel = max(0.,dashfuel-dashboost);
dashcooldown = 40;
@ -239,12 +255,12 @@ Class Demolitionist : PlayerPawn
}
void A_BoostUp( bool initial = false )
{
A_AlertMonsters(800);
vel += (0,0,1)*dashboost;
player.vel = vel.xy;
if ( dashboost < 0.1 ) dashboost = 0.;
else
{
A_AlertMonsters(800);
dashboost *= (player.cmd.buttons&BT_JUMP)?.9:.4;
}
mystats.fuelusage += dashfuel-max(0.,dashfuel-dashboost);
@ -739,11 +755,16 @@ Class Demolitionist : PlayerPawn
{
if ( !player ) return Super.UseInventory(item);
if ( !mute ) mute = CVar.GetCVar('swwm_mutevoice',player);
if ( !(item is 'PuzzleItem') || (mute.GetInt() >= 2) )
return Super.UseInventory(item);
bool res = Super.UseInventory(item);
if ( res ) SWWMHandler.AddOneliner("puzzsucc",10);
else SWWMHandler.AddOneliner("puzzfail",20);
if ( CheckLocalView() )
{
if ( !res && !(item is 'Weapon') ) A_StartSound("menu/noinvuse",CHAN_ITEM);
if ( (item is 'PuzzleItem') && (mute.GetInt() < 2) )
{
if ( res ) SWWMHandler.AddOneliner("puzzsucc",10);
else SWWMHandler.AddOneliner("puzzfail",20);
}
}
return res;
}
void A_Footstep( double yofs, bool run = false, double vol = .3 )

View file

@ -1 +1,236 @@
// Powerups go here
Class GrilledCheeseSandwich : Inventory
{
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"GCSandwich");
return Super.CreateCopy(other);
}
private void DoTheThing()
{
SWWMHandler.DoFlash(Owner,Color(64,255,255,64),10);
Owner.A_QuakeEx(9,9,9,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
Owner.A_StartSound(UseSound,CHAN_ITEM);
Owner.GiveBody(1000,1000);
let n = Owner.FindInventory("ArmorNugget");
if ( !n ) Owner.GiveInventory("ArmorNugget",GetDefaultByType("ArmorNugget").MaxAmount);
else n.Amount = n.MaxAmount;
let b = Owner.FindInventory("BlastSuit");
if ( !b ) Owner.GiveInventory("BlastSuit",GetDefaultByType("BlastSuit").MaxAmount);
else b.Amount = b.MaxAmount;
let w = Owner.FindInventory("WarArmor");
if ( !w ) Owner.GiveInventory("WarArmor",GetDefaultByType("WarArmor").MaxAmount);
else w.Amount = w.MaxAmount;
SWWMLoreLibrary.Add(Owner.player,"Nugget");
SWWMLoreLibrary.Add(Owner.player,"BlastSuit");
SWWMLoreLibrary.Add(Owner.player,"WarArmor");
}
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
if ( Owner.Health >= 1000 ) return false;
DoTheThing();
return true;
}
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( passive && (Owner.Health-damage <= 0) )
{
newdamage = 0;
DoTheThing();
if ( Amount <= 0 ) DepleteOrDestroy();
}
}
Default
{
Tag "$T_SANDWICH";
Inventory.Icon "graphics/HUD/Icons/I_Sandwich.png";
Inventory.PickupSound "misc/p_pkup";
Inventory.UseSound "powerup/sandwich";
Inventory.PickupMessage "$T_SANDWICH";
Inventory.MaxAmount 5;
Inventory.InterHubAmount 5;
+INVENTORY.ALWAYSPICKUP;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.INVBAR;
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
+FLOATBOB;
FloatBobStrength 0.25;
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}
Class GhostSnd : Actor
{
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
}
override void Tick()
{
Super.Tick();
if ( !target || !master )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
if ( players[consoleplayer].Camera == target )
{
A_SoundVolume(CHAN_VOICE,0.);
A_SoundVolume(CHAN_7,.4);
}
else
{
A_SoundVolume(CHAN_VOICE,.1);
A_SoundVolume(CHAN_7,0.);
}
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_StartSound("powerup/ghostact",CHAN_VOICE,CHANF_LOOPING,.1,1.5);
A_StartSound("powerup/ghostact",CHAN_7,CHANF_LOOPING,.4,ATTN_NONE);
}
override void OnDestroy()
{
Super.OnDestroy();
A_StopSound(CHAN_VOICE);
A_StopSound(CHAN_7);
}
}
Class GhostPower : PowerInvisibility
{
Actor snd;
Default
{
Inventory.Icon "graphics/HUD/Icons/I_Ghost.png";
Powerup.Duration -60;
Powerup.Strength 100;
Powerup.Mode "Translucent";
Powerup.Color "F0E0FF", 0.1;
}
override void InitEffect()
{
Super.InitEffect();
if ( !Owner ) return;
Owner.bNOTARGET = true;
}
override void EndEffect()
{
Super.EndEffect();
if ( !Owner ) return;
Owner.bNOTARGET = false;
Owner.A_StartSound("powerup/ghostend",CHAN_ITEM);
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_GHOSTARTI"));
}
override void DoEffect()
{
Super.DoEffect();
if ( !Owner ) return;
if ( !snd ) snd = Spawn("GhostSnd",Owner.pos);
snd.target = Owner;
snd.master = self;
}
override void AlterWeaponSprite( VisStyle vis, in out int changed )
{
// leave weapons alone
vis.RenderStyle = STYLE_Normal;
vis.Alpha = 1.f;
changed = 1;
}
}
Class GhostArtifactX : Actor
{
Default
{
RenderStyle "Add";
+NOGRAVITY;
+NOCLIP;
+DONTSPLASH;
Radius 0.1;
Height 0;
+FLOATBOB;
FloatBobStrength 0.25;
}
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:
XZW1 A -1 Bright;
Stop;
}
}
Class GhostArtifact : Inventory
{
Default
{
Tag "$T_GHOSTARTI";
Inventory.Icon "graphics/HUD/Icons/I_Ghost.png";
Inventory.PickupSound "misc/p_pkup";
Inventory.UseSound "powerup/ghost";
Inventory.PickupMessage "$T_GHOSTARTI";
Inventory.MaxAmount 5;
Inventory.InterHubAmount 5;
+INVENTORY.ALWAYSPICKUP;
+INVENTORY.AUTOACTIVATE;
+INVENTORY.INVBAR;
+COUNTITEM;
+INVENTORY.BIGPOWERUP;
+FLOATBOB;
FloatBobStrength 0.25;
}
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
A_StartSound(UseSound,CHAN_ITEM);
let g = GhostPower(Owner.FindInventory("GhostPower"));
if ( g ) g.EffectTics = g.default.EffectTics;
else Owner.GiveInventory("GhostPower",1);
return true;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
tracer = Spawn("GhostArtifactX",pos);
tracer.angle = angle;
tracer.target = self;
tracer.FloatBobPhase = FloatBobPhase;
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}