diff --git a/README.md b/README.md index 88eb97d0b..7c4e6178a 100644 --- a/README.md +++ b/README.md @@ -247,8 +247,8 @@ Secondary fire is a concentrated beam shot, a very old thing from the original UnSX 1 incarnation. The beam can penetrate multiple solid targets. Reload deploys a capsule that releases a massive sphere of pure energy -that tracks down any hostile targets. It has a rather limited lifespan, and can -be even shot down. +that tracks down any hostile targets. It will rip through everything and even +bounce off surfaces, but it has a rather limited lifespan. If the beam hits either of the other energy blobs, they will detonate with highly amplified damage and range. @@ -267,15 +267,14 @@ you can aim straight. Primary fire shoots, duh. -Secondary fire toggles the recoil compensators. These small jet engines can -potentially deal damage to yourself if you don't have any armor, so be careful. +Secondary fire uses the scope. Can be held to go up to 16x. Reload reloads (what else is new). -Zoom uses the scope. Can be held to go up to 16x. - This weapon is generally not recommended for human use outside of power armor. -Good thing you're not a human, then. +Good thing you're not a human, then. Still, the recoil compensator jet engines +can potentially deal damage to yourself if you don't have any armor, so be +careful. ### 1.150 XSB Bullets, replaces Cells, Runes diff --git a/credits.txt b/credits.txt index 70d6c9b2d..883b88612 100644 --- a/credits.txt +++ b/credits.txt @@ -20,7 +20,7 @@ Most of the work here is original, but there are some notable exceptions: - Title theme, "Traumatic State", by Teque (which a lot of people just know as "the AS-Golgotha music"). - Intermission theme, "Dragony", also by Teque (very comfy music considering the rest of his repertoire). - Trailer theme, "Gateways Part II", also by Teque, and Cube (pretty cool track tbh). - - The anti-BD feature uses art by IOSYS, edited into the Doom palette. + - The anti-BD feature uses art and music by IOSYS, art was edited into the Doom palette. - The crash handler uses a sound bit from Umineko and a short clip of the Curb Your Enthusiasm theme. - Tewi font by lucy (https://github.com/lucy/tewi-font). Modified to add gradients and drop shadow. - MPlus font by M⁺ FONTS PROJECT (http://mplus-fonts.osdn.jp/mplus-bitmap-fonts). Modified to add gradients and drop shadow. diff --git a/language.def_base b/language.def_base index 254b30ca2..0efd9431a 100644 --- a/language.def_base +++ b/language.def_base @@ -145,6 +145,14 @@ QUITMSG12 = "Yeah, I'd need a break after\n" QUITMSG13 = "See you later\n" "Space Cowboy..."; QUITMSG14 = "To be continued?"; +QUITMSG15 = "For the last time, Icarus, the mod's\n" + "name is NOT pronounced 'Swim Jizz'!"; +QUITMSG16 = "AHDSAKAFAJDAGS!"; +QUITMSG17 = "Butt bots gonna bot."; +QUITMSG18 = "WHO IN THEIR RIGHT MIND\n" + "WOULD FROST A CAKE WITH THEIR BUTT?"; +QUITMSG19 = "World hard and cold,\n" + "tiddy soft and warm."; E1TEXT = "You still have no idea how you ended\n" "up in the old UAC Phobos Base, but\n" diff --git a/language.def_lore b/language.def_lore index f35c6d19f..da84654dd 100644 --- a/language.def_lore +++ b/language.def_lore @@ -1001,12 +1001,10 @@ SWWM_LORETXT_SILVERBULLET = "\n" "Primary Fire: Shoot the bullet. Any small targets hit by it are pretty much dead.\n" "\n" -"Secondary Fire: Toggle the recoil compensators. Disabling the recoil compensating jets is not recommended for human users not equipped with power armor or a Silver rated exoskeleton.\n" +"Secondary Fire: Custom-tailored adjustable telescopic sight, up to 16x. Equipped with a soft foam covering to protect the user's face during scoped fire.\n" "\n" "Reloading: Reloads the weapon.\n" "\n" -"Zoom: Custom-tailored adjustable telescopic sight, up to 16x. Equipped with a soft foam covering to protect the user's face during scoped fire.\n" -"\n" "Addendum: The burst from the jets can cause minor damage to the user unless they are wearing protective gear."; SWWM_LORETAG_SPARKSTER = "Biospark Carbine"; diff --git a/language.def_menu b/language.def_menu index 2d03f4f8f..4a2203be1 100644 --- a/language.def_menu +++ b/language.def_menu @@ -8,7 +8,7 @@ SWWM_RELOADFIRE = "Reload"; SWWM_ZOOMFIRE = "Tertiary Fire / Zoom"; SWWM_MELEE = "Melee Attack"; SWWM_DASH = "Dash"; -SWWM_GESTURE1 = "Point Down"; +SWWM_GESTURE1 = "Wave"; SWWM_GESTURE2 = "Thumbs Up"; SWWM_GESTURE3 = "Victory"; SWWM_KBASE = "Demolitionist Menu"; diff --git a/language.es_base b/language.es_base index 95d820b50..30c4af45c 100644 --- a/language.es_base +++ b/language.es_base @@ -135,6 +135,13 @@ QUITMSG11 = "Deja que adivine. ¿Te has vuelto a\n" QUITMSG12 = "Sí, yo tambíen necesitaría un descanso\n" "despues de todo eso..."; QUITMSG14 = "¿Continuará?"; +QUITMSG15 = "Por última vez, Icarus, ¡el nombre\n" + "del mod no se pronuncia 'Swim Jizz'!"; +QUITMSG16 = "¡AHDSAKAFAJDAGS!"; +QUITMSG18 = "¿QUIEN EN SU SANO JUICIO\n" + "GLASEARÍA UNA TARTA CON SU CULO?"; +QUITMSG19 = "El mundo es duro y frío,\n" + "los pechotes suaves y calientes."; E1TEXT = "Sigues sin tener ni idea de como has\n" "ido a parar a la vieja base de Fobos\n" diff --git a/language.es_lore b/language.es_lore index ca26fa8a9..f0eacad97 100644 --- a/language.es_lore +++ b/language.es_lore @@ -820,12 +820,10 @@ SWWM_LORETXT_SILVERBULLET = "\n" "Fuego Primario: Dispara la bala. Cualquier objetivo pequeño que sea alcanzado está más que muerto.\n" "\n" -"Fuego Secundario: Alterna la activación de los compensadores de retroceso. Desactivar los jets de compensadores de retroceso no es recomendado para usuarios humanos no equipados con servoarmadura o un esqueleto nivel Plata.\n" +"Fuego Secundario: Mira telescópica ajustable personalizada, hasta 16 aumentos. Equipada con un revestimiento de espuma suave para proteger la cara del usuario durante el fuego apuntando.\n" "\n" "Recarga: Recarga el arma.\n" "\n" -"Zoom: Mira telescópica ajustable personalizada, hasta 16 aumentos. Equipada con un revestimiento de espuma suave para proteger la cara del usuario durante el fuego apuntando.\n" -"\n" "Apéndice: La ráfaga de los jets puede causar daños menores al usuario a menos que lleven protección."; SWWM_LORETAG_SPARKSTER = "Carabina Biospark"; diff --git a/language.es_menu b/language.es_menu index 7c39e0ba7..a7b1a7b5d 100644 --- a/language.es_menu +++ b/language.es_menu @@ -8,7 +8,7 @@ SWWM_RELOADFIRE = "Recargar"; SWWM_ZOOMFIRE = "Fuego Terciario / Zoom"; SWWM_MELEE = "Ataque a Melé"; SWWM_DASH = "Esprintar"; -SWWM_GESTURE1 = "Apuntar Abajo"; +SWWM_GESTURE1 = "Saludar"; SWWM_GESTURE2 = "Pulgar Arriba"; SWWM_GESTURE3 = "Victoria"; SWWM_KBASE = "Menú de Demolicionista"; diff --git a/modeldef.demolitionist b/modeldef.demolitionist index 3b7018742..85fa72a57 100644 --- a/modeldef.demolitionist +++ b/modeldef.demolitionist @@ -145,13 +145,12 @@ Model "Demolitionist" FrameIndex XZW4 V 0 108 FrameIndex XZW4 W 0 109 FrameIndex XZW4 X 0 110 - // Point Down + // Wave FrameIndex XZW4 Y 0 112 FrameIndex XZW4 Z 0 113 FrameIndex XZW5 A 0 114 FrameIndex XZW5 B 0 115 FrameIndex XZW5 C 0 116 - SurfaceSkin 0 1 "DemoFace_Evil.png" FrameIndex XZW5 D 0 117 FrameIndex XZW5 E 0 118 FrameIndex XZW5 F 0 119 @@ -160,7 +159,6 @@ Model "Demolitionist" FrameIndex XZW5 I 0 122 FrameIndex XZW5 J 0 123 FrameIndex XZW5 K 0 124 - SurfaceSkin 0 1 "DemoFace_Default.png" FrameIndex XZW5 L 0 125 FrameIndex XZW5 M 0 126 // Thumbs Up @@ -268,3 +266,70 @@ Model "Demolitionist" FrameIndex XZW8 R 0 217 FrameIndex XZW8 S 0 218 } + +Model "SWWMGesture" +{ + Path "models" + Model 0 "GestureArms_d.3d" + SurfaceSkin 0 0 "DemoTags.png" + SurfaceSkin 0 1 "DemoArms.png" + SurfaceSkin 0 2 "DemoSoft.png" + AngleOffset -90 + Scale -0.005 0.0025 0.005 + IGNORETRANSLATION + + // Wave + 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 + FrameIndex XZW1 I 0 8 + FrameIndex XZW1 J 0 9 + FrameIndex XZW1 K 0 10 + FrameIndex XZW1 L 0 11 + FrameIndex XZW1 M 0 12 + FrameIndex XZW1 N 0 13 + FrameIndex XZW1 O 0 14 + // Thumbs Up + FrameIndex XZW1 P 0 17 + FrameIndex XZW1 Q 0 18 + FrameIndex XZW1 R 0 19 + FrameIndex XZW1 S 0 20 + FrameIndex XZW1 T 0 21 + FrameIndex XZW1 U 0 22 + FrameIndex XZW1 V 0 23 + FrameIndex XZW1 W 0 24 + FrameIndex XZW1 X 0 25 + FrameIndex XZW1 Y 0 26 + FrameIndex XZW1 Z 0 27 + FrameIndex XZW2 A 0 28 + FrameIndex XZW2 B 0 29 + FrameIndex XZW2 C 0 30 + FrameIndex XZW2 D 0 31 + FrameIndex XZW2 E 0 32 + FrameIndex XZW2 F 0 33 + // Victory + FrameIndex XZW2 G 0 35 + FrameIndex XZW2 H 0 36 + FrameIndex XZW2 I 0 37 + FrameIndex XZW2 J 0 38 + FrameIndex XZW2 K 0 39 + FrameIndex XZW2 L 0 40 + FrameIndex XZW2 M 0 41 + FrameIndex XZW2 N 0 42 + FrameIndex XZW2 O 0 43 + FrameIndex XZW2 P 0 44 + FrameIndex XZW2 Q 0 45 + FrameIndex XZW2 R 0 46 + FrameIndex XZW2 S 0 47 + FrameIndex XZW2 T 0 48 + FrameIndex XZW2 U 0 49 + FrameIndex XZW2 V 0 50 + FrameIndex XZW2 W 0 51 + FrameIndex XZW2 X 0 52 + FrameIndex XZW2 Y 0 53 +} diff --git a/modeldef.sparkster b/modeldef.sparkster index bf23c82ef..26dff0b9c 100644 --- a/modeldef.sparkster +++ b/modeldef.sparkster @@ -68,8 +68,8 @@ Model "BiosparkArcBig" Model 0 "WarpBeam_d.3d" Skin 0 "SparksterBeam.png" - Scale 0.125 0.32 0.32 - Offset 16 0 0 + Scale 0.25 0.64 0.64 + Offset 32 0 0 DONTCULLBACKFACES USEACTORPITCH USEACTORROLL @@ -88,6 +88,77 @@ Model "BiosparkArcBig" FrameIndex XZW1 L 0 12 } +Model "BiosparkBeam" +{ + Path "models/extra" + + Model 0 "BaseBeam_d.3d" + Scale 1.0 0.2 0.2 + Offset 128 0 0 + DONTCULLBACKFACES + USEACTORPITCH + USEACTORROLL + + Skin 0 "SparksterBeamS.png" + FrameIndex XZW1 A 0 0 + Skin 0 "SparksterBeam.png" + FrameIndex XZW1 B 0 0 +} + +Model "BiosparkChildBeam" +{ + Path "models/extra" + + Model 0 "WarpBeam_d.3d" + Scale 1.0 1.0 1.0 + Offset 128 0 0 + DONTCULLBACKFACES + USEACTORPITCH + USEACTORROLL + + Skin 0 "SparksterBeamS.png" + 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 + FrameIndex XZW1 I 0 8 + FrameIndex XZW1 J 0 9 + FrameIndex XZW1 K 0 10 + FrameIndex XZW1 L 0 11 + FrameIndex XZW1 M 0 12 + Skin 0 "SparksterBeam.png" + FrameIndex XZW2 A 0 0 + FrameIndex XZW2 B 0 1 + FrameIndex XZW2 C 0 2 + FrameIndex XZW2 D 0 3 + FrameIndex XZW2 E 0 4 + FrameIndex XZW2 F 0 5 + FrameIndex XZW2 G 0 6 + FrameIndex XZW2 H 0 7 + FrameIndex XZW2 I 0 8 + FrameIndex XZW2 J 0 9 + FrameIndex XZW2 K 0 10 + FrameIndex XZW2 L 0 11 + FrameIndex XZW2 M 0 12 +} + +Model "BiosparkCore" +{ + Path "models" + + Model 0 "SparksterBall_d.3d" + Skin 0 "SparksterBall.png" + Scale 0.003 0.003 0.003 + USEACTORPITCH + USEACTORROLL + + FrameIndex XZW1 A 0 0 +} + Model "Sparkster" { Path "models" @@ -272,4 +343,35 @@ Model "Sparkster" FrameIndex XZW4 V 1 78 FrameIndex XZW4 W 1 79 FrameIndex XZW4 X 1 80 + // Trigger1 + FrameIndex XZW4 Y 1 82 + // Trigger2 + FrameIndex XZW4 Z 1 83 + // Trigger3 + FrameIndex XZW5 A 1 84 + // Idle + FrameIndex XZW5 B 1 86 + FrameIndex XZW5 C 1 87 + FrameIndex XZW5 D 1 88 + FrameIndex XZW5 E 1 89 + FrameIndex XZW5 F 1 90 + FrameIndex XZW5 G 1 91 + FrameIndex XZW5 H 1 92 + FrameIndex XZW5 I 1 93 + FrameIndex XZW5 J 1 94 + FrameIndex XZW5 K 1 95 + FrameIndex XZW5 L 1 96 + FrameIndex XZW5 M 1 97 + FrameIndex XZW5 N 1 98 + FrameIndex XZW5 O 1 99 + FrameIndex XZW5 P 1 100 + FrameIndex XZW5 Q 1 101 + FrameIndex XZW5 R 1 102 + FrameIndex XZW5 S 1 103 + FrameIndex XZW5 T 1 104 + FrameIndex XZW5 U 1 105 + FrameIndex XZW5 V 1 106 + FrameIndex XZW5 W 1 107 + FrameIndex XZW5 X 1 108 + FrameIndex XZW5 Y 1 109 } diff --git a/models/Demolitionist.blend b/models/Demolitionist.blend index 9e670950f..ed9d493c8 100644 Binary files a/models/Demolitionist.blend and b/models/Demolitionist.blend differ diff --git a/models/DemolitionistPlayer.blend b/models/DemolitionistPlayer.blend index acbb5233c..0b0d8f893 100644 Binary files a/models/DemolitionistPlayer.blend and b/models/DemolitionistPlayer.blend differ diff --git a/models/DemolitionistPlayer_a.3d b/models/DemolitionistPlayer_a.3d index 90f166aa4..9b9a736e4 100644 Binary files a/models/DemolitionistPlayer_a.3d and b/models/DemolitionistPlayer_a.3d differ diff --git a/models/DemolitionistPlayer_d.3d b/models/DemolitionistPlayer_d.3d index b768723a8..d26d81bfa 100644 Binary files a/models/DemolitionistPlayer_d.3d and b/models/DemolitionistPlayer_d.3d differ diff --git a/models/Demolitionist_a.3d b/models/Demolitionist_a.3d index d4022cc4f..c2a287351 100644 Binary files a/models/Demolitionist_a.3d and b/models/Demolitionist_a.3d differ diff --git a/models/Demolitionist_d.3d b/models/Demolitionist_d.3d index 6898be9e8..03fcace81 100644 Binary files a/models/Demolitionist_d.3d and b/models/Demolitionist_d.3d differ diff --git a/models/GestureArms.blend b/models/GestureArms.blend new file mode 100644 index 000000000..5fb353146 Binary files /dev/null and b/models/GestureArms.blend differ diff --git a/models/GestureArms_a.3d b/models/GestureArms_a.3d new file mode 100644 index 000000000..6f3d068fd Binary files /dev/null and b/models/GestureArms_a.3d differ diff --git a/models/GestureArms_d.3d b/models/GestureArms_d.3d new file mode 100644 index 000000000..3c36ad630 Binary files /dev/null and b/models/GestureArms_d.3d differ diff --git a/models/ModelNotes.txt b/models/ModelNotes.txt index 1e17c1e30..063b84620 100644 --- a/models/ModelNotes.txt +++ b/models/ModelNotes.txt @@ -72,6 +72,7 @@ X altfire anim X tertiary fire anim X reload X melee bash +X "check out gun" idle anim Silver bullet: @@ -79,7 +80,7 @@ Silver bullet: - fire anim - reload - cock -- toggle anim +- "check out gun" idle anim - melee bash Ynykron: @@ -102,7 +103,6 @@ Demolitionist: - additional animations - more gestures - blow kiss - - wave - dedicated swim animation set - extra weapon animations - melee diff --git a/models/Sparkster1st.blend b/models/Sparkster1st.blend index 441614335..431e28e2a 100644 Binary files a/models/Sparkster1st.blend and b/models/Sparkster1st.blend differ diff --git a/models/Sparkster1st_a.3d b/models/Sparkster1st_a.3d index 8b580504a..1439bb7f0 100644 Binary files a/models/Sparkster1st_a.3d and b/models/Sparkster1st_a.3d differ diff --git a/models/Sparkster1st_d.3d b/models/Sparkster1st_d.3d index d53f42755..8da4ebb92 100644 Binary files a/models/Sparkster1st_d.3d and b/models/Sparkster1st_d.3d differ diff --git a/palettes/SparkBeam.pal b/palettes/SparkBeam.pal new file mode 100644 index 000000000..b7c95827c Binary files /dev/null and b/palettes/SparkBeam.pal differ diff --git a/sndinfo.txt b/sndinfo.txt index 0fc15aac9..802db92b3 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -322,6 +322,8 @@ $random demolitionist/kick { demolitionist/kick1 demolitionist/kick2 demolitioni demolitionist/revive sounds/demolitionist/demorevive.ogg demolitionist/youdied sounds/demolitionist/demoded.ogg demolitionist/parry sounds/demolitionist/demoparry.ogg +demolitionist/handsup sounds/demolitionist/demogesturestart.ogg +demolitionist/handsdown sounds/demolitionist/demogestureend.ogg $playersound demolitionist neutral *grunt DSEMPTY $playeralias demolitionist neutral *pain100 demolitionist/lopain @@ -653,6 +655,11 @@ biospark/bigarc3 sounds/sparkster/spark_arcb3.ogg biospark/bigarc4 sounds/sparkster/spark_arcb4.ogg $random biospark/bigarc { biospark/bigarc1 biospark/bigarc2 biospark/bigarc3 biospark/bigarc4 } $limit biospark/bigarc 64 +biospark/hugearc1 sounds/sparkster/spark_arch1.ogg +biospark/hugearc2 sounds/sparkster/spark_arch2.ogg +biospark/hugearc3 sounds/sparkster/spark_arch3.ogg +$random biospark/hugearc { biospark/hugearc1 biospark/hugearc2 biospark/hugearc3 } +$limit biospark/hugearc 64 biospark/zap1 sounds/sparkster/spark_zap1.ogg biospark/zap2 sounds/sparkster/spark_zap2.ogg biospark/zap3 sounds/sparkster/spark_zap3.ogg @@ -664,6 +671,8 @@ $limit biospark/zap 64 biospark/prefire sounds/sparkster/spark_prefire.ogg biospark/prethird sounds/sparkster/spark_prethird.ogg biospark/hiss sounds/sparkster/spark_hiss.ogg +biospark/fail sounds/sparkster/spark_thirdfail.ogg +biospark/checkout sounds/sparkster/spark_checkout.ogg candygun/fire1 sounds/candygun/candy_fire1.ogg candygun/fire2 sounds/candygun/candy_fire2.ogg diff --git a/sounds/demolitionist/demogestureend.ogg b/sounds/demolitionist/demogestureend.ogg new file mode 100644 index 000000000..5f053a420 Binary files /dev/null and b/sounds/demolitionist/demogestureend.ogg differ diff --git a/sounds/demolitionist/demogesturestart.ogg b/sounds/demolitionist/demogesturestart.ogg new file mode 100644 index 000000000..40d76a23a Binary files /dev/null and b/sounds/demolitionist/demogesturestart.ogg differ diff --git a/sounds/sparkster/spark_arch1.ogg b/sounds/sparkster/spark_arch1.ogg new file mode 100644 index 000000000..cd2399229 Binary files /dev/null and b/sounds/sparkster/spark_arch1.ogg differ diff --git a/sounds/sparkster/spark_arch2.ogg b/sounds/sparkster/spark_arch2.ogg new file mode 100644 index 000000000..ddfadc285 Binary files /dev/null and b/sounds/sparkster/spark_arch2.ogg differ diff --git a/sounds/sparkster/spark_arch3.ogg b/sounds/sparkster/spark_arch3.ogg new file mode 100644 index 000000000..76f0de318 Binary files /dev/null and b/sounds/sparkster/spark_arch3.ogg differ diff --git a/sounds/sparkster/spark_checkout.ogg b/sounds/sparkster/spark_checkout.ogg new file mode 100644 index 000000000..78163ca8d Binary files /dev/null and b/sounds/sparkster/spark_checkout.ogg differ diff --git a/sounds/sparkster/spark_thirdfail.ogg b/sounds/sparkster/spark_thirdfail.ogg new file mode 100644 index 000000000..c9eeaf351 Binary files /dev/null and b/sounds/sparkster/spark_thirdfail.ogg differ diff --git a/zmapinfo.txt b/zmapinfo.txt index 308f08b8a..70cda13e6 100644 --- a/zmapinfo.txt +++ b/zmapinfo.txt @@ -11,7 +11,8 @@ GameInfo QuitMessages = "$QUITMSG", "$QUITMSG1", "$QUITMSG2", "$QUITMSG3", "$QUITMSG4", "$QUITMSG5", "$QUITMSG6", "$QUITMSG7", "$QUITMSG8", "$QUITMSG9", "$QUITMSG10", "$QUITMSG11", - "$QUITMSG12", "$QUITMSG13", "$QUITMSG14" + "$QUITMSG12", "$QUITMSG13", "$QUITMSG14", "$QUITMSG15", + "$QUITMSG16", "$QUITMSG17", "$QUITMSG18", "$QUITMSG19" ChatSound = "misc/chat" IntermissionMusic = "music/DRAGONY.XM" DefaultConversationMenuClass = "SWWMConversationMenu" diff --git a/zscript/swwm_blazeit.zsc b/zscript/swwm_blazeit.zsc index 40b00a517..1ae2af44b 100644 --- a/zscript/swwm_blazeit.zsc +++ b/zscript/swwm_blazeit.zsc @@ -233,7 +233,7 @@ Class HellblazerMissile : Actor while ( bt.Next() ) { let t = bt.Thing; - if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || t.IsFriend(target) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),bNOGRAVITY?50:90) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),bNOGRAVITY?50:90) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; deto++; break; } @@ -862,7 +862,7 @@ Class HellblazerClusterMini : HellblazerMissile while ( bt.Next() ) { let t = bt.Thing; - if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || t.IsFriend(target) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),80) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),80) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; deto++; break; } diff --git a/zscript/swwm_cbt.zsc b/zscript/swwm_cbt.zsc index 9629a11d8..9b06194d2 100644 --- a/zscript/swwm_cbt.zsc +++ b/zscript/swwm_cbt.zsc @@ -18,6 +18,22 @@ Class Wallbuster : SWWMWeapon return false; } + // leave these while it's still unimplemented + override bool ReportHUDAmmo() + { + return false; + } + override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount ) + { + return false; + } + override void AttachToOwner( Actor other ) + { + Super.AttachToOwner(other); + if ( other.player == players[consoleplayer] ) + Console.Printf("\cgWALLBUSTER NOT IMPLEMENTED\c-"); + } + Default { Tag "$T_WALLBUSTER"; @@ -32,5 +48,21 @@ Class Wallbuster : SWWMWeapon Spawn: XZW1 A -1; Stop; + Select: + TNT1 A 1 + { + Console.Printf("\cgWALLBUSTER NOT IMPLEMENTED\c-"); + A_FullRaise(); + } + Goto Ready; + Ready: + TNT1 A 1 A_WeaponReady(); + Wait; + Fire: + TNT1 A 1; + Goto Ready; + Deselect: + TNT1 A -1 A_FullLower(); + Stop; } } diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index a24030335..3a6ff1f73 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -897,7 +897,7 @@ Class SWWMSmoke : Actor if ( isFrozen() ) return; vel *= 0.96; vel.z += 0.01; - if ( waterlevel > 0 ) + if ( (waterlevel > 0) && !bAMBUSH ) { let b = Spawn("SWWMBubble",pos); b.scale *= abs(scale.x); @@ -969,7 +969,7 @@ Class SWWMViewSmoke : SWWMSmoke ofs += vvel; vvel *= 0.96; vvel.z += 0.01; - if ( waterlevel > 0 ) Destroy(); + if ( (waterlevel > 0) && !bAMBUSH ) Destroy(); } } @@ -2457,13 +2457,13 @@ Class SWWMHandler : EventHandler switch ( e.Args[0] ) { case 1: - if ( mo.FindState("Approve") ) mo.SetStateLabel("Approve"); + SWWMGesture.SetGesture(mo,1); break; case 2: - if ( mo.FindState("Victory") ) mo.SetStateLabel("Victory"); + SWWMGesture.SetGesture(mo,2); break; default: - if ( mo.FindState("Taunt") ) mo.SetStateLabel("Taunt"); + SWWMGesture.SetGesture(mo,0); break; } } diff --git a/zscript/swwm_danmaku.zsc b/zscript/swwm_danmaku.zsc index 5d917ca96..8d356befd 100644 --- a/zscript/swwm_danmaku.zsc +++ b/zscript/swwm_danmaku.zsc @@ -588,7 +588,7 @@ Class Eviscerator : SWWMWeapon A_ZoomFactor(1.); A_SWWMFlash(); SWWMHandler.DoFlash(self,Color(64,255,224,96),3); - A_AlertMonsters(); + A_AlertMonsters(4500); A_Recoil(2.); Vector3 x, y, z, x2, y2, z2, dir, origin; double a, s; @@ -645,7 +645,7 @@ Class Eviscerator : SWWMWeapon A_ZoomFactor(1.); A_SWWMFlash(); SWWMHandler.DoFlash(self,Color(16,255,224,96),3); - A_AlertMonsters(); + A_AlertMonsters(4000); A_Recoil(2.2); Vector3 x, y, z, x2, y2, z2, dir, origin; double a, s; diff --git a/zscript/swwm_deathlydeathcannon.zsc b/zscript/swwm_deathlydeathcannon.zsc index 876cfba81..3ffc6e478 100644 --- a/zscript/swwm_deathlydeathcannon.zsc +++ b/zscript/swwm_deathlydeathcannon.zsc @@ -7,6 +7,22 @@ Class Ynykron : SWWMWeapon Property ClipCount : clipcount; + // leave these while it's still unimplemented + override bool ReportHUDAmmo() + { + return false; + } + override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount ) + { + return false; + } + override void AttachToOwner( Actor other ) + { + Super.AttachToOwner(other); + if ( other.player == players[consoleplayer] ) + Console.Printf("\cgYNYKRON ARTIFACT NOT IMPLEMENTED\c-"); + } + Default { Tag "$T_YNYKRON"; @@ -25,5 +41,21 @@ Class Ynykron : SWWMWeapon Spawn: XZW1 A -1; Stop; + Select: + TNT1 A 1 + { + Console.Printf("\cgYNYKRON ARTIFACT NOT IMPLEMENTED\c-"); + A_FullRaise(); + } + Goto Ready; + Ready: + TNT1 A 1 A_WeaponReady(); + Wait; + Fire: + TNT1 A 1; + Goto Ready; + Deselect: + TNT1 A -1 A_FullLower(); + Stop; } } diff --git a/zscript/swwm_deepdarkimpact.zsc b/zscript/swwm_deepdarkimpact.zsc index 18967b74a..718e2a0ab 100644 --- a/zscript/swwm_deepdarkimpact.zsc +++ b/zscript/swwm_deepdarkimpact.zsc @@ -62,7 +62,7 @@ Class AirBullet : FastProjectile } void A_Splode() { - A_AlertMonsters(); + A_AlertMonsters(8000); A_QuakeEx(6,6,6,20,0,250,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.); A_StartSound("deepimpact/bullethit",CHAN_VOICE,CHANF_DEFAULT,1.,.3); A_SprayDecal("ImpactMark"); @@ -350,7 +350,7 @@ Class DeepImpact : SWWMWeapon A_QuakeEx(6,6,6,10,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.7); A_Recoil(4.); A_StartSound("deepimpact/altfire",CHAN_WEAPON,CHANF_OVERLAP,attenuation:.5); - A_AlertMonsters(); + A_AlertMonsters(8000); invoker.clipcount = 0; Vector3 x, y, z, x2, y2, z2; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); diff --git a/zscript/swwm_hud.zsc b/zscript/swwm_hud.zsc index cf8d409db..0ba9ad1fe 100644 --- a/zscript/swwm_hud.zsc +++ b/zscript/swwm_hud.zsc @@ -298,10 +298,11 @@ Class SWWMStatusBar : BaseStatusBar } } } + else trackers.Clear(); // update floating scores, adding the scorenums first, then the damnums int total_sz = 0; if ( scorenums.GetBool() ) total_sz += hnd.scorenums_cnt; - if ( healthnums.GetBool() ) total_sz += min(50,hnd.damnums_cnt); + if ( healthnums.GetBool() ) total_sz += min(100,hnd.damnums_cnt); if ( scoreobjs.Size() != total_sz ) scoreobjs.Resize(total_sz); int i = 0; diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index cd28283e4..44959eb3f 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -496,7 +496,7 @@ Class Demolitionist : PlayerPawn s.special1 = int(-lastvelz); ReactionTime = 17; A_Stop(); - A_AlertMonsters(); + A_AlertMonsters(2500); if ( player == players[consoleplayer] ) { A_StartSound("demolitionist/hardland",CHAN_FOOTSTEP,CHANF_OVERLAP); @@ -973,7 +973,7 @@ Class Demolitionist : PlayerPawn s.special1 = 30; ReactionTime = 17; A_Stop(); - A_AlertMonsters(); + A_AlertMonsters(2500); if ( player == players[consoleplayer] ) { A_StartSound("demolitionist/hardland",CHAN_FOOTSTEP,CHANF_OVERLAP); @@ -1203,7 +1203,7 @@ Class Demolitionist : PlayerPawn if ( !player ) return; // add lore if any SWWMLoreLibrary.Add(player,item.GetClassName()); - if ( (item is 'Weapon') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && CheckLocalView() ) + if ( (item is 'Weapon') && !(item is 'SWWMGesture') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && CheckLocalView() ) SWWMHandler.AddOneliner("getweapon",2); if ( (item is 'Key') && !key_reentrant ) { @@ -1390,7 +1390,7 @@ Class Demolitionist : PlayerPawn DashEnd: XZW4 TUVWX 2; Goto Spawn+1; - Taunt: + Wave: #### # 3; XZW4 YZ 3; XZW5 ABCDEFGHIJKLM 3; @@ -1778,3 +1778,105 @@ Class CastDemolitionist : Actor Stop; } } + +// First person gestures +Class SWWMGesture : SWWMWeapon +{ + Weapon formerweapon; + int whichgesture; + bool deaded; + int gonect; + + static void SetGesture( PlayerPawn mo, int which = 0 ) + { + if ( (mo.player.ReadyWeapon is 'SWWMGesture') || (mo.player.PendingWeapon is 'SWWMGesture') ) return; // already gesturing + SWWMGesture w = SWWMGesture(mo.FindInventory("SWWMGesture")); + if ( !w ) + { + w = SWWMGesture(Spawn("SWWMGesture")); + mo.AddInventory(w); + } + if ( mo.player.PendingWeapon != WP_NOCHANGE ) w.formerweapon = mo.player.PendingWeapon; + else w.formerweapon = mo.player.ReadyWeapon; + w.whichgesture = which; + mo.player.PendingWeapon = w; + } + + action void A_CallPlayerGesture( statelabel st ) + { + if ( invoker.Owner.FindState(st) && (invoker.Owner.Health > 0) ) + invoker.Owner.SetStateLabel(st); + } + + action void A_FinishGesture() + { + player.PendingWeapon = invoker.formerweapon; + player.SetPSprite(PSP_WEAPON,ResolveState("Deselect")); + } + + override void OwnerDied() + { + Super.OwnerDied(); + deaded = true; + } + + Default + { + +WEAPON.CHEATNOTWEAPON; + +INVENTORY.UNDROPPABLE; + +INVENTORY.UNTOSSABLE; + +INVENTORY.UNCLEARABLE; + } + States + { + Select: + TNT1 A 1 + { + A_FullRaise(); + if ( invoker.deaded ) A_FinishGesture(); + } + Goto Ready; + Ready: + TNT1 A 1 + { + if ( invoker.whichgesture == 1 ) return ResolveState("Approve"); + if ( invoker.whichgesture == 2 ) return ResolveState("Victory"); + return ResolveState("Wave"); + } + Wait; + Fire: + TNT1 A 1; + Goto Ready; + Wave: + TNT1 A 3 A_CallPlayerGesture("Wave"); + XZW1 AB 3; + XZW1 C 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP); + XZW1 DEFGHIJ 3; + XZW1 K 3 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP); + XZW1 LMNO 3; + TNT1 A -1 A_FinishGesture(); + Stop; + Approve: + TNT1 A 3 A_CallPlayerGesture("Approve"); + XZW1 PQ 3; + XZW1 R 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP); + XZW1 STUVWX 3; + XZW1 Y 3 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP); + XZW1 Z 3; + XZW2 ABCDEF 3; + TNT1 A -1 A_FinishGesture(); + Stop; + Victory: + TNT1 A 3 A_CallPlayerGesture("Victory"); + XZW2 GH 3; + XZW2 I 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP); + XZW2 JKLMNOPQ 3; + XZW2 R 3 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP); + XZW2 STUVWXY 3; + TNT1 A -1 A_FinishGesture(); + Stop; + Deselect: + TNT1 A -1 A_FullLower(); + Stop; + } +} diff --git a/zscript/swwm_shot.zsc b/zscript/swwm_shot.zsc index d239a64e1..d5f8a95f2 100644 --- a/zscript/swwm_shot.zsc +++ b/zscript/swwm_shot.zsc @@ -564,7 +564,7 @@ Class SaltImpact : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - A_AlertMonsters(); + A_AlertMonsters(6000); SWWMHandler.DoBlast(self,120,15000); A_Explode(25,120); A_QuakeEx(3,3,3,10,0,250,"",QF_RELATIVE|QF_SCALEDOWN,falloff:150,rollintensity:0.2); @@ -1555,7 +1555,7 @@ Class GoldenImpact : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - A_AlertMonsters(); + A_AlertMonsters(40000); SWWMHandler.DoBlast(self,200,120000); A_Explode(7777,200); A_QuakeEx(9,9,9,40,0,5000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:500,rollintensity:1.5); @@ -1682,7 +1682,7 @@ Class GoldenSubImpact : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - A_AlertMonsters(); + A_AlertMonsters(9000); SWWMHandler.DoBlast(self,200,90000); A_Explode(777,200); A_QuakeEx(7,7,7,20,0,2000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:200,rollintensity:.8); @@ -1807,7 +1807,7 @@ Class GoldenSubSubImpact : Actor override void PostBeginPlay() { Super.PostBeginPlay(); - A_AlertMonsters(); + A_AlertMonsters(3000); SWWMHandler.DoBlast(self,200,60000); A_Explode(77,200); A_QuakeEx(4,4,4,15,0,1000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:100,rollintensity:.4); diff --git a/zscript/swwm_sparkyboi.zsc b/zscript/swwm_sparkyboi.zsc index 6eed04ea0..251f61634 100644 --- a/zscript/swwm_sparkyboi.zsc +++ b/zscript/swwm_sparkyboi.zsc @@ -8,13 +8,83 @@ Class BiosparkExplLight : PaletteLight Tag "SparkExpl"; } } +Class BiosparkExplLight2 : PaletteLight +{ + Default + { + Tag "SparkExpl"; + Args 0,0,0,500; + ReactionTime 50; + } +} Class SparkArcLight : PaletteLight { Default { Tag "SparkArc"; - ReactionTime 30; + ReactionTime 20; + } +} +Class SparkArcLightSmall : PaletteLight +{ + Default + { + Tag "SparkArc"; + ReactionTime 10; + } +} +Class SparkArcLightBig : PaletteLight +{ + Default + { + Tag "SparkArc"; + ReactionTime 40; + } +} + +Class SparkBeamLight : PaletteLight +{ + Default + { + Tag "SparkBeam"; + ReactionTime 20; + Args 0,0,0,300; + } +} + +Class BiosparkHitbox : Actor +{ + Default + { + Radius 30; + Height 60; + +NOGRAVITY; + +NOCLIP; + +DONTSPLASH; + +NOTELEPORT; + } + override void Tick() + { + Super.Tick(); + if ( !target || !target.InStateSequence(target.CurState,target.FindState("Spawn")) ) + { + Destroy(); + return; + } + SetOrigin(target.Vec3Offset(0,0,-height*0.5),true); + } + override bool CanCollideWith( Actor other, bool passive ) + { + return false; + } +} +Class BigBiosparkHitbox : BiosparkHitbox +{ + Default + { + Radius 80; + Height 160; } } @@ -24,11 +94,11 @@ Class BiosparkBall : Actor Default { - Obituary "$O_BIOSPARK"; + Obituary "$O_SPARKSTER"; DamageType "Electricity"; RenderStyle "Add"; - Radius 5; - Height 10; + Radius 3; + Height 6; Speed 20; PROJECTILE; +FOILINVUL; @@ -41,6 +111,8 @@ Class BiosparkBall : Actor { Super.PostBeginPlay(); A_StartSound("biospark/spark",CHAN_VOICE,CHANF_LOOPING); + let h = Spawn("BiosparkHitbox",pos); + h.target = self; } void A_SparkTick() { @@ -80,7 +152,8 @@ Class BiosparkBall : Actor magvel *= 1.03; if ( magvel > 50. ) magvel = 50.; Vector3 dir = vel.unit(); - dir = (dir+(FRandom[Sparkster](-1,1),FRandom[Sparkster](-1,1),FRandom[Sparkster](-1,1))*FRandom[Sparkster](.002,.003)).unit(); + if ( bAMBUSH ) + dir = (dir+(FRandom[Sparkster](-1,1),FRandom[Sparkster](-1,1),FRandom[Sparkster](-1,1))*FRandom[Sparkster](.02,.03)).unit(); // check targets at an interval, to save on performance if ( !(GetAge()%5) ) { @@ -90,7 +163,7 @@ Class BiosparkBall : Actor { let t = bt.Thing; double dist; - if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || t.IsFriend(target) || ((dist=Distance3D(t)) > 500) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3D(t)) > 500) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; Vector3 dirto = level.Vec3Diff(pos,t.Vec3Offset(0,0,t.height/2)).unit(); if ( dir dot dirto < .5 ) continue; // don't seek stuff that's behind us if ( dist > closest ) continue; @@ -105,7 +178,7 @@ Class BiosparkBall : Actor if ( dist > 4 ) { dirto /= dist; - dir = (dir+.1*dirto*(clamp(1.-(dist/500.),0.,1.)**3.)).unit(); + dir = (dir+.02*dirto*(clamp(1.-(dist/500.),0.,1.)**3.)).unit(); } } vel = magvel*dir; @@ -121,11 +194,16 @@ Class BiosparkBall : Actor while ( bt.Next() ) { let t = bt.Thing; - if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || t.IsFriend(target) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),50) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || !SWWMUtility.SphereIntersect(t,level.Vec3Offset(pos,vel),16) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; deto++; break; } } + override void OnDestroy() + { + A_StopSound(CHAN_VOICE); + Super.OnDestroy(); + } void A_SparkExplode() { A_StopSound(CHAN_VOICE); @@ -195,6 +273,7 @@ Class BiosparkBall : Actor s.A_SetRenderStyle(s.alpha,STYLE_AddShaded); s.scale *= 4.*factor; s.alpha *= factor; + s.bAMBUSH = true; } numpt = int(Random[ExploS](4,8)); for ( int i=0; i hitlist; + Array ShootThroughList; + + override ETraceStatus TraceCallback() + { + if ( Results.HitType == TRACE_HitActor ) + { + if ( Results.HitActor == ignoreme ) return TRACE_Skip; + if ( Results.HitActor.bSHOOTABLE || (Results.HitActor is 'BiosparkHitbox') ) + { + let ent = new("HitListEntry"); + ent.hitactor = Results.HitActor; + ent.hitlocation = Results.HitPos; + ent.x = Results.HitVector; + hitlist.Push(ent); + } + return TRACE_Skip; + } + else if ( (Results.HitType == TRACE_HitWall) && (Results.Tier == TIER_Middle) ) + { + if ( !Results.HitLine.sidedef[1] || (Results.HitLine.Flags&(Line.ML_BlockHitscan|Line.ML_BlockEverything)) ) + return TRACE_Stop; + ShootThroughList.Push(Results.HitLine); + return TRACE_Skip; + } + return TRACE_Stop; + } } -Class BiosparkChildBeam : BiosparkBeam +Class BiosparkBeamImpact : Actor { + Default + { + Obituary "$O_SPARKSTER"; + DamageType "Electricity"; + RenderStyle "Add"; + Radius .1; + Height 0; + +FOILINVUL; + +FORCERADIUSDMG; + +NODAMAGETHRUST; + +FORCEXYBILLBOARD; + } + override void PostBeginPlay() + { + Super.PostBeginPlay(); + A_AlertMonsters(2000); + SWWMHandler.DoBlast(self,100,120000); + A_Explode(30,100); + A_QuakeEx(3,3,3,12,0,800,"",QF_RELATIVE|QF_SCALEDOWN,falloff:300,rollIntensity:.4); + A_StartSound("biospark/beamhit",CHAN_ITEM,attenuation:1.1); + A_StartSound("biospark/beamhit",CHAN_WEAPON,attenuation:.8); + A_SprayDecal("ShockMark",-172); + Scale *= FRandom[ExploS](0.8,1.1); + Scale.x *= RandomPick[ExploS](-1,1); + Scale.y *= RandomPick[ExploS](-1,1); + int numpt = Random[ExploS](8,16); + for ( int i=0; i 30 ) return; + double factor = (30-special1)/30.; + double invfct = 1.-factor; + SWWMHandler.DoBlast(self,100*invfct,-5000*factor); + A_Explode(int(10*factor),int(50*invfct)); + int numpt = int(Random[ExploS](8,16)*factor); + for ( int i=0; i 20 ) return; + double factor = (20-special1)/20.; + double invfct = 1.-factor; + SWWMHandler.DoBlast(self,800*invfct,-10000*factor); + A_Explode(int(1500*factor),int(600*invfct)); + int numpt = int(Random[ExploS](8,16)*factor); + for ( int i=0; i 30) || !(special2%2) ) return; + int numpt = Random[Sparkster](0,30-special2); + double ang, pt; + for ( int i=0; i 2000) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + Vector3 dirto = level.Vec3Diff(invoker.nextpos,t.Vec3Offset(0,0,t.height/2)); + if ( dir dot dirto < .2 ) continue; + if ( dist > closest ) continue; + closest = dist; + tracer = t; + } + if ( tracer ) + { + Vector3 dirto = level.Vec3Diff(invoker.nextpos,tracer.Vec3Offset(0,0,tracer.height/2)); + double dist = dirto.length(); + if ( dist > 10 ) + { + dirto /= dist; + dir = (dir+.1*dirto*(clamp(1.-(dist/2000.),0.,1.)**4.)).unit(); + } + } + invoker.nextdir = dir; + } + + action void A_Spread() + { + for ( int i=0; i<2; i++ ) + { + let c = Spawn("BiosparkChildBeam",pos); + c.angle = angle; + c.pitch = pitch; + if ( frame ) c.SetStateLabel("TrailSpawn"); + c.roll = i*120; + } + Vector3 tdir = level.Vec3Diff(pos,invoker.nextpos); + int numpt = Random[Sparkster](-1,6); + for ( int i=0; i 1500) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; + if ( !t || !t.bSHOOTABLE || (!t.bISMONSTER && !(t is 'BossBrain')) || (t.Health <= 0) || (target && t.IsFriend(target)) || ((dist=Distance3D(t)) > 1500) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue; Vector3 dirto = level.Vec3Diff(invoker.nextpos,t.Vec3Offset(0,0,t.height/2)); if ( dir dot dirto < .2 ) continue; if ( dist > closest ) continue; @@ -333,16 +1104,32 @@ Class BiosparkArc : Actor if ( dist > 10 ) { dirto /= dist; - dir = (dir+.5*dirto*(clamp(1.-(dist/1500.),0.,1.)**3.)).unit(); + dir = (dir+.5*dirto*(clamp(1.-(dist/1500.),0.,1.)**2.)).unit(); } } } invoker.nextdir = dir; } - action void A_Spread( Sound arcsnd = "", double attn = 1. ) + action void A_Spread( Sound arcsnd = "", double attn = 1., int extra = 0 ) { - if ( special1 > ReactionTime ) return; Vector3 tdir = level.Vec3Diff(pos,invoker.nextpos); + if ( extra && !Random[Sparkster](0,12-extra*3) ) + { + for ( int i=0; i1)?"BiosparkArc":"BiosparkArcSmall",level.Vec3Offset(pos,tdir*FRandom[Sparkster](0,1))); + Vector3 x, y, z; + [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + double a = FRandom[Sparkster](0,360), s = FRandom[Sparkster](0.,1.); + Vector3 sdir = (x+y*cos(a)*s+z*sin(a)*s).unit(); + r.angle = atan2(sdir.y,sdir.x); + r.pitch = asin(-sdir.z); + r.target = target; + r.master = master; + r.ReactionTime /= 4; + } + } + if ( (special1 > ReactionTime) || bAMBUSH ) return; let b = Spawn(GetClass(),invoker.nextpos); b.angle = atan2(invoker.nextdir.y,invoker.nextdir.x); b.pitch = asin(-invoker.nextdir.z); @@ -351,10 +1138,10 @@ Class BiosparkArc : Actor b.tracer = tracer; b.special1 = special1+1; b.special2 = special2; - if ( (arcsnd != "") && !((special1+special2)%3) && !Random[Sparkster](0,5) ) A_StartSound(arcsnd,CHAN_WEAPON,attenuation:attn); - if ( !((special1+special2)%8) && !Random[Sparkster](0,1) ) + if ( (arcsnd != "") && !((special1+special2)%3) && !Random[Sparkster](0,3-extra) ) A_StartSound(arcsnd,CHAN_WEAPON,attenuation:attn); + if ( !((special1+special2)%8) && !Random[Sparkster](0,5-extra) ) { - let p = Spawn("SparkArcLight",level.Vec3Offset(pos,tdir/2)); + let p = Spawn((extra>1)?"SparkArcLightBig":(extra>0)?"SparkArcLight":"SparkArcLightSmall",level.Vec3Offset(pos,tdir/2)); p.args[3] = int(speed*8); } } @@ -362,13 +1149,13 @@ Class BiosparkArc : Actor { Super.PostBeginPlay(); frame = Random[Sparkster](0,11); - special2 = Random[Sparkster](-4,4); + if ( !special1 ) special2 = Random[Sparkster](0,8); } Default { RenderStyle "Add"; DamageFunction 5; - ReactionTime 20; + ReactionTime 16; Speed 16; Radius .1; Height 0; @@ -384,7 +1171,7 @@ Class BiosparkArc : Actor Spawn: XZW1 # 1 Bright; XZW1 # 1 Bright A_Trace(); - XZW1 # 1 Bright A_Spread("biospark/bigarc",.6); + XZW1 # 1 Bright A_Spread("biospark/bigarc",.6,1); XZW1 # 1 Bright A_FadeOut(.05); Wait; } @@ -394,8 +1181,8 @@ Class BiosparkArcSmall : BiosparkArc { Default { - ReactionTime 15; - DamageFunction 2; + ReactionTime 12; + DamageFunction 1; Speed 8; } States @@ -403,7 +1190,7 @@ Class BiosparkArcSmall : BiosparkArc Spawn: XZW1 # 1 Bright; XZW1 # 1 Bright A_Trace(); - XZW1 # 1 Bright A_Spread("biospark/arc",2.); + XZW1 # 1 Bright A_Spread("biospark/arc",2.,0); XZW1 # 1 Bright A_FadeOut(.1); Wait; } @@ -413,16 +1200,16 @@ Class BiosparkArcBig : BiosparkArc { Default { - ReactionTime 40; - DamageFunction 20; - Speed 32; + ReactionTime 8; + DamageFunction 100; + Speed 64; } States { Spawn: XZW1 # 1 Bright; XZW1 # 1 Bright A_Trace(); - XZW1 # 1 Bright A_Spread("biospark/zap",.4); + XZW1 # 1 Bright A_Spread("biospark/hugearc",.4,2); XZW1 # 1 Bright A_FadeOut(.025); Wait; } @@ -457,6 +1244,128 @@ Class BiosparkSpark : Actor Class BiosparkCore : Actor { + Vector3 oldvel; + double anglevel, pitchvel, rollvel; + + Default + { + Obituary "$O_SPARKSTER"; + PROJECTILE; + BounceType "Hexen"; + +CANBOUNCEWATER; + +USEBOUNCESTATE; + +DONTBOUNCEONSKY; + +NODAMAGETHRUST; + +NOTELEPORT; + +INTERPOLATEANGLES; + -NOGRAVITY; + Speed 30; + Gravity .1; + BounceFactor 1.; + WallBounceFactor 1.; + Radius 2; + Height 2; + ReactionTime 25; + } + override void PostBeginPlay() + { + Super.PostBeginPlay(); + anglevel = FRandom[Sparkster](-8,8); + rollvel = FRandom[Sparkster](-8,8); + pitchvel = FRandom[Sparkster](-8,8); + } + override void Tick() + { + oldvel = vel; + Super.Tick(); + } + void A_HandleBounce() + { + bHITOWNER = true; + Vector3 HitNormal = -vel.unit(); + F3DFloor ff; + if ( BlockingFloor ) + { + // find closest 3d floor for its normal + for ( int i=0; igametic)&&((failtime-gametic)%16>=8); + Screen.DrawTexture(AmmoBar[clipcount<4],false,bx-27,by-9,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_WindowRight,iclip?(iclip.GetValue()/10):0,DTA_ColorOverlay,blinking?Color(128,0,0,0):Color(0,0,0,0)); } override void HudTick() @@ -578,7 +1489,7 @@ Class Sparkster : SWWMWeapon p.target = self; p.angle = atan2(dir.y,dir.x); p.pitch = asin(-dir.z); - p.vel = dir*p.speed; + p.frame = 0; break; case 2: // big spark @@ -621,6 +1532,12 @@ Class Sparkster : SWWMWeapon Owner.A_StartSound("biospark/idle",CHAN_WEAPONEXTRA,CHANF_LOOPING,.4,4.); } + action void A_FailZoom() + { + invoker.failtime = gametic+48; + A_StartSound("biospark/fail",CHAN_WEAPON,CHANF_OVERLAP); + } + Default { Tag "$T_SPARKSTER"; @@ -660,27 +1577,27 @@ Class Sparkster : SWWMWeapon Ready: XZW2 A 1 { - int flg = WRF_ALLOWUSER1|WRF_NOSECONDARY; // temp while the two other fire modes are unimplemented - //int flg = WRF_ALLOWZOOM|WRF_ALLOWUSER1; - if ( (invoker.ClipCount < invoker.default.ClipCount) && (invoker.Ammo1.Amount > 0) ) flg |= WRF_ALLOWRELOAD; - A_WeaponReady(flg); + // tertiary disabled for now + A_WeaponReady(/*WRF_ALLOWZOOM|*/WRF_ALLOWUSER1|WRF_ALLOWRELOAD); if ( player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK|BT_ZOOM) ) invoker.CheckAmmo(EitherFire,true); } Wait; Fire: XZW2 A 0 A_JumpIf(invoker.ClipCount<=0,"Reload"); - XZW2 A 12 A_StartSound("biospark/prefire",CHAN_WEAPON,CHANF_OVERLAP); - XZW2 A 1 A_FireSpark(0); + XZW2 A 1 A_StartSound("biospark/prefire",CHAN_WEAPON,CHANF_OVERLAP); + XZW4 Y 12; + XZW4 Y 1 A_FireSpark(0); XZW2 NOPQ 2; - XZW2 A 0 A_JumpIf(!(player.cmd.buttons&BT_ATTACK)||(invoker.ClipCount<=0),"Vent"); + XZW2 A 0 A_JumpIf(!(player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK))||(invoker.ClipCount<=0),"Vent"); Goto Ready; AltFire: XZW2 A 0 A_JumpIf(invoker.ClipCount<=0,"Reload"); - XZW2 A 12 A_StartSound("biospark/prefire",CHAN_WEAPON,CHANF_OVERLAP); - XZW2 A 1 A_FireSpark(1); + XZW2 A 1 A_StartSound("biospark/prefire",CHAN_WEAPON,CHANF_OVERLAP); + XZW4 Z 12; + XZW4 Z 1 A_FireSpark(1); XZW2 RSTU 2; - XZW2 A 0 A_JumpIf(!(player.cmd.buttons&BT_ALTATTACK)||(invoker.ClipCount<=0),"Vent"); + XZW2 A 0 A_JumpIf(!(player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK))||(invoker.ClipCount<=0),"Vent"); Goto Ready; Vent: XZW2 A 12 @@ -695,12 +1612,21 @@ Class Sparkster : SWWMWeapon XZWY ABCDEFGHIJKLMNOPQRSTUVWX 1; Stop; Zoom: - XZW2 A 0 A_JumpIf(invoker.ClipCount<4,"Reload"); - XZW2 A 12 A_StartSound("biospark/prethird",CHAN_WEAPON,CHANF_OVERLAP); - XZW2 A 1 A_FireSpark(2); + XZW2 A 0 A_JumpIf(invoker.ClipCount<=0,"Reload"); + XZW2 A 0 A_JumpIf(invoker.ClipCount<4,"NoZoom"); + XZW2 A 1 A_StartSound("biospark/prethird",CHAN_WEAPON,CHANF_OVERLAP); + XZW5 A 12; + XZW5 A 1 A_FireSpark(2); XZW2 VWXYZ 2; Goto Ready; + NoZoom: + XZW2 A 1 A_StartSound("biospark/prethird",CHAN_WEAPON,CHANF_OVERLAP); + XZW5 A 12; + XZW5 A 8 A_FailZoom(); + XZW2 A 20; + Goto Ready; Reload: + XZW2 A 0 A_JumpIf((invoker.clipcount>=invoker.default.clipcount)||((invoker.Ammo1.Amount<=0)&&!sv_infiniteammo&&!FindInventory('PowerInfiniteAmmo',true)),"Idle"); XZW2 A 2 A_StartSound("biospark/meleestart",CHAN_WEAPON,CHANF_OVERLAP); XZW3 ABCDE 2; XZW3 F 2 @@ -723,6 +1649,15 @@ Class Sparkster : SWWMWeapon XZW3 YZ 2; XZW4 ABCD 2; Goto Vent; + Idle: + XZW2 A 2 A_StartSound("biospark/checkout",CHAN_WEAPON,CHANF_OVERLAP); + XZW5 BCDE 2; + XZW5 FGHI 3; + XZW5 JKLM 2; + XZW5 NOPQ 3; + XZW5 RST 2; + XZW5 UVXY 3; + Goto Ready; User1: XZW2 A 2 { diff --git a/zscript/swwm_tastytreat.zsc b/zscript/swwm_tastytreat.zsc index c83051330..aff5f2ee6 100644 --- a/zscript/swwm_tastytreat.zsc +++ b/zscript/swwm_tastytreat.zsc @@ -215,6 +215,7 @@ Class CandyPop : Actor double hfov = atan(Screen.GetAspectRatio()*tan(vfov)); let mo = players[consoleplayer].camera; Vector3 pp; + if ( !mo.CheckSight(self) ) return; if ( mo is 'PlayerPawn' ) pp = mo.Vec2OffsetZ(0,0,PlayerPawn(mo).player.viewz); else pp = mo.Vec3Offset(0,0,mo.CameraHeight); Vector3 sc = level.SphericalCoords(pp,pos,(mo.angle,mo.pitch)); @@ -230,7 +231,7 @@ Class CandyPop : Actor Spawn: BLPF B 3 NoDelay { - A_AlertMonsters(); + A_AlertMonsters(2000); SWWMHandler.DoBlast(self,120,60000); A_Explode(100,120); Scale *= FRandom[ExploS](0.6,1.8); @@ -297,7 +298,7 @@ Class TinyCandyPop : CandyPop Spawn: BLPF B 3 NoDelay { - A_AlertMonsters(); + A_AlertMonsters(700); SWWMHandler.DoBlast(self,80,32000); A_Explode(40,80); Scale *= FRandom[ExploS](0.6,1.8); diff --git a/zscript/swwm_thiccboolet.zsc b/zscript/swwm_thiccboolet.zsc index 0f147a0b4..30de81251 100644 --- a/zscript/swwm_thiccboolet.zsc +++ b/zscript/swwm_thiccboolet.zsc @@ -8,6 +8,22 @@ Class SilverBullet : SWWMWeapon Property ClipCount : clipcount; + // leave these while it's still unimplemented + override bool ReportHUDAmmo() + { + return false; + } + override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount ) + { + return false; + } + override void AttachToOwner( Actor other ) + { + Super.AttachToOwner(other); + if ( other.player == players[consoleplayer] ) + Console.Printf("\cgSILVER BULLET JET NOT IMPLEMENTED\c-"); + } + Default { Tag "$T_SILVERBULLET"; @@ -26,5 +42,21 @@ Class SilverBullet : SWWMWeapon Spawn: XZW1 A -1; Stop; + Select: + TNT1 A 1 + { + Console.Printf("\cgSILVER BULLET JET NOT IMPLEMENTED\c-"); + A_FullRaise(); + } + Goto Ready; + Ready: + TNT1 A 1 A_WeaponReady(); + Wait; + Fire: + TNT1 A 1; + Goto Ready; + Deselect: + TNT1 A -1 A_FullLower(); + Stop; } }