diff --git a/README.md b/README.md index 09e9101a0..9c9e3f294 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/gldefs.pickups b/gldefs.pickups index 49cc23fc2..dc207b4c1 100644 --- a/gldefs.pickups +++ b/gldefs.pickups @@ -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" } +} diff --git a/language.txt b/language.txt index 48c2f2074..06198051c 100644 --- a/language.txt +++ b/language.txt @@ -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."; diff --git a/modeldef.pickups b/modeldef.pickups index b5b79f7da..1a87fcead 100644 --- a/modeldef.pickups +++ b/modeldef.pickups @@ -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 +} diff --git a/sndinfo.txt b/sndinfo.txt index 175b398e2..41ba30244 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -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 diff --git a/sounds/SUNDOWNER.ogg b/sounds/SUNDOWNER.ogg index eb8fb7a56..c3887bd7e 100644 Binary files a/sounds/SUNDOWNER.ogg and b/sounds/SUNDOWNER.ogg differ diff --git a/sounds/items/hullhit.ogg b/sounds/items/hullhit.ogg new file mode 100644 index 000000000..de804d074 Binary files /dev/null and b/sounds/items/hullhit.ogg differ diff --git a/sounds/items/hullhit2.ogg b/sounds/items/hullhit2.ogg new file mode 100644 index 000000000..812a5be3e Binary files /dev/null and b/sounds/items/hullhit2.ogg differ diff --git a/sounds/items/hullhit3.ogg b/sounds/items/hullhit3.ogg new file mode 100644 index 000000000..9b1fb8673 Binary files /dev/null and b/sounds/items/hullhit3.ogg differ diff --git a/sounds/items/hullhit4.ogg b/sounds/items/hullhit4.ogg new file mode 100644 index 000000000..5cb09ff6e Binary files /dev/null and b/sounds/items/hullhit4.ogg differ diff --git a/sounds/items/hullhit5.ogg b/sounds/items/hullhit5.ogg new file mode 100644 index 000000000..3c14659b4 Binary files /dev/null and b/sounds/items/hullhit5.ogg differ diff --git a/sounds/items/invincihit.ogg b/sounds/items/invincihit.ogg new file mode 100644 index 000000000..9f72cad23 Binary files /dev/null and b/sounds/items/invincihit.ogg differ diff --git a/sounds/items/invincioff.ogg b/sounds/items/invincioff.ogg new file mode 100644 index 000000000..e0983b54f Binary files /dev/null and b/sounds/items/invincioff.ogg differ diff --git a/sounds/items/invincion.ogg b/sounds/items/invincion.ogg new file mode 100644 index 000000000..e6cf8c120 Binary files /dev/null and b/sounds/items/invincion.ogg differ diff --git a/sounds/items/ragekitact.ogg b/sounds/items/ragekitact.ogg new file mode 100644 index 000000000..0d9205ded Binary files /dev/null and b/sounds/items/ragekitact.ogg differ diff --git a/sounds/items/ragekithit.ogg b/sounds/items/ragekithit.ogg new file mode 100644 index 000000000..95361b28d Binary files /dev/null and b/sounds/items/ragekithit.ogg differ diff --git a/sounds/items/ragekitoff.ogg b/sounds/items/ragekitoff.ogg new file mode 100644 index 000000000..d195f2206 Binary files /dev/null and b/sounds/items/ragekitoff.ogg differ diff --git a/sounds/items/ragekiton.ogg b/sounds/items/ragekiton.ogg new file mode 100644 index 000000000..f6470de7c Binary files /dev/null and b/sounds/items/ragekiton.ogg differ diff --git a/zscript/swwm_armor.zsc b/zscript/swwm_armor.zsc index a4f2166db..1cf24ce68 100644 --- a/zscript/swwm_armor.zsc +++ b/zscript/swwm_armor.zsc @@ -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"; } diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index 0970d4acb..3ff4ed6cc 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -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 combattics; transient int highesttic; transient Array flashes; + transient Array 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 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'; } diff --git a/zscript/swwm_health.zsc b/zscript/swwm_health.zsc index 5150292f1..e3d140cb8 100644 --- a/zscript/swwm_health.zsc +++ b/zscript/swwm_health.zsc @@ -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; diff --git a/zscript/swwm_inventory.zsc b/zscript/swwm_inventory.zsc index ba6ce5330..c838522c7 100644 --- a/zscript/swwm_inventory.zsc +++ b/zscript/swwm_inventory.zsc @@ -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 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 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; } diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index 49e9c5652..4b2cf4298 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -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; diff --git a/zscript/swwm_powerup.zsc b/zscript/swwm_powerup.zsc index cf0131119..da7e1534a 100644 --- a/zscript/swwm_powerup.zsc +++ b/zscript/swwm_powerup.zsc @@ -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; + } +}