From 0420d511a688daf2e5d409124f4247fc1d713e98 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Wed, 8 Sep 2021 21:09:13 +0200 Subject: [PATCH] New achievements coded (Most icons still not done). Various random tweaks and fixes. Reformatted and cleaned up Future Plans file. --- FuturePlans.md | 136 ++++++++---------- achievements.lst | 43 ++---- cvarinfo.achievements | 8 -- filter/game-doom/cvarinfo.doomachievements | 19 ++- .../game-heretic/cvarinfo.hereticachievements | 14 +- filter/game-hexen/cvarinfo.hexenachievements | 11 -- graphics/Achievements/AchievementCandy.png | Bin 0 -> 2555 bytes graphics/Achievements/AchievementDeadeye.png | Bin 0 -> 2329 bytes graphics/Achievements/AchievementGrenade.png | Bin 0 -> 2437 bytes graphics/Achievements/AchievementPeace.png | Bin 0 -> 2555 bytes .../Achievements/AchievementUntouchable.png | Bin 0 -> 2493 bytes language.def_base | 60 +------- language.es_base | 60 +------- language.version | 4 +- zscript/handler/swwm_handler_cheats.zsc | 1 + zscript/handler/swwm_handler_damage.zsc | 24 +++- zscript/handler/swwm_handler_worldload.zsc | 86 ++++++++--- zscript/handler/swwm_handler_worldtick.zsc | 6 + zscript/hud/swwm_hud.zsc | 22 +++ zscript/items/swwm_armor.zsc | 7 + zscript/items/swwm_health.zsc | 5 + zscript/swwm_gesture_fx.zsc | 116 ++++++++++++++- zscript/swwm_monsters.zsc | 1 + zscript/swwm_player.zsc | 123 +++++++++++++++- zscript/swwm_thinkers_player.zsc | 2 + zscript/weapons/swwm_baseweapon_melee.zsc | 5 + zscript/weapons/swwm_splode.zsc | 22 ++- zscript/weapons/swwm_splode_fx.zsc | 12 +- 28 files changed, 493 insertions(+), 294 deletions(-) create mode 100644 graphics/Achievements/AchievementCandy.png create mode 100644 graphics/Achievements/AchievementDeadeye.png create mode 100644 graphics/Achievements/AchievementGrenade.png create mode 100644 graphics/Achievements/AchievementPeace.png create mode 100644 graphics/Achievements/AchievementUntouchable.png diff --git a/FuturePlans.md b/FuturePlans.md index f11e2d551..6e2b32a67 100644 --- a/FuturePlans.md +++ b/FuturePlans.md @@ -1,4 +1,8 @@ -This is just a bit of *"future planning"* for stuff that I ***might*** add after the first release. +This is just a bit of *"future planning"* for stuff that I ***might*** add later on. + +## 1.2 update *(The Second Batch)*: + +More weapons, because we need 'em. * **DLC Weaponset:** - [1] Itamex Reinforced Hammer *(UnSX 5)* @@ -21,15 +25,25 @@ This is just a bit of *"future planning"* for stuff that I ***might*** add after - The Most Silent Takedown *(Kill 30 enemies with the Ray-Khom primary without alerting them)* - [0] Grand Lance *(SWWM Iridium)* - Penetrator *(Strike through 20 enemies in a row with a single Grand Lance secondary)* + +## 1.3 update *(Arsenal Appendix)*: + +A couple extra weapons, not enough for a full batch, but still worthy additions. + * **DLC Weaponset 2:** - [1] Hand of Divine *(Total Madness)* - Facepunching Extraordinaire *(Kill 300 enemies with the Hand of Divine)* - [6] Sparkster x3 *(UnSX 2)* - - A Fine Sparking *(Kill 50 enemies at once with a Sparkster Rifle combo shot)* + - A Fine Sparking *(Kill 30 enemies at once with a Sparkster Rifle combo shot)* - [9] Mortal Rifle *(UnSX 2)* - - Railed Hard *(Shoot through 30 enemies with a single Mortal Rifle overpressure shot)* + - Railed Hard *(Shoot through 16 enemies with a single Mortal Rifle overpressure shot)* - [0] Rafan-Kos *(UnSX 4)* - Blasting Ropes *(Melt a grand total of 1000 enemies with the Rafan-Kos)* + +## 1.4 update *(The Final Stage)*: + +All the hard stuff *(some of these aren't guaranteed)*. + * **DLC Gameset:** - Tetris - Pong @@ -37,72 +51,13 @@ This is just a bit of *"future planning"* for stuff that I ***might*** add after - **[Doom]** Demo Land Adventure *(platformer with shooty gameplay)* - **[Heretic]** Interstellar Demolitionist *(a somewhat simple vertical SHMUP, kinda Touhou styled)* - **[Hexen]** Demolition Quest *(a JRPG, kinda like early FF / BoF)* -* **More collectibles (some of which were initially planned but didn't make it in time):** - - [Doom] Moth Plushy *("She loves a good lämp")* - - [Doom] AA-12 *("Ibuki's favorite shotgun. It's just a collectible model, so it doesn't actually shoot")* - - [Doom] Hege Cactus *("Appears to absorb all water, causing intense thirst")* - - [Doom] Hoagie *("Can't eat it, but looks delicious")* - - [Doom] Red Oni Milk *("It's a bit too obvious, isn't it?")* - - [Doom] Black Rat's Coven - Counter-Inquisition *("Man is this some good music")* - - [Heretic] Manarock *("A delicacy for gods, but instantly deadly for mortals")* - - [Heretic] Lithium - Volume One *("A work of art, one of the finest graphic novels")* - - [Hexen] Psykkonovexx *("Some crazy-ass Anarukon instrument, sounds amazing though")* -* **More items:** - - [Heretic/Hexen] Safety Tether *(Original)* - - Sneaky Retreat *(Use 10 Safety Tethers)* - - Devastation Sigil *(SWWM)* - - Deva Station *(Use 10 Devastation Sigils)* - - Divine Sprite *(SWWM Platinum)* - - Divine Delight *(Use 10 Divine Sprites)* -* **More achievements:** - - Piece of Candy *(Collect 1000 nuggets)* - - Kaboom *(Kill 30 enemies with planted Explodium Mags)* - - Pacifist *(Finish a map without dealing damage)* - - Untouchable *(Finish a map without taking damage)* - - Under Pressure *(Break a crusher)* - - The Longest Journey *(Walk a total of 1000km)* - - Mishe Trickery *(Successfully input a cheat code)* - - ...And a Dream *(Kill 10 enemies while having only 1 HP)* - - In a Hurry *(Beat a map with 0% kills, items and secrets)* - - Deadeye *(Land 7 consecutive Explodium Gun shots without missing)* - - Thorough Tenderizing *(Kill 100 enemies with the Pusher)* - - [Doom] Graffiti Master *(Doodle mustaches on 20 demon faces)* - - [Doom] Goodbye Franchise *(Rescue Commander Keen)* - - [Doom] Taking out the Trash *(Kill all Nazis in the Doom 2 secret maps)* - - [Doom] Environmental Disaster *(Destroy 1000 barrels)* - - [Doom] Cyberbullying *(Kill a Cyberdemon with its own rocket)* - - [Doom] Oh That's a Baseball *(Perfect parry a Lost Soul with the Silver Bullet)* - - [Doom] Dynamic Duo *(Defeat the Bruiser Brothers)* - - [Doom] Huge Guts *(Defeat the Tyrant of Babel)* - - [Doom] All Brain *(Defeat the Spider Mastermind)* - - [Doom] More Brain *(Defeat the Spider Sibling)* - - [Doom] Final Cleanup *(Complete Baphomet's Challenge)* - - [Doom] Simply Dead *(Defeat the Demonic Biomech Squad)* - - [Doom] Titan's Fall *(Defeat the Icon of Sin)* - - [Doom] Shot Until Dead *(Defeat the Last Tyrant)* - - [Doom] Evil Eternal *(Defeat the Archangelus)* - - [Doom] A Gazebo Most Insane *(Conquer the Sundered Realms)* - - [Heretic] What The Fuck? *(Punch a tornado???)* - - [Heretic] Crazy Heads *(Defeat the Iron Liches)* - - [Heretic] A Load of Bull *(Defeat the Maulotaur Servants)* - - [Heretic] Abracadabra I Win *(Defeat D'Sparil)* - - [Heretic] What's So Funny? *(Defeat the Iron Liches... again)* - - [Heretic] Big Mooscles *(Defeat the Maulotaur Servants... again)* - - [Hexen] Even Kirin is Upset *(Solve 20 "puzzles")* - - [Hexen] Extreme Kancho *(Break a stone spike)* - - [Hexen] It Just Works *(Defeat the Death Wyvern)* - - [Hexen] Magic Shmagic *(Defeat the Heresiarch)* - - [Hexen] You Again? *(Defeat another Heresiarch)* - - [Hexen] Domination *(Defeat Zedek)* - - [Hexen] Excommunication *(Defeat Traductus)* - - [Hexen] I Hate Puzzles *(Defeat Menelkir)* - - [Hexen] Worship This *(Defeat Korax)* - - [Hexen] Another One *(Defeat yet another Heresiarch)* - - [Hexen] And Another One *(Defeat... yup, one more Heresiarch)* - - [Hexen] The Last One *(Defeat the last Heresiarch)* - - [Hexen] Didn't I Kick Your Ass Before? *(Defeat the Deathkings)* * **Mothgirl summon for Lämp easter egg** - Layers of White *(Summon the White Lady)* +* **Demolitionist Menu Refactor:** + - Non 16:10 ratio support + - Smooth scrolling + - Much cleaner code + - Modular design * **Replace all hitscan with *"light projectiles"*** * **Crouch sliding *(+ proper crouch dashing)*** * **Expand third person animations** @@ -116,28 +71,49 @@ This is just a bit of *"future planning"* for stuff that I ***might*** add after - Giggle - Shrug - Beckon +* **Photo Mode** + - Dedicated poses + - Stickers + +## Unspecified + +Things that I'm unsure whether or not they'll be made. + * **Japanese localization???** * ***(Maybe)* Fake livestream chat overlay, with dynamic reactions to all sorts of stuff** * **Customized cluster text stuff if that ever gets scriptified** * **Official Sunder support *(when the WAD is complete)*** -* **Photo Mode** - - Dedicated poses - - Stickers +* **Original English Voice Acting** + +## Other Projects + +Add-ons and other related stuff. + * **Monster/decoration replacements add-on:** - Potentially standalone, usable with other mods - Balanced for this mod - Unique bosses - Some extra enemy variants - - Coverage for all supported IWADs *(oof)* -* **Original English Voice Acting:** - - Demolitionist - - Ibuki - - Saya - - Kirin -* **Ibuki sub-mod *(Red Oni)*** -* **Saya sub-mod *(Red-Eyed Rampage)*** -* **Kirin sub-mod *(Red Star of Innocence)*** -* **Hardcore Mode sub-mod:** + - Coverage for all supported WADs *(oof)* +* **Ibuki side mod *(Red Oni):*** + - A more *"mundane"* arsenal + - Featuring a very big girl with very big... Assets + - Possibly will have its own DLC Weaponset too + - Featuring a toggleable companion + - Nudity, in a Doom mod? Wow, never seen that one before + - This one's surprisingly meant to be more of a power trip than SWWM GZ +* **Saya side mod *(Red-Eyed Rampage)*** + - The first mod where you play as a mere squishy person + - Spellcasting! + - A more interesting take on "infinite lives" + - Featuring the Pancor Jackhammer *(lol)* +* **[Hexen]** **Kirin side mod *(Red Star of Innocence)*** + - Finally, you get to play as the precious femboy emperor + - Designed entirely for Hexen's funky gameplay™ + - Watch as our boy complains about *"puzzles"* + - Some unique touches to spice things up + - Basically a lite version of what you could expect in **UNDEATH** +* ***(Maybe)* Hardcore Mode sub-mod:** - Featuring Demolitionist on Maidbot frame - More complex game mechanics - Manual Hammerspace management diff --git a/achievements.lst b/achievements.lst index ee1aadb51..bcab9b113 100644 --- a/achievements.lst +++ b/achievements.lst @@ -8,8 +8,8 @@ # gametype: the game this belongs to (any, doom, heretic, hexen, raven, etc.) acid,50,yes,any allcoll,-1,no,any -allitems,30,yes,any -allkills,30,yes,any +allitems,30,yes,nothexen +allkills,30,yes,nothexen allsecrets,30,yes,nothexen anom,10,yes,any anone,0,no,any @@ -17,6 +17,7 @@ balls,10,yes,any barrel,1000,yes,doom barrier,20,yes,doom baseball,0,no,doom +blaze,0,no,nothexen bonk,300,yes,any bossdash,5,yes,any brake,10,yes,any @@ -39,16 +40,6 @@ dime,0,no,any divine,10,yes,any doodle,20,yes,doom dosh,1000000000,no,any -doomboss1,0,no,doom -doomboss2,0,no,doom -doomboss3,0,no,doom -doomboss4,0,no,doom -doomboss5,0,no,doom -doomboss6,0,no,doom -doomboss7,0,no,doom -doomboss8,0,no,doom -doomboss9,0,no,doom -#doomboss10,0,no,doom everything,0,no,any ezkill,50,yes,any #fisto,300,yes,any @@ -63,22 +54,6 @@ gib,1500,yes,any golden,24,yes,any gravity,10,yes,raven grenade,30,yes,any -hereticboss1,0,no,heretic -hereticboss2,0,no,heretic -hereticboss3,0,no,heretic -hereticboss4,0,no,heretic -hereticboss5,0,no,heretic -hexenboss1,0,no,hexen -hexenboss2,0,no,hexen -hexenboss3,0,no,hexen -hexenboss4,0,no,hexen -hexenboss5,0,no,hexen -hexenboss6,0,no,hexen -hexenboss7,0,no,hexen -hexenboss8,0,no,hexen -hexenboss9,0,no,hexen -hexenboss10,0,no,hexen -hexenboss11,0,no,hexen #hnd,6,yes,any hurry,0,no,any #ice,40,yes,any @@ -93,20 +68,20 @@ love,10,yes,any mbf,0,no,doom mega,10000,yes,any moth,50,yes,any -nice,0,no,any +nice,0,no,nothexen oneguy,0,no,any onehp,10,yes,any -onestanding,0,no,any +onestanding,0,no,nothexen oopsie,0,no,any par,15,yes,nothexen parry,200,yes,any -peace,0,no,any +peace,0,no,nothexen #pene,20,yes,any #plasma,50,yes,any plush,10,yes,any puzzle,20,yes,hexen rage,20,yes,any -#rail,30,yes,any +#rail,16,yes,any reflect,20,yes,any refresh,30,yes,any #roast,50,yes,any @@ -119,7 +94,7 @@ slayer,40,yes,any slemg,100,yes,any sneaky,10,yes,raven sneeze,20,yes,any -#spark,50,yes,any +#spark,30,yes,any step,30,yes,any stomp,50,yes,any sunny,15,yes,any @@ -130,7 +105,7 @@ thruwall,20,yes,any tornado,0,no,heretic trash,0,no,doom travel,1000,yes,any -untouchable,0,no,any +untouchable,0,no,nothexen wantdie,0,no,any wave,0,no,any yeet,0,no,doom diff --git a/cvarinfo.achievements b/cvarinfo.achievements index 845283c8e..3e38b75af 100644 --- a/cvarinfo.achievements +++ b/cvarinfo.achievements @@ -3,8 +3,6 @@ // cross-session achievement cvars (0: locked, 1: unlocked, 2: notified) nosave int swwm_achievement_acid = 0; nosave int swwm_achievement_allcoll = 0; -nosave int swwm_achievement_allitems = 0; -nosave int swwm_achievement_allkills = 0; nosave int swwm_achievement_anom = 0; nosave int swwm_achievement_anone = 0; nosave int swwm_achievement_balls = 0; @@ -51,13 +49,10 @@ nosave int swwm_achievement_love = 0; nosave int swwm_achievement_mashiro = 0; nosave int swwm_achievement_mega = 0; nosave int swwm_achievement_moth = 0; -nosave int swwm_achievement_nice = 0; nosave int swwm_achievement_oneguy = 0; nosave int swwm_achievement_onehp = 0; -nosave int swwm_achievement_onestanding = 0; nosave int swwm_achievement_oopsie = 0; nosave int swwm_achievement_parry = 0; -nosave int swwm_achievement_peace = 0; nosave int swwm_achievement_pene = 0; nosave int swwm_achievement_plasma = 0; nosave int swwm_achievement_plush = 0; @@ -83,14 +78,11 @@ nosave int swwm_achievement_tender = 0; nosave int swwm_achievement_thicc = 0; nosave int swwm_achievement_thruwall = 0; nosave int swwm_achievement_travel = 0; -nosave int swwm_achievement_untouchable = 0; nosave int swwm_achievement_wantdie = 0; nosave int swwm_achievement_wave = 0; // cross-session progress cvars nosave int swwm_progress_acid = 0; nosave int swwm_progress_allcoll = 0; -nosave int swwm_progress_allitems = 0; -nosave int swwm_progress_allkills = 0; nosave int swwm_progress_anom = 0; nosave int swwm_progress_balls = 0; nosave int swwm_progress_bonk = 0; diff --git a/filter/game-doom/cvarinfo.doomachievements b/filter/game-doom/cvarinfo.doomachievements index ab0b3f845..762a47dd0 100644 --- a/filter/game-doom/cvarinfo.doomachievements +++ b/filter/game-doom/cvarinfo.doomachievements @@ -1,29 +1,28 @@ // doom-exclusive achievements // cross-session achievement cvars (0: locked, 1: unlocked, 2: notified) +nosave int swwm_achievement_allitems = 0; +nosave int swwm_achievement_allkills = 0; nosave int swwm_achievement_allsecrets = 0; nosave int swwm_achievement_barrel = 0; nosave int swwm_achievement_barrier = 0; nosave int swwm_achievement_baseball = 0; +nosave int swwm_achievement_blaze = 0; nosave int swwm_achievement_cliffyb = 0; nosave int swwm_achievement_cybully = 0; nosave int swwm_achievement_doodle = 0; -nosave int swwm_achievement_doomboss1 = 0; -nosave int swwm_achievement_doomboss2 = 0; -nosave int swwm_achievement_doomboss3 = 0; -nosave int swwm_achievement_doomboss4 = 0; -nosave int swwm_achievement_doomboss5 = 0; -nosave int swwm_achievement_doomboss6 = 0; -nosave int swwm_achievement_doomboss7 = 0; -nosave int swwm_achievement_doomboss8 = 0; -nosave int swwm_achievement_doomboss9 = 0; -nosave int swwm_achievement_doomboss10 = 0; nosave int swwm_achievement_keen = 0; nosave int swwm_achievement_mbf = 0; +nosave int swwm_achievement_nice = 0; +nosave int swwm_achievement_onestanding = 0; nosave int swwm_achievement_par = 0; +nosave int swwm_achievement_peace = 0; nosave int swwm_achievement_trash = 0; +nosave int swwm_achievement_untouchable = 0; nosave int swwm_achievement_yeet = 0; // cross-session progress cvars +nosave int swwm_progress_allitems = 0; +nosave int swwm_progress_allkills = 0; nosave int swwm_progress_allsecrets = 0; nosave int swwm_progress_barrel = 0; nosave int swwm_progress_barrier = 0; diff --git a/filter/game-heretic/cvarinfo.hereticachievements b/filter/game-heretic/cvarinfo.hereticachievements index ae5922ac9..1627939dd 100644 --- a/filter/game-heretic/cvarinfo.hereticachievements +++ b/filter/game-heretic/cvarinfo.hereticachievements @@ -1,17 +1,21 @@ // heretic-exclusive achievements // cross-session achievement cvars (0: locked, 1: unlocked, 2: notified) +nosave int swwm_achievement_allitems = 0; +nosave int swwm_achievement_allkills = 0; nosave int swwm_achievement_allsecrets = 0; +nosave int swwm_achievement_blaze = 0; nosave int swwm_achievement_cliffyb = 0; nosave int swwm_achievement_gravity = 0; -nosave int swwm_achievement_hereticboss1 = 0; -nosave int swwm_achievement_hereticboss2 = 0; -nosave int swwm_achievement_hereticboss3 = 0; -nosave int swwm_achievement_hereticboss4 = 0; -nosave int swwm_achievement_hereticboss5 = 0; +nosave int swwm_achievement_nice = 0; +nosave int swwm_achievement_onestanding = 0; +nosave int swwm_achievement_peace = 0; nosave int swwm_achievement_sneaky = 0; nosave int swwm_achievement_tornado = 0; +nosave int swwm_achievement_untouchable = 0; // cross-session progress cvars +nosave int swwm_progress_allitems = 0; +nosave int swwm_progress_allkills = 0; nosave int swwm_progress_allsecrets = 0; nosave int swwm_progress_gravity = 0; nosave int swwm_progress_sneaky = 0; diff --git a/filter/game-hexen/cvarinfo.hexenachievements b/filter/game-hexen/cvarinfo.hexenachievements index c6af258ce..a82fd5b7d 100644 --- a/filter/game-hexen/cvarinfo.hexenachievements +++ b/filter/game-hexen/cvarinfo.hexenachievements @@ -2,17 +2,6 @@ // cross-session achievement cvars (0: locked, 1: unlocked, 2: notified) nosave int swwm_achievement_gravity = 0; -nosave int swwm_achievement_hexenboss1 = 0; -nosave int swwm_achievement_hexenboss2 = 0; -nosave int swwm_achievement_hexenboss3 = 0; -nosave int swwm_achievement_hexenboss4 = 0; -nosave int swwm_achievement_hexenboss5 = 0; -nosave int swwm_achievement_hexenboss6 = 0; -nosave int swwm_achievement_hexenboss7 = 0; -nosave int swwm_achievement_hexenboss8 = 0; -nosave int swwm_achievement_hexenboss9 = 0; -nosave int swwm_achievement_hexenboss10 = 0; -nosave int swwm_achievement_hexenboss11 = 0; nosave int swwm_achievement_kancho = 0; nosave int swwm_achievement_puzzle = 0; nosave int swwm_achievement_sneaky = 0; diff --git a/graphics/Achievements/AchievementCandy.png b/graphics/Achievements/AchievementCandy.png new file mode 100644 index 0000000000000000000000000000000000000000..f12a0c70574420b2005b98597118543545205fd3 GIT binary patch literal 2555 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 A#sB~S literal 0 HcmV?d00001 diff --git a/graphics/Achievements/AchievementDeadeye.png b/graphics/Achievements/AchievementDeadeye.png new file mode 100644 index 0000000000000000000000000000000000000000..aa49d55f21c78823983668a9afa0a6fb9da07b15 GIT binary patch literal 2329 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 SX*CQC3=E#GelF{r5}E)_?U9uL literal 0 HcmV?d00001 diff --git a/graphics/Achievements/AchievementPeace.png b/graphics/Achievements/AchievementPeace.png new file mode 100644 index 0000000000000000000000000000000000000000..79b8986f2b2cc581ea8b068db2fb3a67430e42bf GIT binary patch literal 2555 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 literal 0 HcmV?d00001 diff --git a/graphics/Achievements/AchievementUntouchable.png b/graphics/Achievements/AchievementUntouchable.png new file mode 100644 index 0000000000000000000000000000000000000000..d99ea3e6a7d86ff9322c07ec3dab686256fe1315 GIT binary patch literal 2493 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4kiW$hCdQ-7c($$ws^WYhIkyeoqD=I=6LC` z*EXwO-FtWY{L4yyd8PJzFA~;LIoO~q&*m@Kfr(JPrbn#W_R8bZd;yS6L>aAJ5^SYk@<~uX)Jh_%~En@x?v$L^T zck}aJ_mm#1{MW=c%g|zxv8cpWm6Iztrn)GlxUF5nRbut=(c=e?-d?SLn0Q9x0z*^7 z9Y!t|fr2RwOdJer9_zmlF=FdkxTHaI!V1+)PA?;4FQ=6rY*sq0(nmF!dR8TN^?3+9 z&tXaHGwNn&IKW}V&O9MXCDBshN{?c)f@TVjXlsvGpoXVb$fPAMnx0uU@D6fknzbY;G+>p~ zt)h)qMzd9$lhz*LN@?`fpSp2kq1xjZ$!w!+T?f5iGqocGgS_%X-23KOE^42}HS16V z^V!4`Rw}Za`lhUVu|RO^Y4OBAK6)7;`qQ&rB{f!dsD8evB;fh1DM;gM|BoeB)xUon zG?Moca{o_`z^%2?`tdUoD;5e) z$zHm^)`xwi@0`tFzJ0#;W@~uu=g1JANMTV4=1#A`1s}Y3@p-VSI8Rb6j66B(*~VAT z(h8rR{6A-I*S}Bw`<8XP#_Bw|mbWeX_iF9uN1nM@ZZG^d-~aoe)BC5V-&}oVlFE(3Jv8jJ>_SeZBtM_@nIq zEZ@%Dai`P#n78oN8jEeaZ!0GFDoAc+Ss9=iGHZ(4*VNyF!AD{OWB9L6@>+Z=zE|De zw&3yab2{rZd0fg20{!+Cy^UFGSM+=K{r&dW_ZGgLb#~LGzvXi_%#-m}a$PZFii)bI z)`YGlZjuXhgv4ifb!jtBJ+yYI4cFBt()s7I>i#b;U$%Ls+uAUlfc@hCKmD8a{_mfy z(c$aPY>_{2Z((+8hst-W1Xhb_Jd-9$s5XaasBUr!^I!}-AfmZSL#I_who3L^{ipYH zR*5?wdR+hKclo=TfQ289Y+P~MbJ7*_?LXfB-%-C)?)9P0;-AyDul#4K_sUj5S&@qW8?L^}H_y9s zMT{K7Ar@Ao*>TLd)r@%-3iv1-BA&D-|gJ@eb*+Jtz? z=V$%=HF=p-9$t^%rNYu6?tR;OyWYItm$&cx*u7gm{=@0gl-utaA!TrAV`#H|{ zE#D7uf4Eoudhf>lrA3q7grnEh?XuG7KbQ9Y-}i&^HPNh2iW(~FdjuYR`LROD>{{5W zsaK->s@~*0+FO2)^Zj0j*L#caalhXy?!KuZu0xr3qSXAEy;GNM{dTD&^LWpnm_{?*I< zIQ;zgTkKi6dG*iVyi97~T+H*oGWq?~pozxWH=Xk4ZnYEt^8Nkx_ST{uRd!ESm|g0q zw(Z-tJzD#5))K>@sv9zE^7UhM=J?EcU(&u=J=XVW-^az@->nm?`>U>gZofwO=eKc6 zPx|NE{MIwUj}E3@w1a=9q0YVpqvm&?2Tzt3JAZL#^6!x{T^`L&x`-rueNxBmCt{VT$ku@+^? zMyD62uMOwR_xE4n_VV4eYa8F+u_*kvW|B}R>yHuv{qy=;#O&;S-YlPOeS7blU#!1t z+`kIPUk{0~w2YV|^@J!IO{Nd4D%^E?8S(;8T2V zjd<9G!=>!b{104hwMyHY=ia@mW2&*?ww=xQKaZ1DvwDmRcKw`OU-RGnOb-8-x(=`P{HS@^6b5$RlEO(?APk!2IXtrJLyj^sx z?VWqZhf|*2_&8rY?a`S7N^WLA8&`p{qvk19b0_iWZkak zU$=()#qW7B$9QFA^{zX2?iS14-h1s`-Q}nbudgRNgLyBgZ9Zlta?V@bj&Zic<^J}+ z7Vnl9&PrWr= zyXl>t_oaGc@wbB&&S@Z^6%j3>;LnrlUHAj zsx+~;vYR;Dq>F2JYfzopr0D 0 ) livenazis = true; + } + if ( hasnazis && !livenazis ) + { + if ( level.levelnum == 31 ) s.nazicleanup |= 1; + else if ( level.levelnum == 32 ) s.nazicleanup |= 2; + } + if ( s.nazicleanup == 3 ) + SWWMUtility.MarkAchievement('swwm_achievement_trash',s.myplayer); } // reset score on dead players (death exit™) for ( int i=0; i 0) || (level.total_items > 0) || (level.total_secrets > 0)) + && (level.killed_monsters == 0) && (level.found_items == 0) && (level.found_secrets == 0) ) + SWWMUtility.MarkAchievement('swwm_achievement_hurry',players[consoleplayer]); } private void SetupLockdefsCache( SWWMCachedLockInfo cli ) @@ -226,42 +260,48 @@ extend Class SWWMHandler if ( !SWWMUtility.IsExitLine(l) ) continue; if ( skipme.Find(l) < skipme.Size() ) continue; - Vector3 lpos = SWWMUtility.UseLinePos(l); + skipme.Push(l); // look for connected lines - int xcnt = 1; + Array con; + con.Clear(); + con.Push(l); + int found; if ( l.frontsector ) { - for ( int j=0; j 0 ); } if ( l.backsector ) { - for ( int j=0; j 0 ); } - lpos /= xcnt; + Vector3 lpos = (0,0,0); + for ( int i=0; i con; + con.Clear(); + con.Push(HitLine); + Sector s = LineSide?HitLine.backsector:HitLine.frontsector; + int found = 0; + do + { + found = 0; + for ( int i=0; i 0 ); + for ( int i=0; i con; + con.Clear(); + con.Push(HitSector); + int found; + do + { + found = 0; + for ( int i=0; i= con.Size()) ) + { + found++; + con.Push(l.frontsector); + } + if ( (l.backsector.GetTexture(1) == HitTexture) && (con.Find(l.backsector) >= con.Size()) ) + { + found++; + con.Push(l.backsector); + } + } + } + } + while ( found > 0 ); + for ( int i=0; i con; + con.Clear(); + con.Push(HitSector); + int found; + do + { + found = 0; + for ( int i=0; i= con.Size()) ) + { + found++; + con.Push(l.frontsector); + } + if ( (l.backsector.GetTexture(0) == HitTexture) && (con.Find(l.backsector) >= con.Size()) ) + { + found++; + con.Push(l.backsector); + } + } + } + } + while ( found > 0 ); + for ( int i=0; i con; + con.Clear(); + con.Push(d.HitLine); + Sector s = d.LineSide?d.HitLine.backsector:d.HitLine.frontsector; + int found = 0; + do + { + found = 0; + for ( int i=0; i 0 ); + for ( int i=0; i con; + con.Clear(); + con.Push(d.HitSector); + int found; + do + { + found = 0; + for ( int i=0; i= con.Size()) ) + { + found++; + con.Push(l.frontsector); + } + if ( (l.backsector.GetTexture(1) == d.HitTexture) && (con.Find(l.backsector) >= con.Size()) ) + { + found++; + con.Push(l.backsector); + } + } + } + } + while ( found > 0 ); + for ( int i=0; i con; + con.Clear(); + con.Push(d.HitSector); + int found; + do + { + found = 0; + for ( int i=0; i= con.Size()) ) + { + found++; + con.Push(l.frontsector); + } + if ( (l.backsector.GetTexture(0) == d.HitTexture) && (con.Find(l.backsector) >= con.Size()) ) + { + found++; + con.Push(l.backsector); + } + } + } + } + while ( found > 0 ); + for ( int i=0; i height*.6 ) return; + if ( gaph > height*.8 ) return; // the smaller the gap, the more likely the crusher will snap - if ( Random[Demolitionist](0,3) && (FRandom[Demolitionist](0,gaph/height) > .1) ) return; + if ( Random[Demolitionist](0,2) && (FRandom[Demolitionist](0,gaph/height) > .2) ) return; double diffh = 8.+(default.height-gaph); // how much the crusher will have to "snap" after breaking let ceil = ceilingsector; let flor = floorsector; @@ -1452,6 +1563,7 @@ Class Demolitionist : PlayerPawn q.special1 = 10; SWWMCrusherBroken.Create(flor,null,diffh); } + SWWMUtility.MarkAchievement('swwm_achievement_crush',player); } override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle ) { @@ -1493,6 +1605,7 @@ Class Demolitionist : PlayerPawn if ( source.master ) source.master.Destroy(); source.Destroy(); damage = 20; // reduce so it's not instant kill + SWWMUtility.MarkAchievement('swwm_achievement_kancho',player); } } // no damage whatsoever diff --git a/zscript/swwm_thinkers_player.zsc b/zscript/swwm_thinkers_player.zsc index 03bb8a5e7..b41409140 100644 --- a/zscript/swwm_thinkers_player.zsc +++ b/zscript/swwm_thinkers_player.zsc @@ -45,6 +45,8 @@ Class SWWMStats : Thinker int plushuses; // for pistol start info (to avoid it within hubs) int lastcluster; + // for trash removal chievement + int nazicleanup; bool GotWeapon( Class which ) { diff --git a/zscript/weapons/swwm_baseweapon_melee.zsc b/zscript/weapons/swwm_baseweapon_melee.zsc index e685e4e3c..e0274ccef 100644 --- a/zscript/weapons/swwm_baseweapon_melee.zsc +++ b/zscript/weapons/swwm_baseweapon_melee.zsc @@ -138,10 +138,12 @@ Class ParryField : Actor while ( a = Actor(ti.Next()) ) { if ( (justparried.Find(a) < justparried.Size()) || !(SWWMUtility.ValidProjectile(a) || a.bSKULLFLY) || a.bTHRUACTORS || (level.Vec3Diff(a.pos,pos).length() > 80) ) continue; + if ( a is 'Whirlwind' ) SWWMUtility.MarkAchievement('swwm_achievement_tornado',master.player); justparried.Push(a); Vector3 vdir = a.vel; Vector3 dir = level.Vec3Diff(master.Vec2OffsetZ(0,0,pos.z),a.pos).unit(); Vector3 hdir = dir; + Actor oldtarget = a.target; if ( (a.target != master) && (a.bMISSILE || (a is 'HolySpirit')) ) // special wraithverge handling { // deflect directly to target @@ -161,6 +163,7 @@ Class ParryField : Actor { buff = Inventory(Spawn("ParriedBuff")); buff.AttachToOwner(a); + buff.tracer = oldtarget; } double mvel = a.vel.length(); double nspeed = min(100,mvel*FRandom[Parry](1.2,1.4)+20); @@ -199,6 +202,8 @@ Class ParryField : Actor if ( s ) s.pparries++; } critsnd = true; + if ( (a is 'LostSoul') && (master.player.ReadyWeapon is 'SilverBullet') ) + SWWMUtility.MarkAchievement('swwm_achievement_baseball',master.player); } if ( s ) s.parries++; SWWMUtility.AchievementProgressInc('swwm_progress_parry',1,master.player); diff --git a/zscript/weapons/swwm_splode.zsc b/zscript/weapons/swwm_splode.zsc index b7a0a7aca..05f67179e 100644 --- a/zscript/weapons/swwm_splode.zsc +++ b/zscript/weapons/swwm_splode.zsc @@ -10,6 +10,7 @@ Class ExplodiumGun : SWWMWeapon double casex, casey; transient ui TextureID WeaponBox; transient ui Font TewiFont; + int deadeyecnt; Property ClipCount : ClipCount; @@ -111,12 +112,17 @@ Class ExplodiumGun : SWWMWeapon SWWMBulletTrail.DoTrail(self,origin,dir,10000,2); if ( d.HitType == TRACE_HitActor ) { + if ( d.HitActor.IsHostile(self) ) + { + invoker.deadeyecnt++; + SWWMUtility.AchievementProgress('swwm_progress_deadeye',invoker.deadeyecnt,player); + } int dmg = 15; // might as well apply explosion on top if ( dmg >= d.HitActor.Health ) dmg += 20; SWWMUtility.DoKnockback(d.HitActor,d.HitDir,48000); dmg = d.HitActor.DamageMobj(invoker,self,dmg,'Explodium',DMG_USEANGLE|DMG_THRUSTLESS,atan2(d.HitDir.y,d.HitDir.x)); - if ( d.HitActor.bNOBLOOD || d.HitActor.bDORMANT || d.HitActor.bINVULNERABLE ) + if ( !d.HitActor || d.HitActor.bNOBLOOD || d.HitActor.bDORMANT || d.HitActor.bINVULNERABLE ) { let p = Spawn("SWWMBulletImpact",d.HitLocation); p.angle = atan2(d.HitDir.y,d.HitDir.x)+180; @@ -134,6 +140,7 @@ Class ExplodiumGun : SWWMWeapon } else if ( d.HitType != TRACE_HitNone ) { + invoker.deadeyecnt = 0; Vector3 hitnormal = -d.HitDir; if ( d.HitType == TRACE_HitFloor ) { @@ -160,6 +167,7 @@ Class ExplodiumGun : SWWMWeapon b.target = self; if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z); } + else invoker.deadeyecnt = 0; for ( int i=0; i<6; i++ ) { let s = Spawn("SWWMSmoke",origin); @@ -172,6 +180,7 @@ Class ExplodiumGun : SWWMWeapon action void A_ThrowMag() { + invoker.deadeyecnt = 0; let weap = Weapon(invoker); if ( !weap ) return; Vector3 x, y, z, x2, y2, z2; @@ -192,6 +201,7 @@ Class ExplodiumGun : SWWMWeapon action void A_DropMag() { + invoker.deadeyecnt = 0; if ( swwm_nomagdrop ) return; Vector3 x, y, z; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); @@ -338,6 +348,7 @@ Class ExplodiumGun : SWWMWeapon Select: XZW2 B 2 { + invoker.deadeyecnt = 0; A_FullRaise(); return A_JumpIf(invoker.firstselect,"FirstSelect"); } @@ -665,6 +676,11 @@ Class DualExplodiumGun : SWWMWeapon SWWMBulletTrail.DoTrail(self,origin,dir,10000,2); if ( d.HitType == TRACE_HitActor ) { + if ( d.HitActor.IsHostile(self) ) + { + ExplodiumGun(invoker.SisterWeapon).deadeyecnt++; + SWWMUtility.AchievementProgress('swwm_progress_deadeye',ExplodiumGun(invoker.SisterWeapon).deadeyecnt,player); + } int dmg = 15; // might as well apply explosion on top if ( dmg >= d.HitActor.Health ) dmg += 20; @@ -688,6 +704,7 @@ Class DualExplodiumGun : SWWMWeapon } else if ( d.HitType != TRACE_HitNone ) { + ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0; Vector3 hitnormal = -d.HitDir; if ( d.HitType == TRACE_HitFloor ) { @@ -714,6 +731,7 @@ Class DualExplodiumGun : SWWMWeapon b.target = self; if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z); } + else ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0; for ( int i=0; i<6; i++ ) { let s = Spawn("SWWMSmoke",origin); @@ -726,6 +744,7 @@ Class DualExplodiumGun : SWWMWeapon action void A_DropMag( int side = 1 ) { + ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0; if ( swwm_nomagdrop ) return; Vector3 x, y, z; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); @@ -788,6 +807,7 @@ Class DualExplodiumGun : SWWMWeapon Select: XZW2 B 2 { + ExplodiumGun(invoker.SisterWeapon).deadeyecnt = 0; A_FullRaise(); ExplodiumGun(invoker.SisterWeapon).firstselect = false; } diff --git a/zscript/weapons/swwm_splode_fx.zsc b/zscript/weapons/swwm_splode_fx.zsc index 8fa9bdb46..2a8c51636 100644 --- a/zscript/weapons/swwm_splode_fx.zsc +++ b/zscript/weapons/swwm_splode_fx.zsc @@ -64,7 +64,11 @@ Class ExplodiumMagArm : Actor { Spawn("ExplodiumMagTrail",pos); if ( !(ReactionTime%2) ) - SWWMUtility.DoExplosion(self,2+reactiontime/2,3000+500*reactiontime,40+3*reactiontime,20); + { + int nhit, nkill; + [nhit, nkill] = SWWMUtility.DoExplosion(self,2+reactiontime/2,3000+500*reactiontime,40+3*reactiontime,20,DE_COUNTENEMIES); + if ( target && special1 ) SWWMUtility.AchievementProgressInc('swwm_progress_grenade',nkill,target.player); + } Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5); let s = Spawn("SWWMHalfSmoke",pos); s.vel = pvel+vel*.2; @@ -147,13 +151,16 @@ Class ExplodiumMagProj : Actor } void A_BlowUp() { + bool isplanted = (self is 'ExplodiumMagAttach'); angle = atan2(cvel.y,cvel.x); pitch = asin(-cvel.z); bNOGRAVITY = true; A_SetRenderStyle(1.,STYLE_Add); Scale *= 2.+.2*special1; A_AlertMonsters(swwm_uncapalert?0:6000); - SWWMUtility.DoExplosion(self,10+20*special1,80000+8000*special1,90+10*special1,60,DE_EXTRAZTHRUST); + int nhit, nkill; + [nhit, nkill] = SWWMUtility.DoExplosion(self,10+20*special1,80000+8000*special1,90+10*special1,60,DE_EXTRAZTHRUST|DE_COUNTENEMIES); + if ( target && isplanted ) SWWMUtility.AchievementProgressInc('swwm_progress_grenade',nkill,target.player); A_QuakeEx(9,9,9,30,0,400+80*special1,"",QF_RELATIVE|QF_SCALEDOWN,falloff:300,rollintensity:2.); A_StartSound("explodium/maghit",CHAN_VOICE,attenuation:.35); A_StartSound("explodium/maghit",CHAN_WEAPON,attenuation:.2); @@ -191,6 +198,7 @@ Class ExplodiumMagProj : Actor { let s = Spawn("ExplodiumMagArm",pos); s.target = target; + s.special1 = isplanted; } Spawn("ExploLight2",pos); if ( swwm_omnibust ) BusterWall.ProjectileBust(self,20+15*special1,cvel);