diff --git a/FuturePlans.md b/FuturePlans.md new file mode 100644 index 000000000..ebfa2a4cc --- /dev/null +++ b/FuturePlans.md @@ -0,0 +1,25 @@ +This is just a bit of "future planning" for stuff that I *might* add +after the first release. + +* DLC Weapon Set: + - Itamex Reinforced Hammer (UnSX 5) + - Gravity Gun (Ultra Suite) + - Splatter (SWWM) + - Skull Launcher (Weirdweapons) + - Blackfire Igniter (UnSX 5, Ultra Suite 3) + - Puntzer Gamma (Ultra Suite 2) + - Rail Carbine ("Tesla Beamer" in Ultra Suite 2 & 3) + - PROWEL & TADEL (Ultra Suite 2 & 3) + - Super Happy Fun Ball (SWWM Z) +* Additional Demolitionist Menu features + - Per-monster kill tracker in stats tab + - Music player with a selection of Saya's favourite tracks + - Pong minigame +* Additional HUD stuff + - Minimap with radar like in SWWM Z +* Character and item images for the library +* Full Mashiro model for Lämp easter egg +* Option to hear other players' voice lines +* Localization + - Spanish + - Japanese??? diff --git a/README.md b/README.md index 1fe507d2b..09e9101a0 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ re-added to their respective ammo type pool. The Spreadgun uses 10 gauge ammunition (like the Quadshot). -### 10Ga shells, replaces Clip / Shells, Wand Crystal / Ethereal Arrows, Flechette, Chaos Device +### 10Ga shells, replaces Clip / Shells, Wand Crystal / Ethereal Arrows, Flechette, Chaos Device/Banishment Device Available in the following types, with varying chances of appearing depending on replaced item, may also come in bundles: @@ -151,8 +151,8 @@ on replaced item, may also come in bundles: designed by someone completely insane, and definitely guaranteed to not fail catastrophically and blow up your gun, your hands, your arms, and the rest of your upper body. Unlike the others, this one is only available as a - rare drop from boss monsters, and as a rare spawn for chaos devices in - Heretic and Hexen. + rare drop from boss monsters, and as a rare spawn for chaos/banishment + devices in Heretic and Hexen. The two first standard types will also pop up in Hammerspace Embiggeners and Ammo Fabricators. @@ -349,7 +349,7 @@ have a spare. Most powerups can be toggled, unless specified otherwise. Health nuggets increase health by 5% up to a cap of 200. -### Health Tetrahedron, replaces Stimpak, Crystal Vial (Heretic) +### Health Tetrahedron, replaces Stimpak, Quartz Flask Health tetrahedrons provide a 15% health boost up to a cap of 100. @@ -373,14 +373,14 @@ The upper cap for these is 200%. Protection decreases by a 10% of absorbed damage. -### Blast Suit, replaces Green Armor, Silver Shield, Platinum Helm, Mesh Armor +### Blast Suit, replaces Green Armor, Silver Shield, Mesh Armor 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. -### War Armor, replaces Blue Armor, Enchanged Shield, Falcon Shield +### War Armor, replaces Blue Armor, Enchanted Shield, Falcon Shield Decent armor, protects very well against all damage. Reduction factors are as follows: @@ -390,7 +390,7 @@ follows: The armor can eat up a total of 1000 damage before breaking. -### Grilled Cheese Sandwich, replaces Megasphere, Morph Ovum, Banishment Device +### Grilled Cheese Sandwich, replaces Megasphere, Morph Ovum, Platinum Helm The ultimate meal. Grants a full 1000 health and magically gives you a full stack of armor nuggets, a blast suit and a war armor. In addition it prevents diff --git a/gldefs.chancebox b/gldefs.chancebox new file mode 100644 index 000000000..68b305119 --- /dev/null +++ b/gldefs.chancebox @@ -0,0 +1,53 @@ +HardwareShader Texture "models/Chancebox.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/Chancebox_mask.png" + Texture "envtex" "models/silvermap.png" + Texture "brighttex" "models/Chancebox_bright.png" +} +HardwareShader Texture "models/Chancebox_Tier2.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/Chancebox_mask.png" + Texture "envtex" "models/silvermap.png" + Texture "brighttex" "models/Chancebox_bright.png" +} +HardwareShader Texture "models/Chancebox_Tier3.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/Chancebox_mask.png" + Texture "envtex" "models/silvermap.png" + Texture "brighttex" "models/Chancebox_bright.png" +} +HardwareShader Texture "models/Chancebox_Tier4.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/Chancebox_mask.png" + Texture "envtex" "models/goldmap.png" + Texture "brighttex" "models/Chancebox_bright.png" +} + +PointLight CHANCELIGHT +{ + Color 1.0 0.7 0.2 + Size 50 + Offset 0 16 0 + Attenuate 1 +} + +Object DroppedChanceboxTier1 +{ + Frame "XZW2" { light "CHANCELIGHT" } +} +Object DroppedChanceboxTier2 +{ + Frame "XZW2" { light "CHANCELIGHT" } +} +Object DroppedChanceboxTier3 +{ + Frame "XZW2" { light "CHANCELIGHT" } +} +Object DroppedChanceboxTier4 +{ + Frame "XZW2" { light "CHANCELIGHT" } +} \ No newline at end of file diff --git a/gldefs.pickups b/gldefs.pickups new file mode 100644 index 000000000..ac78f2945 --- /dev/null +++ b/gldefs.pickups @@ -0,0 +1,102 @@ +HardwareShader Texture "models/Nugget_Armor.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/Nugget_mask.png" + Texture "envtex" "models/greenmap.png" + Texture "brighttex" "models/Nugget_mask.png" +} +HardwareShader Texture "models/Nugget.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/Nugget_mask.png" + Texture "envtex" "models/blumap.png" + Texture "brighttex" "models/Nugget_mask.png" +} +HardwareShader Texture "models/TetraHealth.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/TetraHealth_mask.png" + Texture "envtex" "models/blumap.png" + Texture "brighttex" "models/TetraHealth_mask.png" +} +HardwareShader Texture "models/CubeHealth.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/CubeHealth_mask.png" + Texture "envtex" "models/blumap.png" + Texture "brighttex" "models/CubeHealth_mask.png" +} +HardwareShader Texture "models/Refresher.png" +{ + Shader "shaders/glsl/Shinemask_bright.fp" + Texture "masktex" "models/Refresher_mask.png" + Texture "envtex" "models/purpmap.png" + Texture "brighttex" "models/Refresher_mask.png" +} +Brightmap Texture "models/GhostArtifact.png" +{ + Map "models/GhostArtifact_bright.png" +} + +PointLight ARMORNUGGETLIGHT +{ + Color 0.4 0.7 0.2 + Size 12 + Offset 0 16 0 + Attenuate 1 +} +Object ArmorNuggetItem +{ + Frame "XZW1" { light "ARMORNUGGETLIGHT" } +} +PointLight HEALTHNUGGETLIGHT +{ + Color 0.1 0.3 0.7 + Size 12 + Offset 0 16 0 + Attenuate 1 +} +Object HealthNuggetItem +{ + Frame "XZW1" { light "HEALTHNUGGETLIGHT" } +} + +PointLight GEOMHEALTHLIGHT +{ + Color 0.2 0.4 1.0 + Size 30 + Offset 0 16 0 + Attenuate 1 +} +Object TetraHealthItem +{ + Frame "XZW1" { light "GEOMHEALTHLIGHT" } +} +Object CubeHealthItem +{ + Frame "XZW1" { light "GEOMHEALTHLIGHT" } +} + +PointLight REFRESHERLIGHT +{ + Color 0.7 0.2 1.0 + Size 40 + Offset 0 16 0 + Attenuate 1 +} +Object RefresherItem +{ + Frame "XZW1" { light "REFRESHERLIGHT" } +} + +PointLight GHOSTARTILIGHT +{ + Color 0.8 0.6 1.0 + Size 40 + Offset 0 16 0 + Attenuate 1 +} +Object GhostArtifact +{ + Frame "XZW1" { light "GHOSTARTILIGHT" } +} diff --git a/graphics/HUD/HealthBarS.png b/graphics/HUD/HealthBarS.png index c78ac1010..97b59a046 100644 Binary files a/graphics/HUD/HealthBarS.png and b/graphics/HUD/HealthBarS.png differ diff --git a/graphics/HUD/Icons/I_Refresher.png b/graphics/HUD/Icons/I_Refresher.png new file mode 100644 index 000000000..8d5025f70 Binary files /dev/null and b/graphics/HUD/Icons/I_Refresher.png differ diff --git a/graphics/HUD/InventoryBox.png b/graphics/HUD/InventoryBox.png index d44a2e60b..b4321b823 100644 Binary files a/graphics/HUD/InventoryBox.png and b/graphics/HUD/InventoryBox.png differ diff --git a/graphics/tempbg.png b/graphics/tempbg.png index 889c262ab..c3eadd7bc 100644 Binary files a/graphics/tempbg.png and b/graphics/tempbg.png differ diff --git a/language.txt b/language.txt index bb449fb0d..9e0fa589e 100644 --- a/language.txt +++ b/language.txt @@ -160,7 +160,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 5,000 units of damage before breaking.\n" +"Durability: Can absorb a total of 500 units of damage before breaking.\n" "\n" "Addendum: The blast suit can be worn under other armor."; SWWM_LORETAG_COLLAR = "Lucky Collar"; @@ -518,11 +518,11 @@ SWWM_LORETXT_WARARMOR = "Summary: Very robust, durable plate armor. Made of the finest almasteel in Devanikna. Originally commissioned for the third entry in Zanaveth's Instant Action arena events.\n" "\n" "Protection:\n" -" - 90% reduction to heat, cold and electricity.\n" +" - 90% reduction to heat, cold, electricity, slime and other elemental types.\n" " - 80% reduction to all other types of damage.\n" " - Additional 70% reduction to explosions.\n" "\n" -"Durability: Can absorb a total of 10,000 units of damage before breaking.\n" +"Durability: Can absorb a total of 1000 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"; diff --git a/modeldef.chancebox b/modeldef.chancebox new file mode 100644 index 000000000..22efb7bba --- /dev/null +++ b/modeldef.chancebox @@ -0,0 +1,321 @@ +Model "FancyConfetti" +{ + Model 0 "models/extra/Flat_d.3d" + Scale 0.003 0.003 0.003 + ZOffset 1 + USEACTORPITCH + USEACTORROLL + + Skin 0 "models/goldmap.png" + FrameIndex XZW1 A 0 0 + Skin 0 "models/blumap.png" + FrameIndex XZW1 B 0 0 + Skin 0 "models/darkmap.png" + FrameIndex XZW1 C 0 0 + Skin 0 "models/greenmap.png" + FrameIndex XZW1 D 0 0 + Skin 0 "models/invincimap.png" + FrameIndex XZW1 E 0 0 + Skin 0 "models/pinkmap.png" + FrameIndex XZW1 F 0 0 + Skin 0 "models/purpmap.png" + FrameIndex XZW1 G 0 0 + Skin 0 "models/ragemap.png" + FrameIndex XZW1 H 0 0 + Skin 0 "models/redmap.png" + FrameIndex XZW1 I 0 0 + Skin 0 "models/silvermap.png" + FrameIndex XZW1 J 0 0 +} + +Model "ChanceboxTier1" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 24 + ROTATING + + FrameIndex XZW1 A 0 0 +} +Model "ChanceboxTier2" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox_Tier2.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 24 + ROTATING + + FrameIndex XZW1 A 0 0 +} +Model "ChanceboxTier3" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox_Tier3.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 24 + ROTATING + + FrameIndex XZW1 A 0 0 +} +Model "ChanceboxTier4" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox_Tier4.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 24 + ROTATING + + FrameIndex XZW1 A 0 0 +} + +Model "ChanceTopTier1" +{ + Path "models" + Model 0 "Chancebox_Top_d.3d" + Skin 0 "Chancebox.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 4 + + FrameIndex XZW1 A 0 0 +} +Model "ChanceTopTier2" +{ + Path "models" + Model 0 "Chancebox_Top_d.3d" + Skin 0 "Chancebox.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 4 + + FrameIndex XZW1 A 0 0 +} +Model "ChanceTopTier3" +{ + Path "models" + Model 0 "Chancebox_Top_d.3d" + Skin 0 "Chancebox_Tier3.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 4 + + FrameIndex XZW1 A 0 0 +} +Model "ChanceTopTier4" +{ + Path "models" + Model 0 "Chancebox_Top_d.3d" + Skin 0 "Chancebox_Tier4.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 4 + + FrameIndex XZW1 A 0 0 +} + +Model "ChanceSideTier1" +{ + Path "models" + Model 0 "Chancebox_Side_d.3d" + Skin 0 "Chancebox.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + + FrameIndex XZW1 A 0 0 +} +Model "ChanceSideTier2" +{ + Path "models" + Model 0 "Chancebox_Side_d.3d" + Skin 0 "Chancebox.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + + FrameIndex XZW1 A 0 0 +} +Model "ChanceSideTier3" +{ + Path "models" + Model 0 "Chancebox_Side_d.3d" + Skin 0 "Chancebox_Tier3.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + + FrameIndex XZW1 A 0 0 +} +Model "ChanceSideTier4" +{ + Path "models" + Model 0 "Chancebox_Side_d.3d" + Skin 0 "Chancebox_Tier4.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + + FrameIndex XZW1 A 0 0 +} + +Model "DroppedChanceboxTier1" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + USEACTORPITCH + USEACTORROLL + + FrameIndex XZW1 A 0 0 + // shake + FrameIndex XZW1 B 0 1 + FrameIndex XZW1 C 0 2 + FrameIndex XZW1 D 0 3 + FrameIndex XZW1 E 0 4 + FrameIndex XZW1 F 0 5 + FrameIndex XZW1 G 0 6 + // deploy + FrameIndex XZW2 A 0 8 + FrameIndex XZW2 B 0 9 + FrameIndex XZW2 C 0 10 + FrameIndex XZW2 D 0 11 + FrameIndex XZW2 E 0 12 + FrameIndex XZW2 F 0 13 + FrameIndex XZW2 G 0 14 + FrameIndex XZW2 H 0 15 + FrameIndex XZW2 I 0 16 + FrameIndex XZW2 J 0 17 + FrameIndex XZW2 K 0 18 + FrameIndex XZW2 L 0 19 + FrameIndex XZW2 M 0 20 + FrameIndex XZW2 N 0 21 + FrameIndex XZW2 O 0 22 + FrameIndex XZW2 P 0 23 + FrameIndex XZW2 Q 0 24 +} +Model "DroppedChanceboxTier2" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox_Tier2.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + USEACTORPITCH + USEACTORROLL + + FrameIndex XZW1 A 0 0 + // shake + FrameIndex XZW1 B 0 1 + FrameIndex XZW1 C 0 2 + FrameIndex XZW1 D 0 3 + FrameIndex XZW1 E 0 4 + FrameIndex XZW1 F 0 5 + FrameIndex XZW1 G 0 6 + // deploy + FrameIndex XZW2 A 0 8 + FrameIndex XZW2 B 0 9 + FrameIndex XZW2 C 0 10 + FrameIndex XZW2 D 0 11 + FrameIndex XZW2 E 0 12 + FrameIndex XZW2 F 0 13 + FrameIndex XZW2 G 0 14 + FrameIndex XZW2 H 0 15 + FrameIndex XZW2 I 0 16 + FrameIndex XZW2 J 0 17 + FrameIndex XZW2 K 0 18 + FrameIndex XZW2 L 0 19 + FrameIndex XZW2 M 0 20 + FrameIndex XZW2 N 0 21 + FrameIndex XZW2 O 0 22 + FrameIndex XZW2 P 0 23 + FrameIndex XZW2 Q 0 24 +} +Model "DroppedChanceboxTier3" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox_Tier3.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + USEACTORPITCH + USEACTORROLL + + FrameIndex XZW1 A 0 0 + // shake + FrameIndex XZW1 B 0 1 + FrameIndex XZW1 C 0 2 + FrameIndex XZW1 D 0 3 + FrameIndex XZW1 E 0 4 + FrameIndex XZW1 F 0 5 + FrameIndex XZW1 G 0 6 + // deploy + FrameIndex XZW2 A 0 8 + FrameIndex XZW2 B 0 9 + FrameIndex XZW2 C 0 10 + FrameIndex XZW2 D 0 11 + FrameIndex XZW2 E 0 12 + FrameIndex XZW2 F 0 13 + FrameIndex XZW2 G 0 14 + FrameIndex XZW2 H 0 15 + FrameIndex XZW2 I 0 16 + FrameIndex XZW2 J 0 17 + FrameIndex XZW2 K 0 18 + FrameIndex XZW2 L 0 19 + FrameIndex XZW2 M 0 20 + FrameIndex XZW2 N 0 21 + FrameIndex XZW2 O 0 22 + FrameIndex XZW2 P 0 23 + FrameIndex XZW2 Q 0 24 +} +Model "DroppedChanceboxTier4" +{ + Path "models" + Model 0 "Chancebox_d.3d" + Skin 0 "Chancebox_Tier4.png" + Scale 0.25 0.25 0.25 + AngleOffset -90 + ZOffset 16 + USEACTORPITCH + USEACTORROLL + + FrameIndex XZW1 A 0 0 + // shake + FrameIndex XZW1 B 0 1 + FrameIndex XZW1 C 0 2 + FrameIndex XZW1 D 0 3 + FrameIndex XZW1 E 0 4 + FrameIndex XZW1 F 0 5 + FrameIndex XZW1 G 0 6 + // deploy + FrameIndex XZW2 A 0 8 + FrameIndex XZW2 B 0 9 + FrameIndex XZW2 C 0 10 + FrameIndex XZW2 D 0 11 + FrameIndex XZW2 E 0 12 + FrameIndex XZW2 F 0 13 + FrameIndex XZW2 G 0 14 + FrameIndex XZW2 H 0 15 + FrameIndex XZW2 I 0 16 + FrameIndex XZW2 J 0 17 + FrameIndex XZW2 K 0 18 + FrameIndex XZW2 L 0 19 + FrameIndex XZW2 M 0 20 + FrameIndex XZW2 N 0 21 + FrameIndex XZW2 O 0 22 + FrameIndex XZW2 P 0 23 + FrameIndex XZW2 Q 0 24 +} diff --git a/modeldef.pickups b/modeldef.pickups index 8b1378917..c49b38ca8 100644 --- a/modeldef.pickups +++ b/modeldef.pickups @@ -1 +1,134 @@ +Model "ArmorNuggetItem" +{ + Path "models" + Model 0 "Nugget_d.3d" + Skin 0 "Nugget_Armor.png" + Scale 0.03 0.03 0.03 + ZOffset 16 + ROTATING + FrameIndex XZW1 A 0 0 + FrameIndex XZW1 B 0 1 + FrameIndex XZW1 C 0 2 + FrameIndex XZW1 D 0 3 + FrameIndex XZW1 E 0 4 + FrameIndex XZW1 F 0 5 + FrameIndex XZW1 G 0 6 + FrameIndex XZW1 H 0 7 +} +Model "HealthNuggetItem" +{ + Path "models" + Model 0 "Nugget_d.3d" + Skin 0 "Nugget.png" + Scale 0.03 0.03 0.03 + ZOffset 16 + ROTATING + + FrameIndex XZW1 A 0 0 + FrameIndex XZW1 B 0 1 + FrameIndex XZW1 C 0 2 + FrameIndex XZW1 D 0 3 + FrameIndex XZW1 E 0 4 + FrameIndex XZW1 F 0 5 + FrameIndex XZW1 G 0 6 + FrameIndex XZW1 H 0 7 +} + +Model "TetraHealthItem" +{ + Path "models" + Model 0 "TetraHealth_d.3d" + Skin 0 "TetraHealth.png" + Scale 0.05 0.05 0.05 + ZOffset 16 + ROTATING + + FrameIndex XZW1 A 0 0 +} + +Model "CubeHealthItem" +{ + Path "models" + Model 0 "CubeHealth_d.3d" + Skin 0 "CubeHealth.png" + Scale 0.05 0.05 0.05 + ZOffset 16 + ROTATING + + FrameIndex XZW1 A 0 0 +} + +Model "RefresherItem" +{ + Path "models" + Model 0 "Refresher_d.3d" + Skin 0 "Refresher.png" + Scale 0.05 0.05 0.05 + ZOffset 16 + RollOffset 30 + ROTATING + + FrameIndex XZW1 A 0 0 +} + +Model "BlastSuitItem" +{ + Path "models" + Model 0 "BlastSuit_d.3d" + Skin 0 "BlastSuit.png" + Scale 0.05 0.05 0.05 + ZOffset 20 + ROTATING + + FrameIndex XZW1 A 0 0 +} + +Model "WarArmorItem" +{ + Path "models" + Model 0 "WarArmor_d.3d" + Skin 0 "WarArmor.png" + Scale 0.07 0.07 0.07 + ZOffset 20 + ROTATING + + FrameIndex XZW1 A 0 0 +} + +Model "GrilledCheeseSandwich" +{ + Path "models" + Model 0 "Sandwich_d.3d" + SurfaceSkin 0 0 "goldmap.png" + SurfaceSkin 0 1 "Sandwich.png" + Scale 0.05 0.05 0.05 + PitchOffset -45 + ZOffset 16 + ROTATING + + FrameIndex XZW1 A 0 0 +} + +Model "GhostArtifact" +{ + Path "models" + Model 0 "GhostArtifact_d.3d" + SurfaceSkin 0 1 "GhostArtifact.png" + Scale 0.05 0.05 0.05 + ZOffset 16 + ROTATING + + FrameIndex XZW1 A 0 0 +} +Model "GhostArtifactX" +{ + Path "models" + Model 0 "GhostArtifact_d.3d" + SurfaceSkin 0 0 "darkmap.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 2a75179e4..4a46dc1b1 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -309,6 +309,20 @@ demolitionist/bump2 sounds/demolitionist/demobump2.ogg demolitionist/bump3 sounds/demolitionist/demobump3.ogg $random demolitionist/bump { demolitionist/bump1 demolitionist/bump2 demolitionist/bump3 } +$playersound demolitionist neutral *grunt DSEMPTY +$playeralias demolitionist neutral *pain100 demolitionist/lopain +$playeralias demolitionist neutral *pain75 demolitionist/pain +$playeralias demolitionist neutral *pain50 demolitionist/pain +$playeralias demolitionist neutral *pain25 demolitionist/hipain +$playersound demolitionist neutral *usefail sounds/menu/failuse.ogg +$playeralias demolitionist neutral *death demolitionist/death +$playeralias demolitionist neutral *xdeath demolitionist/xdeath +$playeralias demolitionist neutral *gibbed demolitionist/xdeath +$playeralias demolitionist neutral *wimpydeath demolitionist/wdeath +$playersound demolitionist neutral *land DSEMPTY +$playersound demolitionist neutral *falling DSEMPTY +$playersound demolitionist neutral *puzzfail sounds/menu/failuse.ogg + explodium/casing1 sounds/explodiumgun/expl_case1.ogg explodium/casing2 sounds/explodiumgun/expl_case2.ogg explodium/casing3 sounds/explodiumgun/expl_case3.ogg @@ -361,19 +375,16 @@ $limit candygun/hit 32 $limit candygun/maghit 32 $limit candygun/gunhit 32 -$playersound demolitionist neutral *grunt DSEMPTY -$playeralias demolitionist neutral *pain100 demolitionist/lopain -$playeralias demolitionist neutral *pain75 demolitionist/pain -$playeralias demolitionist neutral *pain50 demolitionist/pain -$playeralias demolitionist neutral *pain25 demolitionist/hipain -$playersound demolitionist neutral *usefail sounds/menu/failuse.ogg -$playeralias demolitionist neutral *death demolitionist/death -$playeralias demolitionist neutral *xdeath demolitionist/xdeath -$playeralias demolitionist neutral *gibbed demolitionist/xdeath -$playeralias demolitionist neutral *wimpydeath demolitionist/wdeath -$playersound demolitionist neutral *land DSEMPTY -$playersound demolitionist neutral *falling DSEMPTY -$playersound demolitionist neutral *puzzfail sounds/menu/failuse.ogg +chancebox/explode1 sounds/items/lootexpl1.ogg +chancebox/explode2 sounds/items/lootexpl2.ogg +chancebox/explode3 sounds/items/lootexpl3.ogg +$random chancebox/explode { chancebox/explode1 chancebox/explode2 chancebox/explode3 } +chancebox/land1 sounds/items/lootland1.ogg +chancebox/land2 sounds/items/lootland2.ogg +chancebox/land3 sounds/items/lootland3.ogg +$random chancebox/land { chancebox/land1 chancebox/land2 chancebox/land3 } +chancebox/drumroll sounds/DRUMROLL.ogg +chancebox/tada sounds/TADA.ogg misc/secret sounds/menu/findsecret.ogg misc/keytry sounds/menu/failuse.ogg @@ -389,6 +400,15 @@ misc/teleport sounds/general/teleport.ogg misc/chat sounds/menu/chatsnd.ogg misc/chat2 sounds/menu/chatsnd.ogg +armor/blastsuit sounds/items/blastsuit.ogg +armor/wararmor sounds/items/wararmor.ogg + +powerup/refresher sounds/items/refresh.ogg +powerup/sandwich sounds/CORK.ogg +powerup/ghost sounds/items/CloakOn.ogg +powerup/ghostact sounds/items/CloakLoop3.ogg +powerup/ghostend sounds/items/CloakOff.ogg + menu/activate sounds/hmenu/hmenu1.ogg menu/backup sounds/hmenu/hmenu2.ogg menu/prompt sounds/hmenu/hmenu1.ogg @@ -405,5 +425,4 @@ menu/demosel sounds/menu/menuset.ogg menu/demoscroll sounds/menu/menuscroll.ogg menu/democlose sounds/menu/menuclose.ogg -menu/invsel sounds/menu/invsel.ogg menu/noinvuse sounds/menu/failinv.ogg diff --git a/sounds/DRUMROLL.ogg b/sounds/DRUMROLL.ogg new file mode 100644 index 000000000..47c65bd51 Binary files /dev/null and b/sounds/DRUMROLL.ogg differ diff --git a/sounds/TADA.ogg b/sounds/TADA.ogg new file mode 100644 index 000000000..5a7ad50d9 Binary files /dev/null and b/sounds/TADA.ogg differ diff --git a/sounds/items/CloakLoop3.ogg b/sounds/items/CloakLoop3.ogg new file mode 100644 index 000000000..013260382 Binary files /dev/null and b/sounds/items/CloakLoop3.ogg differ diff --git a/sounds/items/CloakOff.ogg b/sounds/items/CloakOff.ogg new file mode 100644 index 000000000..cc85d1b09 Binary files /dev/null and b/sounds/items/CloakOff.ogg differ diff --git a/sounds/items/CloakOn.ogg b/sounds/items/CloakOn.ogg new file mode 100644 index 000000000..ba81a1706 Binary files /dev/null and b/sounds/items/CloakOn.ogg differ diff --git a/sounds/items/blastsuit.ogg b/sounds/items/blastsuit.ogg new file mode 100644 index 000000000..4d4e15117 Binary files /dev/null and b/sounds/items/blastsuit.ogg differ diff --git a/sounds/items/blastsuit.wav b/sounds/items/blastsuit.wav deleted file mode 100644 index 9f5a68431..000000000 Binary files a/sounds/items/blastsuit.wav and /dev/null differ diff --git a/sounds/items/lootexpl1.ogg b/sounds/items/lootexpl1.ogg new file mode 100644 index 000000000..712ce12ce Binary files /dev/null and b/sounds/items/lootexpl1.ogg differ diff --git a/sounds/items/lootexpl2.ogg b/sounds/items/lootexpl2.ogg new file mode 100644 index 000000000..cdc9493e1 Binary files /dev/null and b/sounds/items/lootexpl2.ogg differ diff --git a/sounds/items/lootexpl3.ogg b/sounds/items/lootexpl3.ogg new file mode 100644 index 000000000..9b9b240de Binary files /dev/null and b/sounds/items/lootexpl3.ogg differ diff --git a/sounds/items/lootland1.ogg b/sounds/items/lootland1.ogg new file mode 100644 index 000000000..b3874fa61 Binary files /dev/null and b/sounds/items/lootland1.ogg differ diff --git a/sounds/items/lootland2.ogg b/sounds/items/lootland2.ogg new file mode 100644 index 000000000..93566e339 Binary files /dev/null and b/sounds/items/lootland2.ogg differ diff --git a/sounds/items/lootland3.ogg b/sounds/items/lootland3.ogg new file mode 100644 index 000000000..a2dd90806 Binary files /dev/null and b/sounds/items/lootland3.ogg differ diff --git a/sounds/items/refresh.ogg b/sounds/items/refresh.ogg new file mode 100644 index 000000000..16380b620 Binary files /dev/null and b/sounds/items/refresh.ogg differ diff --git a/sounds/items/wararmor.ogg b/sounds/items/wararmor.ogg new file mode 100644 index 000000000..b530a153f Binary files /dev/null and b/sounds/items/wararmor.ogg differ diff --git a/sounds/items/wararmor.wav b/sounds/items/wararmor.wav deleted file mode 100644 index 090d2ff95..000000000 Binary files a/sounds/items/wararmor.wav and /dev/null differ diff --git a/sounds/menu/failuse.ogg b/sounds/menu/failuse.ogg index 712c360a7..934e86887 100644 Binary files a/sounds/menu/failuse.ogg and b/sounds/menu/failuse.ogg differ diff --git a/swwmvoicepack.txt b/swwmvoicepack.txt index 777d07e00..4e614588c 100644 --- a/swwmvoicepack.txt +++ b/swwmvoicepack.txt @@ -3,7 +3,8 @@ # file in the root of the zip/pk3/whatever, wads are not supported # list the names of your voice types here and don't forget to define your voice # lines using a similar format to the base game's: - +# voice//<#> for the sndinfo entries +# SWWM_SUBS__<#> for the language strings # with the exception of pain/death/grunt sounds, all lines you may want to # register require a subtitle language string so they can be properly detected, # but you can set them to an empty string if you don't want text to display. diff --git a/zscript.txt b/zscript.txt index f6d1a9ced..13f1f44a7 100644 --- a/zscript.txt +++ b/zscript.txt @@ -18,6 +18,7 @@ version "4.3" #include "zscript/swwm_armor.zsc" #include "zscript/swwm_powerup.zsc" #include "zscript/swwm_ammo.zsc" +#include "zscript/swwm_chancebox.zsc" #include "zscript/swwm_jackhammer.zsc" #include "zscript/swwm_deepdarkimpact.zsc" #include "zscript/swwm_splode.zsc" diff --git a/zscript/swwm_ammo.zsc b/zscript/swwm_ammo.zsc index 56e8a890b..865d4e9b4 100644 --- a/zscript/swwm_ammo.zsc +++ b/zscript/swwm_ammo.zsc @@ -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 diff --git a/zscript/swwm_armor.zsc b/zscript/swwm_armor.zsc index ce9286830..f7bb1d018 100644 --- a/zscript/swwm_armor.zsc +++ b/zscript/swwm_armor.zsc @@ -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; + } +} \ No newline at end of file diff --git a/zscript/swwm_chancebox.zsc b/zscript/swwm_chancebox.zsc new file mode 100644 index 000000000..a5263beb9 --- /dev/null +++ b/zscript/swwm_chancebox.zsc @@ -0,0 +1,516 @@ +// gacha nonsense + +Class Chancebox : Inventory abstract +{ + Class 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 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; i40,"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; + } +} diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index a2f0ac69c..e2d7da1d9 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -1277,7 +1277,8 @@ Class SWWMHandler : EventHandler static const Class purplepool[] = {"PurpleShell","PurpleShell2","PurpleShell4"}; static const Class bluepool[] = {"BlueShell","BlueShell2","BlueShell4","BlueShell8"}; static const Class 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 ) diff --git a/zscript/swwm_health.zsc b/zscript/swwm_health.zsc index 3073d4f5f..de5851759 100644 --- a/zscript/swwm_health.zsc +++ b/zscript/swwm_health.zsc @@ -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; + } +} diff --git a/zscript/swwm_hud.zsc b/zscript/swwm_hud.zsc index 9b902460c..acf87c365 100644 --- a/zscript/swwm_hud.zsc +++ b/zscript/swwm_hud.zsc @@ -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 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 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); diff --git a/zscript/swwm_inventory.zsc b/zscript/swwm_inventory.zsc index 40823f8c0..cc9886882 100644 --- a/zscript/swwm_inventory.zsc +++ b/zscript/swwm_inventory.zsc @@ -2,8 +2,14 @@ Class SWWMArmor : Armor abstract { int priority; + double reduction; + String drainmsg; + Class 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 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 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 diff --git a/zscript/swwm_menu.zsc b/zscript/swwm_menu.zsc index 778cf47fd..4aee8a0a8 100644 --- a/zscript/swwm_menu.zsc +++ b/zscript/swwm_menu.zsc @@ -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= 369 ) diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index bbb000c6d..2592f56d5 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -124,6 +124,19 @@ Class Demolitionist : PlayerPawn if ( !item.CallTryPickup(self) ) item.Destroy(); } } + // Also give spares + for ( int i=0; i)(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 ) diff --git a/zscript/swwm_powerup.zsc b/zscript/swwm_powerup.zsc index c1290dc30..c08cca976 100644 --- a/zscript/swwm_powerup.zsc +++ b/zscript/swwm_powerup.zsc @@ -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; + } +}