More powerup/item work:

- Added Invinciball and Ragekit.
 - Fixed items not autoactivating on pickup if spares are held.
 - Fixed crashing when Refresher and Sandwich autoactivate to prevent death.
 - Fixed PainChance not being reset when finishing a dash.
 - Adjusted armor values.
 - Set Nugget pickup ammount to 1, like vanilla bonus items.
This commit is contained in:
Mari the Deer 2020-02-04 13:55:17 +01:00
commit 1cc4861bf3
24 changed files with 475 additions and 42 deletions

View file

@ -347,7 +347,7 @@ have a spare. Most powerups can be toggled, unless specified otherwise.
### Health Nugget, replaces Health Bonus, Crystal Vial
Health nuggets increase health by 5% up to a cap of 200.
Health nuggets increase health by 1% up to a cap of 200.
### Health Tetrahedron, replaces Stimpak, Quartz Flask
@ -367,7 +367,7 @@ you're about to die, though it sometimes won't be enough to save you.
### Armor Nugget, replaces Armor Bonus, Timebomb of the Ancients, Disc of Repulsion
Cumulative armor items that can increase resistance to all damage by as much
as you can find. Each nugget adds 5% to the total. Above 100%, damage gets
as you can find. Each nugget adds 1% to the total. Above 100%, damage gets
turned into additional health (up to the standard 100% cap).
The upper cap for these is 200%.
@ -378,7 +378,7 @@ Protection decreases by a 10% of absorbed damage.
The blast suit is a nice little light armor which provides a 75% reduction to
damage and an additional 50% to splash damage.
Can handle a total of 500 damage before breaking.
Can handle a total of 200 damage before breaking.
### War Armor, replaces Blue Armor, Enchanted Shield, Falcon Shield
@ -388,7 +388,7 @@ follows:
* 80% reduction to everything else
* 70% reduction for all splash damage (multiplicative on top of the other two)
The armor can eat up a total of 1000 damage before breaking.
The armor can eat up a total of 600 damage before breaking.
### Grilled Cheese Sandwich, replaces Megasphere, Morph Ovum, Platinum Helm
@ -413,7 +413,7 @@ The ragekit is a special item that has some... interesting effects.
Octuples melee damage, doubles movement speed, quarters damage taken... and has
the side effect of turning you into a screaming beast.
Ragequit happens after 30 seconds, also cannot be toggled after activation.
Ragequit happens after 30 seconds.
### Gravity suppressor, replaces Radsuit, Wings of Wrath, Boots of Speed
@ -428,7 +428,7 @@ Just be careful with height when the effect is about to run out.
This thing makes you impervious to pretty much everything excluding the Ynykron
Artifact.
You're fucking invincible for a total of 90 seconds, cannot be toggled.
You're fucking invincible for a total of 90 seconds.
### Hammerspace Embiggener, replaces Backpack, Bag of Holding, Porkalator

View file

@ -41,6 +41,10 @@ Brightmap Texture "models/Gravity.png"
{
Map "models/Gravity_bright.png"
}
Brightmap Texture "models/Ragekit.png"
{
Map "models/Ragekit_bright.png"
}
PointLight ARMORNUGGETLIGHT
{
@ -116,3 +120,27 @@ Object GravitySuppressor
{
Frame "XZW1" { light "GRAVITYLIGHT" }
}
PointLight INVINCIBALLLIGHT
{
Color 0.8 0.2 0.0
Size 40
Offset 0 16 0
Attenuate 1
}
Object FuckingInvinciball
{
Frame "XZW1" { light "INVINCIBALLLIGHT" }
}
PointLight RAGELIGHT
{
Color 1.0 0.1 0.0
Size 40
Offset 0 16 0
Attenuate 1
}
Object Ragekit
{
Frame "XZW1" { light "RAGELIGHT" }
}

View file

@ -161,7 +161,7 @@ SWWM_LORETXT_BLASTSUIT =
" - 75% reduction to all types of damage.\n"
" - Additional 50% reduction to explosions.\n"
"\n"
"Durability: Can absorb a total of 500 units of damage before breaking.\n"
"Durability: Can absorb a total of 200 units of damage before breaking.\n"
"\n"
"Addendum: The blast suit can be worn under other armor.";
SWWM_LORETAG_COLLAR = "Lucky Collar";
@ -428,7 +428,7 @@ SWWM_LORETXT_HEALTHGEOM =
"Saya's Note: I talked with the guy and you're allowed to use these, and any other things they have, so you're going to see them all over the place during your mission.";
SWWM_LORETAG_INVINCIBALL = "Invinciball";
SWWM_LORETXT_INVINCIBALL =
"Designation: Total Safety Device aka \"Fucking Invinciball\""
"Designation: Total Safety Device aka \"Fucking Invinciball\"\n"
"Manufacturer: Cyrus Enterprises\n"
"\n"
"Summary: For a limited time, makes the user impervious to all harm that could come to them, even if self-inflicted.\n"
@ -523,7 +523,7 @@ SWWM_LORETXT_WARARMOR =
" - 80% reduction to all other types of damage.\n"
" - Additional 70% reduction to explosions.\n"
"\n"
"Durability: Can absorb a total of 1000 units of damage before breaking.\n"
"Durability: Can absorb a total of 600 units of damage before breaking.\n"
"\n"
"Addendum: Worn over a blast suit, you're pretty much ready for anything that could be thrown at you.";
SWWM_LORETAG_BIGSHOT = "Mr. BIG SHOT";
@ -874,6 +874,7 @@ D_BLASTSUIT = "The Blast Suit broke down.";
D_GHOSTARTI = "The Ghost Artifact ran out of energy.";
D_GRAVITYS = "The Gravity Suppressor is out of power.";
D_LAMP = "The Lamp ran out of oil.";
D_INVINCIBALL = "You are no longer invincible.";
D_RAGEKIT = "The Ragekit has ragequit.";
D_REFRESHER = "The Refresher boost has ended.";
D_WARARMOR = "The War Armor is no more.";

View file

@ -145,3 +145,29 @@ Model "GravitySuppressor"
FrameIndex XZW1 A 0 0
}
Model "FuckingInvinciball"
{
Path "models"
Model 0 "Invinciball_d.3d"
SurfaceSkin 0 0 "Invinciball.png"
SurfaceSkin 0 1 "invincimap.png"
Scale 0.04 0.04 0.04
ZOffset 16
ROTATING
FrameIndex XZW1 A 0 0
}
Model "Ragekit"
{
Path "models"
Model 0 "Ragekit_d.3d"
SurfaceSkin 0 0 "Ragekit.png"
SurfaceSkin 0 1 "ragemap.png"
Scale 0.05 0.05 0.05
ZOffset 16
ROTATING
FrameIndex XZW1 A 0 0
}

View file

@ -399,9 +399,16 @@ misc/spawn sounds/CORK.ogg
misc/teleport sounds/general/teleport.ogg
misc/chat sounds/menu/chatsnd.ogg
misc/chat2 sounds/menu/chatsnd.ogg
misc/sundowner sounds/SUNDOWNER.ogg
armor/blastsuit sounds/items/blastsuit.ogg
armor/wararmor sounds/items/wararmor.ogg
armor/hit1 sounds/items/hullhit.ogg
armor/hit2 sounds/items/hullhit2.ogg
armor/hit3 sounds/items/hullhit3.ogg
armor/hit4 sounds/items/hullhit4.ogg
armor/hit5 sounds/items/hullhit5.ogg
$random armor/hit { armor/hit1 armor/hit2 armor/hit3 armor/hit4 armor/hit5 }
powerup/refresher sounds/items/refresh.ogg
powerup/sandwich sounds/CORK.ogg
@ -411,6 +418,13 @@ powerup/ghostend sounds/items/CloakOff.ogg
powerup/gravity sounds/items/gravityon.ogg
powerup/gravityact sounds/items/gravityact.ogg
powerup/gravityend sounds/items/gravityoff.ogg
powerup/invinciball sounds/items/invincion.ogg
powerup/invinciballhit sounds/items/invincihit.ogg
powerup/invinciballend sounds/items/invinciend.ogg
powerup/ragekit sounds/items/ragekiton.ogg
powerup/ragekitact sounds/items/ragekitact.ogg
powerup/ragekithit sounds/items/ragekithit.ogg
powerup/ragekitend sounds/items/ragekitend.ogg
menu/activate sounds/hmenu/hmenu1.ogg
menu/backup sounds/hmenu/hmenu2.ogg

Binary file not shown.

BIN
sounds/items/hullhit.ogg Normal file

Binary file not shown.

BIN
sounds/items/hullhit2.ogg Normal file

Binary file not shown.

BIN
sounds/items/hullhit3.ogg Normal file

Binary file not shown.

BIN
sounds/items/hullhit4.ogg Normal file

Binary file not shown.

BIN
sounds/items/hullhit5.ogg Normal file

Binary file not shown.

BIN
sounds/items/invincihit.ogg Normal file

Binary file not shown.

BIN
sounds/items/invincioff.ogg Normal file

Binary file not shown.

BIN
sounds/items/invincion.ogg Normal file

Binary file not shown.

BIN
sounds/items/ragekitact.ogg Normal file

Binary file not shown.

BIN
sounds/items/ragekithit.ogg Normal file

Binary file not shown.

BIN
sounds/items/ragekitoff.ogg Normal file

Binary file not shown.

BIN
sounds/items/ragekiton.ogg Normal file

Binary file not shown.

View file

@ -4,7 +4,7 @@ Class ArmorNugget : SWWMArmor
Default
{
Inventory.Icon "graphics/HUD/Icons/I_ArmorNugget.png";
Inventory.Amount 5;
Inventory.Amount 1;
Inventory.MaxAmount 200;
Inventory.InterHubAmount 200;
SWWMArmor.ArmorPriority 10;
@ -32,8 +32,8 @@ Class ArmorNuggetItem : SWWMSpareArmor
Stamina 1000;
Inventory.Icon "graphics/HUD/Icons/I_ArmorNugget.png";
Inventory.PickupMessage "$T_NUGGETA";
Inventory.MaxAmount 40;
Inventory.InterHubAmount 40;
Inventory.MaxAmount 50;
Inventory.InterHubAmount 50;
Inventory.UseSound "misc/armor_pkup";
SWWMSpareArmor.GiveArmor "ArmorNugget";
+INVENTORY.ALWAYSPICKUP;
@ -58,11 +58,10 @@ Class BlastSuit : SWWMArmor
Default
{
Inventory.Icon "graphics/HUD/Icons/I_BlastSuit.png";
Inventory.Amount 500;
Inventory.MaxAmount 500;
Inventory.InterHubAmount 500;
Inventory.Amount 200;
Inventory.MaxAmount 200;
Inventory.InterHubAmount 200;
SWWMArmor.ArmorPriority 2;
SWWMArmor.DrainFactor 1.;
SWWMArmor.DrainMessage "$D_BLASTSUIT";
SWWMArmor.GiverArmor "BlastSuitItem";
}
@ -104,11 +103,10 @@ Class WarArmor : SWWMArmor
Default
{
Inventory.Icon "graphics/HUD/Icons/I_WarArmor.png";
Inventory.Amount 1000;
Inventory.MaxAmount 1000;
Inventory.InterHubAmount 1000;
Inventory.Amount 600;
Inventory.MaxAmount 600;
Inventory.InterHubAmount 600;
SWWMArmor.ArmorPriority 6;
SWWMArmor.DrainFactor 1.0;
SWWMArmor.DrainMessage "$D_WARARMOR";
SWWMArmor.GiverArmor "WarArmorItem";
}

View file

@ -7,7 +7,8 @@ enum ESWWMGZChannels
CHAN_WEAPONEXTRA = 63203,
CHAN_POWERUP = 63204,
CHAN_POWERUPEXTRA = 63205,
CHAN_JETPACK = 63206
CHAN_JETPACK = 63206,
CHAN_ITEMEXTRA = 63207
};
// Misc. Utility code
@ -881,6 +882,12 @@ Class QueuedFlash
Actor cam;
}
Class LastLine
{
String type;
int lineno;
}
// Handler responsible for item replacements and whatever else
Class SWWMHandler : EventHandler
{
@ -891,6 +898,7 @@ Class SWWMHandler : EventHandler
transient Array<Int> combattics;
transient int highesttic;
transient Array<QueuedFlash> flashes;
transient Array<LastLine> lastlines;
bool tookdamage[MAXPLAYERS];
int spreecount[MAXPLAYERS];
int lastkill[MAXPLAYERS];
@ -901,7 +909,11 @@ Class SWWMHandler : EventHandler
static int AddOneliner( String type, int delay = 5 )
{
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return 0;
CVar voicetype = CVar.GetCVar('swwm_voicetype',players[consoleplayer]);
// suppress non-rage comments when ragekit is active, only screaming allowed
if ( players[consoleplayer].mo.FindInventory("RagekitPower") && (type != "ragekit") ) return 0;
int whichline;
int countem = 0, i = 1;
String testme, locme;
@ -914,9 +926,29 @@ Class SWWMHandler : EventHandler
}
while ( (testme != locme) && (i < 100) ); // gotta prevent infinite loops
if ( countem == 0 ) return 0;
whichline = Random[DemoLines](1,countem);
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return 0;
// check last line so we don't repeat
int last = 0, ent;
for ( int i=0; i<hnd.lastlines.Size(); i++ )
{
if ( hnd.lastlines[i].type != type ) continue;
last = hnd.lastlines[i].lineno;
ent = i;
break;
}
if ( last > 0 )
{
whichline = Random[DemoLines](1,countem-1);
if ( whichline >= last ) whichline++;
hnd.lastlines[ent].lineno = whichline;
}
else
{
whichline = Random[DemoLines](1,countem);
let lst = new("LastLine");
lst.type = type;
lst.lineno = whichline;
hnd.lastlines.Push(lst);
}
hnd.oneliner = String.Format("$SWWM_SUBS_%s_%s%d",voicetype.GetString().MakeUpper(),type.MakeUpper(),whichline);
hnd.onelinersnd = String.Format("voice/%s/%s%d",voicetype.GetString(),type,whichline);
hnd.onelinertic = gametic+delay;
@ -1490,6 +1522,8 @@ Class SWWMHandler : EventHandler
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 == 'Radsuit') || (e.Replacee == 'ArtiFly') || (e.Replacee == 'ArtiSpeedBoots') ) e.Replacement = 'GravitySuppressor';
else if ( (e.Replacee == 'InvulnerabilitySphere') || (e.Replacee == 'ArtiInvulnerability') || (e.Replacee == 'ArtiInvulnerability2') ) e.Replacement = 'FuckingInvinciball';
else if ( (e.Replacee == 'Berserk') || (e.Replacee == 'ArtiTomeOfPower') || (e.Replacee == 'ArtiDarkServant') || (e.Replacee == 'ArtiBoostArmor') ) e.Replacement = 'Ragekit';
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';
}

View file

@ -3,7 +3,7 @@ Class HealthNugget : Health
{
Default
{
Inventory.Amount 5;
Inventory.Amount 1;
Inventory.MaxAmount 200;
}
}
@ -90,8 +90,8 @@ Class HealthNuggetItem : SWWMHealth
Stamina 1200;
Inventory.Icon "graphics/HUD/Icons/I_HealthNugget.png";
Inventory.PickupMessage "$T_NUGGETH";
Inventory.MaxAmount 40;
Inventory.InterHubAmount 40;
Inventory.MaxAmount 50;
Inventory.InterHubAmount 50;
SWWMHealth.GiveHealth "HealthNugget";
+INVENTORY.ALWAYSPICKUP;
+COUNTITEM;

View file

@ -1,4 +1,18 @@
// Base class for all SWWM Armors
Mixin Class SWWMAutoUseFix
{
override bool HandlePickup( Inventory item )
{
bool res = Super.HandlePickup(item);
if ( res && (item.GetClass() == item.GetClass()) )
{
if ( Use(true) ) Amount--;
if ( Amount <= 0 ) DepleteOrDestroy();
}
return res;
}
}
Class SWWMArmor : Armor abstract
{
int priority;
@ -18,6 +32,7 @@ Class SWWMArmor : Armor abstract
+INVENTORY.UNDROPPABLE;
+INVENTORY.KEEPDEPLETED;
+INVENTORY.ALWAYSPICKUP;
SWWMArmor.DrainFactor 1.;
}
override void AttachToOwner( Actor other )
{
@ -47,6 +62,8 @@ Class SWWMArmor : Armor abstract
int saved;
if ( (amount > 0) && !DamageTypeDefinition.IgnoreArmor(damageType) && (damage > 0) )
{
SWWMHandler.DoFlash(Owner,Color(int(clamp(damage*.15,1,16)),255,224,192),3);
Owner.A_StartSound("armor/hit",CHAN_BODY,CHANF_DEFAULT,clamp(damage*.03,0.,1.),2.5);
saved = HandleDamage(damage,damageType,flags);
if ( amount <= int(ceil(saved*reduction)) ) saved = amount;
newdamage -= saved;
@ -59,7 +76,7 @@ Class SWWMArmor : Armor abstract
if ( Owner.CountInv(parent) > 0 )
{
Amount = default.Amount;
if ( GetDefaultByType(parent).UseSound ) Owner.A_StartSound(GetDefaultByType(parent).UseSound,CHAN_ITEM,CHANF_DEFAULT,.6);
if ( GetDefaultByType(parent).UseSound ) Owner.A_StartSound(GetDefaultByType(parent).UseSound,CHAN_ITEMEXTRA,CHANF_DEFAULT,.6);
Owner.TakeInventory(parent,1);
}
else
@ -77,6 +94,8 @@ Class SWWMArmor : Armor abstract
// gives armor when used
Class SWWMSpareArmor : Inventory abstract
{
Mixin SWWMAutoUseFix;
Class<SWWMArmor> giveme;
Property GiveArmor : giveme;
@ -87,7 +106,7 @@ Class SWWMSpareArmor : Inventory abstract
if ( !cur || (cur.Amount < cur.MaxAmount) )
{
Owner.GiveInventory(giveme,GetDefaultByType(giveme).Amount);
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEM,CHANF_DEFAULT,.6);
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA,CHANF_DEFAULT,.6);
SWWMHandler.DoFlash(Owner,Color(48,96,255,64),5);
return true;
}
@ -108,6 +127,8 @@ Class SWWMSpareArmor : Inventory abstract
Class SWWMHealth : Inventory abstract
{
Mixin SWWMAutoUseFix;
// can't use the Health class for whatever reason
// nice parser you got there I guess?
Class<Inventory> giveme;
@ -117,7 +138,7 @@ Class SWWMHealth : Inventory abstract
override bool Use( bool pickup )
{
if ( Owner.Health >= GetDefaultByType(giveme).MaxAmount ) return false;
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEM,CHANF_DEFAULT,.6);
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA,CHANF_DEFAULT,.6);
SWWMHandler.DoFlash(Owner,Color(48,64,128,255),5);
Owner.GiveInventory(giveme,GetDefaultByType(giveme).Amount);
return true;
@ -127,17 +148,22 @@ Class SWWMHealth : Inventory abstract
{
}
override void DoEffect()
{
Super.DoEffect();
if ( Amount <= 0 ) DepleteOrDestroy();
}
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);
if ( UseSound ) Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA,CHANF_DEFAULT,.6);
while ( (Amount > 0) && (newdamage > 0) )
{
newdamage = max(0,damage-GetDefaultByType(giveme).Amount);
AutoUseExtra();
Amount--;
if ( Amount <= 0 ) DepleteOrDestroy();
}
}
else newdamage = damage;
@ -416,7 +442,7 @@ Class SWWMWeapon : Weapon abstract
double diff = deltaangle(self.angle,AngleTo(d.HitActor));
self.angle += clamp(diff,-5.,5.);
dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Melee',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x));
SWWMHandler.DoKnockback(d.HitActor,d.HitDir+(0,0,.2),dmg*5000);
SWWMHandler.DoKnockback(d.HitActor,d.HitDir+(0,0,.2),dmg*2000);
if ( d.HitActor.player ) d.HitActor.A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
if ( !d.HitActor.bNOBLOOD )
{
@ -434,7 +460,7 @@ Class SWWMWeapon : Weapon abstract
}
return false;
}
action void A_Melee( int dmg = 20 )
action void A_Melee( int dmg = 40 )
{
for ( int i=0; i<16; i++ ) if ( TryMelee(angle+i*(45./16),dmg) || TryMelee(angle-i*(45./16),dmg) ) return;
}

View file

@ -346,8 +346,8 @@ Class Demolitionist : PlayerPawn
A_StartSound("demolitionist/jetstop",CHAN_JETPACK);
dashsnd = false;
}
if ( dashboost <= 0. ) return;
PainChance = InStateSequence(CurState,FindState("Dash"))?0:255;
if ( dashboost <= 0. ) return;
if ( InStateSequence(CurState,FindState("Dash")) )
{
Actor a;

View file

@ -1,6 +1,8 @@
// Powerups go here
Class GrilledCheeseSandwich : Inventory
{
Mixin SWWMAutoUseFix;
override Inventory CreateCopy( Actor other )
{
// additional lore
@ -11,7 +13,7 @@ Class GrilledCheeseSandwich : Inventory
{
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.A_StartSound(UseSound,CHAN_ITEMEXTRA);
Owner.GiveBody(1000,1000);
let n = Owner.FindInventory("ArmorNugget");
if ( !n ) Owner.GiveInventory("ArmorNugget",GetDefaultByType("ArmorNugget").MaxAmount);
@ -35,13 +37,18 @@ Class GrilledCheeseSandwich : Inventory
}
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 ( passive && (Owner.Health-damage <= 0) && (Amount > 0) )
{
newdamage = 0;
DoTheThing();
if ( Amount <= 0 ) DepleteOrDestroy();
Amount--;
}
}
override void DoEffect()
{
Super.DoEffect();
if ( Amount <= 0 ) DepleteOrDestroy();
}
Default
{
@ -135,7 +142,7 @@ Class GhostPower : PowerInvisibility
Super.EndEffect();
if ( !Owner ) return;
Owner.bNOTARGET = false;
Owner.A_StartSound("powerup/ghostend",CHAN_ITEM);
Owner.A_StartSound("powerup/ghostend",CHAN_ITEMEXTRA);
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_GHOSTARTI"));
}
@ -192,6 +199,8 @@ Class GhostArtifactX : Actor
Class GhostArtifact : Inventory
{
Mixin SWWMAutoUseFix;
Default
{
Tag "$T_GHOSTARTI";
@ -214,7 +223,7 @@ Class GhostArtifact : Inventory
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
Owner.A_StartSound(UseSound,CHAN_ITEM);
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
let g = GhostPower(Owner.FindInventory("GhostPower"));
if ( g ) g.EffectTics = g.default.EffectTics;
else Owner.GiveInventory("GhostPower",1);
@ -307,7 +316,7 @@ Class GravityPower : Powerup
Owner.bNOGRAVITY = false;
if ( Owner.pos.z > Owner.floorz ) Owner.player.centering = true;
}
Owner.A_StartSound("powerup/gravityend",CHAN_ITEM);
Owner.A_StartSound("powerup/gravityend",CHAN_ITEMEXTRA);
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_GRAVITYS"));
}
@ -326,10 +335,12 @@ Class GravityPower : Powerup
Class GravitySuppressor : Inventory
{
Mixin SWWMAutoUseFix;
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
Owner.A_StartSound(UseSound,CHAN_ITEM);
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
let g = GravityPower(Owner.FindInventory("GravityPower"));
if ( g ) g.EffectTics = g.default.EffectTics;
else Owner.GiveInventory("GravityPower",1);
@ -360,3 +371,298 @@ Class GravitySuppressor : Inventory
Stop;
}
}
Class InvinciballLight : PointLightAttenuated
{
Default
{
Args 192,64,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[Invinciball](10,12)*8;
bDORMANT = Powerup(master).isBlinking();
}
}
Class InvinciballPower : Powerup
{
Actor l;
int lasteffect;
Default
{
Powerup.Duration -90;
Inventory.Icon "graphics/HUD/Icons/I_Invinciball.png";
Powerup.Color "FF3000", 0.1;
}
override void InitEffect()
{
Super.InitEffect();
if ( !Owner ) return;
lasteffect = int.min;
l = Spawn("InvinciballLight",Owner.pos);
l.target = Owner;
l.master = self;
}
override void EndEffect()
{
Super.EndEffect();
if ( !Owner ) return;
Owner.A_StartSound("powerup/invinciballend",CHAN_ITEMEXTRA);
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_INVINCIBALL"));
}
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( (damage > 0) && passive )
{
if ( damageType == 'Ynykron' )
{
newdamage = damage;
return;
}
newdamage = 0;
if ( level.maptime > lasteffect+5 )
{
SWWMHandler.DoFlash(Owner,Color(64,255,64,0),15);
Owner.A_StartSound("powerup/invinciballhit",CHAN_POWERUP);
lasteffect = level.maptime;
}
}
}
}
Class FuckingInvinciball : Inventory
{
Mixin SWWMAutoUseFix;
override Inventory CreateCopy( Actor other )
{
// additional lore
SWWMLoreLibrary.Add(other.player,"Invinciball");
return Super.CreateCopy(other);
}
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
Owner.A_StartSound("misc/sundowner",CHAN_POWERUPEXTRA);
let i = InvinciballPower(Owner.FindInventory("InvinciballPower"));
if ( i ) i.EffectTics = i.default.EffectTics;
else Owner.GiveInventory("InvinciballPower",1);
return true;
}
Default
{
Tag "$T_INVINCIBALL";
Stamina 150000;
Inventory.Icon "graphics/HUD/Icons/I_Invinciball.png";
Inventory.PickupSound "misc/p_pkup";
Inventory.UseSound "powerup/invinciball";
Inventory.PickupMessage "$T_INVINCIBALL";
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 RagekitLight : PointLightAttenuated
{
Default
{
Args 255,0,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[Invinciball](10,12)*8;
bDORMANT = Powerup(master).isBlinking();
}
}
Class RageSnd : 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,.5);
}
else
{
A_SoundVolume(CHAN_VOICE,.4);
A_SoundVolume(CHAN_7,0.);
}
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_StartSound("powerup/ragekitact",CHAN_VOICE,CHANF_LOOPING,.4,1.5);
A_StartSound("powerup/ragekitact",CHAN_7,CHANF_LOOPING,.5,ATTN_NONE);
}
override void OnDestroy()
{
Super.OnDestroy();
A_StopSound(CHAN_VOICE);
A_StopSound(CHAN_7);
}
}
Class RagekitPower : Powerup
{
Actor l, snd;
int lasteffect, lastrage;
override double GetSpeedFactor()
{
return 2.;
}
Default
{
Powerup.Duration -30;
Inventory.Icon "graphics/HUD/Icons/I_Ragekit.png";
Powerup.Color "FF0000", 0.2;
}
override void InitEffect()
{
Super.InitEffect();
if ( !Owner ) return;
if ( Owner.player == players[consoleplayer] )
lastrage = SWWMHandler.AddOneliner("ragekit",20);
SWWMHandler.DoFlash(Owner,Color(64,255,0,0),30);
Owner.A_QuakeEx(8,8,8,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
lasteffect = int.min;
l = Spawn("RagekitLight",Owner.pos);
l.target = Owner;
l.master = self;
}
override void DoEffect()
{
Super.DoEffect();
if ( !Owner ) return;
if ( !snd ) snd = Spawn("RageSnd",Owner.pos);
snd.target = Owner;
snd.master = self;
if ( !(level.maptime%30) )
{
SWWMHandler.DoFlash(Owner,Color(16,255,0,0),5);
if ( (Owner.player == players[consoleplayer]) && (gametic > lastrage) )
lastrage = SWWMHandler.AddOneliner("ragekit",5);
Owner.A_QuakeEx(2,2,2,Random[Rage](1,2),0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.5);
}
}
override void EndEffect()
{
Super.EndEffect();
if ( !Owner ) return;
Owner.A_StartSound("powerup/ragekitend",CHAN_ITEMEXTRA);
if ( (EffectTics <= 0) && Owner && Owner.CheckLocalView() ) Console.Printf(StringTable.Localize("$D_RAGEKIT"));
}
override void ModifyDamage( int damage, Name damageType, out int newdamage, bool passive, Actor inflictor, Actor source, int flags )
{
if ( !passive && ((damageType == 'Melee') || (damageType == 'Dash') || (damageType == 'GroundPound')) )
{
newdamage = damage*8;
if ( level.maptime > lasteffect+5 )
{
SWWMHandler.DoFlash(Owner,Color(64,255,0,0),10);
Owner.A_QuakeEx(8,8,8,Random[Rage](3,8),0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
if ( (Owner.player == players[consoleplayer]) && (gametic > lastrage) )
lastrage = SWWMHandler.AddOneliner("ragekit",5);
Owner.A_StartSound("powerup/ragekithit",CHAN_POWERUP);
lasteffect = level.maptime;
}
}
else if ( passive )
newdamage = damage/4;
}
}
Class Ragekit : Inventory
{
Mixin SWWMAutoUseFix;
override bool Use( bool pickup )
{
if ( pickup && !deathmatch ) return false;
Owner.A_StartSound(UseSound,CHAN_ITEMEXTRA);
let r = RagekitPower(Owner.FindInventory("RagekitPower"));
if ( r ) r.EffectTics = r.default.EffectTics;
else Owner.GiveInventory("RagekitPower",1);
return true;
}
Default
{
Tag "$T_RAGEKIT";
Stamina 120000;
Inventory.Icon "graphics/HUD/Icons/I_Ragekit.png";
Inventory.PickupSound "misc/p_pkup";
Inventory.UseSound "powerup/ragekit";
Inventory.PickupMessage "$T_RAGEKIT";
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;
}
}