diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..be033a7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +. filter=lfs diff=lfs merge=lfs -text +localappdata/xlabs/data/cef/release/libcef.dll filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md index 19d6435..dde687d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ If you don't have `git` installed on your machine, follow these steps: 1. Visit the [Git download page](https://git-scm.com/downloads). 2. Download the appropriate version for your operating system. -3. Run the installer. +3. Run the installer. - During the installation, you will be asked if you want to add Git to your system's PATH environment variable. Ensure you choose the option to do so. This allows you to use Git from the command line without specifying its full path. 4. After installation, open a terminal or command prompt and type `git --version` to ensure Git is correctly installed. @@ -27,9 +27,19 @@ If you don't have `git` installed on your machine, follow these steps: git clone https://github.com/YourUsername/GameClientRepo.git ``` ### Setting Up - -1. -``` 1. Move the `xlabs` folder to your local app data directory. > **Note**: Ensure the game client points to the correct local app data directory for proper functionality. + +[![patreon](https://img.shields.io/badge/patreon-support-blue.svg?logo=patreon)](https://www.patreon.com/xlabsproject) +[![discord](https://img.shields.io/endpoint?url=https://momo5502.com/iw4x/members-badge.php)](https://discord.gg/sKeVmR3) + +
+ +
+ ++ +
\ No newline at end of file diff --git a/assets/github/banner-iw6x.png b/assets/github/banner-iw6x.png new file mode 100644 index 0000000..27a72d3 Binary files /dev/null and b/assets/github/banner-iw6x.png differ diff --git a/assets/github/banner-iw6x.psd b/assets/github/banner-iw6x.psd new file mode 100644 index 0000000..4426fcb Binary files /dev/null and b/assets/github/banner-iw6x.psd differ diff --git a/assets/github/banner-s1x.png b/assets/github/banner-s1x.png new file mode 100644 index 0000000..a48d5fa Binary files /dev/null and b/assets/github/banner-s1x.png differ diff --git a/assets/github/banner-s1x.psd b/assets/github/banner-s1x.psd new file mode 100644 index 0000000..4426fcb Binary files /dev/null and b/assets/github/banner-s1x.psd differ diff --git a/bin/iw4x/iw4sp.exe b/bin/iw4x/iw4sp.exe new file mode 100644 index 0000000..5f1fdfd Binary files /dev/null and b/bin/iw4x/iw4sp.exe differ diff --git a/bin/iw4x/iw4x.exe b/bin/iw4x/iw4x.exe new file mode 100644 index 0000000..bbf6269 Binary files /dev/null and b/bin/iw4x/iw4x.exe differ diff --git a/bin/iw6x/iw6mp64_ship.exe b/bin/iw6x/iw6mp64_ship.exe new file mode 100644 index 0000000..c7de19a Binary files /dev/null and b/bin/iw6x/iw6mp64_ship.exe differ diff --git a/bin/iw6x/iw6sp64_ship.exe b/bin/iw6x/iw6sp64_ship.exe new file mode 100644 index 0000000..6979ce5 Binary files /dev/null and b/bin/iw6x/iw6sp64_ship.exe differ diff --git a/bin/s1x/s1_mp64_ship.exe b/bin/s1x/s1_mp64_ship.exe new file mode 100644 index 0000000..82d257a Binary files /dev/null and b/bin/s1x/s1_mp64_ship.exe differ diff --git a/bin/s1x/s1_sp64_ship.exe b/bin/s1x/s1_sp64_ship.exe new file mode 100644 index 0000000..6dae810 Binary files /dev/null and b/bin/s1x/s1_sp64_ship.exe differ diff --git a/iw4x/iw4x-sp.exe b/iw4x/iw4x-sp.exe new file mode 100644 index 0000000..f35f3d5 Binary files /dev/null and b/iw4x/iw4x-sp.exe differ diff --git a/iw4x/iw4x.dll b/iw4x/iw4x.dll new file mode 100644 index 0000000..996fc3d Binary files /dev/null and b/iw4x/iw4x.dll differ diff --git a/iw4x/r4344/iw4x.dll b/iw4x/r4344/iw4x.dll new file mode 100644 index 0000000..54f2b65 Binary files /dev/null and b/iw4x/r4344/iw4x.dll differ diff --git a/iw6x/data/dw/entitlement_config_tu14.info b/iw6x/data/dw/entitlement_config_tu14.info new file mode 100644 index 0000000..1bae79a --- /dev/null +++ b/iw6x/data/dw/entitlement_config_tu14.info @@ -0,0 +1,228 @@ +version 7 + +// Entitlement ID Ranges +// 0 - 299 ??? +// 300 - 399 Clan Entitlements +// 400 - 599 ??? +// 600 - 699 Clan War Entitlements +// 700 - 799 Generic Elite Entitlements + +// Number of keys to read from the key archive +keys_to_read 16 + +// unlocks in game - type, key index, bit, name, payload... +unlock 0 0 600 //clan wars demon_skull_p +unlock 0 1 601 //clan wars dead_ninja_p +unlock 0 2 602 //clan wars mummy_p +unlock 0 3 603 //clan wars skull_bow_p +unlock 0 4 604 //clan wars cyclops_skull_p +unlock 0 5 605 //clan wars dead_gnome_p +unlock 0 6 606 //clan wars gold_grill_p +unlock 0 7 607 //clan wars pirate_skull_p +unlock 0 8 608 //clan wars gargoyle_p +unlock 0 9 609 //clan wars vulture_p +unlock 0 10 610 //clan wars warrior_mask_p +unlock 0 11 611 //clan wars yeti_p +unlock 0 12 612 //clan wars dead_owl_p +unlock 0 13 613 //clan wars money_bags_p +unlock 0 14 614 //clan wars injured_octopus_p +unlock 0 15 615 //clan wars hotdog_p +unlock 0 16 616 //clan wars crab_p +unlock 0 17 617 //clan wars angry_robot_p +unlock 0 18 618 //clan wars triangle_dot_ret +unlock 0 19 619 //clan wars gold_chain_emb +unlock 0 20 620 //clan wars wing_emb +unlock 0 21 621 //clan wars brass_knuck_emb +unlock 0 22 622 //clan wars ninja_emb +unlock 0 25 623 //clan wars reaper head +unlock 0 26 624 //clan wars merc head +unlock 0 27 625 //clan wars body +unlock 0 28 460 //clan wars diamond division reticle +unlock 0 29 401 //clan wars diamond division camo +unlock 0 30 627 //clan wars diamond division assassin head +unlock 0 31 626 //clan wars diamond division savage head +unlock 0 32 628 //clan wars diamond division body + +unlock 3 0 700 //Download the mobile app +unlock 3 1 701 //Founder Skull + +unlock 3 4 500 //NEVERSOFT +unlock 3 3 501 //IW +unlock 3 5 502 //RAVEN +unlock 3 7 503 //HIGH_MOON +unlock 3 6 504 //BEACHHEAD + +unlock 13 0 209 //monster beast patch +unlock 13 2 210 //monster beast playercard +unlock 13 1 211 //monster viper patch +unlock 13 3 212 //monster viper playercard + +unlock 13 4 216 //riley / classic ghost head + +unlock 13 30 217 //watcher patch +unlock 13 31 213 //federation patch +unlock 13 32 215 //into the deep patch +unlock 13 33 214 //no man's land patch + +//Platform Unlocks +platform 200 255161 //team leader head +platform 201 255161 //team leader playercard +platform 202 255161 //team leader patch +platform 403 255161 //team leader camo +platform 451 255161 //team leader reticle + +platform 200 255160 //team leader head +platform 201 255160 //team leader playercard +platform 202 255160 //team leader patch +platform 403 255160 //team leader camo +platform 451 255160 //team leader reticle + +platform 206 255162 //insignia playercard +platform 205 255162 //insignia patch + +platform 216 255165 //classic ghost character + +platform 213 255167 //federation patch +platform 214 255168 //no mans land patch +platform 215 255169 //into the deep patch + +platform 207 255163 //digital hardened patch +platform 208 255163 //digital hardened playercard + +platform 217 255166 //Steam Patch - The Watcher + +platform 222 268100 //festive playercard +platform 221 268100 //festive patch +platform 410 268100 //festive camo +platform 453 268100 //festive reticle + +platform 550 268101 //wolf + +platform 551 277670 //extra slots + +platform 552 277671 // hero character - elias +platform 553 277672 // hero character - hesh +platform 554 277673 // hero character - merrick +platform 555 277674 // hero character - keegan +platform 556 277675 // hero character - price + +platform 557 281343 // Hazmat character +platform 558 281340 // Makarov Legend Pack +platform 559 281342 // Rorke Character +platform 560 281341 // Zakhaev Character + +platform 561 286632 // Soap Legend Pack +platform 562 286633 // Extinction Squad +platform 563 286634 // TF141 + +platform 490 277676 // Personalization pack 1 - Ducky +platform 491 277677 // Personalization pack 2 - Blood +platform 492 277678 // Personalization pack 3 - Inferno +platform 493 277679 // Personalization pack 4 - Kittens + +platform 494 281344 // Personalization pack 5 +platform 495 281345 // Personalization pack 6 +platform 496 281346 // Personalization pack 7 +platform 497 281347 // Personalization pack 8 +platform 498 286630 // Personalization pack 9 +platform 499 286631 // Personalization pack 10 + +platform 510 295430 // Personalization pack 11 +platform 511 295431 // Personalization pack 12 +platform 512 295432 // Personalization pack 13 +platform 513 295433 // Personalization pack 14 +platform 515 295434 // Personalization pack 15 +platform 516 295435 // Personalization pack 16 + +platform 517 295439 // Personalization pack 17 +platform 518 295440 // Personalization pack 18 +platform 519 301111 // Personalization pack 19 +platform 520 301112 // Personalization pack 20 +platform 521 301113 // Personalization pack 21 +platform 522 301114 // Personalization pack 22 +platform 523 301110 // Personalization pack Flags + +platform 564 295436 // Spectrum Character +platform 565 295437 // Astronaut Character +platform 566 295438 // Resistance Squad + +platform 567 309870 // Bluntforce Character +platform 568 309871 // Inferno Character +platform 569 309872 // Bling Character + +platform 480 259250 //dlc gun 1 +platform 480 301116 //dlc gun 1 +platform 481 259250 //dlc gun 1 +platform 481 301116 //dlc gun 1 + +platform 482 259251 //Ripper from Devastation +platform 482 255161 //Ripper from Season Pass +platform 482 301115 //Ripper from mDLC + +//Clan Entitlements - ID 300 - 399 - type, bit, entitlement id +clan 0 300 +clan 0 301 +clan 1 302 +clan 2 303 +clan 3 304 +clan 3 305 +clan 3 306 +clan 4 307 +clan 4 308 +clan 4 309 +clan 5 310 +clan 5 311 +clan 6 312 +clan 7 313 +clan 8 314 +clan 8 315 +clan 8 316 +clan 9 317 +clan 10 318 +clan 10 319 +clan 10 320 +clan 10 321 +clan 10 322 +clan 11 323 +clan 12 324 +clan 13 325 +clan 13 326 +clan 13 327 +clan 13 328 +clan 13 329 +clan 14 330 +clan 15 331 +clan 15 332 +clan 15 333 +clan 16 334 +clan 16 335 +clan 16 336 +clan 16 337 +clan 16 338 +clan 17 339 +clan 18 340 +clan 19 341 +clan 19 342 +clan 19 343 +clan 19 344 +clan 20 345 +clan 20 346 +clan 21 347 +clan 21 348 +clan 21 349 +clan 22 350 +clan 23 351 +clan 24 352 +clan 25 353 +clan 26 354 +clan 26 355 +clan 26 356 +clan 26 357 +clan 27 358 + +//Clan Level Challenges - type, required level, challenge id +clanlevelchallenge 23 ch_cam_clan_02 // Kiss of Death Camo + +//Clan War Challenges - type, key index, bit offset, challenge id +entitlementchallenge 0 18 ch_ret_clan // clan wars reticle - Triad +entitlementchallenge 0 24 ch_cam_clan_01 // clan wars camo - Body Count diff --git a/iw6x/data/dw/mm.cfg b/iw6x/data/dw/mm.cfg new file mode 100644 index 0000000..bbb75d7 --- /dev/null +++ b/iw6x/data/dw/mm.cfg @@ -0,0 +1,2 @@ +VERSION 5 +XX 0 D100 0 P50 0 G5 4 F 6 H 8 P75 16 P100 16 S 24 P120 32 P150 40 P-1 10 M192 20 M48 \ No newline at end of file diff --git a/iw6x/data/dw/newsfeed.txt b/iw6x/data/dw/newsfeed.txt new file mode 100644 index 0000000..28de37c --- /dev/null +++ b/iw6x/data/dw/newsfeed.txt @@ -0,0 +1,162 @@ +article 1 +header "FLAGS OF THE WORLD PACK" +body "Show your national pride with individual patches, playercards, and backgrounds for England, France, Germany, Italy, Spain, Mexico, USA, Brazil, Australia, Japan, UK, Russia, Netherlands, Portugal, Colombia, Argentina, Canada, Ireland, and Sweden. + +Plus, go international in any firefight with a unique reticle and flags of the world weapon camo. + +Available now. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_pers_pack_flags.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack40 +localJPEGImage + +article 2 +header "CALL OF DUTY APP" +body "The Call of Duty App is everything you need to keep track of your Ghosts experience on the go. + +Get unique info on Clan Wars: A brand new game mode that connects directly to Call of Duty®: Ghosts multiplayer, where clans compete against each other for additional XP and in-game content. + +Communicate via the Rally Up and Clan Chat features, to keep in touch with your friends and Clan members." +type news +image img_sf_generic_news2 +imagewidth 320 +imageheight 320 + +article 3 +header "PLAY HOW YOU WANT WITH EXTRA LOADOUT SLOTS" +body "You can increase the number of loadout slots from 6 to 10, so you can take even more options into battle. Never get caught with the wrong gear and give yourself great flexibility by creating different loadouts for different situations. + +Top Tip - Set up different characters for different game modes, that way you can select the right man for the job. + +Another Top Tip - With all the extra loadouts, set up variations of your favorite loadout so you’re always ready for the unexpected. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_extra_slots.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack2 +localJPEGImage + +article 4 +header "DROP ZONE IS BACK!" +body "We are bringing this fan favorite mode from Call of Duty: Modern Warfare 3 to Call of Duty: Ghosts Multiplayer. + +Fight to take control of the Drop Zone marked with a red smoke grenade, a location where Care Packages are regularly delivered by air drops. + +This mode gives you multiple chances to change the game with awesome killstreaks like the Gryphon, Juggernaut, or the earth shattering Loki. + +Control the Drop Zone, collect killstreaks, and wreak havoc on the opposing team!" +type news +image img_squadmode_03 +imagewidth 320 +imageheight 176 + +article 5 +header "THE REAL ORIGINS OF EXTINCTION" +body "Find out the origins of the Extinction story by collecting hidden intel items in Episode 1: Nightfall. + +Find out the real story of Dr. Cross, Archer and discover more secrets from Project Nightfall. + +Episode 1: Nightfall is part of DLC 1: Onslaught, available now. + +Visit the in-game store to find out more." +type item +image bg_large_073 +imagewidth 320 +imageheight 320 +data dlc3 + +article 6 +header "NEW CUSTOMIZATION CONTENT" +body "New content is being released all the time. Personalize your look and your loadout with customization items. + +- Special Characters: Customize your look head-to-toe in Multiplayer, Squads and Extinction. + +- Personalization Packs: Uniquely themed weapon camo, reticle, patch, playercard and background. + +- Legend Packs: A Special Character and themed Personalization Pack for a legendary figure in Call of Duty lore. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_pers_pack_07.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack17 +localJPEGImage + +article 7 +header "NEW TO EXTINCTION - THE ARMORY" +body "Spend Teeth in the Armory to purchase upgrades for classes and equipment. + +Earn Teeth by completing Extinction missions. Bonus Teeth are awarded for completing with a relic, completing in Hardcore mode, or helping other players complete a mission for the first time. + +You can also earn teeth by killing aliens in both Extinction and Chaos Mode. + +Upgrades include the Weapon Specialist's Infinite Ammo Ability and the Medic's Energy Field, instantly heal and revive anyone within its perimeter!" +type news +image img_sf_extinction_armory +imagewidth 320 +imageheight 320 + +article 8 +header "CAN YOU SURVIVE THE CHAOS?" +body "Extinction's Chaos Mode is an all-new, adrenaline pumping game type that pits 1-4 players against a never ending alien onslaught. + +Keep the combo meter filled by damaging aliens, collecting weaponry or upgrades, and making use of your abilities. Combos provide players with an ever-expanding set of perks such as Fast Health Regen, Gas Mask, and Stopping Power. + +Special bonus drops provide new ability upgrades including the Tank Class Skill and the Venom-X that further your arsenal and overall score potential. + +The aliens are ready, are you?" +type news +image img_sf_extinction_chaos +imagewidth 320 +imageheight 320 + +article 9 +header "WHAT'S GOING ON WITH YOUR CLAN?" +body "Check out what your Clan is up to in-game via Clan Details inside the Barracks. See what's going on with other players' Clans by checking out View Clan when you select them in the lobby. + +Get even more details on your Clan via the Call of Duty App, available now on the App Store, Google Play and Windows Store. + +Not in a Clan? Create one now via the Barracks and invite your friends straight from the game." +type news +image img_squadmode_02 +imagewidth 320 +imageheight 176 + +article 10 +header "DRILL INSTRUCTOR VOICE PACK" +body "Multiplayer returns to boot camp with the all-new Drill Instructor Voice Pack voiced by the one and only R. Lee Ermey, aka The Gunny. + +Swap out your in-game alerts with ones that will get you back into top combat shape. + +Now, drop down and give me twenty! + +Available now. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_drill_sergeant.jpg +imagewidth 320 +imageheight 160 +data dlc10 +localJPEGImage + +article 11 +header "TRY REINFORCE" +body "Reinforce is a new game mode where you annihilate the enemy team or capture points to win a match. + +You only respawn if a teammate captures a point, so be careful out there! + +This new game mode is now live in our Multiplayer playlist. + +Enjoy!" +type news +image bg_large_045 +imagewidth 320 +imageheight 320 \ No newline at end of file diff --git a/iw6x/data/dw/playlists_tu14.aggr b/iw6x/data/dw/playlists_tu14.aggr new file mode 100644 index 0000000..0e3e8eb Binary files /dev/null and b/iw6x/data/dw/playlists_tu14.aggr differ diff --git a/iw6x/data/dw/social_tu14.cfg b/iw6x/data/dw/social_tu14.cfg new file mode 100644 index 0000000..bbb75d7 --- /dev/null +++ b/iw6x/data/dw/social_tu14.cfg @@ -0,0 +1,2 @@ +VERSION 5 +XX 0 D100 0 P50 0 G5 4 F 6 H 8 P75 16 P100 16 S 24 P120 32 P150 40 P-1 10 M192 20 M48 \ No newline at end of file diff --git a/iw6x/data/maps/mp/gametypes/_damage.gsc b/iw6x/data/maps/mp/gametypes/_damage.gsc new file mode 100644 index 0000000..b7318f3 --- /dev/null +++ b/iw6x/data/maps/mp/gametypes/_damage.gsc @@ -0,0 +1,3302 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +isswitchingteams() +{ + if ( isdefined( self.switching_teams ) ) + return 1; + + return 0; +} + +isteamswitchbalanced() +{ + var_0 = maps\mp\gametypes\_teams::countplayers(); + var_0[self.leaving_team]--; + var_0[self.joining_team]++; + return var_0[self.joining_team] - var_0[self.leaving_team] < 2; +} + +isfriendlyfire( var_0, var_1 ) +{ + if ( !level.teambased ) + return 0; + + if ( !isdefined( var_1 ) ) + return 0; + + if ( !isplayer( var_1 ) && !isdefined( var_1.team ) ) + return 0; + + if ( var_0.team != var_1.team ) + return 0; + + if ( var_0 == var_1 ) + return 0; + + return 1; +} + +killedself( var_0 ) +{ + if ( !isplayer( var_0 ) ) + return 0; + + if ( var_0 != self ) + return 0; + + return 1; +} + +handleteamchangedeath() +{ + if ( !level.teambased ) + return; + + if ( self.joining_team == "spectator" || !isteamswitchbalanced() ) + { + self thread [[ level.onxpevent ]]( "suicide" ); + maps\mp\_utility::incpersstat( "suicides", 1 ); + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + } + + if ( isdefined( level.onteamchangedeath ) ) + [[ level.onteamchangedeath ]]( self ); +} + +handleworlddeath( var_0, var_1, var_2, var_3 ) +{ + if ( !isdefined( var_0 ) ) + return; + + if ( !isdefined( var_0.team ) ) + { + handlesuicidedeath( var_2, var_3 ); + return; + } + + if ( level.teambased && var_0.team != self.team || !level.teambased ) + { + if ( isdefined( level.onnormaldeath ) && ( isplayer( var_0 ) || isagent( var_0 ) ) && var_0.team != "spectator" ) + [[ level.onnormaldeath ]]( self, var_0, var_1 ); + } +} + +handlesuicidedeath( var_0, var_1 ) +{ + self thread [[ level.onxpevent ]]( "suicide" ); + maps\mp\_utility::incpersstat( "suicides", 1 ); + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + + if ( !maps\mp\_utility::matchmakinggame() ) + maps\mp\_utility::incplayerstat( "suicides", 1 ); + + var_2 = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "suicidepointloss" ); + maps\mp\gametypes\_gamescore::_setplayerscore( self, maps\mp\gametypes\_gamescore::_getplayerscore( self ) - var_2 ); + + if ( var_0 == "MOD_SUICIDE" && var_1 == "none" && isdefined( self.throwinggrenade ) ) + self.lastgrenadesuicidetime = gettime(); + + if ( isdefined( level.onsuicidedeath ) ) + [[ level.onsuicidedeath ]]( self ); + + if ( isdefined( self.friendlydamage ) ) + self iprintlnbold( &"MP_FRIENDLY_FIRE_WILL_NOT" ); +} + +handlefriendlyfiredeath( var_0 ) +{ + var_0 thread [[ level.onxpevent ]]( "teamkill" ); + var_0.pers["teamkills"] += 1.0; + var_0.teamkillsthisround++; + + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "team", "teamkillpointloss" ) ) + { + var_1 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ); + maps\mp\gametypes\_gamescore::_setplayerscore( var_0, maps\mp\gametypes\_gamescore::_getplayerscore( var_0 ) - var_1 ); + } + + if ( level.maxallowedteamkills < 0 ) + return; + + if ( level.ingraceperiod ) + { + var_2 = 1; + var_0.pers["teamkills"] += level.maxallowedteamkills; + } + else if ( var_0.pers["teamkills"] > 1 && maps\mp\_utility::gettimepassed() < level.graceperiod * 1000 + 8000 + var_0.pers["teamkills"] * 1000 ) + { + var_2 = 1; + var_0.pers["teamkills"] += level.maxallowedteamkills; + } + else + var_2 = var_0 maps\mp\gametypes\_playerlogic::teamkilldelay(); + + if ( var_2 > 0 ) + { + var_0.pers["teamKillPunish"] = 1; + var_0 maps\mp\_utility::_suicide(); + } +} + +handlenormaldeath( var_0, var_1, var_2, var_3, var_4 ) +{ + var_1 thread maps\mp\_events::killedplayer( var_0, self, var_3, var_4 ); + + if ( var_4 == "MOD_HEAD_SHOT" ) + { + var_1 maps\mp\_utility::incpersstat( "headshots", 1 ); + var_1.headshots = var_1 maps\mp\_utility::getpersstat( "headshots" ); + var_1 maps\mp\_utility::incplayerstat( "headshots", 1 ); + + if ( isdefined( var_1.laststand ) ) + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ) * 2; + else + var_5 = undefined; + + var_1 playlocalsound( "bullet_impact_headshot_plr" ); + self playsound( "bullet_impact_headshot" ); + } + else if ( isdefined( var_1.laststand ) ) + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ) * 2; + else + var_5 = undefined; + + var_6 = var_1; + + if ( isdefined( var_1.commanding_bot ) ) + var_6 = var_1.commanding_bot; + + var_7 = 0; + + if ( issquadsmode() ) + var_7 = 1; + + var_6 maps\mp\_utility::incpersstat( "kills", 1, var_7 ); + var_6.kills = var_6 maps\mp\_utility::getpersstat( "kills" ); + var_6 maps\mp\_utility::updatepersratio( "kdRatio", "kills", "deaths" ); + var_6 maps\mp\gametypes\_persistence::statsetchild( "round", "kills", var_6.kills ); + var_6 maps\mp\_utility::incplayerstat( "kills", 1 ); + + if ( isflankkill( self, var_1 ) ) + { + var_6 maps\mp\_utility::incplayerstat( "flankkills", 1 ); + maps\mp\_utility::incplayerstat( "flankdeaths", 1 ); + } + + var_8 = var_1.pers["cur_kill_streak"]; + + if ( isalive( var_1 ) || var_1.streaktype == "support" ) + { + if ( var_4 == "MOD_MELEE" && !var_1 maps\mp\_utility::isjuggernaut() || var_1 maps\mp\_utility::killshouldaddtokillstreak( var_3 ) ) + var_1 registerkill( var_3, 1 ); + + var_1 maps\mp\_utility::setplayerstatifgreater( "killstreak", var_1.pers["cur_kill_streak"] ); + + if ( var_1.pers["cur_kill_streak"] > var_1 maps\mp\_utility::getpersstat( "longestStreak" ) ) + var_1 maps\mp\_utility::setpersstat( "longestStreak", var_1.pers["cur_kill_streak"] ); + } + + var_1.pers["cur_death_streak"] = 0; + var_1 thread maps\mp\gametypes\_rank::giverankxp( "kill", var_5, var_3, var_4, undefined, self ); + + if ( var_1.pers["cur_kill_streak"] > var_1 maps\mp\gametypes\_persistence::statgetchild( "round", "killStreak" ) ) + var_1 maps\mp\gametypes\_persistence::statsetchild( "round", "killStreak", var_1.pers["cur_kill_streak"] ); + + if ( var_1 maps\mp\_utility::rankingenabled() ) + { + if ( var_1.pers["cur_kill_streak"] > var_1.kill_streak ) + { + if ( !issquadsmode() ) + var_1 maps\mp\gametypes\_persistence::statset( "killStreak", var_1.pers["cur_kill_streak"] ); + + var_1.kill_streak = var_1.pers["cur_kill_streak"]; + } + } + + maps\mp\gametypes\_gamescore::giveplayerscore( "kill", var_1, self ); + var_9 = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "deathpointloss" ); + maps\mp\gametypes\_gamescore::_setplayerscore( self, maps\mp\gametypes\_gamescore::_getplayerscore( self ) - var_9 ); + + if ( isdefined( level.ac130player ) && level.ac130player == var_1 ) + level notify( "ai_killed", self ); + + if ( isdefined( var_1.odin ) ) + level notify( "odin_killed_player", self ); + + level notify( "player_got_killstreak_" + var_1.pers["cur_kill_streak"], var_1 ); + var_1 notify( "got_killstreak", var_1.pers["cur_kill_streak"] ); + var_1 notify( "killed_enemy", self, var_3, var_4 ); + + if ( isdefined( self.motionsensormarkedby ) ) + { + if ( self.motionsensormarkedby != var_1 ) + self.motionsensormarkedby thread maps\mp\gametypes\_weapons::motionsensor_processtaggedassist( self ); + + self.motionsensormarkedby = undefined; + } + + if ( isdefined( level.onnormaldeath ) && var_1.pers["team"] != "spectator" ) + [[ level.onnormaldeath ]]( self, var_1, var_0 ); + + if ( !level.teambased ) + { + self.attackers = []; + return; + } + + level thread maps\mp\gametypes\_battlechatter_mp::saylocalsounddelayed( var_1, "kill", 0.75 ); + + if ( isdefined( self.lastattackedshieldplayer ) && isdefined( self.lastattackedshieldtime ) && self.lastattackedshieldplayer != var_1 ) + { + if ( gettime() - self.lastattackedshieldtime < 2500 ) + { + self.lastattackedshieldplayer thread maps\mp\gametypes\_gamescore::processshieldassist( self ); + + if ( self.lastattackedshieldplayer maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + self.lastattackedshieldplayer.pers["assistsToKill"]++; + + if ( !( self.lastattackedshieldplayer.pers["assistsToKill"] % 2 ) ) + { + self.lastattackedshieldplayer maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + self.lastattackedshieldplayer maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.lastattackedshieldplayer.pers["cur_kill_streak"]++; + } + } + else + self.lastattackedshieldplayer.pers["assistsToKill"] = 0; + } + else if ( isalive( self.lastattackedshieldplayer ) && gettime() - self.lastattackedshieldtime < 5000 ) + { + var_10 = vectornormalize( anglestoforward( self.angles ) ); + var_11 = vectornormalize( self.lastattackedshieldplayer.origin - self.origin ); + + if ( vectordot( var_11, var_10 ) > 0.925 ) + { + self.lastattackedshieldplayer thread maps\mp\gametypes\_gamescore::processshieldassist( self ); + + if ( self.lastattackedshieldplayer maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + self.lastattackedshieldplayer.pers["assistsToKill"]++; + + if ( !( self.lastattackedshieldplayer.pers["assistsToKill"] % 2 ) ) + { + self.lastattackedshieldplayer maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + self.lastattackedshieldplayer maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.lastattackedshieldplayer.pers["cur_kill_streak"]++; + } + } + else + self.lastattackedshieldplayer.pers["assistsToKill"] = 0; + } + } + } + + if ( isdefined( self.attackers ) ) + { + foreach ( var_13 in self.attackers ) + { + if ( !isdefined( maps\mp\_utility::_validateattacker( var_13 ) ) ) + continue; + + if ( var_13 == var_1 ) + continue; + + if ( self == var_13 ) + continue; + + if ( isdefined( level.assists_disabled ) ) + continue; + + var_13 thread maps\mp\gametypes\_gamescore::processassist( self ); + + if ( var_13 maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + var_13.pers["assistsToKill"]++; + + if ( !( var_13.pers["assistsToKill"] % 2 ) ) + { + var_13 maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + var_13 registerkill( var_3, 0 ); + } + + continue; + } + + var_13.pers["assistsToKill"] = 0; + } + + self.attackers = []; + } +} + +isplayerweapon( var_0 ) +{ + if ( weaponclass( var_0 ) == "non-player" ) + return 0; + + if ( weaponclass( var_0 ) == "turret" ) + return 0; + + if ( weaponinventorytype( var_0 ) == "primary" || weaponinventorytype( var_0 ) == "altmode" ) + return 1; + + return 0; +} + +waitskipkillcambuttonduringdeathtimer() +{ + self endon( "disconnect" ); + self endon( "killcam_death_done_waiting" ); + self notifyonplayercommand( "death_respawn", "+usereload" ); + self notifyonplayercommand( "death_respawn", "+activate" ); + self waittill( "death_respawn" ); + self notify( "killcam_death_button_cancel" ); +} + +waitskipkillcamduringdeathtimer( var_0 ) +{ + self endon( "disconnect" ); + self endon( "killcam_death_button_cancel" ); + wait(var_0); + self notify( "killcam_death_done_waiting" ); +} + +skipkillcamduringdeathtimer( var_0 ) +{ + self endon( "disconnect" ); + + if ( level.showingfinalkillcam ) + return 0; + + if ( !isai( self ) ) + { + thread waitskipkillcambuttonduringdeathtimer(); + thread waitskipkillcamduringdeathtimer( var_0 ); + var_1 = common_scripts\utility::waittill_any_return( "killcam_death_done_waiting", "killcam_death_button_cancel" ); + + if ( var_1 == "killcam_death_done_waiting" ) + return 0; + else + return 1; + } + + return 0; +} + +callback_playerkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 ) +{ + playerkilled_internal( var_0, var_1, self, var_2, var_3, var_4, var_5, var_6, var_7, var_8, 0 ); +} + +queueshieldforremoval( var_0 ) +{ + var_1 = 5; + + if ( !isdefined( level.shieldtrasharray ) ) + level.shieldtrasharray = []; + + if ( level.shieldtrasharray.size >= var_1 ) + { + var_2 = level.shieldtrasharray.size - 1; + level.shieldtrasharray[0] delete(); + + for ( var_3 = 0; var_3 < var_2; var_3++ ) + level.shieldtrasharray[var_3] = level.shieldtrasharray[var_3 + 1]; + + level.shieldtrasharray[var_2] = undefined; + } + + level.shieldtrasharray[level.shieldtrasharray.size] = var_0; +} + +launchshield( var_0, var_1 ) +{ + if ( isdefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped ) + { + if ( isdefined( self.riotshieldmodel ) ) + maps\mp\_utility::riotshield_detach( 1 ); + else if ( isdefined( self.riotshieldmodelstowed ) ) + maps\mp\_utility::riotshield_detach( 0 ); + } +} + +playerkilled_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + var_2 endon( "spawned" ); + var_2 notify( "killed_player" ); + var_2 maps\mp\gametypes\_playerlogic::resetuidvarsondeath(); + var_2.abilitychosen = 0; + var_2.perkoutlined = 0; + + if ( maps\mp\_utility::gamehasneutralcrateowner( level.gametype ) ) + { + if ( var_2 != var_1 && var_4 == "MOD_CRUSH" ) + { + var_0 = var_2; + var_1 = var_2; + var_4 = "MOD_SUICIDE"; + var_5 = "none"; + var_7 = "none"; + var_2.attackers = []; + } + } + + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + + if ( isdefined( var_1 ) ) + var_1.assistedsuicide = undefined; + + if ( !isdefined( var_2.idflags ) ) + { + if ( var_4 == "MOD_SUICIDE" ) + var_2.idflags = 0; + else if ( var_4 == "MOD_GRENADE" ) + { + if ( ( issubstr( var_5, "frag_grenade" ) || issubstr( var_5, "thermobaric_grenade" ) || issubstr( var_5, "mortar_shell" ) ) && var_3 == 100000 ) + var_2.idflags = 0; + else if ( var_5 == "nuke_mp" ) + var_2.idflags = 0; + else if ( level.friendlyfire >= 2 ) + var_2.idflags = 0; + else + { + + } + } + } + + if ( isdefined( var_2.hasriotshieldequipped ) && var_2.hasriotshieldequipped ) + var_2 launchshield( var_3, var_4 ); + + var_2 maps\mp\_utility::riotshield_clear(); + maps\mp\gametypes\_weapons::recordtogglescopestates(); + + if ( !var_10 ) + { + if ( isdefined( var_2.endgame ) ) + maps\mp\_utility::restorebasevisionset( 2 ); + else + { + maps\mp\_utility::restorebasevisionset( 0 ); + var_2 thermalvisionoff(); + } + } + else + { + var_2.fauxdead = 1; + self notify( "death" ); + } + + if ( game["state"] == "postgame" ) + return; + + maps\mp\perks\_perks::updateactiveperks( var_0, var_1, var_2, var_3, var_4 ); + var_11 = 0; + + if ( !isplayer( var_0 ) && isdefined( var_0.primaryweapon ) ) + var_12 = var_0.primaryweapon; + else if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_12 = var_1 getcurrentprimaryweapon(); + else if ( issubstr( var_5, "alt_" ) ) + var_12 = getsubstr( var_5, 4, var_5.size ); + else + var_12 = undefined; + + if ( isdefined( var_2.uselaststandparams ) || isdefined( var_2.laststandparams ) && var_4 == "MOD_SUICIDE" ) + { + var_2 ensurelaststandparamsvalidity(); + var_2.uselaststandparams = undefined; + var_0 = var_2.laststandparams.einflictor; + var_1 = var_2.laststandparams.attacker; + var_3 = var_2.laststandparams.idamage; + var_4 = var_2.laststandparams.smeansofdeath; + var_5 = var_2.laststandparams.sweapon; + var_12 = var_2.laststandparams.sprimaryweapon; + var_6 = var_2.laststandparams.vdir; + var_7 = var_2.laststandparams.shitloc; + var_11 = ( gettime() - var_2.laststandparams.laststandstarttime ) / 1000; + var_2.laststandparams = undefined; + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + } + + if ( ( !isdefined( var_1 ) || var_1.classname == "trigger_hurt" || var_1.classname == "worldspawn" || var_1 == var_2 ) && isdefined( self.attackers ) ) + { + var_13 = undefined; + + foreach ( var_15 in self.attackers ) + { + if ( !isdefined( maps\mp\_utility::_validateattacker( var_15 ) ) ) + continue; + + if ( !isdefined( var_2.attackerdata[var_15.guid].damage ) ) + continue; + + if ( var_15 == var_2 || level.teambased && var_15.team == var_2.team ) + continue; + + if ( var_2.attackerdata[var_15.guid].lasttimedamaged + 2500 < gettime() && ( var_1 != var_2 && ( isdefined( var_2.laststand ) && var_2.laststand ) ) ) + continue; + + if ( var_2.attackerdata[var_15.guid].damage > 1 && !isdefined( var_13 ) ) + { + var_13 = var_15; + continue; + } + + if ( isdefined( var_13 ) && var_2.attackerdata[var_15.guid].damage > var_2.attackerdata[var_13.guid].damage ) + var_13 = var_15; + } + + if ( isdefined( var_13 ) ) + { + var_1 = var_13; + var_1.assistedsuicide = 1; + var_5 = var_2.attackerdata[var_13.guid].weapon; + var_6 = var_2.attackerdata[var_13.guid].vdir; + var_7 = var_2.attackerdata[var_13.guid].shitloc; + var_8 = var_2.attackerdata[var_13.guid].psoffsettime; + var_4 = var_2.attackerdata[var_13.guid].smeansofdeath; + var_3 = var_2.attackerdata[var_13.guid].damage; + var_12 = var_2.attackerdata[var_13.guid].sprimaryweapon; + var_0 = var_1; + } + } + else if ( isdefined( var_1 ) ) + var_1.assistedsuicide = undefined; + + if ( maps\mp\_utility::isheadshot( var_5, var_7, var_4, var_1 ) ) + var_4 = "MOD_HEAD_SHOT"; + else if ( !isdefined( var_2.nuked ) ) + { + if ( isdefined( level.custom_death_sound ) ) + [[ level.custom_death_sound ]]( var_2, var_4, var_0 ); + else if ( var_4 != "MOD_MELEE" ) + var_2 maps\mp\_utility::playdeathsound(); + } + + if ( isdefined( level.custom_death_effect ) ) + [[ level.custom_death_effect ]]( var_2, var_4, var_0 ); + + var_17 = isfriendlyfire( var_2, var_1 ); + + if ( isdefined( var_1 ) ) + { + if ( var_1.code_classname == "script_vehicle" && isdefined( var_1.owner ) ) + var_1 = var_1.owner; + + if ( var_1.code_classname == "misc_turret" && isdefined( var_1.owner ) ) + { + if ( isdefined( var_1.vehicle ) ) + var_1.vehicle notify( "killedPlayer", var_2 ); + + var_1 = var_1.owner; + } + + if ( isagent( var_1 ) ) + { + var_5 = "agent_mp"; + var_4 = "MOD_RIFLE_BULLET"; + + if ( isdefined( var_1.agent_type ) ) + { + if ( var_1.agent_type == "dog" ) + var_5 = "guard_dog_mp"; + else if ( var_1.agent_type == "squadmate" ) + var_5 = "agent_support_mp"; + else if ( var_1.agent_type == "pirate" ) + var_5 = "pirate_agent_mp"; + else if ( var_1.agent_type == "wolf" ) + var_5 = "killstreak_wolfpack_mp"; + else if ( var_1.agent_type == "beastmen" ) + var_5 = "beast_agent_mp"; + } + + if ( isdefined( var_1.owner ) ) + var_1 = var_1.owner; + } + + if ( var_1.code_classname == "script_model" && isdefined( var_1.owner ) ) + { + var_1 = var_1.owner; + + if ( !isfriendlyfire( var_2, var_1 ) && var_1 != var_2 ) + var_1 notify( "crushed_enemy" ); + } + } + + if ( var_4 != "MOD_SUICIDE" && ( maps\mp\_utility::isaigameparticipant( var_2 ) || maps\mp\_utility::isaigameparticipant( var_1 ) ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["get_attacker_ent"] ) ) + { + var_18 = [[ level.bot_funcs["get_attacker_ent"] ]]( var_1, var_0 ); + + if ( isdefined( var_18 ) ) + { + if ( maps\mp\_utility::isaigameparticipant( var_2 ) ) + var_2 botmemoryevent( "death", var_5, var_18.origin, var_2.origin, var_18 ); + + if ( maps\mp\_utility::isaigameparticipant( var_1 ) ) + { + var_19 = 1; + + if ( var_18.classname == "script_vehicle" && isdefined( var_18.helitype ) || var_18.classname == "rocket" || var_18.classname == "misc_turret" ) + var_19 = 0; + + if ( var_19 ) + var_1 botmemoryevent( "kill", var_5, var_18.origin, var_2.origin, var_2 ); + } + } + } + + var_2 maps\mp\gametypes\_weapons::dropscavengerfordeath( var_1 ); + var_2 [[ level.weapondropfunction ]]( var_1, var_4 ); + + if ( !var_10 ) + var_2 maps\mp\_utility::updatesessionstate( "dead", "hud_status_dead" ); + + var_20 = isdefined( var_2.fauxdead ) && var_2.fauxdead && isdefined( var_2.switching_teams ) && var_2.switching_teams; + + if ( !var_20 ) + var_2 maps\mp\gametypes\_playerlogic::removefromalivecount(); + + if ( !isdefined( var_2.switching_teams ) ) + { + var_21 = var_2; + + if ( isdefined( var_2.commanding_bot ) ) + var_21 = var_2.commanding_bot; + + if ( isdefined( level.ishorde ) ) + var_21.deaths++; + else + { + var_22 = 0; + + if ( issquadsmode() ) + var_22 = 1; + + var_21 maps\mp\_utility::incpersstat( "deaths", 1, var_22 ); + var_21.deaths = var_21 maps\mp\_utility::getpersstat( "deaths" ); + var_21 maps\mp\_utility::updatepersratio( "kdRatio", "kills", "deaths" ); + var_21 maps\mp\gametypes\_persistence::statsetchild( "round", "deaths", var_21.deaths ); + var_21 maps\mp\_utility::incplayerstat( "deaths", 1 ); + } + } + + if ( isdefined( var_1 ) && isplayer( var_1 ) ) + var_1 checkkillsteal( var_2 ); + + obituary( var_2, var_1, var_5, var_4 ); + var_23 = 0; + var_24 = var_2 maps\mp\_matchdata::logplayerlife(); + var_2 logprintplayerdeath( var_24, var_1, var_3, var_4, var_5, var_12, var_7 ); + var_2 maps\mp\_matchdata::logplayerdeath( var_24, var_1, var_3, var_4, var_5, var_12, var_7 ); + + if ( isplayer( var_1 ) ) + { + if ( var_4 == "MOD_MELEE" ) + { + if ( maps\mp\gametypes\_weapons::isriotshield( var_5 ) ) + { + var_1 maps\mp\_utility::incplayerstat( "shieldkills", 1 ); + + if ( !maps\mp\_utility::matchmakinggame() ) + var_2 maps\mp\_utility::incplayerstat( "shielddeaths", 1 ); + } + else + var_1 maps\mp\_utility::incplayerstat( "knifekills", 1 ); + + addattacker( var_2, var_1, var_0, var_5, var_3, ( 0, 0, 0 ), var_6, var_7, var_8, var_4 ); + } + } + + if ( var_2 isswitchingteams() ) + handleteamchangedeath(); + else if ( !isplayer( var_1 ) || isplayer( var_1 ) && var_4 == "MOD_FALLING" ) + { + handleworlddeath( var_1, var_24, var_4, var_7 ); + + if ( isagent( var_1 ) ) + var_23 = 1; + } + else if ( var_1 == var_2 ) + handlesuicidedeath( var_4, var_7 ); + else if ( var_17 ) + { + if ( !( isdefined( var_2.nuked ) || var_5 == "bomb_site_mp" ) ) + handlefriendlyfiredeath( var_1 ); + } + else + { + if ( var_4 == "MOD_GRENADE" && var_0 == var_1 ) + addattacker( var_2, var_1, var_0, var_5, var_3, ( 0, 0, 0 ), var_6, var_7, var_8, var_4 ); + + var_23 = 1; + + if ( isai( var_2 ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["should_do_killcam"] ) ) + var_23 = var_2 [[ level.bot_funcs["should_do_killcam"] ]](); + + if ( isdefined( level.disable_killcam ) && level.disable_killcam ) + var_23 = 0; + + handlenormaldeath( var_24, var_1, var_0, var_5, var_4 ); + var_2 thread maps\mp\gametypes\_missions::playerkilled( var_0, var_1, var_3, var_4, var_5, var_12, var_7, var_1.modifiers ); + var_2.pers["cur_death_streak"]++; + + if ( isplayer( var_1 ) && var_2 maps\mp\_utility::isjuggernaut() ) + { + if ( isdefined( var_2.isjuggernautmaniac ) && var_2.isjuggernautmaniac ) + { + var_1 thread maps\mp\_utility::teamplayercardsplash( "callout_killed_maniac", var_1 ); + + if ( var_4 == "MOD_MELEE" ) + var_1 maps\mp\gametypes\_missions::processchallenge( "ch_thisisaknife" ); + } + else if ( isdefined( var_2.isjuggernautlevelcustom ) && var_2.isjuggernautlevelcustom ) + var_1 thread maps\mp\_utility::teamplayercardsplash( level.mapcustomjuggkilledsplash, var_1 ); + else + var_1 thread maps\mp\_utility::teamplayercardsplash( "callout_killed_juggernaut", var_1 ); + } + } + + var_25 = 0; + var_26 = undefined; + + if ( isdefined( self.previousprimary ) ) + { + var_25 = 1; + var_26 = self.previousprimary; + self.previousprimary = undefined; + } + + if ( isplayer( var_1 ) && var_1 != self && ( !level.teambased || level.teambased && self.team != var_1.team ) ) + { + if ( var_25 && isdefined( var_26 ) ) + var_27 = var_26; + else + var_27 = self.lastdroppableweapon; + + var_27 = maps\mp\_utility::weaponmap( var_27 ); + thread maps\mp\gametypes\_gamelogic::trackleaderboarddeathstats( var_27, var_4 ); + var_1 thread maps\mp\gametypes\_gamelogic::trackattackerleaderboarddeathstats( var_5, var_4 ); + } + + if ( isdefined( var_1 ) && isdefined( var_2 ) ) + bbprint( "kills", "attackername %s attackerteam %s attackerx %f attackery %f attackerz %f attackerweapon %s victimx %f victimy %f victimz %f victimname %s victimteam %s damage %i damagetype %s damagelocation %s attackerisbot %i victimisbot %i timesincespawn %f", var_1.name, var_1.team, var_1.origin[0], var_1.origin[1], var_1.origin[2], var_5, var_2.origin[0], var_2.origin[1], var_2.origin[2], var_2.name, var_2.team, var_3, var_4, var_7, isai( var_1 ), isai( var_2 ), ( gettime() - var_2.lastspawntime ) / 1000 ); + + var_2.wasswitchingteamsforonplayerkilled = undefined; + + if ( isdefined( var_2.switching_teams ) ) + var_2.wasswitchingteamsforonplayerkilled = 1; + + var_2 resetplayervariables(); + var_2.lastattacker = var_1; + var_2.lastdeathpos = var_2.origin; + var_2.deathtime = gettime(); + var_2.wantsafespawn = 0; + var_2.revived = 0; + var_2.sameshotdamage = 0; + + if ( maps\mp\killstreaks\_killstreaks::streaktyperesetsondeath( var_2.streaktype ) ) + var_2 maps\mp\killstreaks\_killstreaks::resetadrenaline(); + + var_28 = undefined; + + if ( maps\mp\_utility::isrocketcorpse() ) + { + var_23 = 1; + var_10 = 0; + var_28 = self.killcament; + self waittill( "final_rocket_corpse_death" ); + } + else + { + if ( var_10 ) + { + var_23 = 0; + var_9 = var_2 playerforcedeathanim( var_0, var_4, var_5, var_7, var_6 ); + } + + var_2.body = var_2 cloneplayer( var_9 ); + var_2.body.targetname = "player_corpse"; + + if ( var_10 ) + var_2 playerhide(); + + if ( var_2 isonladder() || var_2 ismantling() || !var_2 isonground() || isdefined( var_2.nuked ) || isdefined( var_2.customdeath ) ) + { + var_29 = 0; + + if ( var_4 == "MOD_MELEE" ) + { + if ( isdefined( var_2.isplanting ) && var_2.isplanting || isdefined( var_2.nuked ) ) + var_29 = 1; + } + + if ( !var_29 ) + { + var_2.body startragdoll(); + var_2 notify( "start_instant_ragdoll", var_4, var_0 ); + } + } + + if ( !isdefined( var_2.switching_teams ) ) + { + if ( isdefined( var_1 ) && isplayer( var_1 ) && !var_1 maps\mp\_utility::_hasperk( "specialty_silentkill" ) ) + thread maps\mp\gametypes\_deathicons::adddeathicon( var_2.body, var_2, var_2.team, 5.0 ); + } + + thread delaystartragdoll( var_2.body, var_7, var_6, var_5, var_0, var_4 ); + } + + var_2 thread [[ level.onplayerkilled ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_24 ); + + if ( isai( var_2 ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["on_killed"] ) ) + var_2 thread [[ level.bot_funcs["on_killed"] ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_24 ); + + if ( maps\mp\_utility::isgameparticipant( var_1 ) ) + var_30 = var_1 getentitynumber(); + else + var_30 = -1; + + if ( !isdefined( var_28 ) ) + var_28 = var_2 getkillcamentity( var_1, var_0, var_5 ); + + var_31 = -1; + var_32 = 0; + + if ( isdefined( var_28 ) ) + { + var_31 = var_28 getentitynumber(); + var_32 = var_28.birthtime; + + if ( !isdefined( var_32 ) ) + var_32 = 0; + } + + if ( ( !isdefined( level.disable_killcam ) || !level.disable_killcam ) && var_4 != "MOD_SUICIDE" && !( !isdefined( var_1 ) || var_1.classname == "trigger_hurt" || var_1.classname == "worldspawn" || var_1 == var_2 ) ) + recordfinalkillcam( 5.0, var_2, var_1, var_30, var_0, var_31, var_32, var_5, var_11, var_8, var_4 ); + + var_2 setcommonplayerdata( "killCamHowKilled", 0 ); + + switch ( var_4 ) + { + case "MOD_HEAD_SHOT": + var_2 setcommonplayerdata( "killCamHowKilled", 1 ); + break; + default: + break; + } + + var_33 = undefined; + + if ( var_23 ) + { + var_2 maps\mp\gametypes\_killcam::prekillcamnotify( var_0, var_1 ); + + if ( isdefined( var_0 ) && isagent( var_0 ) ) + { + var_33 = spawnstruct(); + var_33.agent_type = var_0.agent_type; + var_33.lastspawntime = var_0.lastspawntime; + } + } + + if ( !var_10 ) + { + self.respawntimerstarttime = gettime() + 1000; + var_34 = maps\mp\gametypes\_playerlogic::timeuntilspawn( 1 ); + + if ( var_34 < 1 ) + var_34 = 1; + + var_2 thread maps\mp\gametypes\_playerlogic::predictabouttospawnplayerovertime( var_34 ); + wait 1.0; + + if ( var_23 ) + var_23 = !skipkillcamduringdeathtimer( 0.5 ); + + var_2 notify( "death_delay_finished" ); + } + + var_35 = ( gettime() - var_2.deathtime ) / 1000; + self.respawntimerstarttime = gettime(); + var_23 = var_23 && !var_2 maps\mp\gametypes\_battlebuddy::canbuddyspawn(); + + if ( !( isdefined( var_2.cancelkillcam ) && var_2.cancelkillcam ) && var_23 && level.killcam && game["state"] == "playing" && !var_2 maps\mp\_utility::isusingremote() && !level.showingfinalkillcam ) + { + var_36 = !( maps\mp\_utility::getgametypenumlives() && !var_2.pers["lives"] ); + var_34 = maps\mp\gametypes\_playerlogic::timeuntilspawn( 1 ); + var_37 = var_36 && var_34 <= 0; + + if ( !var_36 ) + { + var_34 = -1; + level notify( "player_eliminated", var_2 ); + } + + var_2 maps\mp\gametypes\_killcam::killcam( var_0, var_33, var_30, var_31, var_32, var_5, var_35 + var_11, var_8, var_34, maps\mp\gametypes\_gamelogic::timeuntilroundend(), var_1, var_2, var_4 ); + } + + if ( game["state"] != "playing" ) + { + if ( !level.showingfinalkillcam ) + { + var_2 maps\mp\_utility::updatesessionstate( "dead" ); + var_2 maps\mp\_utility::clearkillcamstate(); + } + + return; + } + + var_38 = maps\mp\_utility::getgametypenumlives(); + var_39 = self.pers["lives"]; + + if ( self == var_2 && isdefined( var_2.battlebuddy ) && maps\mp\_utility::isreallyalive( var_2.battlebuddy ) && ( !maps\mp\_utility::getgametypenumlives() || self.pers["lives"] ) && !var_2 maps\mp\_utility::isusingremote() ) + maps\mp\gametypes\_battlebuddy::waitforplayerrespawnchoice(); + + if ( maps\mp\_utility::isvalidclass( var_2.class ) ) + var_2 thread maps\mp\gametypes\_playerlogic::spawnclient(); +} + +checkforcebleedout() +{ + if ( level.diehardmode != 1 ) + return 0; + + if ( !maps\mp\_utility::getgametypenumlives() ) + return 0; + + if ( level.livescount[self.team] > 0 ) + return 0; + + foreach ( var_1 in level.players ) + { + if ( !isalive( var_1 ) ) + continue; + + if ( var_1.team != self.team ) + continue; + + if ( var_1 == self ) + continue; + + if ( !var_1.inlaststand ) + return 0; + } + + foreach ( var_1 in level.players ) + { + if ( !isalive( var_1 ) ) + continue; + + if ( var_1.team != self.team ) + continue; + + if ( var_1.inlaststand && var_1 != self ) + var_1 laststandbleedout( 0 ); + } + + return 1; +} + +checkkillsteal( var_0 ) +{ + if ( maps\mp\_utility::matchmakinggame() ) + return; + + var_1 = 0; + var_2 = undefined; + + if ( isdefined( var_0.attackerdata ) && var_0.attackerdata.size > 1 ) + { + foreach ( var_4 in var_0.attackerdata ) + { + if ( var_4.damage > var_1 ) + { + var_1 = var_4.damage; + var_2 = var_4.attackerent; + } + } + + if ( isdefined( var_2 ) && var_2 != self ) + maps\mp\_utility::incplayerstat( "killsteals", 1 ); + } +} + +initfinalkillcam() +{ + level.finalkillcam_delay = []; + level.finalkillcam_victim = []; + level.finalkillcam_attacker = []; + level.finalkillcam_attackernum = []; + level.finalkillcam_inflictor = []; + level.finalkillcam_inflictor_agent_type = []; + level.finalkillcam_inflictor_lastspawntime = []; + level.finalkillcam_killcamentityindex = []; + level.finalkillcam_killcamentitystarttime = []; + level.finalkillcam_sweapon = []; + level.finalkillcam_deathtimeoffset = []; + level.finalkillcam_psoffsettime = []; + level.finalkillcam_timerecorded = []; + level.finalkillcam_timegameended = []; + level.finalkillcam_smeansofdeath = []; + + if ( level.multiteambased ) + { + foreach ( var_1 in level.teamnamelist ) + { + level.finalkillcam_delay[var_1] = undefined; + level.finalkillcam_victim[var_1] = undefined; + level.finalkillcam_attacker[var_1] = undefined; + level.finalkillcam_attackernum[var_1] = undefined; + level.finalkillcam_inflictor[var_1] = undefined; + level.finalkillcam_inflictor_agent_type[var_1] = undefined; + level.finalkillcam_inflictor_lastspawntime[var_1] = undefined; + level.finalkillcam_killcamentityindex[var_1] = undefined; + level.finalkillcam_killcamentitystarttime[var_1] = undefined; + level.finalkillcam_sweapon[var_1] = undefined; + level.finalkillcam_deathtimeoffset[var_1] = undefined; + level.finalkillcam_psoffsettime[var_1] = undefined; + level.finalkillcam_timerecorded[var_1] = undefined; + level.finalkillcam_timegameended[var_1] = undefined; + level.finalkillcam_smeansofdeath[var_1] = undefined; + } + } + else + { + level.finalkillcam_delay["axis"] = undefined; + level.finalkillcam_victim["axis"] = undefined; + level.finalkillcam_attacker["axis"] = undefined; + level.finalkillcam_attackernum["axis"] = undefined; + level.finalkillcam_inflictor["axis"] = undefined; + level.finalkillcam_inflictor_agent_type["axis"] = undefined; + level.finalkillcam_inflictor_lastspawntime["axis"] = undefined; + level.finalkillcam_killcamentityindex["axis"] = undefined; + level.finalkillcam_killcamentitystarttime["axis"] = undefined; + level.finalkillcam_sweapon["axis"] = undefined; + level.finalkillcam_deathtimeoffset["axis"] = undefined; + level.finalkillcam_psoffsettime["axis"] = undefined; + level.finalkillcam_timerecorded["axis"] = undefined; + level.finalkillcam_timegameended["axis"] = undefined; + level.finalkillcam_smeansofdeath["axis"] = undefined; + level.finalkillcam_delay["allies"] = undefined; + level.finalkillcam_victim["allies"] = undefined; + level.finalkillcam_attacker["allies"] = undefined; + level.finalkillcam_attackernum["allies"] = undefined; + level.finalkillcam_inflictor["allies"] = undefined; + level.finalkillcam_inflictor_agent_type["allies"] = undefined; + level.finalkillcam_inflictor_lastspawntime["allies"] = undefined; + level.finalkillcam_killcamentityindex["allies"] = undefined; + level.finalkillcam_killcamentitystarttime["allies"] = undefined; + level.finalkillcam_sweapon["allies"] = undefined; + level.finalkillcam_deathtimeoffset["allies"] = undefined; + level.finalkillcam_psoffsettime["allies"] = undefined; + level.finalkillcam_timerecorded["allies"] = undefined; + level.finalkillcam_timegameended["allies"] = undefined; + level.finalkillcam_smeansofdeath["allies"] = undefined; + } + + level.finalkillcam_delay["none"] = undefined; + level.finalkillcam_victim["none"] = undefined; + level.finalkillcam_attacker["none"] = undefined; + level.finalkillcam_attackernum["none"] = undefined; + level.finalkillcam_inflictor["none"] = undefined; + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + level.finalkillcam_killcamentityindex["none"] = undefined; + level.finalkillcam_killcamentitystarttime["none"] = undefined; + level.finalkillcam_sweapon["none"] = undefined; + level.finalkillcam_deathtimeoffset["none"] = undefined; + level.finalkillcam_psoffsettime["none"] = undefined; + level.finalkillcam_timerecorded["none"] = undefined; + level.finalkillcam_timegameended["none"] = undefined; + level.finalkillcam_smeansofdeath["none"] = undefined; + level.finalkillcam_winner = undefined; +} + +recordfinalkillcam( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + if ( level.teambased && isdefined( var_2.team ) ) + { + level.finalkillcam_delay[var_2.team] = var_0; + level.finalkillcam_victim[var_2.team] = var_1; + level.finalkillcam_attacker[var_2.team] = var_2; + level.finalkillcam_attackernum[var_2.team] = var_3; + level.finalkillcam_inflictor[var_2.team] = var_4; + level.finalkillcam_killcamentityindex[var_2.team] = var_5; + level.finalkillcam_killcamentitystarttime[var_2.team] = var_6; + level.finalkillcam_sweapon[var_2.team] = var_7; + level.finalkillcam_deathtimeoffset[var_2.team] = var_8; + level.finalkillcam_psoffsettime[var_2.team] = var_9; + level.finalkillcam_timerecorded[var_2.team] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended[var_2.team] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_smeansofdeath[var_2.team] = var_10; + + if ( isdefined( var_4 ) && isagent( var_4 ) ) + { + level.finalkillcam_inflictor_agent_type[var_2.team] = var_4.agent_type; + level.finalkillcam_inflictor_lastspawntime[var_2.team] = var_4.lastspawntime; + } + else + { + level.finalkillcam_inflictor_agent_type[var_2.team] = undefined; + level.finalkillcam_inflictor_lastspawntime[var_2.team] = undefined; + } + } + + level.finalkillcam_delay["none"] = var_0; + level.finalkillcam_victim["none"] = var_1; + level.finalkillcam_attacker["none"] = var_2; + level.finalkillcam_attackernum["none"] = var_3; + level.finalkillcam_inflictor["none"] = var_4; + level.finalkillcam_killcamentityindex["none"] = var_5; + level.finalkillcam_killcamentitystarttime["none"] = var_6; + level.finalkillcam_sweapon["none"] = var_7; + level.finalkillcam_deathtimeoffset["none"] = var_8; + level.finalkillcam_psoffsettime["none"] = var_9; + level.finalkillcam_timerecorded["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_smeansofdeath["none"] = var_10; + + if ( isdefined( var_4 ) && isagent( var_4 ) ) + { + level.finalkillcam_inflictor_agent_type["none"] = var_4.agent_type; + level.finalkillcam_inflictor_lastspawntime["none"] = var_4.lastspawntime; + } + else + { + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + } +} + +erasefinalkillcam() +{ + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + level.finalkillcam_delay[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_victim[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_attacker[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_attackernum[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor_agent_type[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor_lastspawntime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_killcamentityindex[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_killcamentitystarttime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_sweapon[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_deathtimeoffset[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_psoffsettime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_timerecorded[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_timegameended[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_smeansofdeath[level.teamnamelist[var_0]] = undefined; + } + } + else + { + level.finalkillcam_delay["axis"] = undefined; + level.finalkillcam_victim["axis"] = undefined; + level.finalkillcam_attacker["axis"] = undefined; + level.finalkillcam_attackernum["axis"] = undefined; + level.finalkillcam_inflictor["axis"] = undefined; + level.finalkillcam_inflictor_agent_type["axis"] = undefined; + level.finalkillcam_inflictor_lastspawntime["axis"] = undefined; + level.finalkillcam_killcamentityindex["axis"] = undefined; + level.finalkillcam_killcamentitystarttime["axis"] = undefined; + level.finalkillcam_sweapon["axis"] = undefined; + level.finalkillcam_deathtimeoffset["axis"] = undefined; + level.finalkillcam_psoffsettime["axis"] = undefined; + level.finalkillcam_timerecorded["axis"] = undefined; + level.finalkillcam_timegameended["axis"] = undefined; + level.finalkillcam_smeansofdeath["axis"] = undefined; + level.finalkillcam_delay["allies"] = undefined; + level.finalkillcam_victim["allies"] = undefined; + level.finalkillcam_attacker["allies"] = undefined; + level.finalkillcam_attackernum["allies"] = undefined; + level.finalkillcam_inflictor["allies"] = undefined; + level.finalkillcam_inflictor_agent_type["allies"] = undefined; + level.finalkillcam_inflictor_lastspawntime["allies"] = undefined; + level.finalkillcam_killcamentityindex["allies"] = undefined; + level.finalkillcam_killcamentitystarttime["allies"] = undefined; + level.finalkillcam_sweapon["allies"] = undefined; + level.finalkillcam_deathtimeoffset["allies"] = undefined; + level.finalkillcam_psoffsettime["allies"] = undefined; + level.finalkillcam_timerecorded["allies"] = undefined; + level.finalkillcam_timegameended["allies"] = undefined; + level.finalkillcam_smeansofdeath["allies"] = undefined; + } + + level.finalkillcam_delay["none"] = undefined; + level.finalkillcam_victim["none"] = undefined; + level.finalkillcam_attacker["none"] = undefined; + level.finalkillcam_attackernum["none"] = undefined; + level.finalkillcam_inflictor["none"] = undefined; + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + level.finalkillcam_killcamentityindex["none"] = undefined; + level.finalkillcam_killcamentitystarttime["none"] = undefined; + level.finalkillcam_sweapon["none"] = undefined; + level.finalkillcam_deathtimeoffset["none"] = undefined; + level.finalkillcam_psoffsettime["none"] = undefined; + level.finalkillcam_timerecorded["none"] = undefined; + level.finalkillcam_timegameended["none"] = undefined; + level.finalkillcam_smeansofdeath["none"] = undefined; + level.finalkillcam_winner = undefined; +} + +dofinalkillcam() +{ + level waittill( "round_end_finished" ); + level.showingfinalkillcam = 1; + var_0 = "none"; + + if ( isdefined( level.finalkillcam_winner ) ) + var_0 = level.finalkillcam_winner; + + var_1 = level.finalkillcam_delay[var_0]; + var_2 = level.finalkillcam_victim[var_0]; + var_3 = level.finalkillcam_attacker[var_0]; + var_4 = level.finalkillcam_attackernum[var_0]; + var_5 = level.finalkillcam_inflictor[var_0]; + var_6 = level.finalkillcam_inflictor_agent_type[var_0]; + var_7 = level.finalkillcam_inflictor_lastspawntime[var_0]; + var_8 = level.finalkillcam_killcamentityindex[var_0]; + var_9 = level.finalkillcam_killcamentitystarttime[var_0]; + var_10 = level.finalkillcam_sweapon[var_0]; + var_11 = level.finalkillcam_deathtimeoffset[var_0]; + var_12 = level.finalkillcam_psoffsettime[var_0]; + var_13 = level.finalkillcam_timerecorded[var_0]; + var_14 = level.finalkillcam_timegameended[var_0]; + var_15 = level.finalkillcam_smeansofdeath[var_0]; + + if ( !isdefined( var_2 ) || !isdefined( var_3 ) ) + { + level.showingfinalkillcam = 0; + level notify( "final_killcam_done" ); + return; + } + + var_16 = 15; + var_17 = var_14 - var_13; + + if ( var_17 > var_16 ) + { + level.showingfinalkillcam = 0; + level notify( "final_killcam_done" ); + return; + } + + if ( isdefined( var_3 ) ) + { + var_3.finalkill = 1; + var_18 = "none"; + + if ( level.teambased ) + var_18 = var_3.team; + + if ( isdefined( level.finalkillcam_attacker[var_18] ) && level.finalkillcam_attacker[var_18] == var_3 ) + maps\mp\gametypes\_missions::processfinalkillchallenges( var_3, var_2 ); + } + + var_19 = spawnstruct(); + var_19.agent_type = var_6; + var_19.lastspawntime = var_7; + var_20 = ( gettime() - var_2.deathtime ) / 1000; + + foreach ( var_22 in level.players ) + { + var_22 maps\mp\_utility::restorebasevisionset( 0 ); + var_22.killcamentitylookat = var_2 getentitynumber(); + var_22 thread maps\mp\gametypes\_killcam::killcam( var_5, var_19, var_4, var_8, var_9, var_10, var_20 + var_11, var_12, 0, 12, var_3, var_2, var_15 ); + } + + wait 0.1; + + while ( anyplayersinkillcam() ) + wait 0.05; + + level notify( "final_killcam_done" ); + level.showingfinalkillcam = 0; +} + +anyplayersinkillcam() +{ + foreach ( var_1 in level.players ) + { + if ( isdefined( var_1.killcam ) ) + return 1; + } + + return 0; +} + +resetplayervariables() +{ + self.killedplayerscurrent = []; + self.ch_extremecrueltycomplete = 0; + self.switching_teams = undefined; + self.joining_team = undefined; + self.leaving_team = undefined; + self.pers["cur_kill_streak"] = 0; + self.pers["cur_kill_streak_for_nuke"] = 0; + maps\mp\gametypes\_gameobjects::detachusemodels(); +} + +getkillcamentity( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_0 ) || !isdefined( var_1 ) || var_0 == var_1 && !isagent( var_0 ) ) + return undefined; + + switch ( var_2 ) + { + case "trophy_mp": + case "bomb_site_mp": + case "proximity_explosive_mp": + case "heli_pilot_turret_mp": + case "sentry_minigun_mp": + case "hashima_missiles_mp": + return var_1.killcament; + case "remote_tank_projectile_mp": + case "hind_bomb_mp": + case "hind_missile_mp": + case "aamissile_projectile_mp": + if ( isdefined( var_1.vehicle_fired_from ) && isdefined( var_1.vehicle_fired_from.killcament ) ) + return var_1.vehicle_fired_from.killcament; + else if ( isdefined( var_1.vehicle_fired_from ) ) + return var_1.vehicle_fired_from; + + break; + case "sam_projectile_mp": + if ( isdefined( var_1.samturret ) && isdefined( var_1.samturret.killcament ) ) + return var_1.samturret.killcament; + + break; + case "ims_projectile_mp": + if ( isdefined( var_0 ) && isdefined( var_0.imskillcament ) ) + return var_0.imskillcament; + + break; + case "ball_drone_gun_mp": + case "ball_drone_projectile_mp": + if ( isplayer( var_0 ) && isdefined( var_0.balldrone ) && isdefined( var_0.balldrone.turret ) && isdefined( var_0.balldrone.turret.killcament ) ) + return var_0.balldrone.turret.killcament; + + break; + case "none": + case "artillery_mp": + if ( isdefined( var_1.targetname ) && var_1.targetname == "care_package" || isdefined( var_1.killcament ) && ( var_1.classname == "script_brushmodel" || var_1.classname == "trigger_multiple" || var_1.classname == "script_model" ) ) + return var_1.killcament; + + break; + case "ac130_105mm_mp": + case "ac130_40mm_mp": + case "remotemissile_projectile_mp": + case "ac130_25mm_mp": + case "osprey_player_minigun_mp": + case "ugv_turret_mp": + case "remote_turret_mp": + return undefined; + } + + if ( maps\mp\_utility::isdestructibleweapon( var_2 ) || maps\mp\_utility::isbombsiteweapon( var_2 ) ) + { + if ( isdefined( var_1.killcament ) && !var_0 attackerinremotekillstreak() ) + return var_1.killcament; + else + return undefined; + } + + return var_1; +} + +attackerinremotekillstreak() +{ + if ( !isdefined( self ) ) + return 0; + + if ( isdefined( level.ac130player ) && self == level.ac130player ) + return 1; + + if ( isdefined( level.chopper ) && isdefined( level.chopper.gunner ) && self == level.chopper.gunner ) + return 1; + + if ( isdefined( level.remote_mortar ) && isdefined( level.remote_mortar.owner ) && self == level.remote_mortar.owner ) + return 1; + + if ( isdefined( self.using_remote_turret ) && self.using_remote_turret ) + return 1; + + if ( isdefined( self.using_remote_tank ) && self.using_remote_tank ) + return 1; + else if ( isdefined( self.using_remote_a10 ) ) + return 1; + + return 0; +} + +hitlocdebug( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = []; + var_5[0] = 2; + var_5[1] = 3; + var_5[2] = 5; + var_5[3] = 7; + + if ( !getdvarint( "scr_hitloc_debug" ) ) + return; + + if ( !isdefined( var_0.hitlocinited ) ) + { + for ( var_6 = 0; var_6 < 6; var_6++ ) + var_0 setclientdvar( "ui_hitloc_" + var_6, "" ); + + var_0.hitlocinited = 1; + } + + if ( level.splitscreen || !isplayer( var_0 ) ) + return; + + var_7 = 6; + + if ( !isdefined( var_0.damageinfo ) ) + { + var_0.damageinfo = []; + + for ( var_6 = 0; var_6 < var_7; var_6++ ) + { + var_0.damageinfo[var_6] = spawnstruct(); + var_0.damageinfo[var_6].damage = 0; + var_0.damageinfo[var_6].hitloc = ""; + var_0.damageinfo[var_6].bp = 0; + var_0.damageinfo[var_6].jugg = 0; + var_0.damageinfo[var_6].colorindex = 0; + } + + var_0.damageinfocolorindex = 0; + var_0.damageinfovictim = undefined; + } + + for ( var_6 = var_7 - 1; var_6 > 0; var_6-- ) + { + var_0.damageinfo[var_6].damage = var_0.damageinfo[var_6 - 1].damage; + var_0.damageinfo[var_6].hitloc = var_0.damageinfo[var_6 - 1].hitloc; + var_0.damageinfo[var_6].bp = var_0.damageinfo[var_6 - 1].bp; + var_0.damageinfo[var_6].jugg = var_0.damageinfo[var_6 - 1].jugg; + var_0.damageinfo[var_6].colorindex = var_0.damageinfo[var_6 - 1].colorindex; + } + + var_0.damageinfo[0].damage = var_2; + var_0.damageinfo[0].hitloc = var_3; + var_0.damageinfo[0].bp = var_4 & level.idflags_penetration; + var_0.damageinfo[0].jugg = var_1 maps\mp\_utility::isjuggernaut(); + + if ( isdefined( var_0.damageinfovictim ) && var_0.damageinfovictim != var_1 ) + { + var_0.damageinfocolorindex++; + + if ( var_0.damageinfocolorindex == var_5.size ) + var_0.damageinfocolorindex = 0; + } + + var_0.damageinfovictim = var_1; + var_0.damageinfo[0].colorindex = var_0.damageinfocolorindex; + + for ( var_6 = 0; var_6 < var_7; var_6++ ) + { + var_8 = "^" + var_5[var_0.damageinfo[var_6].colorindex]; + + if ( var_0.damageinfo[var_6].hitloc != "" ) + { + var_9 = var_8 + var_0.damageinfo[var_6].hitloc; + + if ( var_0.damageinfo[var_6].bp ) + var_9 += " (BP)"; + + if ( var_0.damageinfo[var_6].jugg ) + var_9 += " (Jugg)"; + + var_0 setclientdvar( "ui_hitloc_" + var_6, var_9 ); + } + + var_0 setclientdvar( "ui_hitloc_damage_" + var_6, var_8 + var_0.damageinfo[var_6].damage ); + } +} + +giverecentshieldxp() +{ + self endon( "death" ); + self endon( "disconnect" ); + self notify( "giveRecentShieldXP" ); + self endon( "giveRecentShieldXP" ); + self.recentshieldxp++; + wait 20.0; + self.recentshieldxp = 0; +} + +updateinflictorstat( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_0 ) || !isdefined( var_0.alreadyhit ) || !var_0.alreadyhit || !maps\mp\_utility::issinglehitweapon( var_2 ) ) + maps\mp\gametypes\_gamelogic::setinflictorstat( var_0, var_1, var_2 ); + + if ( isdefined( var_0 ) ) + var_0.alreadyhit = 1; +} + +callback_playerdamage_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + var_11 = getdvar( "g_gametype" ); + + if ( isdefined( var_5 ) && var_5 == "MOD_CRUSH" && isdefined( var_0 ) && isdefined( var_0.classname ) && var_0.classname == "script_vehicle" ) + return "crushed"; + + if ( !maps\mp\_utility::isreallyalive( var_2 ) ) + return "!isReallyAlive( victim )"; + + if ( var_6 == "hind_bomb_mp" || var_6 == "hind_missile_mp" ) + { + if ( isdefined( var_1 ) && var_2 == var_1 ) + return 0; + } + + if ( isdefined( var_1 ) && var_1.classname == "script_origin" && isdefined( var_1.type ) && var_1.type == "soft_landing" ) + return "soft_landing"; + + if ( var_6 == "killstreak_emp_mp" ) + return "sWeapon == killstreak_emp_mp"; + + if ( var_6 == "bouncingbetty_mp" && !maps\mp\gametypes\_weapons::minedamageheightpassed( var_0, var_2 ) ) + return "mineDamageHeightPassed"; + + if ( var_6 == "bouncingbetty_mp" && ( var_2 getstance() == "crouch" || var_2 getstance() == "prone" ) ) + var_3 = int( var_3 / 2 ); + + if ( var_6 == "emp_grenade_mp" && var_5 != "MOD_IMPACT" ) + var_2 notify( "emp_damage", var_1 ); + + if ( isdefined( level.hostmigrationtimer ) ) + return "level.hostMigrationTimer"; + + if ( var_5 == "MOD_FALLING" ) + var_2 thread emitfalldamage( var_3 ); + + if ( var_5 == "MOD_EXPLOSIVE_BULLET" && var_3 != 1 ) + { + var_3 *= getdvarfloat( "scr_explBulletMod" ); + var_3 = int( var_3 ); + } + + if ( isdefined( var_1 ) && var_1.classname == "worldspawn" ) + var_1 = undefined; + + if ( isdefined( var_1 ) && isdefined( var_1.gunner ) ) + var_1 = var_1.gunner; + + if ( isdefined( var_0 ) && isdefined( var_0.damagedby ) ) + var_1 = var_0.damagedby; + + var_12 = isdefined( var_1 ) && !isdefined( var_1.gunner ) && ( var_1.classname == "script_vehicle" || var_1.classname == "misc_turret" || var_1.classname == "script_model" ); + var_13 = maps\mp\_utility::attackerishittingteam( var_2, var_1 ); + var_14 = isdefined( var_1 ) && isdefined( var_0 ) && isdefined( var_2 ) && isplayer( var_1 ) && var_1 == var_0 && var_1 == var_2 && !isdefined( var_0.poison ); + + if ( var_14 ) + return "attackerIsInflictorVictim"; + + var_15 = 0.0; + + if ( var_4 & level.idflags_stun ) + { + var_15 = 0.0; + var_3 = 0.0; + } + else if ( var_9 == "shield" ) + { + if ( var_13 && level.friendlyfire == 0 ) + return "attackerIsHittingTeammate"; + + if ( var_5 == "MOD_PISTOL_BULLET" || var_5 == "MOD_RIFLE_BULLET" || var_5 == "MOD_EXPLOSIVE_BULLET" && !var_13 ) + { + if ( isplayer( var_1 ) ) + { + if ( isdefined( var_2.owner ) ) + var_2 = var_2.owner; + + var_1.lastattackedshieldplayer = var_2; + var_1.lastattackedshieldtime = gettime(); + } + + var_2 notify( "shield_blocked" ); + + if ( maps\mp\_utility::isenvironmentweapon( var_6 ) ) + var_16 = 25; + else + var_16 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + var_2.shielddamage += var_16; + + if ( !maps\mp\_utility::isenvironmentweapon( var_6 ) || common_scripts\utility::cointoss() ) + var_2.shieldbullethits++; + + if ( var_2.shieldbullethits >= level.riotshieldxpbullets ) + { + if ( self.recentshieldxp > 4 ) + var_17 = int( 50 / self.recentshieldxp ); + else + var_17 = 50; + + var_2 thread maps\mp\gametypes\_rank::giverankxp( "shield_damage", var_17 ); + var_2 thread giverecentshieldxp(); + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_damage", var_2.shielddamage ); + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_bullet_hits", var_2.shieldbullethits ); + var_2.shielddamage = 0; + var_2.shieldbullethits = 0; + } + } + + if ( var_4 & level.idflags_shield_explosive_impact ) + { + if ( !var_13 ) + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_explosive_hits", 1 ); + + var_9 = "none"; + + if ( !( var_4 & level.idflags_shield_explosive_impact_huge ) ) + var_3 *= 0.0; + } + else if ( var_4 & level.idflags_shield_explosive_splash ) + { + if ( isdefined( var_0 ) && isdefined( var_0.stuckenemyentity ) && var_0.stuckenemyentity == var_2 ) + var_3 = 151; + + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_explosive_hits", 1 ); + var_9 = "none"; + } + else + return "hit shield"; + } + else if ( var_5 == "MOD_MELEE" && maps\mp\gametypes\_weapons::isriotshield( var_6 ) ) + { + if ( !( var_13 && level.friendlyfire == 0 ) ) + { + var_15 = 0.0; + var_2 stunplayer( 0.0 ); + } + } + + if ( isdefined( var_0 ) && isdefined( var_0.stuckenemyentity ) && var_0.stuckenemyentity == var_2 ) + var_3 = 151; + + if ( !var_13 ) + { + if ( maps\mp\_utility::_hasperk( "specialty_moredamage" ) ) + maps\mp\_utility::_unsetperk( "specialty_moredamage" ); + + if ( maps\mp\_utility::isbulletdamage( var_5 ) && var_1 maps\mp\_utility::_hasperk( "specialty_deadeye" ) ) + var_1 maps\mp\perks\_perkfunctions::setdeadeyeinternal(); + + var_3 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9, var_0 ); + + if ( isplayer( var_1 ) && ( var_6 == "smoke_grenade_mp" || var_6 == "throwingknife_mp" ) ) + var_1 thread maps\mp\gametypes\_gamelogic::threadedsetweaponstatbyname( var_6, 1, "hits" ); + } + + if ( isdefined( level.modifyplayerdamage ) ) + var_3 = [[ level.modifyplayerdamage ]]( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + if ( !var_3 ) + return "!iDamage"; + + var_2.idflags = var_4; + var_2.idflagstime = gettime(); + + if ( game["state"] == "postgame" ) + return "game[ state ] == postgame"; + + if ( var_2.sessionteam == "spectator" ) + return "victim.sessionteam == spectator"; + + if ( isdefined( var_2.candocombat ) && !var_2.candocombat ) + return "!victim.canDoCombat"; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_1.candocombat ) && !var_1.candocombat ) + return "!eAttacker.canDoCombat"; + + if ( var_12 && var_13 ) + { + if ( var_5 == "MOD_CRUSH" ) + { + var_2 maps\mp\_utility::_suicide(); + return "suicide crush"; + } + + if ( !level.friendlyfire ) + return "!level.friendlyfire"; + } + + if ( isai( self ) ) + self [[ level.bot_funcs["on_damaged"] ]]( var_1, var_3, var_5, var_6, var_0, var_9 ); + + if ( !isdefined( var_8 ) ) + var_4 |= level.idflags_no_knockback; + + var_18 = 0; + + if ( var_2.health == var_2.maxhealth && ( !isdefined( var_2.laststand ) || !var_2.laststand ) || !isdefined( var_2.attackers ) && !isdefined( var_2.laststand ) ) + var_2 resetattackerlist_internal(); + + if ( maps\mp\_utility::isheadshot( var_6, var_9, var_5, var_1 ) ) + var_5 = "MOD_HEAD_SHOT"; + + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "onlyheadshots" ) ) + { + if ( var_5 == "MOD_PISTOL_BULLET" || var_5 == "MOD_RIFLE_BULLET" || var_5 == "MOD_EXPLOSIVE_BULLET" ) + return "getTweakableValue( game, onlyheadshots )"; + else if ( var_5 == "MOD_HEAD_SHOT" ) + { + if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_3 = 75; + else + var_3 = 150; + } + } + + if ( var_6 == "destructible_toy" && isdefined( var_0 ) ) + var_6 = "destructible_car"; + + if ( gettime() < var_2.spawntime + level.killstreakspawnshield ) + { + var_19 = int( max( var_2.health / 4, 1 ) ); + + if ( var_3 >= var_19 && maps\mp\_utility::iskillstreakweapon( var_6 ) && var_5 != "MOD_MELEE" ) + var_3 = var_19; + } + + if ( !( var_4 & level.idflags_no_protection ) ) + { + if ( !level.teambased && var_12 && isdefined( var_1.owner ) && var_1.owner == var_2 ) + { + if ( var_5 == "MOD_CRUSH" ) + var_2 maps\mp\_utility::_suicide(); + + return "ffa suicide"; + } + + if ( ( issubstr( var_5, "MOD_GRENADE" ) || issubstr( var_5, "MOD_EXPLOSIVE" ) || issubstr( var_5, "MOD_PROJECTILE" ) ) && isdefined( var_0 ) && isdefined( var_1 ) ) + { + if ( var_2 != var_1 && var_0.classname == "grenade" && var_2.lastspawntime + 3500 > gettime() && isdefined( var_2.lastspawnpoint ) && distance( var_0.origin, var_2.lastspawnpoint.origin ) < 500 ) + return "spawnkill grenade protection"; + + var_2.explosiveinfo = []; + var_2.explosiveinfo["damageTime"] = gettime(); + var_2.explosiveinfo["damageId"] = var_0 getentitynumber(); + var_2.explosiveinfo["returnToSender"] = 0; + var_2.explosiveinfo["counterKill"] = 0; + var_2.explosiveinfo["chainKill"] = 0; + var_2.explosiveinfo["cookedKill"] = 0; + var_2.explosiveinfo["throwbackKill"] = 0; + var_2.explosiveinfo["suicideGrenadeKill"] = 0; + var_2.explosiveinfo["weapon"] = var_6; + var_20 = issubstr( var_6, "frag_" ); + + if ( var_1 != var_2 ) + { + if ( ( issubstr( var_6, "c4_" ) || issubstr( var_6, "proximity_explosive_" ) || issubstr( var_6, "claymore_" ) ) && isdefined( var_0.owner ) ) + { + var_2.explosiveinfo["returnToSender"] = var_0.owner == var_2; + var_2.explosiveinfo["counterKill"] = isdefined( var_0.wasdamaged ); + var_2.explosiveinfo["chainKill"] = isdefined( var_0.waschained ); + var_2.explosiveinfo["bulletPenetrationKill"] = isdefined( var_0.wasdamagedfrombulletpenetration ); + var_2.explosiveinfo["cookedKill"] = 0; + } + + if ( isdefined( var_1.lastgrenadesuicidetime ) && var_1.lastgrenadesuicidetime >= gettime() - 50 && var_20 ) + var_2.explosiveinfo["suicideGrenadeKill"] = 1; + } + + if ( var_20 ) + { + var_2.explosiveinfo["cookedKill"] = isdefined( var_0.iscooked ); + var_2.explosiveinfo["throwbackKill"] = isdefined( var_0.threwback ); + } + + var_2.explosiveinfo["stickKill"] = isdefined( var_0.isstuck ) && var_0.isstuck == "enemy"; + var_2.explosiveinfo["stickFriendlyKill"] = isdefined( var_0.isstuck ) && var_0.isstuck == "friendly"; + + if ( isplayer( var_1 ) && var_1 != self && var_11 != "aliens" ) + updateinflictorstat( var_0, var_1, var_6 ); + } + + if ( issubstr( var_5, "MOD_IMPACT" ) && var_6 == "iw6_rgm_mp" ) + { + if ( isplayer( var_1 ) && var_1 != self && var_11 != "aliens" ) + updateinflictorstat( var_0, var_1, var_6 ); + } + + if ( isplayer( var_1 ) && isdefined( var_1.pers["participation"] ) ) + var_1.pers["participation"]++; + else if ( isplayer( var_1 ) ) + var_1.pers["participation"] = 1; + + var_21 = var_2.health / var_2.maxhealth; + + if ( var_13 ) + { + if ( !maps\mp\_utility::matchmakinggame() && isplayer( var_1 ) ) + var_1 maps\mp\_utility::incplayerstat( "mostff", 1 ); + + if ( level.friendlyfire == 0 || !isplayer( var_1 ) && level.friendlyfire != 1 || var_6 == "bomb_site_mp" ) + { + if ( var_6 == "artillery_mp" || var_6 == "stealth_bomb_mp" ) + var_2 damageshellshockandrumble( var_0, var_6, var_5, var_3, var_4, var_1 ); + + return "friendly fire"; + } + else if ( level.friendlyfire == 1 ) + { + if ( var_3 < 1 ) + var_3 = 1; + + if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_3 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + var_2.lastdamagewasfromenemy = 0; + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + } + else if ( level.friendlyfire == 2 && maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_3 = int( var_3 * 0.5 ); + + if ( var_3 < 1 ) + var_3 = 1; + + var_1.lastdamagewasfromenemy = 0; + var_1.friendlydamage = 1; + var_1 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + var_1.friendlydamage = undefined; + } + else if ( level.friendlyfire == 3 && maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_3 = int( var_3 * 0.5 ); + + if ( var_3 < 1 ) + var_3 = 1; + + var_2.lastdamagewasfromenemy = 0; + var_1.lastdamagewasfromenemy = 0; + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + + if ( maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_1.friendlydamage = 1; + var_1 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + var_1.friendlydamage = undefined; + } + } + + var_18 = 1; + } + else + { + if ( var_3 < 1 ) + var_3 = 1; + + if ( isdefined( var_1 ) && isplayer( var_1 ) ) + addattacker( var_2, var_1, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + + if ( isdefined( var_1 ) && !isplayer( var_1 ) && isdefined( var_1.owner ) && ( !isdefined( var_1.scrambled ) || !var_1.scrambled ) ) + addattacker( var_2, var_1.owner, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + else if ( isdefined( var_1 ) && !isplayer( var_1 ) && isdefined( var_1.secondowner ) && isdefined( var_1.scrambled ) && var_1.scrambled ) + addattacker( var_2, var_1.secondowner, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + + if ( var_5 == "MOD_EXPLOSIVE" || var_5 == "MOD_GRENADE_SPLASH" && var_3 < var_2.health ) + var_2 notify( "survived_explosion", var_1 ); + + if ( isdefined( var_1 ) ) + level.lastlegitimateattacker = var_1; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_6 ) ) + var_1 thread maps\mp\gametypes\_weapons::checkhit( var_6, var_2 ); + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_6 ) && var_1 != var_2 ) + { + var_1 thread maps\mp\_events::damagedplayer( self, var_3, var_6 ); + var_2.attackerposition = var_1.origin; + } + else + var_2.attackerposition = undefined; + + if ( issubstr( var_5, "MOD_GRENADE" ) && isdefined( var_0.iscooked ) ) + var_2.wascooked = gettime(); + else + var_2.wascooked = undefined; + + var_2.lastdamagewasfromenemy = isdefined( var_1 ) && var_1 != var_2; + + if ( var_2.lastdamagewasfromenemy ) + { + var_22 = gettime(); + var_1.damagedplayers[var_2.guid] = var_22; + var_2.lastdamagedtime = var_22; + } + + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + + if ( isdefined( level.ac130player ) && isdefined( var_1 ) && level.ac130player == var_1 ) + level notify( "ai_pain", var_2 ); + + var_2 thread maps\mp\gametypes\_missions::playerdamaged( var_0, var_1, var_3, var_5, var_6, var_9 ); + } + + if ( var_12 && isdefined( var_1.gunner ) ) + var_23 = var_1.gunner; + else + var_23 = var_1; + + if ( isdefined( var_23 ) && var_23 != var_2 && var_3 > 0 && ( !isdefined( var_9 ) || var_9 != "shield" ) ) + { + var_24 = !maps\mp\_utility::isreallyalive( var_2 ) || isagent( var_2 ) && var_3 >= var_2.health; + + if ( var_4 & level.idflags_stun ) + var_25 = "stun"; + else if ( isexplosivedamagemod( var_5 ) && ( isdefined( var_2.thermodebuffed ) && var_2.thermodebuffed ) ) + var_25 = common_scripts\utility::ter_op( var_24, "thermodebuff_kill", "thermobaric_debuff" ); + else if ( isexplosivedamagemod( var_5 ) && var_2 maps\mp\_utility::_hasperk( "_specialty_blastshield" ) && !maps\mp\_utility::weaponignoresblastshield( var_6 ) ) + var_25 = common_scripts\utility::ter_op( var_24, "hitkillblast", "hitblastshield" ); + else if ( var_2 maps\mp\_utility::_hasperk( "specialty_combathigh" ) ) + var_25 = "hitendgame"; + else if ( isdefined( var_2.lightarmorhp ) && var_5 != "MOD_HEAD_SHOT" && !maps\mp\_utility::isfmjdamage( var_6, var_5, var_1 ) ) + var_25 = "hitlightarmor"; + else if ( maps\mp\perks\_perkfunctions::hasheavyarmor( var_2 ) ) + var_25 = "hitlightarmor"; + else if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_25 = common_scripts\utility::ter_op( var_24, "hitkilljugg", "hitjuggernaut" ); + else if ( var_2 maps\mp\_utility::_hasperk( "specialty_moreHealth" ) ) + var_25 = "hitmorehealth"; + else if ( var_23 maps\mp\_utility::_hasperk( "specialty_moredamage" ) ) + { + var_25 = common_scripts\utility::ter_op( var_24, "hitdeadeyekill", "hitcritical" ); + var_23 maps\mp\_utility::_unsetperk( "specialty_moredamage" ); + } + else if ( !shouldweaponfeedback( var_6 ) ) + var_25 = "none"; + else + var_25 = common_scripts\utility::ter_op( var_24, "hitkill", "standard" ); + + var_23 thread maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_25 ); + } + + maps\mp\gametypes\_gamelogic::sethasdonecombat( var_2, 1 ); + } + + if ( isdefined( var_1 ) && var_1 != var_2 && !var_18 ) + level.usestartspawns = 0; + + if ( var_3 > 10 && isdefined( var_0 ) && !var_2 maps\mp\_utility::isusingremote() && isplayer( var_2 ) ) + { + var_2 thread maps\mp\gametypes\_shellshock::bloodeffect( var_0.origin ); + + if ( isplayer( var_0 ) && var_5 == "MOD_MELEE" ) + var_0 thread maps\mp\gametypes\_shellshock::bloodmeleeeffect(); + } + + if ( var_2.sessionstate != "dead" ) + { + var_23 = var_2 getentitynumber(); + var_24 = var_2.name; + var_25 = var_2.pers["team"]; + var_26 = var_2.guid; + var_27 = ""; + + if ( isplayer( var_1 ) ) + { + var_28 = var_1 getentitynumber(); + var_29 = var_1.guid; + var_30 = var_1.name; + var_27 = var_1.pers["team"]; + } + else + { + var_28 = -1; + var_29 = ""; + var_30 = ""; + var_27 = "world"; + } + + logprint( "D;" + var_26 + ";" + var_23 + ";" + var_25 + ";" + var_24 + ";" + var_29 + ";" + var_28 + ";" + var_27 + ";" + var_30 + ";" + var_6 + ";" + var_3 + ";" + var_5 + ";" + var_9 + "\n" ); + } + + hitlocdebug( var_1, var_2, var_3, var_9, var_4 ); + + if ( isdefined( var_1 ) && var_1 != var_2 ) + { + if ( isplayer( var_1 ) ) + var_1 maps\mp\_utility::incplayerstat( "damagedone", var_3 ); + + var_2 maps\mp\_utility::incplayerstat( "damagetaken", var_3 ); + } + + if ( isagent( self ) ) + self [[ maps\mp\agents\_agent_utility::agentfunc( "on_damaged_finished" ) ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + + return "finished"; +} + +shouldweaponfeedback( var_0 ) +{ + switch ( var_0 ) + { + case "artillery_mp": + case "stealth_bomb_mp": + return 0; + } + + return 1; +} + +checkvictimstutter( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( var_4 == "MOD_PISTOL_BULLET" || var_4 == "MOD_RIFLE_BULLET" || var_4 == "MOD_HEAD_SHOT" ) + { + if ( distance( var_0.origin, var_1.origin ) > 256 ) + return; + + var_5 = var_0 getvelocity(); + + if ( lengthsquared( var_5 ) < 10 ) + return; + + var_6 = maps\mp\_utility::findisfacing( var_0, var_1, 25 ); + + if ( var_6 ) + var_0 thread stutterstep(); + } +} + +stutterstep( var_0 ) +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); + self.instutter = 1; + self.movespeedscaler = 0.05; + maps\mp\gametypes\_weapons::updatemovespeedscale(); + wait 0.5; + self.movespeedscaler = 1; + + if ( maps\mp\_utility::_hasperk( "specialty_lightweight" ) ) + self.movespeedscaler = maps\mp\_utility::lightweightscalar(); + + maps\mp\gametypes\_weapons::updatemovespeedscale(); + self.instutter = 0; +} + +addattacker( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + if ( !isdefined( var_0.attackerdata ) ) + var_0.attackerdata = []; + + if ( !isdefined( var_0.attackerdata[var_1.guid] ) ) + { + var_0.attackers[var_1.guid] = var_1; + var_0.attackerdata[var_1.guid] = spawnstruct(); + var_0.attackerdata[var_1.guid].damage = 0; + var_0.attackerdata[var_1.guid].attackerent = var_1; + var_0.attackerdata[var_1.guid].firsttimedamaged = gettime(); + } + + if ( maps\mp\gametypes\_weapons::isprimaryweapon( var_3 ) && !maps\mp\gametypes\_weapons::issidearm( var_3 ) ) + var_0.attackerdata[var_1.guid].isprimary = 1; + + var_0.attackerdata[var_1.guid].damage += var_4; + var_0.attackerdata[var_1.guid].weapon = var_3; + var_0.attackerdata[var_1.guid].vpoint = var_5; + var_0.attackerdata[var_1.guid].vdir = var_6; + var_0.attackerdata[var_1.guid].shitloc = var_7; + var_0.attackerdata[var_1.guid].psoffsettime = var_8; + var_0.attackerdata[var_1.guid].smeansofdeath = var_9; + var_0.attackerdata[var_1.guid].attackerent = var_1; + var_0.attackerdata[var_1.guid].lasttimedamaged = gettime(); + + if ( isdefined( var_2 ) && !isplayer( var_2 ) && isdefined( var_2.primaryweapon ) ) + var_0.attackerdata[var_1.guid].sprimaryweapon = var_2.primaryweapon; + else if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_0.attackerdata[var_1.guid].sprimaryweapon = var_1 getcurrentprimaryweapon(); + else + var_0.attackerdata[var_1.guid].sprimaryweapon = undefined; +} + +resetattackerlist( var_0 ) +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); + wait 1.75; + resetattackerlist_internal(); +} + +resetattackerlist_internal() +{ + self.attackers = []; + self.attackerdata = []; +} + +callback_playerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + var_10 = callback_playerdamage_internal( var_0, var_1, self, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); +} + +finishplayerdamagewrapper( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + if ( maps\mp\_utility::isusingremote() && var_2 >= self.health && !( var_3 & level.idflags_stun ) && allowfauxdeath() || maps\mp\_utility::isrocketcorpse() ) + { + if ( !isdefined( var_7 ) ) + var_7 = ( 0, 0, 0 ); + + if ( !isdefined( var_1 ) && !isdefined( var_0 ) ) + { + var_1 = self; + var_0 = var_1; + } + + playerkilled_internal( var_0, var_1, self, var_2, var_4, var_5, var_7, var_8, var_9, 0, 1 ); + } + else + { + if ( !callback_killingblow( var_0, var_1, var_2 - var_2 * var_10, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) ) + return; + + if ( !isalive( self ) ) + return; + + if ( isplayer( self ) ) + self finishplayerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + } + + if ( var_4 == "MOD_EXPLOSIVE_BULLET" && !maps\mp\_utility::is_aliens() ) + self shellshock( "damage_mp", getdvarfloat( "scr_csmode" ) ); + + damageshellshockandrumble( var_0, var_5, var_4, var_2, var_3, var_1 ); +} + +allowfauxdeath() +{ + if ( !isdefined( level.allowfauxdeath ) ) + level.allowfauxdeath = 1; + + return level.allowfauxdeath; +} + +callback_playerlaststand( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 ) +{ + var_9 = spawnstruct(); + var_9.einflictor = var_0; + var_9.attacker = var_1; + var_9.idamage = var_2; + var_9.attackerposition = var_1.origin; + + if ( var_1 == self ) + var_9.smeansofdeath = "MOD_SUICIDE"; + else + var_9.smeansofdeath = var_3; + + var_9.sweapon = var_4; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_9.sprimaryweapon = var_1 getcurrentprimaryweapon(); + else + var_9.sprimaryweapon = undefined; + + var_9.vdir = var_5; + var_9.shitloc = var_6; + var_9.laststandstarttime = gettime(); + var_10 = maydolaststand( var_4, var_3, var_6 ); + + if ( isdefined( self.endgame ) ) + var_10 = 0; + + if ( level.teambased && isdefined( var_1.team ) && var_1.team == self.team ) + var_10 = 0; + + if ( level.diehardmode ) + { + if ( level.teamcount[self.team] <= 1 ) + var_10 = 0; + else if ( maps\mp\_utility::isteaminlaststand() ) + { + var_10 = 0; + maps\mp\_utility::killteaminlaststand( self.team ); + } + } + + if ( !var_10 ) + { + self.laststandparams = var_9; + self.uselaststandparams = 1; + maps\mp\_utility::_suicide(); + } + else + { + self.inlaststand = 1; + var_11 = spawnstruct(); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) ) + { + var_11.titletext = game["strings"]["final_stand"]; + var_11.iconname = "specialty_finalstand"; + } + else if ( maps\mp\_utility::_hasperk( "specialty_c4death" ) ) + { + var_11.titletext = game["strings"]["c4_death"]; + var_11.iconname = "specialty_c4death"; + } + else + { + var_11.titletext = game["strings"]["last_stand"]; + var_11.iconname = "specialty_finalstand"; + } + + var_11.glowcolor = ( 1, 0, 0 ); + var_11.sound = "mp_last_stand"; + var_11.duration = 2.0; + self.health = 1; + thread maps\mp\gametypes\_hud_message::notifymessage( var_11 ); + var_12 = "frag_grenade_mp"; + + if ( isdefined( level.ac130player ) && isdefined( var_1 ) && level.ac130player == var_1 ) + level notify( "ai_crawling", self ); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) ) + { + self.laststandparams = var_9; + self.infinalstand = 1; + var_13 = self getweaponslistexclusives(); + + foreach ( var_15 in var_13 ) + self takeweapon( var_15 ); + + common_scripts\utility::_disableusability(); + thread enablelaststandweapons(); + thread laststandtimer( 20, 1 ); + } + else if ( maps\mp\_utility::_hasperk( "specialty_c4death" ) ) + { + self.previousprimary = self.lastdroppableweapon; + self.laststandparams = var_9; + self takeallweapons(); + self giveweapon( "c4death_mp", 0, 0 ); + self switchtoweapon( "c4death_mp" ); + common_scripts\utility::_disableusability(); + self.inc4death = 1; + thread laststandtimer( 20, 0 ); + thread detonateonuse(); + thread detonateondeath(); + } + else + { + if ( level.diehardmode ) + { + var_1 maps\mp\gametypes\_rank::giverankxp( "kill", 100, var_4, var_3 ); + self.laststandparams = var_9; + common_scripts\utility::_disableweapon(); + thread laststandtimer( 20, 0 ); + common_scripts\utility::_disableusability(); + return; + } + + self.laststandparams = var_9; + var_17 = undefined; + var_18 = self getweaponslistprimaries(); + + foreach ( var_15 in var_18 ) + { + if ( maps\mp\gametypes\_weapons::issidearm( var_15 ) ) + var_17 = var_15; + } + + if ( !isdefined( var_17 ) ) + { + var_17 = "iw6_p226_mp"; + maps\mp\_utility::_giveweapon( var_17 ); + } + + self givemaxammo( var_17 ); + self disableweaponswitch(); + common_scripts\utility::_disableusability(); + + if ( !maps\mp\_utility::_hasperk( "specialty_laststandoffhand" ) ) + self disableoffhandweapons(); + + self switchtoweapon( var_17 ); + thread laststandtimer( 10, 0 ); + } + } +} + +dieaftertime( var_0 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + wait(var_0); + self.uselaststandparams = 1; + maps\mp\_utility::_suicide(); +} + +detonateonuse() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + self waittill( "detonate" ); + self.uselaststandparams = 1; + c4deathdetonate(); +} + +detonateondeath() +{ + self endon( "detonate" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + self waittill( "death" ); + c4deathdetonate(); +} + +c4deathdetonate() +{ + self playsound( "detpack_explo_default" ); + radiusdamage( self.origin, 312, 100, 100, self ); + + if ( isalive( self ) ) + maps\mp\_utility::_suicide(); +} + +enablelaststandweapons() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + maps\mp\_utility::freezecontrolswrapper( 1 ); + wait 0.3; + maps\mp\_utility::freezecontrolswrapper( 0 ); +} + +laststandtimer( var_0, var_1 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "revive" ); + level endon( "game_ended" ); + level notify( "player_last_stand" ); + thread laststandwaittilldeath(); + self.laststand = 1; + + if ( !var_1 && ( !isdefined( self.inc4death ) || !self.inc4death ) ) + { + thread laststandallowsuicide(); + maps\mp\_utility::setlowermessage( "last_stand", &"PLATFORM_COWARDS_WAY_OUT", undefined, undefined, undefined, undefined, undefined, undefined, 1 ); + thread laststandkeepoverlay(); + } + + if ( level.diehardmode == 1 && level.diehardmode != 2 ) + { + var_2 = spawn( "script_model", self.origin ); + var_2 setmodel( "tag_origin" ); + var_2 setcursorhint( "HINT_NOICON" ); + var_2 sethintstring( &"PLATFORM_REVIVE" ); + var_2 revivesetup( self ); + var_2 endon( "death" ); + var_3 = newteamhudelem( self.team ); + var_3 setshader( "waypoint_revive", 8, 8 ); + var_3 setwaypoint( 1, 1 ); + var_3 settargetent( self ); + var_3 thread destroyonreviveentdeath( var_2 ); + var_3.color = ( 0.33, 0.75, 0.24 ); + maps\mp\_utility::playdeathsound(); + + if ( var_1 ) + { + wait(var_0); + + if ( self.infinalstand ) + thread laststandbleedout( var_1, var_2 ); + } + + return; + } + else if ( level.diehardmode == 2 ) + { + thread laststandkeepoverlay(); + var_2 = spawn( "script_model", self.origin ); + var_2 setmodel( "tag_origin" ); + var_2 setcursorhint( "HINT_NOICON" ); + var_2 sethintstring( &"PLATFORM_REVIVE" ); + var_2 revivesetup( self ); + var_2 endon( "death" ); + var_3 = newteamhudelem( self.team ); + var_3 setshader( "waypoint_revive", 8, 8 ); + var_3 setwaypoint( 1, 1 ); + var_3 settargetent( self ); + var_3 thread destroyonreviveentdeath( var_2 ); + var_3.color = ( 0.33, 0.75, 0.24 ); + maps\mp\_utility::playdeathsound(); + + if ( var_1 ) + { + wait(var_0); + + if ( self.infinalstand ) + thread laststandbleedout( var_1, var_2 ); + } + + wait(var_0 / 3); + var_3.color = ( 1, 0.64, 0 ); + + while ( var_2.inuse ) + wait 0.05; + + maps\mp\_utility::playdeathsound(); + wait(var_0 / 3); + var_3.color = ( 1, 0, 0 ); + + while ( var_2.inuse ) + wait 0.05; + + maps\mp\_utility::playdeathsound(); + wait(var_0 / 3); + + while ( var_2.inuse ) + wait 0.05; + + wait 0.05; + thread laststandbleedout( var_1 ); + return; + } + + thread laststandkeepoverlay(); + wait(var_0); + thread laststandbleedout( var_1 ); +} + +maxhealthoverlay( var_0, var_1 ) +{ + self endon( "stop_maxHealthOverlay" ); + self endon( "revive" ); + self endon( "death" ); + + for (;;) + { + self.health -= 1; + self.maxhealth = var_0; + wait 0.05; + self.maxhealth = 50; + self.health += 1; + wait 0.5; + } +} + +laststandbleedout( var_0, var_1 ) +{ + if ( var_0 ) + { + self.laststand = undefined; + self.infinalstand = 0; + self notify( "revive" ); + maps\mp\_utility::clearlowermessage( "last_stand" ); + maps\mp\gametypes\_playerlogic::laststandrespawnplayer(); + + if ( isdefined( var_1 ) ) + var_1 delete(); + } + else + { + self.uselaststandparams = 1; + self.beingrevived = 0; + maps\mp\_utility::_suicide(); + } +} + +laststandallowsuicide() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "game_ended" ); + self endon( "revive" ); + + for (;;) + { + if ( self usebuttonpressed() ) + { + var_0 = gettime(); + + while ( self usebuttonpressed() ) + { + wait 0.05; + + if ( gettime() - var_0 > 700 ) + break; + } + + if ( gettime() - var_0 > 700 ) + break; + } + + wait 0.05; + } + + thread laststandbleedout( 0 ); +} + +laststandkeepoverlay() +{ + level endon( "game_ended" ); + self endon( "death" ); + self endon( "disconnect" ); + self endon( "revive" ); + + while ( !level.gameended ) + { + self.health = 2; + wait 0.05; + self.health = 1; + wait 0.5; + } + + self.health = self.maxhealth; +} + +laststandwaittilldeath() +{ + self endon( "disconnect" ); + self endon( "revive" ); + level endon( "game_ended" ); + self waittill( "death" ); + maps\mp\_utility::clearlowermessage( "last_stand" ); + self.laststand = undefined; +} + +maydolaststand( var_0, var_1, var_2 ) +{ + if ( var_1 == "MOD_TRIGGER_HURT" ) + return 0; + + if ( var_1 != "MOD_PISTOL_BULLET" && var_1 != "MOD_RIFLE_BULLET" && var_1 != "MOD_FALLING" && var_1 != "MOD_EXPLOSIVE_BULLET" ) + return 0; + + if ( var_1 == "MOD_IMPACT" && maps\mp\gametypes\_weapons::isthrowingknife( var_0 ) ) + return 0; + + if ( var_1 == "MOD_IMPACT" && ( var_0 == "m79_mp" || issubstr( var_0, "gl_" ) ) ) + return 0; + + if ( maps\mp\_utility::isheadshot( var_0, var_2, var_1 ) ) + return 0; + + if ( maps\mp\_utility::isusingremote() ) + return 0; + + return 1; +} + +ensurelaststandparamsvalidity() +{ + if ( !isdefined( self.laststandparams.attacker ) ) + self.laststandparams.attacker = self; +} + +gethitlocheight( var_0 ) +{ + switch ( var_0 ) + { + case "head": + case "helmet": + case "neck": + return 60; + case "gun": + case "torso_upper": + case "right_arm_upper": + case "left_arm_upper": + case "right_arm_lower": + case "left_arm_lower": + case "right_hand": + case "left_hand": + return 48; + case "torso_lower": + return 40; + case "right_leg_upper": + case "left_leg_upper": + return 32; + case "right_leg_lower": + case "left_leg_lower": + return 10; + case "right_foot": + case "left_foot": + return 5; + } + + return 48; +} + +delaystartragdoll( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + if ( isdefined( var_0 ) ) + { + var_6 = var_0 getcorpseanim(); + + if ( animhasnotetrack( var_6, "ignore_ragdoll" ) ) + return; + } + + if ( isdefined( level.noragdollents ) && level.noragdollents.size ) + { + foreach ( var_8 in level.noragdollents ) + { + if ( distancesquared( var_0.origin, var_8.origin ) < 65536 ) + return; + } + } + + wait 0.2; + + if ( !isdefined( var_0 ) ) + return; + + if ( var_0 isragdoll() ) + return; + + var_6 = var_0 getcorpseanim(); + var_10 = 0.35; + + if ( animhasnotetrack( var_6, "start_ragdoll" ) ) + { + var_11 = getnotetracktimes( var_6, "start_ragdoll" ); + + if ( isdefined( var_11 ) ) + var_10 = var_11[0]; + } + + var_12 = var_10 * getanimlength( var_6 ); + wait(var_12); + + if ( isdefined( var_0 ) ) + var_0 startragdoll(); +} + +getmostkilledby() +{ + var_0 = ""; + var_1 = 0; + var_2 = getarraykeys( self.killedby ); + + for ( var_3 = 0; var_3 < var_2.size; var_3++ ) + { + var_4 = var_2[var_3]; + + if ( self.killedby[var_4] <= var_1 ) + continue; + + var_1 = self.killedby[var_4]; + var_5 = var_4; + } + + return var_0; +} + +getmostkilled() +{ + var_0 = ""; + var_1 = 0; + var_2 = getarraykeys( self.killedplayers ); + + for ( var_3 = 0; var_3 < var_2.size; var_3++ ) + { + var_4 = var_2[var_3]; + + if ( self.killedplayers[var_4] <= var_1 ) + continue; + + var_1 = self.killedplayers[var_4]; + var_0 = var_4; + } + + return var_0; +} + +damageshellshockandrumble( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + thread maps\mp\gametypes\_weapons::onweapondamage( var_0, var_1, var_2, var_3, var_5 ); + + if ( !isai( self ) ) + self playrumbleonentity( "damage_heavy" ); +} + +revivesetup( var_0 ) +{ + var_1 = var_0.team; + self linkto( var_0, "tag_origin" ); + self.owner = var_0; + self.inuse = 0; + self makeusable(); + updateusablebyteam( var_1 ); + thread trackteamchanges( var_1 ); + thread revivetriggerthink( var_1 ); + thread deleteonreviveordeathordisconnect(); +} + +deleteonreviveordeathordisconnect() +{ + self endon( "death" ); + self.owner common_scripts\utility::waittill_any( "death", "disconnect" ); + self delete(); +} + +updateusablebyteam( var_0 ) +{ + foreach ( var_2 in level.players ) + { + if ( var_0 == var_2.team && var_2 != self.owner ) + { + self enableplayeruse( var_2 ); + continue; + } + + self disableplayeruse( var_2 ); + } +} + +trackteamchanges( var_0 ) +{ + self endon( "death" ); + + for (;;) + { + level waittill( "joined_team" ); + updateusablebyteam( var_0 ); + } +} + +tracklaststandchanges( var_0 ) +{ + self endon( "death" ); + + for (;;) + { + level waittill( "player_last_stand" ); + updateusablebyteam( var_0 ); + } +} + +revivetriggerthink( var_0 ) +{ + self endon( "death" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "trigger", var_1 ); + self.owner.beingrevived = 1; + + if ( isdefined( var_1.beingrevived ) && var_1.beingrevived ) + { + self.owner.beingrevived = 0; + continue; + } + + self makeunusable(); + self.owner maps\mp\_utility::freezecontrolswrapper( 1 ); + var_2 = useholdthink( var_1 ); + self.owner.beingrevived = 0; + + if ( !isalive( self.owner ) ) + { + self delete(); + return; + } + + self.owner maps\mp\_utility::freezecontrolswrapper( 0 ); + + if ( var_2 ) + { + var_1 thread maps\mp\gametypes\_hud_message::splashnotifydelayed( "reviver", maps\mp\gametypes\_rank::getscoreinfovalue( "reviver" ) ); + var_1 thread maps\mp\gametypes\_rank::giverankxp( "reviver" ); + self.owner.laststand = undefined; + self.owner maps\mp\_utility::clearlowermessage( "last_stand" ); + self.owner.movespeedscaler = 1; + + if ( self.owner maps\mp\_utility::_hasperk( "specialty_lightweight" ) ) + self.owner.movespeedscaler = maps\mp\_utility::lightweightscalar(); + + self.owner common_scripts\utility::_enableweapon(); + self.owner.maxhealth = 100; + self.owner maps\mp\gametypes\_weapons::updatemovespeedscale(); + self.owner maps\mp\gametypes\_playerlogic::laststandrespawnplayer(); + self.owner maps\mp\_utility::giveperk( "specialty_pistoldeath", 0 ); + self.owner.beingrevived = 0; + self delete(); + return; + } + + self makeusable(); + updateusablebyteam( var_0 ); + } +} + +useholdthink( var_0, var_1 ) +{ + var_2 = 3000; + var_3 = spawn( "script_origin", self.origin ); + var_3 hide(); + var_0 playerlinkto( var_3 ); + var_0 playerlinkedoffsetenable(); + var_0 common_scripts\utility::_disableweapon(); + self.curprogress = 0; + self.inuse = 1; + self.userate = 0; + + if ( isdefined( var_1 ) ) + self.usetime = var_1; + else + self.usetime = var_2; + + var_4 = useholdthinkloop( var_0 ); + self.inuse = 0; + var_3 delete(); + + if ( isdefined( var_0 ) && maps\mp\_utility::isreallyalive( var_0 ) ) + { + var_0 unlink(); + var_0 common_scripts\utility::_enableweapon(); + } + + if ( isdefined( var_4 ) && var_4 ) + { + self.owner thread maps\mp\gametypes\_hud_message::playercardsplashnotify( "revived", var_0 ); + self.owner.inlaststand = 0; + return 1; + } + + return 0; +} + +useholdthinkloop( var_0 ) +{ + level endon( "game_ended" ); + self.owner endon( "death" ); + self.owner endon( "disconnect" ); + + while ( maps\mp\_utility::isreallyalive( var_0 ) && var_0 usebuttonpressed() && self.curprogress < self.usetime && ( !isdefined( var_0.laststand ) || !var_0.laststand ) ) + { + self.curprogress += 50 * self.userate; + self.userate = 1; + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 1 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 1 ); + + if ( self.curprogress >= self.usetime ) + { + self.inuse = 0; + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + return maps\mp\_utility::isreallyalive( var_0 ); + } + + wait 0.05; + } + + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + return 0; +} + +callback_killingblow( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + if ( isdefined( self.lastdamagewasfromenemy ) && self.lastdamagewasfromenemy && var_2 >= self.health && isdefined( self.combathigh ) && self.combathigh == "specialty_endgame" ) + { + maps\mp\_utility::giveperk( "specialty_endgame", 0 ); + return 0; + } + + return 1; +} + +emitfalldamage( var_0 ) +{ + physicsexplosionsphere( self.origin, 64, 64, 1 ); + var_1 = []; + + for ( var_2 = 0; var_2 < 360; var_2 += 30 ) + { + var_3 = cos( var_2 ) * 16; + var_4 = sin( var_2 ) * 16; + var_5 = bullettrace( self.origin + ( var_3, var_4, 4 ), self.origin + ( var_3, var_4, -6 ), 1, self ); + + if ( isdefined( var_5["entity"] ) && isdefined( var_5["entity"].targetname ) && ( var_5["entity"].targetname == "destructible_vehicle" || var_5["entity"].targetname == "destructible_toy" ) ) + var_1[var_1.size] = var_5["entity"]; + } + + if ( var_1.size ) + { + var_6 = spawn( "script_origin", self.origin ); + var_6 hide(); + var_6.type = "soft_landing"; + var_6.destructibles = var_1; + radiusdamage( self.origin, 64, 100, 100, var_6 ); + wait 0.1; + var_6 delete(); + } +} + +isflankkill( var_0, var_1 ) +{ + var_2 = anglestoforward( var_0.angles ); + var_2 = ( var_2[0], var_2[1], 0 ); + var_2 = vectornormalize( var_2 ); + var_3 = var_0.origin - var_1.origin; + var_3 = ( var_3[0], var_3[1], 0 ); + var_3 = vectornormalize( var_3 ); + var_4 = vectordot( var_2, var_3 ); + + if ( var_4 > 0 ) + return 1; + else + return 0; +} + +logprintplayerdeath( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + var_7 = self getentitynumber(); + var_8 = self.name; + var_9 = self.team; + var_10 = self.guid; + + if ( isplayer( var_1 ) ) + { + var_11 = var_1.guid; + var_12 = var_1.name; + var_13 = var_1.team; + var_14 = var_1 getentitynumber(); + var_15 = var_1 getxuid() + "(" + var_12 + ")"; + } + else + { + var_11 = ""; + var_12 = ""; + var_13 = "world"; + var_14 = -1; + var_15 = "none"; + } + + logprint( "k;" + var_10 + ";" + var_7 + ";" + var_9 + ";" + var_8 + ";" + var_11 + ";" + var_14 + ";" + var_13 + ";" + var_12 + ";" + var_4 + ";" + var_2 + ";" + var_3 + ";" + var_6 + "\n" ); +} + +destroyonreviveentdeath( var_0 ) +{ + var_0 waittill( "death" ); + self destroy(); +} + +gamemodemodifyplayerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 ) +{ + if ( isdefined( var_1 ) && isplayer( var_1 ) && isalive( var_1 ) ) + { + if ( level.matchrules_damagemultiplier ) + var_2 *= level.matchrules_damagemultiplier; + + if ( level.matchrules_vampirism ) + var_1.health = int( min( float( var_1.maxhealth ), float( var_1.health + 20 ) ) ); + } + + return var_2; +} + +registerkill( var_0, var_1 ) +{ + thread maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.pers["cur_kill_streak"]++; + + if ( var_1 ) + self notify( "kill_streak_increased" ); + + var_2 = !maps\mp\_utility::iskillstreakweapon( var_0 ); + + if ( var_2 ) + self.pers["cur_kill_streak_for_nuke"]++; + + var_3 = 25; + + if ( maps\mp\_utility::_hasperk( "specialty_hardline" ) ) + var_3--; + + if ( var_2 && self.pers["cur_kill_streak_for_nuke"] == var_3 && !maps\mp\_utility::isanymlgmatch() ) + { + if ( !isdefined( level.supportnuke ) || level.supportnuke ) + giveultimatekillstreak( var_3 ); + } +} + +giveultimatekillstreak( var_0 ) +{ + thread maps\mp\killstreaks\_killstreaks::givekillstreak( "nuke", 0, 1, self ); + thread maps\mp\gametypes\_hud_message::killstreaksplashnotify( "nuke", var_0 ); +} + +monitordamage( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + self endon( "death" ); + level endon( "game_ended" ); + + if ( !isdefined( var_5 ) ) + var_5 = 0; + + self setcandamage( 1 ); + self.health = 999999; + self.maxhealth = var_0; + self.damagetaken = 0; + + if ( !isdefined( var_4 ) ) + var_4 = 0; + + for ( var_6 = 1; var_6; var_6 = monitordamageoneshot( var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14, var_15, var_16, var_1, var_2, var_3, var_4 ) ) + { + self waittill( "damage", var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14, var_15, var_16 ); + + if ( var_5 ) + self playrumbleonentity( "damage_light" ); + + if ( isdefined( self.helitype ) && self.helitype == "littlebird" ) + { + if ( !isdefined( self.attackers ) ) + self.attackers = []; + + var_17 = ""; + + if ( isdefined( var_8 ) && isplayer( var_8 ) ) + var_17 = var_8 maps\mp\_utility::getuniqueid(); + + if ( isdefined( self.attackers[var_17] ) ) + self.attackers[var_17] += var_7; + else + self.attackers[var_17] = var_7; + } + } +} + +monitordamageoneshot( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11, var_12, var_13 ) +{ + if ( !isdefined( self ) ) + return 0; + + if ( isdefined( var_1 ) && !maps\mp\_utility::isgameparticipant( var_1 ) && !isdefined( var_1.allowmonitoreddamage ) ) + return 1; + + if ( maps\mp\_utility::is_aliens() || isdefined( var_1 ) && !maps\mp\gametypes\_weapons::friendlyfirecheck( self.owner, var_1 ) ) + return 1; + + var_14 = var_0; + + if ( isdefined( var_9 ) ) + { + switch ( var_9 ) + { + case "flash_grenade_mp": + case "smoke_grenade_mp": + case "smoke_grenadejugg_mp": + case "concussion_grenade_mp": + return 1; + } + + if ( !isdefined( var_12 ) ) + var_12 = ::modifydamage; + + var_14 = [[ var_12 ]]( var_1, var_9, var_4, var_0 ); + } + + if ( var_14 < 0 ) + return 1; + + self.wasdamaged = 1; + self.damagetaken += var_14; + + if ( isdefined( var_8 ) && var_8 & level.idflags_penetration ) + self.wasdamagedfrombulletpenetration = 1; + + if ( var_13 ) + maps\mp\killstreaks\_killstreaks::killstreakhit( var_1, var_9, self ); + + if ( isdefined( var_1 ) ) + { + if ( isplayer( var_1 ) ) + { + if ( self.damagetaken >= self.maxhealth ) + var_10 = "hitkill"; + + var_1 maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_10 ); + } + else if ( isdefined( var_1.owner ) && isplayer( var_1.owner ) ) + var_1.owner maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_10 ); + } + + if ( self.damagetaken >= self.maxhealth ) + { + self thread [[ var_11 ]]( var_1, var_9, var_4, var_0 ); + return 0; + } + + return 1; +} + +modifydamage( var_0, var_1, var_2, var_3 ) +{ + var_4 = var_3; + var_4 = handleempdamage( var_1, var_2, var_4 ); + var_4 = handlemissiledamage( var_1, var_2, var_4 ); + var_4 = handlegrenadedamage( var_1, var_2, var_4 ); + var_4 = handleapdamage( var_1, var_2, var_4, var_0 ); + return var_4; +} + +handlemissiledamage( var_0, var_1, var_2 ) +{ + var_3 = var_2; + + switch ( var_0 ) + { + case "bomb_site_mp": + case "iw6_maawschild_mp": + case "iw6_maawshoming_mp": + case "iw6_maaws_mp": + case "iw6_panzerfaust3_mp": + case "drone_hive_projectile_mp": + case "odin_projectile_large_rod_mp": + case "odin_projectile_small_rod_mp": + case "aamissile_projectile_mp": + case "ac130_105mm_mp": + case "ac130_40mm_mp": + case "maverick_projectile_mp": + self.largeprojectiledamage = 1; + var_3 = self.maxhealth + 1; + break; + case "remote_tank_projectile_mp": + case "switch_blade_child_mp": + case "hind_bomb_mp": + case "hind_missile_mp": + self.largeprojectiledamage = 0; + var_3 = self.maxhealth + 1; + break; + case "heli_pilot_turret_mp": + case "a10_30mm_turret_mp": + self.largeprojectiledamage = 0; + var_3 *= 2; + break; + case "sam_projectile_mp": + self.largeprojectiledamage = 1; + var_3 = var_2; + break; + } + + return var_3; +} + +handlegrenadedamage( var_0, var_1, var_2 ) +{ + if ( isexplosivedamagemod( var_1 ) ) + { + switch ( var_0 ) + { + case "mortar_shell_mp": + case "c4_mp": + case "proximity_explosive_mp": + case "iw6_rgm_mp": + var_2 *= 3; + break; + case "frag_grenade_mp": + case "semtex_mp": + case "semtexproj_mp": + case "iw6_mk32_mp": + var_2 *= 4; + break; + default: + if ( maps\mp\_utility::isstrstart( var_0, "alt_" ) ) + var_2 *= 3; + + break; + } + } + + return var_2; +} + +handlemeleedamage( var_0, var_1, var_2 ) +{ + if ( var_1 == "MOD_MELEE" ) + return self.maxhealth + 1; + + return var_2; +} + +handleempdamage( var_0, var_1, var_2 ) +{ + if ( var_0 == "emp_grenade_mp" && var_1 == "MOD_GRENADE_SPLASH" ) + { + self notify( "emp_damage", var_0.owner, 8.0 ); + return 0; + } + + return var_2; +} + +handleapdamage( var_0, var_1, var_2, var_3 ) +{ + if ( var_1 == "MOD_RIFLE_BULLET" || var_1 == "MOD_PISTOL_BULLET" ) + { + if ( var_3 maps\mp\_utility::_hasperk( "specialty_armorpiercing" ) || maps\mp\_utility::isfmjdamage( var_0, var_1, var_3 ) ) + return var_2 * level.armorpiercingmod; + } + + return var_2; +} + +onkillstreakkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + var_7 = 0; + var_8 = undefined; + + if ( isdefined( var_0 ) && isdefined( self.owner ) ) + { + if ( isdefined( var_0.owner ) && isplayer( var_0.owner ) ) + var_0 = var_0.owner; + + if ( self.owner maps\mp\_utility::isenemy( var_0 ) ) + var_8 = var_0; + } + + if ( isdefined( var_8 ) ) + { + var_8 notify( "destroyed_killstreak", var_1 ); + var_9 = 100; + + if ( isdefined( var_4 ) ) + { + var_9 = maps\mp\gametypes\_rank::getscoreinfovalue( var_4 ); + var_8 thread maps\mp\gametypes\_rank::xpeventpopup( var_4 ); + } + + var_8 thread maps\mp\gametypes\_rank::giverankxp( "kill", var_9, var_1, var_2 ); + + if ( isdefined( var_6 ) ) + thread maps\mp\_utility::teamplayercardsplash( var_6, var_8 ); + + thread maps\mp\gametypes\_missions::killstreakkilled( self.owner, self, undefined, var_8, var_3, var_2, var_1 ); + var_7 = 1; + } + + if ( isdefined( self.owner ) && isdefined( var_5 ) ) + self.owner thread maps\mp\_utility::leaderdialogonplayer( var_5, undefined, undefined, self.origin ); + + self notify( "death" ); + return var_7; +} diff --git a/iw6x/data/maps/mp/gametypes/_menus.gsc b/iw6x/data/maps/mp/gametypes/_menus.gsc new file mode 100644 index 0000000..13180b7 --- /dev/null +++ b/iw6x/data/maps/mp/gametypes/_menus.gsc @@ -0,0 +1,727 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +init() +{ + if ( !isdefined( game["gamestarted"] ) ) + { + game["menu_team"] = "team_marinesopfor"; + + if ( level.multiteambased ) + game["menu_team"] = "team_mt_options"; + + if ( maps\mp\_utility::bot_is_fireteam_mode() ) + { + level.fireteam_menu = "class_commander_" + level.gametype; + game["menu_class"] = level.fireteam_menu; + game["menu_class_allies"] = level.fireteam_menu; + game["menu_class_axis"] = level.fireteam_menu; + } + else + { + game["menu_class"] = "class"; + game["menu_class_allies"] = "class_marines"; + game["menu_class_axis"] = "class_opfor"; + } + + game["menu_changeclass_allies"] = "changeclass_marines"; + game["menu_changeclass_axis"] = "changeclass_opfor"; + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + var_1 = "menu_class_" + level.teamnamelist[var_0]; + var_2 = "menu_changeclass_" + level.teamnamelist[var_0]; + game[var_1] = game["menu_class_allies"]; + game[var_2] = "changeclass_marines"; + } + } + + game["menu_changeclass"] = "changeclass"; + + if ( level.console ) + { + game["menu_controls"] = "ingame_controls"; + + if ( level.splitscreen ) + { + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + var_1 = "menu_class_" + level.teamnamelist[var_0]; + var_2 = "menu_changeclass_" + level.teamnamelist[var_0]; + game[var_1] += "_splitscreen"; + game[var_2] += "_splitscreen"; + } + } + + game["menu_team"] += "_splitscreen"; + game["menu_class_allies"] += "_splitscreen"; + game["menu_class_axis"] += "_splitscreen"; + game["menu_changeclass_allies"] += "_splitscreen"; + game["menu_changeclass_axis"] += "_splitscreen"; + game["menu_controls"] += "_splitscreen"; + game["menu_changeclass_defaults_splitscreen"] = "changeclass_splitscreen_defaults"; + game["menu_changeclass_custom_splitscreen"] = "changeclass_splitscreen_custom"; + precachemenu( game["menu_changeclass_defaults_splitscreen"] ); + precachemenu( game["menu_changeclass_custom_splitscreen"] ); + } + + precachemenu( game["menu_controls"] ); + } + + precachemenu( game["menu_team"] ); + precachemenu( game["menu_class_allies"] ); + precachemenu( game["menu_class_axis"] ); + precachemenu( game["menu_changeclass"] ); + precachemenu( game["menu_changeclass_allies"] ); + precachemenu( game["menu_changeclass_axis"] ); + precachemenu( game["menu_class"] ); + precachestring( &"MP_HOST_ENDED_GAME" ); + precachestring( &"MP_HOST_ENDGAME_RESPONSE" ); + } + + level thread onplayerconnect(); +} + +onplayerconnect() +{ + for (;;) + { + level waittill( "connected", var_0 ); + var_0 thread watchforclasschange(); + var_0 thread watchforteamchange(); + var_0 thread watchforleavegame(); + var_0 thread connectedmenus(); + } +} + +connectedmenus() +{ + +} + +getclasschoice( var_0 ) +{ + if ( var_0 > 10 ) + { + if ( var_0 > 10 && var_0 < 17 ) + { + var_0 -= 10; + var_0 = "axis_recipe" + var_0; + } + else if ( var_0 > 16 && var_0 < 23 ) + { + var_0 -= 16; + var_0 = "allies_recipe" + var_0; + } + } + else + var_0 = "custom" + var_0; + + return var_0; +} + +watchforclasschange() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "class_select" ) + continue; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) && self ismlgspectator() ) + { + self setclientomnvar( "ui_options_menu", 0 ); + continue; + } + + var_2 = isai( self ) || issubstr( self.name, "tcBot" ); + + if ( !var_2 ) + { + if ( !isai( self ) && "" + var_1 != "callback" ) + self setclientomnvar( "ui_loadout_selected", var_1 ); + } + + if ( isdefined( self.waitingtoselectclass ) && self.waitingtoselectclass ) + continue; + + if ( !maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() ) + continue; + + if ( "" + var_1 != "callback" ) + { + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] ) + { + self.pers["class"] = var_1; + self.class = var_1; + } + else + { + var_3 = var_1 + 1; + var_3 = getclasschoice( var_3 ); + + if ( !isdefined( self.pers["class"] ) || var_3 == self.pers["class"] ) + continue; + + self.pers["class"] = var_3; + self.class = var_3; + + if ( level.ingraceperiod && !self.hasdonecombat ) + { + maps\mp\gametypes\_class::setclass( self.pers["class"] ); + self.tag_stowed_back = undefined; + self._id_7E62 = undefined; + maps\mp\gametypes\_class::giveloadout( self.pers["team"], self.pers["class"] ); + } + else if ( isalive( self ) ) + self iprintlnbold( game["strings"]["change_class"] ); + } + + continue; + } + + menuclass( "callback" ); + } +} + +watchforleavegame() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "end_game" ) + continue; + + if ( maps\mp\_utility::is_aliens() ) + { + [[ level.forceendgame_alien ]](); + continue; + } + + level thread maps\mp\gametypes\_gamelogic::forceend( var_1 ); + } +} + +watchforteamchange() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "team_select" ) + continue; + + if ( maps\mp\_utility::matchmakinggame() && !getdvarint( "force_ranking" ) ) + continue; + + if ( var_1 != 3 ) + thread showloadoutmenu(); + + if ( var_1 == 3 ) + { + self setclientomnvar( "ui_spectator_selected", 1 ); + self setclientomnvar( "ui_loadout_selected", -1 ); + self.spectating_actively = 1; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) ) + { + self setmlgspectator( 1 ); + self.pers["mlgSpectator"] = 1; + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 1 ); + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + self setclientomnvar( "ui_options_menu", 2 ); + } + } + else + { + self setclientomnvar( "ui_spectator_selected", -1 ); + self.spectating_actively = 0; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) ) + { + self setmlgspectator( 0 ); + self.pers["mlgSpectator"] = 0; + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 0 ); + } + } + + self setclientomnvar( "ui_team_selected", var_1 ); + + if ( var_1 == 0 ) + var_1 = "axis"; + else if ( var_1 == 1 ) + var_1 = "allies"; + else if ( var_1 == 2 ) + var_1 = "random"; + else + var_1 = "spectator"; + + if ( isdefined( self.pers["team"] ) && var_1 == self.pers["team"] ) + { + self notify( "selected_same_team" ); + continue; + } + + self setclientomnvar( "ui_loadout_selected", -1 ); + + if ( var_1 == "axis" ) + { + thread setteam( "axis" ); + continue; + } + + if ( var_1 == "allies" ) + { + thread setteam( "allies" ); + continue; + } + + if ( var_1 == "random" ) + { + thread autoassign(); + continue; + } + + if ( var_1 == "spectator" ) + thread setspectator(); + } +} + +showloadoutmenu() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + common_scripts\utility::waittill_any( "joined_team", "selected_same_team" ); + self setclientomnvar( "ui_options_menu", 2 ); +} + +autoassign() +{ + if ( maps\mp\_utility::is_aliens() || level.gametype == "infect" ) + thread setteam( "allies" ); + else if ( ( getdvarint( "squad_match" ) == 1 || getdvarint( "squad_vs_squad" ) == 1 || getdvarint( "squad_use_hosts_squad" ) == 1 ) && isdefined( self.bot_team ) ) + thread setteam( self.bot_team ); + else if ( !isdefined( self.team ) ) + { + if ( self ismlgspectator() ) + thread setspectator(); + else if ( level.teamcount["axis"] < level.teamcount["allies"] ) + thread setteam( "axis" ); + else if ( level.teamcount["allies"] < level.teamcount["axis"] ) + thread setteam( "allies" ); + else if ( getteamscore( "allies" ) > getteamscore( "axis" ) ) + thread setteam( "axis" ); + else + thread setteam( "allies" ); + } + else + { + if ( self ismlgspectator() ) + { + thread setspectator(); + return; + } + + if ( level.teamcount["axis"] < level.teamcount["allies"] && self.team != "axis" ) + { + thread setteam( "axis" ); + return; + } + + if ( level.teamcount["allies"] < level.teamcount["axis"] && self.team != "allies" ) + { + thread setteam( "allies" ); + return; + } + + if ( level.teamcount["allies"] == level.teamcount["axis"] ) + { + if ( getteamscore( "allies" ) > getteamscore( "axis" ) && self.team != "axis" ) + thread setteam( "axis" ); + else if ( self.team != "allies" ) + thread setteam( "allies" ); + } + } +} + +setteam( var_0 ) +{ + self endon( "disconnect" ); + + if ( !isai( self ) && level.teambased && !maps\mp\gametypes\_teams::getjointeampermissions( var_0 ) ) + return; + + if ( level.ingraceperiod && !self.hasdonecombat ) + self.hasspawned = 0; + + if ( self.sessionstate == "playing" ) + { + self.switching_teams = 1; + self.joining_team = var_0; + self.leaving_team = self.pers["team"]; + } + + addtoteam( var_0 ); + + if ( self.sessionstate == "playing" ) + self suicide(); + + waitforclassselect(); + endrespawnnotify(); + + if ( self.sessionstate == "spectator" ) + { + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + { + if ( isdefined( self.waitingtospawnamortize ) && self.waitingtospawnamortize ) + return; + + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + self notify( "okToSpawn" ); +} + +setspectator() +{ + if ( isdefined( self.pers["team"] ) && self.pers["team"] == "spectator" ) + return; + + if ( isalive( self ) ) + { + self.switching_teams = 1; + self.joining_team = "spectator"; + self.leaving_team = self.pers["team"]; + self suicide(); + } + + self notify( "becameSpectator" ); + addtoteam( "spectator" ); + self.pers["class"] = undefined; + self.class = undefined; + thread maps\mp\gametypes\_playerlogic::spawnspectator(); +} + +waitforclassselect() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self.waitingtoselectclass = 1; + + for (;;) + { + if ( level.gametype == "infect" ) + { + bypassclasschoice(); + break; + } + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self waittill( "luinotifyserver", var_0, var_1 ); + else + { + bypassclasschoice(); + break; + } + + if ( var_0 != "class_select" ) + continue; + + if ( self.team == "spectator" ) + continue; + + if ( "" + var_1 != "callback" ) + { + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] ) + { + self.pers["class"] = var_1; + self.class = var_1; + } + else + { + var_1 += 1; + self.pers["class"] = getclasschoice( var_1 ); + self.class = getclasschoice( var_1 ); + } + + self.waitingtoselectclass = 0; + } + else + { + self.waitingtoselectclass = 0; + menuclass( "callback" ); + } + + break; + } +} + +beginclasschoice( var_0 ) +{ + var_1 = self.pers["team"]; + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + { + self setclientomnvar( "ui_options_menu", 2 ); + + if ( !self ismlgspectator() ) + waitforclassselect(); + + endrespawnnotify(); + + if ( self.sessionstate == "spectator" ) + { + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + { + if ( isdefined( self.waitingtospawnamortize ) && self.waitingtospawnamortize ) + return; + + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + self.connecttime = gettime(); + self notify( "okToSpawn" ); + } + else + thread bypassclasschoice(); + + if ( !isalive( self ) ) + thread maps\mp\gametypes\_playerlogic::predictabouttospawnplayerovertime( 0.1 ); +} + +bypassclasschoice() +{ + self.selectedclass = 1; + self.waitingtoselectclass = 0; + + if ( isdefined( level.bypassclasschoicefunc ) ) + { + var_0 = self [[ level.bypassclasschoicefunc ]](); + self.class = var_0; + } + else + self.class = "class0"; +} + +beginteamchoice() +{ + self setclientomnvar( "ui_options_menu", 1 ); +} + +showmainmenuforteam() +{ + var_0 = self.pers["team"]; + self openpopupmenu( game["menu_class_" + var_0] ); +} + +menuspectator() +{ + if ( isdefined( self.pers["team"] ) && self.pers["team"] == "spectator" ) + return; + + if ( isalive( self ) ) + { + self.switching_teams = 1; + self.joining_team = "spectator"; + self.leaving_team = self.pers["team"]; + self suicide(); + } + + addtoteam( "spectator" ); + self.pers["class"] = undefined; + self.class = undefined; + thread maps\mp\gametypes\_playerlogic::spawnspectator(); +} + +menuclass( var_0 ) +{ + if ( var_0 == "demolitions_mp,0" && self getrankedplayerdata( "featureNew", "demolitions" ) ) + self setrankedplayerdata( "featureNew", "demolitions", 0 ); + + if ( var_0 == "sniper_mp,0" && self getrankedplayerdata( "featureNew", "sniper" ) ) + self setrankedplayerdata( "featureNew", "sniper", 0 ); + + var_1 = self.pers["team"]; + var_2 = maps\mp\gametypes\_class::getclasschoice( var_0 ); + var_3 = maps\mp\gametypes\_class::getweaponchoice( var_0 ); + + if ( var_2 == "restricted" ) + { + beginclasschoice(); + return; + } + + if ( isdefined( self.pers["class"] ) && self.pers["class"] == var_2 && ( isdefined( self.pers["primary"] ) && self.pers["primary"] == var_3 ) ) + return; + + if ( self.sessionstate == "playing" ) + { + if ( isdefined( self.pers["lastClass"] ) && isdefined( self.pers["class"] ) ) + { + self.pers["lastClass"] = self.pers["class"]; + self.lastclass = self.pers["lastClass"]; + } + + self.pers["class"] = var_2; + self.class = var_2; + self.pers["primary"] = var_3; + + if ( game["state"] == "postgame" ) + return; + + if ( level.ingraceperiod && !self.hasdonecombat ) + { + maps\mp\gametypes\_class::setclass( self.pers["class"] ); + self.tag_stowed_back = undefined; + self._id_7E62 = undefined; + maps\mp\gametypes\_class::giveloadout( self.pers["team"], self.pers["class"] ); + } + else + self iprintlnbold( game["strings"]["change_class"] ); + } + else + { + if ( isdefined( self.pers["lastClass"] ) && isdefined( self.pers["class"] ) ) + { + self.pers["lastClass"] = self.pers["class"]; + self.lastclass = self.pers["lastClass"]; + } + + self.pers["class"] = var_2; + self.class = var_2; + self.pers["primary"] = var_3; + + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); +} + +update_wargame_after_migration() +{ + foreach ( var_1 in level.players ) + { + if ( !isai( var_1 ) && var_1 ishost() ) + level.wargame_client = var_1; + } +} + +addtoteam( var_0, var_1, var_2 ) +{ + if ( isdefined( self.team ) ) + { + maps\mp\gametypes\_playerlogic::removefromteamcount(); + + if ( isdefined( var_2 ) && var_2 ) + maps\mp\gametypes\_playerlogic::decrementalivecount( self.team ); + } + + self.pers["team"] = var_0; + self.team = var_0; + + if ( getdvar( "squad_vs_squad" ) == "1" ) + { + if ( !isai( self ) ) + { + if ( var_0 == "allies" ) + { + if ( !isdefined( level.squad_vs_squad_allies_client ) ) + level.squad_vs_squad_allies_client = self; + } + else if ( var_0 == "axis" ) + { + if ( !isdefined( level.squad_vs_squad_axis_client ) ) + level.squad_vs_squad_axis_client = self; + } + } + } + + if ( getdvar( "squad_match" ) == "1" ) + { + if ( !isai( self ) && self ishost() ) + { + if ( !isdefined( level.squad_match_client ) ) + level.squad_match_client = self; + } + } + + if ( getdvar( "squad_use_hosts_squad" ) == "1" ) + { + if ( !isai( self ) && self ishost() ) + { + if ( !isdefined( level.wargame_client ) ) + level.wargame_client = self; + } + } + + // session team is readonly in ranked matches if "teambased" is set on the playlist + if ( level.teambased ) + self.sessionteam = var_0; + else if ( var_0 == "spectator" ) + self.sessionteam = "spectator"; + else + self.sessionteam = "none"; + + if ( game["state"] != "postgame" ) + { + maps\mp\gametypes\_playerlogic::addtoteamcount(); + + if ( isdefined( var_2 ) && var_2 ) + maps\mp\gametypes\_playerlogic::incrementalivecount( self.team ); + } + + maps\mp\_utility::updateobjectivetext(); + + if ( isdefined( var_1 ) && var_1 ) + waittillframeend; + + maps\mp\_utility::updatemainmenu(); + + if ( var_0 == "spectator" ) + { + self notify( "joined_spectators" ); + level notify( "joined_team", self ); + } + else + { + self notify( "joined_team" ); + level notify( "joined_team", self ); + } +} + +endrespawnnotify() +{ + self.waitingtospawn = 0; + self notify( "end_respawn" ); +} diff --git a/iw6x/data/maps/mp/gametypes/_playerlogic.gsc b/iw6x/data/maps/mp/gametypes/_playerlogic.gsc new file mode 100644 index 0000000..a1906e6 --- /dev/null +++ b/iw6x/data/maps/mp/gametypes/_playerlogic.gsc @@ -0,0 +1,1902 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +timeuntilwavespawn( var_0 ) +{ + if ( !self.hasspawned ) + return 0; + + var_1 = gettime() + var_0 * 1000; + var_2 = level.lastwave[self.pers["team"]]; + var_3 = level.wavedelay[self.pers["team"]] * 1000; + var_4 = ( var_1 - var_2 ) / var_3; + var_5 = ceil( var_4 ); + var_6 = var_2 + var_5 * var_3; + + if ( isdefined( self.respawntimerstarttime ) ) + { + var_7 = ( gettime() - self.respawntimerstarttime ) / 1000.0; + + if ( self.respawntimerstarttime < var_2 ) + return 0; + } + + if ( isdefined( self.wavespawnindex ) ) + var_6 += 50 * self.wavespawnindex; + + return ( var_6 - gettime() ) / 1000; +} + +teamkilldelay() +{ + var_0 = self.pers["teamkills"]; + + if ( level.maxallowedteamkills < 0 || var_0 <= level.maxallowedteamkills ) + return 0; + + var_1 = var_0 - level.maxallowedteamkills; + return maps\mp\gametypes\_tweakables::gettweakablevalue( "team", "teamkillspawndelay" ) * var_1; +} + +timeuntilspawn( var_0 ) +{ + if ( level.ingraceperiod && !self.hasspawned || level.gameended ) + return 0; + + var_1 = 0; + + if ( self.hasspawned ) + { + var_2 = self [[ level.onrespawndelay ]](); + + if ( isdefined( var_2 ) ) + var_1 = var_2; + else + var_1 = getdvarint( "scr_" + level.gametype + "_playerrespawndelay" ); + + if ( var_0 && isdefined( self.pers["teamKillPunish"] ) && self.pers["teamKillPunish"] ) + var_1 += teamkilldelay(); + + if ( isdefined( self.respawntimerstarttime ) ) + { + var_3 = ( gettime() - self.respawntimerstarttime ) / 1000.0; + var_1 -= var_3; + + if ( var_1 < 0 ) + var_1 = 0; + } + + if ( isdefined( self.setspawnpoint ) ) + var_1 += level.tispawndelay; + } + + var_4 = getdvarint( "scr_" + level.gametype + "_waverespawndelay" ) > 0; + + if ( var_4 ) + return timeuntilwavespawn( var_1 ); + + return var_1; +} + +mayspawn() +{ + if ( maps\mp\_utility::getgametypenumlives() || isdefined( level.disablespawning ) ) + { + if ( isdefined( level.disablespawning ) && level.disablespawning ) + return 0; + + if ( isdefined( self.pers["teamKillPunish"] ) && self.pers["teamKillPunish"] ) + return 0; + + if ( self.pers["lives"] <= 0 && maps\mp\_utility::gamehasstarted() ) + return 0; + else if ( maps\mp\_utility::gamehasstarted() ) + { + if ( !level.ingraceperiod && !self.hasspawned && ( isdefined( level.allowlatecomers ) && !level.allowlatecomers ) ) + { + if ( isdefined( self.siegelatecomer ) && !self.siegelatecomer ) + return 1; + + return 0; + } + } + } + + return 1; +} + +spawnclient() +{ + self endon( "becameSpectator" ); + + if ( isdefined( self.waitingtoselectclass ) && self.waitingtoselectclass ) + self waittill( "okToSpawn" ); + + if ( isdefined( self.addtoteam ) ) + { + maps\mp\gametypes\_menus::addtoteam( self.addtoteam ); + self.addtoteam = undefined; + } + + if ( !mayspawn() ) + { + wait 0.05; + var_0 = self.origin; + var_1 = self.angles; + self notify( "attempted_spawn" ); + var_2 = self.pers["teamKillPunish"]; + + if ( isdefined( var_2 ) && var_2 ) + { + self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 ); + maps\mp\_utility::setlowermessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT" ); + + if ( !self.hasspawned && self.pers["teamkills"] <= level.maxallowedteamkills ) + self.pers["teamKillPunish"] = 0; + } + else if ( maps\mp\_utility::isroundbased() && !maps\mp\_utility::islastround() ) + { + if ( isdefined( self.tagavailable ) && self.tagavailable ) + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_tag_wait"] ); + else if ( level.gametype == "siege" ) + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_flag_wait"] ); + else + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_next_round"] ); + + thread removespawnmessageshortly( 3.0 ); + } + + if ( self.sessionstate != "spectator" ) + var_0 += ( 0, 0, 60 ); + + thread spawnspectator( var_0, var_1 ); + return; + } + + if ( self.waitingtospawn ) + return; + + self.waitingtospawn = 1; + waitandspawnclient(); + + if ( isdefined( self ) ) + self.waitingtospawn = 0; +} + +waitandspawnclient() +{ + self endon( "disconnect" ); + self endon( "end_respawn" ); + level endon( "game_ended" ); + self notify( "attempted_spawn" ); + var_0 = 0; + var_1 = self.pers["teamKillPunish"]; + + if ( isdefined( var_1 ) && var_1 ) + { + var_2 = teamkilldelay(); + + if ( var_2 > 0 ) + { + maps\mp\_utility::setlowermessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT", var_2, 1, 1 ); + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + var_0 = 1; + wait(var_2); + maps\mp\_utility::clearlowermessage( "friendly_fire" ); + self.respawntimerstarttime = gettime(); + } + + self.pers["teamKillPunish"] = 0; + } + else if ( !maps\mp\_utility::is_aliens() && teamkilldelay() ) + self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 ); + + if ( maps\mp\_utility::isusingremote() ) + { + self.spawningafterremotedeath = 1; + self.deathposition = self.origin; + self waittill( "stopped_using_remote" ); + } + + if ( !isdefined( self.wavespawnindex ) && isdefined( level.waveplayerspawnindex[self.team] ) ) + { + self.wavespawnindex = level.waveplayerspawnindex[self.team]; + level.waveplayerspawnindex[self.team]++; + } + + var_3 = timeuntilspawn( 0 ); + thread predictabouttospawnplayerovertime( var_3 ); + + if ( var_3 > 0 ) + { + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["waiting_to_spawn"], var_3, 1, 1 ); + + if ( !var_0 ) + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + + var_0 = 1; + maps\mp\_utility::waitfortimeornotify( var_3, "force_spawn" ); + self notify( "stop_wait_safe_spawn_button" ); + } + + if ( needsbuttontorespawn() ) + { + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["press_to_spawn"], undefined, undefined, undefined, undefined, undefined, undefined, 1 ); + + if ( !var_0 ) + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + + var_0 = 1; + waitrespawnbutton(); + } + + self.waitingtospawn = 0; + maps\mp\_utility::clearlowermessage( "spawn_info" ); + self.wavespawnindex = undefined; + thread spawnplayer(); +} + +needsbuttontorespawn() +{ + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "player", "forcerespawn" ) != 0 ) + return 0; + + if ( !self.hasspawned ) + return 0; + + var_0 = getdvarint( "scr_" + level.gametype + "_waverespawndelay" ) > 0; + + if ( var_0 ) + return 0; + + if ( self.wantsafespawn ) + return 0; + + return 1; +} + +waitrespawnbutton() +{ + self endon( "disconnect" ); + self endon( "end_respawn" ); + + for (;;) + { + if ( self usebuttonpressed() ) + break; + + wait 0.05; + } +} + +removespawnmessageshortly( var_0 ) +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + waittillframeend; + self endon( "end_respawn" ); + wait(var_0); + maps\mp\_utility::clearlowermessage( "spawn_info" ); +} + +laststandrespawnplayer() +{ + self laststandrevive(); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) && !level.diehardmode ) + maps\mp\_utility::_unsetperk( "specialty_finalstand" ); + + if ( level.diehardmode ) + self.headicon = ""; + + self setstance( "crouch" ); + self.revived = 1; + self notify( "revive" ); + + if ( isdefined( self.standardmaxhealth ) ) + self.maxhealth = self.standardmaxhealth; + + self.health = self.maxhealth; + common_scripts\utility::_enableusability(); + + if ( game["state"] == "postgame" ) + maps\mp\gametypes\_gamelogic::freezeplayerforroundend(); +} + +getdeathspawnpoint() +{ + var_0 = spawn( "script_origin", self.origin ); + var_0 hide(); + var_0.angles = self.angles; + return var_0; +} + +showspawnnotifies() +{ + if ( isdefined( game["defcon"] ) ) + thread maps\mp\gametypes\_hud_message::defconsplashnotify( game["defcon"], 0 ); + + if ( !maps\mp\_utility::is_aliens() && maps\mp\_utility::isrested() ) + thread maps\mp\gametypes\_hud_message::splashnotify( "rested" ); +} + +predictabouttospawnplayerovertime( var_0 ) +{ + if ( !0 ) + return; + + self endon( "disconnect" ); + self endon( "spawned" ); + self endon( "used_predicted_spawnpoint" ); + self notify( "predicting_about_to_spawn_player" ); + self endon( "predicting_about_to_spawn_player" ); + + if ( var_0 <= 0 ) + return; + + if ( var_0 > 1.0 ) + wait(var_0 - 1.0); + + predictabouttospawnplayer(); + self predictstreampos( self.predictedspawnpoint.origin + ( 0, 0, 60 ), self.predictedspawnpoint.angles ); + self.predictedspawnpointtime = gettime(); + + for ( var_1 = 0; var_1 < 30; var_1++ ) + { + wait 0.4; + var_2 = self.predictedspawnpoint; + predictabouttospawnplayer(); + + if ( self.predictedspawnpoint != var_2 ) + { + self predictstreampos( self.predictedspawnpoint.origin + ( 0, 0, 60 ), self.predictedspawnpoint.angles ); + self.predictedspawnpointtime = gettime(); + } + } +} + +predictabouttospawnplayer() +{ + if ( timeuntilspawn( 1 ) > 1.0 ) + { + self.predictedspawnpoint = getspectatepoint(); + return; + } + + if ( isdefined( self.setspawnpoint ) ) + { + self.predictedspawnpoint = self.setspawnpoint; + return; + } + + var_0 = self [[ level.getspawnpoint ]](); + self.predictedspawnpoint = var_0; +} + +checkpredictedspawnpointcorrectness( var_0 ) +{ + self notify( "used_predicted_spawnpoint" ); + self.predictedspawnpoint = undefined; +} + +percentage( var_0, var_1 ) +{ + return var_0 + " (" + int( var_0 / var_1 * 100 ) + "%)"; +} + +printpredictedspawnpointcorrectness() +{ + +} + +getspawnorigin( var_0 ) +{ + if ( !positionwouldtelefrag( var_0.origin ) ) + return var_0.origin; + + if ( !isdefined( var_0.alternates ) ) + return var_0.origin; + + foreach ( var_2 in var_0.alternates ) + { + if ( !positionwouldtelefrag( var_2 ) ) + return var_2; + } + + return var_0.origin; +} + +tivalidationcheck() +{ + if ( !isdefined( self.setspawnpoint ) ) + return 0; + + var_0 = getentarray( "care_package", "targetname" ); + + foreach ( var_2 in var_0 ) + { + if ( distance( var_2.origin, self.setspawnpoint.playerspawnpos ) > 64 ) + continue; + + if ( isdefined( var_2.owner ) ) + maps\mp\gametypes\_hud_message::playercardsplashnotify( "destroyed_insertion", var_2.owner ); + + maps\mp\perks\_perkfunctions::deleteti( self.setspawnpoint ); + return 0; + } + + if ( !bullettracepassed( self.setspawnpoint.origin + ( 0, 0, 60 ), self.setspawnpoint.origin, 0, self.setspawnpoint ) ) + return 0; + + var_4 = self.setspawnpoint.origin + ( 0, 0, 1 ); + var_5 = playerphysicstrace( var_4, self.setspawnpoint.origin + ( 0, 0, -16 ) ); + + if ( var_4[2] == var_5[2] ) + return 0; + + return 1; +} + +spawningclientthisframereset() +{ + self notify( "spawningClientThisFrameReset" ); + self endon( "spawningClientThisFrameReset" ); + wait 0.05; + level.numplayerswaitingtospawn--; +} + +spawnplayer( var_0 ) +{ + self endon( "disconnect" ); + self endon( "joined_spectators" ); + self notify( "spawned" ); + self notify( "end_respawn" ); + self notify( "started_spawnPlayer" ); + + if ( !isdefined( var_0 ) ) + var_0 = 0; + + var_1 = undefined; + self.ti_spawn = 0; + self setclientomnvar( "ui_options_menu", 0 ); + self setclientomnvar( "ui_hud_shake", 0 ); + self.lastkillsplash = undefined; + + if ( !level.ingraceperiod && !self.hasdonecombat ) + { + level.numplayerswaitingtospawn++; + + if ( level.numplayerswaitingtospawn > 1 ) + { + self.waitingtospawnamortize = 1; + wait(0.05 * ( level.numplayerswaitingtospawn - 1 )); + } + + thread spawningclientthisframereset(); + self.waitingtospawnamortize = 0; + } + + // // Returning false we use default character model and prevent a 5 second respawn delay. (Github issue #109) + if ( !self hasloadedcustomizationplayerview( self ) ) + self.waitingtospawnamortize = 0; + + if ( isdefined( self.forcespawnorigin ) ) + { + var_2 = self.forcespawnorigin; + self.forcespawnorigin = undefined; + + if ( isdefined( self.forcespawnangles ) ) + { + var_3 = self.forcespawnangles; + self.forcespawnangles = undefined; + } + else + var_3 = ( 0, randomfloatrange( 0, 360 ), 0 ); + } + else if ( isdefined( self.setspawnpoint ) && ( isdefined( self.setspawnpoint.notti ) || tivalidationcheck() ) ) + { + var_1 = self.setspawnpoint; + + if ( !isdefined( self.setspawnpoint.notti ) ) + { + self.ti_spawn = 1; + self playlocalsound( "tactical_spawn" ); + + if ( level.multiteambased ) + { + foreach ( var_5 in level.teamnamelist ) + { + if ( var_5 != self.team ) + self playsoundtoteam( "tactical_spawn", var_5 ); + } + } + else if ( level.teambased ) + self playsoundtoteam( "tactical_spawn", level.otherteam[self.team] ); + else + self playsound( "tactical_spawn" ); + } + + foreach ( var_8 in level.ugvs ) + { + if ( distancesquared( var_8.origin, var_1.playerspawnpos ) < 1024 ) + var_8 notify( "damage", 5000, var_8.owner, ( 0, 0, 0 ), ( 0, 0, 0 ), "MOD_EXPLOSIVE", "", "", "", undefined, "killstreak_emp_mp" ); + } + + var_2 = self.setspawnpoint.playerspawnpos; + var_3 = self.setspawnpoint.angles; + + if ( isdefined( self.setspawnpoint.enemytrigger ) ) + self.setspawnpoint.enemytrigger delete(); + + self.setspawnpoint delete(); + var_1 = undefined; + } + else if ( isdefined( self.isspawningonbattlebuddy ) && isdefined( self.battlebuddy ) ) + { + var_2 = undefined; + var_3 = undefined; + var_10 = maps\mp\gametypes\_battlebuddy::checkbuddyspawn(); + + if ( var_10.status == 0 ) + { + var_2 = var_10.origin; + var_3 = var_10.angles; + } + else + { + var_1 = self [[ level.getspawnpoint ]](); + var_2 = var_1.origin; + var_3 = var_1.angles; + } + + maps\mp\gametypes\_battlebuddy::cleanupbuddyspawn(); + self setclientomnvar( "cam_scene_name", "battle_spawn" ); + self setclientomnvar( "cam_scene_lead", self.battlebuddy getentitynumber() ); + self setclientomnvar( "cam_scene_support", self getentitynumber() ); + } + else if ( isdefined( self.helispawning ) && ( !isdefined( self.firstspawn ) || isdefined( self.firstspawn ) && self.firstspawn ) && level.prematchperiod > 0 && self.team == "allies" ) + { + while ( !isdefined( level.allieschopper ) ) + wait 0.1; + + var_2 = level.allieschopper.origin; + var_3 = level.allieschopper.angles; + self.firstspawn = 0; + } + else if ( isdefined( self.helispawning ) && ( !isdefined( self.firstspawn ) || isdefined( self.firstspawn ) && self.firstspawn ) && level.prematchperiod > 0 && self.team == "axis" ) + { + while ( !isdefined( level.axischopper ) ) + wait 0.1; + + var_2 = level.axischopper.origin; + var_3 = level.axischopper.angles; + self.firstspawn = 0; + } + else + { + var_1 = self [[ level.getspawnpoint ]](); + var_2 = var_1.origin; + var_3 = var_1.angles; + } + + setspawnvariables(); + var_11 = self.hasspawned; + self.fauxdead = undefined; + + if ( !var_0 ) + { + self.killsthislife = []; + self.killsthislifeperweapon = []; + maps\mp\_utility::updatesessionstate( "playing" ); + maps\mp\_utility::clearkillcamstate(); + self.cancelkillcam = undefined; + self.maxhealth = maps\mp\gametypes\_tweakables::gettweakablevalue( "player", "maxhealth" ); + self.health = self.maxhealth; + self.friendlydamage = undefined; + self.hasspawned = 1; + self.spawntime = gettime(); + self.wasti = !isdefined( var_1 ); + self.afk = 0; + self.damagedplayers = []; + self.killstreakscaler = 1; + self.xpscaler = 1; + self.objectivescaler = 1; + self.clampedhealth = undefined; + self.shielddamage = 0; + self.shieldbullethits = 0; + self.recentshieldxp = 0; + } + + self.movespeedscaler = 1; + self.inlaststand = 0; + self.laststand = undefined; + self.infinalstand = undefined; + self.inc4death = undefined; + self.disabledweapon = 0; + self.disabledweaponswitch = 0; + self.disabledoffhandweapons = 0; + common_scripts\utility::resetusability(); + + if ( !var_0 ) + { + self.avoidkillstreakonspawntimer = 5.0; + + if ( !maps\mp\_utility::is_aliens() ) + { + var_12 = self.pers["lives"]; + + if ( var_12 == maps\mp\_utility::getgametypenumlives() ) + addtolivescount(); + + if ( var_12 ) + self.pers["lives"]--; + } + + addtoalivecount(); + + if ( !var_11 || maps\mp\_utility::gamehasstarted() || maps\mp\_utility::gamehasstarted() && level.ingraceperiod && self.hasdonecombat ) + removefromlivescount(); + + if ( !self.wasaliveatmatchstart ) + { + var_13 = 20; + + if ( maps\mp\_utility::gettimelimit() > 0 && var_13 < maps\mp\_utility::gettimelimit() * 60 / 4 ) + var_13 = maps\mp\_utility::gettimelimit() * 60 / 4; + + if ( level.ingraceperiod || maps\mp\_utility::gettimepassed() < var_13 * 1000 ) + self.wasaliveatmatchstart = 1; + } + } + + self setdepthoffield( 0, 0, 512, 512, 4, 0 ); + + if ( level.console ) + self setclientdvar( "cg_fov", "65" ); + + resetuidvarsonspawn(); + + if ( isdefined( var_1 ) ) + { + maps\mp\gametypes\_spawnlogic::finalizespawnpointchoice( var_1 ); + var_2 = getspawnorigin( var_1 ); + var_3 = var_1.angles; + } + else if ( !isdefined( self.faux_spawn_infected ) ) + self.lastspawntime = gettime(); + + self.spawnpos = var_2; + self spawn( var_2, var_3 ); + + if ( var_0 && isdefined( self.faux_spawn_stance ) ) + { + self setstance( self.faux_spawn_stance ); + self.faux_spawn_stance = undefined; + } + + if ( isai( self ) ) + maps\mp\_utility::freezecontrolswrapper( 1 ); + + [[ level.onspawnplayer ]](); + + if ( isdefined( var_1 ) ) + checkpredictedspawnpointcorrectness( var_1.origin ); + + if ( !var_0 ) + { + maps\mp\gametypes\_missions::playerspawned(); + + if ( isai( self ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["player_spawned"] ) ) + self [[ level.bot_funcs["player_spawned"] ]](); + + if ( !isai( self ) ) + thread watchforslide(); + } + + maps\mp\gametypes\_class::setclass( self.class ); + + if ( isdefined( level.custom_giveloadout ) ) + self [[ level.custom_giveloadout ]]( var_0 ); + else + maps\mp\gametypes\_class::giveloadout( self.team, self.class ); + + if ( isdefined( game["roundsPlayed"] ) && game["roundsPlayed"] > 0 ) + { + if ( !isdefined( self.classrefreshed ) || !self.classrefreshed ) + { + if ( isdefined( self.class_num ) ) + { + self setclientomnvar( "ui_loadout_selected", self.class_num ); + self.classrefreshed = 1; + } + } + } + + if ( getdvarint( "camera_thirdPerson" ) ) + maps\mp\_utility::setthirdpersondof( 1 ); + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) ) + maps\mp\_utility::freezecontrolswrapper( 1 ); + else + maps\mp\_utility::freezecontrolswrapper( 0 ); + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) || !var_11 && game["state"] == "playing" ) + { + if ( !maps\mp\_utility::is_aliens() ) + { + if ( game["status"] == "overtime" ) + thread maps\mp\gametypes\_hud_message::oldnotifymessage( game["strings"]["overtime"], game["strings"]["overtime_hint"], undefined, ( 1, 0, 0 ), "mp_last_stand" ); + } + + thread showspawnnotifies(); + } + + if ( maps\mp\_utility::getintproperty( "scr_showperksonspawn", 1 ) == 1 && game["state"] != "postgame" ) + { + if ( !maps\mp\_utility::is_aliens() ) + self setclientomnvar( "ui_spawn_abilities_show", 1 ); + } + + waittillframeend; + self.spawningafterremotedeath = undefined; + self notify( "spawned_player" ); + level notify( "player_spawned", self ); + + if ( game["state"] == "postgame" ) + maps\mp\gametypes\_gamelogic::freezeplayerforroundend(); +} + +spawnspectator( var_0, var_1 ) +{ + self notify( "spawned" ); + self notify( "end_respawn" ); + self notify( "joined_spectators" ); + in_spawnspectator( var_0, var_1 ); +} + +respawn_asspectator( var_0, var_1 ) +{ + in_spawnspectator( var_0, var_1 ); +} + +in_spawnspectator( var_0, var_1 ) +{ + setspawnvariables(); + var_2 = self.pers["team"]; + + if ( isdefined( var_2 ) && var_2 == "spectator" && !level.gameended ) + maps\mp\_utility::clearlowermessage( "spawn_info" ); + + maps\mp\_utility::updatesessionstate( "spectator" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + resetuidvarsonspectate(); + + if ( isdefined( var_2 ) && var_2 == "spectator" ) + self.statusicon = ""; + else + self.statusicon = "hud_status_dead"; + + maps\mp\gametypes\_spectating::setspectatepermissions(); + onspawnspectator( var_0, var_1 ); + + if ( level.teambased && !level.splitscreen && !self issplitscreenplayer() ) + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); +} + +getplayerfromclientnum( var_0 ) +{ + if ( var_0 < 0 ) + return undefined; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + if ( level.players[var_1] getentitynumber() == var_0 ) + return level.players[var_1]; + } + + return undefined; +} + +onspawnspectator( var_0, var_1 ) +{ + if ( isdefined( var_0 ) && isdefined( var_1 ) ) + { + self setspectatedefaults( var_0, var_1 ); + self spawn( var_0, var_1 ); + checkpredictedspawnpointcorrectness( var_0 ); + return; + } + + var_2 = getspectatepoint(); + + if ( !maps\mp\_utility::is_aliens() ) + { + var_3 = getentarray( "mp_mlg_camera", "classname" ); + + if ( isdefined( var_3 ) && var_3.size ) + { + for ( var_4 = 0; var_4 < var_3.size && var_4 < 4; var_4++ ) + { + self setmlgcameradefaults( var_4, var_3[var_4].origin, var_3[var_4].angles ); + level.cameramapobjs[var_4].origin = var_3[var_4].origin; + level.cameramapobjs[var_4].angles = var_3[var_4].angles; + } + } + else if ( isdefined( level.camera3pos ) ) + { + var_5 = tolower( getdvar( "mapname" ) ); + + if ( var_5 == "mp_strikezone" && isdefined( level.teleport_zone_current ) && level.teleport_zone_current != "start" ) + { + self setmlgcameradefaults( 0, level.camera5pos, level.camera5ang ); + level.cameramapobjs[0].origin = level.camera5pos; + level.cameramapobjs[0].angles = level.camera5ang; + self setmlgcameradefaults( 1, level.camera6pos, level.camera6ang ); + level.cameramapobjs[1].origin = level.camera6pos; + level.cameramapobjs[1].angles = level.camera6ang; + self setmlgcameradefaults( 2, level.camera7pos, level.camera7ang ); + level.cameramapobjs[2].origin = level.camera7pos; + level.cameramapobjs[2].angles = level.camera7ang; + self setmlgcameradefaults( 3, level.camera8pos, level.camera8ang ); + level.cameramapobjs[3].origin = level.camera8pos; + level.cameramapobjs[3].angles = level.camera8ang; + } + else + { + self setmlgcameradefaults( 0, level.camera1pos, level.camera1ang ); + level.cameramapobjs[0].origin = level.camera1pos; + level.cameramapobjs[0].angles = level.camera1ang; + self setmlgcameradefaults( 1, level.camera2pos, level.camera2ang ); + level.cameramapobjs[1].origin = level.camera2pos; + level.cameramapobjs[1].angles = level.camera2ang; + self setmlgcameradefaults( 2, level.camera3pos, level.camera3ang ); + level.cameramapobjs[2].origin = level.camera3pos; + level.cameramapobjs[2].angles = level.camera3ang; + self setmlgcameradefaults( 3, level.camera4pos, level.camera4ang ); + level.cameramapobjs[3].origin = level.camera4pos; + level.cameramapobjs[3].angles = level.camera4ang; + } + } + else + { + for ( var_4 = 0; var_4 < 4; var_4++ ) + self setmlgcameradefaults( var_4, var_2.origin, var_2.angles ); + } + } + + self setspectatedefaults( var_2.origin, var_2.angles ); + self spawn( var_2.origin, var_2.angles ); + checkpredictedspawnpointcorrectness( var_2.origin ); +} + +getspectatepoint() +{ + var_0 = getentarray( "mp_global_intermission", "classname" ); + var_1 = maps\mp\gametypes\_spawnlogic::getspawnpoint_random( var_0 ); + return var_1; +} + +spawnintermission() +{ + self endon( "disconnect" ); + self notify( "spawned" ); + self notify( "end_respawn" ); + setspawnvariables(); + maps\mp\_utility::clearlowermessages(); + maps\mp\_utility::freezecontrolswrapper( 1 ); + self setclientdvar( "cg_everyoneHearsEveryone", 1 ); + var_0 = self.pers["postGameChallenges"]; + + if ( !maps\mp\_utility::is_aliens() && level.rankedmatch && ( self.postgamepromotion || isdefined( var_0 ) && var_0 ) ) + { + if ( self.postgamepromotion ) + self playlocalsound( "mp_level_up" ); + else if ( isdefined( var_0 ) ) + self playlocalsound( "mp_challenge_complete" ); + + if ( self.postgamepromotion > level.postgamenotifies ) + level.postgamenotifies = 1; + + if ( isdefined( var_0 ) && var_0 > level.postgamenotifies ) + level.postgamenotifies = var_0; + + var_1 = 7.0; + + if ( isdefined( var_0 ) ) + var_1 = 4.0 + min( var_0, 3 ); + + while ( var_1 ) + { + wait 0.25; + var_1 -= 0.25; + } + } + + if ( isdefined( level.finalkillcam_winner ) && level.finalkillcam_winner != "none" && isdefined( level.match_end_delay ) && maps\mp\_utility::waslastround() ) + wait(level.match_end_delay); + + maps\mp\_utility::updatesessionstate( "intermission" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + var_2 = getentarray( "mp_global_intermission", "classname" ); + var_2 = maps\mp\gametypes\_spawnscoring::checkdynamicspawns( var_2 ); + var_3 = var_2[0]; + + if ( !isdefined( level.custom_ending ) ) + { + self spawn( var_3.origin, var_3.angles ); + checkpredictedspawnpointcorrectness( var_3.origin ); + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); + } + else + level notify( "scoreboard_displaying" ); +} + +spawnendofgame() +{ + if ( 1 ) + { + if ( isdefined( level.custom_ending ) && maps\mp\_utility::waslastround() ) + level notify( "start_custom_ending" ); + + maps\mp\_utility::freezecontrolswrapper( 1 ); + spawnspectator(); + maps\mp\_utility::freezecontrolswrapper( 1 ); + return; + } + + self notify( "spawned" ); + self notify( "end_respawn" ); + setspawnvariables(); + maps\mp\_utility::clearlowermessages(); + self setclientdvar( "cg_everyoneHearsEveryone", 1 ); + maps\mp\_utility::updatesessionstate( "dead" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + var_0 = getspectatepoint(); + spawnspectator( var_0.origin, var_0.angles ); + checkpredictedspawnpointcorrectness( var_0.origin ); + maps\mp\_utility::freezecontrolswrapper( 1 ); + self setdepthoffield( 0, 0, 512, 512, 4, 0 ); +} + +setspawnvariables() +{ + self stopshellshock(); + self stoprumble( "damage_heavy" ); + self.deathposition = undefined; +} + +notifyconnecting() +{ + waittillframeend; + + if ( isdefined( self ) ) + level notify( "connecting", self ); +} + +callback_playerdisconnect( var_0 ) +{ + if ( !isdefined( self.connected ) ) + return; + + var_1 = getmatchdata( "gameLength" ); + var_1 += int( maps\mp\_utility::getsecondspassed() ); + setmatchdata( "players", self.clientid, "disconnectTime", var_1 ); + setmatchdata( "players", self.clientid, "disconnectReason", var_0 ); + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + maps\mp\_matchdata::logfinalstats(); + + if ( isdefined( self.pers["confirmed"] ) ) + maps\mp\_matchdata::logkillsconfirmed(); + + if ( isdefined( self.pers["denied"] ) ) + maps\mp\_matchdata::logkillsdenied(); + + removeplayerondisconnect(); + maps\mp\gametypes\_spawnlogic::removefromparticipantsarray(); + maps\mp\gametypes\_spawnlogic::removefromcharactersarray(); + var_2 = self getentitynumber(); + + if ( !level.teambased ) + game["roundsWon"][self.guid] = undefined; + + if ( level.splitscreen ) + { + var_3 = level.players; + + if ( var_3.size <= 1 ) + level thread maps\mp\gametypes\_gamelogic::forceend(); + } + + if ( isdefined( self.score ) && isdefined( self.pers["team"] ) ) + { + var_4 = self.score; + + if ( maps\mp\_utility::getminutespassed() ) + var_4 = self.score / maps\mp\_utility::getminutespassed(); + + setplayerteamrank( self, self.clientid, int( var_4 ) ); + } + + var_5 = self getentitynumber(); + var_6 = self.guid; + logprint( "Q;" + var_6 + ";" + var_5 + ";" + self.name + "\n" ); + thread maps\mp\_events::disconnected(); + + if ( level.gameended ) + maps\mp\gametypes\_gamescore::removedisconnectedplayerfromplacement(); + + if ( isdefined( self.team ) ) + removefromteamcount(); + + if ( self.sessionstate == "playing" && !( isdefined( self.fauxdead ) && self.fauxdead ) ) + removefromalivecount( 1 ); + else if ( self.sessionstate == "spectator" || self.sessionstate == "dead" ) + level thread maps\mp\gametypes\_gamelogic::updategameevents(); +} + +removeplayerondisconnect() +{ + var_0 = 0; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + if ( level.players[var_1] == self ) + { + for ( var_0 = 1; var_1 < level.players.size - 1; var_1++ ) + level.players[var_1] = level.players[var_1 + 1]; + + level.players[var_1] = undefined; + break; + } + } +} + +initclientdvarssplitscreenspecific() +{ + if ( level.splitscreen || self issplitscreenplayer() ) + { + self setclientdvars( "cg_hudGrenadeIconHeight", "37.5", "cg_hudGrenadeIconWidth", "37.5", "cg_hudGrenadeIconOffset", "75", "cg_hudGrenadePointerHeight", "18", "cg_hudGrenadePointerWidth", "37.5", "cg_hudGrenadePointerPivot", "18 40.5", "cg_fovscale", "0.75" ); + setdvar( "r_materialBloomHQScriptMasterEnable", 0 ); + } + else + self setclientdvars( "cg_hudGrenadeIconHeight", "25", "cg_hudGrenadeIconWidth", "25", "cg_hudGrenadeIconOffset", "50", "cg_hudGrenadePointerHeight", "12", "cg_hudGrenadePointerWidth", "25", "cg_hudGrenadePointerPivot", "12 27", "cg_fovscale", "1" ); +} + +initclientdvars() +{ + setdvar( "cg_drawTalk", 1 ); + setdvar( "cg_drawCrosshair", 1 ); + setdvar( "cg_drawCrosshairNames", 1 ); + setdvar( "cg_hudGrenadeIconMaxRangeFrag", 250 ); + + if ( level.hardcoremode ) + { + setdvar( "cg_drawTalk", 3 ); + setdvar( "cg_drawCrosshair", 0 ); + setdvar( "cg_drawCrosshairNames", 1 ); + setdvar( "cg_hudGrenadeIconMaxRangeFrag", 0 ); + } + + if ( isdefined( level.alwaysdrawfriendlynames ) && level.alwaysdrawfriendlynames ) + setdvar( "cg_drawFriendlyNamesAlways", 1 ); + else + setdvar( "cg_drawFriendlyNamesAlways", 0 ); + + self setclientdvars( "cg_drawSpectatorMessages", 1, "cg_scoreboardPingGraph", 1 ); + initclientdvarssplitscreenspecific(); + + if ( maps\mp\_utility::getgametypenumlives() ) + self setclientdvars( "cg_deadChatWithDead", 1, "cg_deadChatWithTeam", 0, "cg_deadHearTeamLiving", 0, "cg_deadHearAllLiving", 0 ); + else + self setclientdvars( "cg_deadChatWithDead", 0, "cg_deadChatWithTeam", 1, "cg_deadHearTeamLiving", 1, "cg_deadHearAllLiving", 0 ); + + if ( level.teambased ) + self setclientdvars( "cg_everyonehearseveryone", 0 ); + + self setclientdvar( "ui_altscene", 0 ); + + if ( getdvarint( "scr_hitloc_debug" ) ) + { + for ( var_0 = 0; var_0 < 6; var_0++ ) + self setclientdvar( "ui_hitloc_" + var_0, "" ); + + self.hitlocinited = 1; + } +} + +getlowestavailableclientid() +{ + var_0 = 0; + + for ( var_1 = 0; var_1 < 30; var_1++ ) + { + foreach ( var_3 in level.players ) + { + if ( !isdefined( var_3 ) ) + continue; + + if ( var_3.clientid == var_1 ) + { + var_0 = 1; + break; + } + + var_0 = 0; + } + + if ( !var_0 ) + return var_1; + } +} + +setupsavedactionslots() +{ + self.saved_actionslotdata = []; + + for ( var_0 = 1; var_0 <= 4; var_0++ ) + { + self.saved_actionslotdata[var_0] = spawnstruct(); + self.saved_actionslotdata[var_0].type = ""; + self.saved_actionslotdata[var_0].item = undefined; + } + + if ( !level.console ) + { + for ( var_0 = 5; var_0 <= 8; var_0++ ) + { + self.saved_actionslotdata[var_0] = spawnstruct(); + self.saved_actionslotdata[var_0].type = ""; + self.saved_actionslotdata[var_0].item = undefined; + } + } +} + +callback_playerconnect() +{ + thread notifyconnecting(); + self.statusicon = "hud_status_connecting"; + self waittill( "begin" ); + self.statusicon = ""; + self.connecttime = undefined; + level notify( "connected", self ); + self.connected = 1; + + if ( self ishost() ) + level.player = self; + + if ( !level.splitscreen && !isdefined( self.pers["score"] ) ) + iprintln( &"MP_CONNECTED", self ); + + self.usingonlinedataoffline = self isusingonlinedataoffline(); + initclientdvars(); + + if ( !maps\mp\_utility::is_aliens() ) + initplayerstats(); + + if ( getdvar( "r_reflectionProbeGenerate" ) == "1" ) + level waittill( "eternity" ); + + self.guid = maps\mp\_utility::getuniqueid(); + var_0 = 0; + + if ( !isdefined( self.pers["clientid"] ) ) + { + if ( game["clientid"] >= 30 ) + self.pers["clientid"] = getlowestavailableclientid(); + else + self.pers["clientid"] = game["clientid"]; + + if ( game["clientid"] < 30 ) + game["clientid"]++; + + var_0 = 1; + } + + if ( var_0 ) + maps\mp\killstreaks\_killstreaks::resetadrenaline(); + + self.clientid = self.pers["clientid"]; + self.pers["teamKillPunish"] = 0; + logprint( "J;" + self.guid + ";" + self getentitynumber() + ";" + self.name + "\n" ); + + if ( game["clientid"] <= 30 && game["clientid"] != getmatchdata( "playerCount" ) ) + { + var_1 = 0; + var_2 = 0; + + if ( !isai( self ) && maps\mp\_utility::matchmakinggame() ) + self registerparty( self.clientid ); + + setmatchdata( "playerCount", game["clientid"] ); + setmatchdata( "players", self.clientid, "playerID", "xuid", self getxuid() ); + setmatchdata( "players", self.clientid, "playerID", "ucdIDHigh", self getucdidhigh() ); + setmatchdata( "players", self.clientid, "playerID", "ucdIDLow", self getucdidlow() ); + setmatchdata( "players", self.clientid, "playerID", "clanIDHigh", self getclanidhigh() ); + setmatchdata( "players", self.clientid, "playerID", "clanIDLow", self getclanidlow() ); + setmatchdata( "players", self.clientid, "gamertag", self.name ); + var_2 = self getcommonplayerdata( "connectionIDChunkLow", 0 ); + var_1 = self getcommonplayerdata( "connectionIDChunkHigh", 0 ); + setmatchdata( "players", self.clientid, "connectionIDChunkLow", var_2 ); + setmatchdata( "players", self.clientid, "connectionIDChunkHigh", var_1 ); + setmatchclientip( self, self.clientid ); + var_3 = getmatchdata( "gameLength" ); + var_3 += int( maps\mp\_utility::getsecondspassed() ); + setmatchdata( "players", self.clientid, "joinType", self getjointype() ); + setmatchdata( "players", self.clientid, "connectTime", var_3 ); + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + maps\mp\_matchdata::loginitialstats(); + + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] || isai( self ) ) + var_4 = 1; + else + var_4 = 0; + + if ( maps\mp\_utility::matchmakinggame() && maps\mp\_utility::allowteamchoice() && !var_4 ) + setmatchdata( "players", self.clientid, "team", self.sessionteam ); + } + + if ( !level.teambased ) + game["roundsWon"][self.guid] = 0; + + self.leaderdialogqueue = []; + self.leaderdialoglocqueue = []; + self.leaderdialogactive = ""; + self.leaderdialoggroups = []; + self.leaderdialoggroup = ""; + + if ( !isdefined( self.pers["cur_kill_streak"] ) ) + self.pers["cur_kill_streak"] = 0; + + if ( !isdefined( self.pers["cur_death_streak"] ) ) + self.pers["cur_death_streak"] = 0; + + if ( !isdefined( self.pers["assistsToKill"] ) ) + self.pers["assistsToKill"] = 0; + + if ( !isdefined( self.pers["cur_kill_streak_for_nuke"] ) ) + self.pers["cur_kill_streak_for_nuke"] = 0; + + if ( !isdefined( self.pers["objectivePointStreak"] ) ) + self.pers["objectivePointStreak"] = 0; + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + self.kill_streak = maps\mp\gametypes\_persistence::statget( "killStreak" ); + + self.lastgrenadesuicidetime = -1; + self.teamkillsthisround = 0; + self.hasspawned = 0; + self.waitingtospawn = 0; + self.wantsafespawn = 0; + self.wasaliveatmatchstart = 0; + self.movespeedscaler = 1; + self.killstreakscaler = 1; + self.xpscaler = 1; + self.objectivescaler = 1; + self.issniper = 0; + + if ( !maps\mp\_utility::is_aliens() ) + setrestxpgoal(); + + setupsavedactionslots(); + thread maps\mp\_flashgrenades::monitorflash(); + resetuidvarsonconnect(); + waittillframeend; + level.players[level.players.size] = self; + maps\mp\gametypes\_spawnlogic::addtoparticipantsarray(); + maps\mp\gametypes\_spawnlogic::addtocharactersarray(); + + if ( level.teambased ) + self updatescores(); + + if ( game["state"] == "postgame" ) + { + self.connectedpostgame = 1; + self setclientdvars( "cg_drawSpectatorMessages", 0 ); + spawnintermission(); + } + else + { + if ( isai( self ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["think"] ) ) + self thread [[ level.bot_funcs["think"] ]](); + + level endon( "game_ended" ); + + if ( isdefined( level.hostmigrationtimer ) ) + thread maps\mp\gametypes\_hostmigration::hostmigrationtimerthink(); + + if ( isdefined( level.onplayerconnectaudioinit ) ) + [[ level.onplayerconnectaudioinit ]](); + + if ( maps\mp\_utility::bot_is_fireteam_mode() && !isai( self ) ) + { + thread spawnspectator(); + self setclientomnvar( "ui_options_menu", 0 ); + } + else if ( !isdefined( self.pers["team"] ) ) + { + if ( maps\mp\_utility::matchmakinggame() && self.sessionteam != "none" ) + { + thread spawnspectator(); + thread maps\mp\gametypes\_menus::setteam( self.sessionteam ); + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self setclientomnvar( "ui_options_menu", 2 ); + + thread kickifdontspawn(); + return; + } + else if ( issquadsmode() && getdvarint( "onlinegame" ) == 0 && level.gametype != "horde" && isbot( self ) == 0 ) + { + thread spawnspectator(); + thread maps\mp\gametypes\_menus::setteam( "allies" ); + self setclientomnvar( "ui_options_menu", 2 ); + } + else if ( maps\mp\_utility::allowteamchoice() && isbot( self ) == 0 ) + { + maps\mp\gametypes\_menus::menuspectator(); + self setclientomnvar( "ui_options_menu", 1 ); + } + else + { + thread spawnspectator(); + maps\mp\gametypes\_menus::autoassign(); + + if ( maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self setclientomnvar( "ui_options_menu", 2 ); + + if ( maps\mp\_utility::matchmakinggame() ) + thread kickifdontspawn(); + + return; + } + } + else + { + maps\mp\gametypes\_menus::addtoteam( self.pers["team"], 1 ); + + if ( maps\mp\_utility::isvalidclass( self.pers["class"] ) ) + { + thread spawnclient(); + return; + } + + thread spawnspectator(); + + if ( self.pers["team"] == "spectator" ) + { + if ( isdefined( self.pers["mlgSpectator"] ) && self.pers["mlgSpectator"] ) + { + self setmlgspectator( 1 ); + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 1 ); + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + if ( maps\mp\_utility::allowteamchoice() ) + { + maps\mp\gametypes\_menus::beginteamchoice(); + return; + } + + self [[ level.autoassign ]](); + return; + return; + } + + maps\mp\gametypes\_menus::beginclasschoice(); + } + } +} + +callback_playermigrated() +{ + if ( isdefined( self.connected ) && self.connected ) + { + maps\mp\_utility::updateobjectivetext(); + maps\mp\_utility::updatemainmenu(); + + if ( level.teambased ) + self updatescores(); + } + + if ( self ishost() ) + initclientdvarssplitscreenspecific(); + + var_0 = 0; + + foreach ( var_2 in level.players ) + { + if ( !isdefined( var_2.pers["isBot"] ) || var_2.pers["isBot"] == 0 ) + var_0++; + } + + if ( !isdefined( self.pers["isBot"] ) || self.pers["isBot"] == 0 ) + { + level.hostmigrationreturnedplayercount++; + + if ( level.hostmigrationreturnedplayercount >= var_0 * 2 / 3 ) + level notify( "hostmigration_enoughplayers" ); + } +} + +addlevelstoexperience( var_0, var_1 ) +{ + var_2 = maps\mp\gametypes\_rank::getrankforxp( var_0 ); + var_3 = maps\mp\gametypes\_rank::getrankinfominxp( var_2 ); + var_4 = maps\mp\gametypes\_rank::getrankinfomaxxp( var_2 ); + var_2 += ( var_0 - var_3 ) / ( var_4 - var_3 ); + var_2 += var_1; + + if ( var_2 < 0 ) + { + var_2 = 0; + var_5 = 0.0; + } + else if ( var_2 >= level.maxrank + 1.0 ) + { + var_2 = level.maxrank; + var_5 = 1.0; + } + else + { + var_5 = var_2 - floor( var_2 ); + var_2 = int( floor( var_2 ) ); + } + + var_3 = maps\mp\gametypes\_rank::getrankinfominxp( var_2 ); + var_4 = maps\mp\gametypes\_rank::getrankinfomaxxp( var_2 ); + return int( var_5 * ( var_4 - var_3 ) ) + var_3; +} + +getrestxpcap( var_0 ) +{ + var_1 = getdvarfloat( "scr_restxp_cap" ); + return addlevelstoexperience( var_0, var_1 ); +} + +setrestxpgoal() +{ + if ( !maps\mp\_utility::rankingenabled() ) + return; + + if ( !getdvarint( "scr_restxp_enable" ) ) + { + self setrankedplayerdata( "restXPGoal", 0 ); + return; + } + + var_0 = self getrestedtime(); + var_1 = var_0 / 3600; + var_2 = self getrankedplayerdata( "experience" ); + var_3 = getdvarfloat( "scr_restxp_minRestTime" ); + var_4 = getdvarfloat( "scr_restxp_levelsPerDay" ) / 24.0; + var_5 = getrestxpcap( var_2 ); + var_6 = self getrankedplayerdata( "restXPGoal" ); + + if ( var_6 < var_2 ) + var_6 = var_2; + + var_7 = var_6; + var_8 = 0; + + if ( var_1 > var_3 ) + { + var_8 = var_4 * var_1; + var_6 = addlevelstoexperience( var_6, var_8 ); + } + + var_9 = ""; + + if ( var_6 >= var_5 ) + { + var_6 = var_5; + var_9 = " (hit cap)"; + } + + self setrankedplayerdata( "restXPGoal", var_6 ); +} + +forcespawn() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "spawned" ); + wait 60.0; + + if ( self.hasspawned ) + return; + + if ( self.pers["team"] == "spectator" ) + return; + + if ( !maps\mp\_utility::isvalidclass( self.pers["class"] ) ) + { + self.pers["class"] = "CLASS_CUSTOM1"; + self.class = self.pers["class"]; + } + + thread spawnclient(); +} + +kickifdontspawn() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "spawned" ); + self endon( "attempted_spawn" ); + var_0 = getdvarfloat( "scr_kick_time", 90 ); + var_1 = getdvarfloat( "scr_kick_mintime", 45 ); + var_2 = getdvarfloat( "scr_kick_hosttime", 120 ); + var_3 = gettime(); + + if ( self ishost() ) + kickwait( var_2 ); + else + kickwait( var_0 ); + + var_4 = ( gettime() - var_3 ) / 1000; + + if ( var_4 < var_0 - 0.1 && var_4 < var_1 ) + return; + + if ( self.hasspawned ) + return; + + if ( self.pers["team"] == "spectator" ) + return; + + kick( self getentitynumber(), "EXE_PLAYERKICKED_INACTIVE" ); + level thread maps\mp\gametypes\_gamelogic::updategameevents(); +} + +kickwait( var_0 ) +{ + level endon( "game_ended" ); + maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_0 ); +} + +initplayerstats() +{ + maps\mp\gametypes\_persistence::initbufferedstats(); + self.pers["lives"] = maps\mp\_utility::getgametypenumlives(); + + if ( !isdefined( self.pers["deaths"] ) ) + { + maps\mp\_utility::initpersstat( "deaths" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "deaths", 0 ); + } + + self.deaths = maps\mp\_utility::getpersstat( "deaths" ); + + if ( !isdefined( self.pers["score"] ) ) + { + maps\mp\_utility::initpersstat( "score" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "score", 0 ); + } + + self.score = maps\mp\_utility::getpersstat( "score" ); + + if ( !isdefined( self.pers["suicides"] ) ) + maps\mp\_utility::initpersstat( "suicides" ); + + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + + if ( !isdefined( self.pers["kills"] ) ) + { + maps\mp\_utility::initpersstat( "kills" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "kills", 0 ); + } + + self.kills = maps\mp\_utility::getpersstat( "kills" ); + + if ( !isdefined( self.pers["headshots"] ) ) + maps\mp\_utility::initpersstat( "headshots" ); + + self.headshots = maps\mp\_utility::getpersstat( "headshots" ); + + if ( !isdefined( self.pers["assists"] ) ) + { + maps\mp\_utility::initpersstat( "assists" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "assists", 0 ); + } + + self.assists = maps\mp\_utility::getpersstat( "assists" ); + + if ( !isdefined( self.pers["captures"] ) ) + { + maps\mp\_utility::initpersstat( "captures" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "captures", 0 ); + } + + self.captures = maps\mp\_utility::getpersstat( "captures" ); + + if ( !isdefined( self.pers["returns"] ) ) + { + maps\mp\_utility::initpersstat( "returns" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "returns", 0 ); + } + + self.returns = maps\mp\_utility::getpersstat( "returns" ); + + if ( !isdefined( self.pers["defends"] ) ) + { + maps\mp\_utility::initpersstat( "defends" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "defends", 0 ); + } + + self.defends = maps\mp\_utility::getpersstat( "defends" ); + + if ( !isdefined( self.pers["plants"] ) ) + { + maps\mp\_utility::initpersstat( "plants" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "plants", 0 ); + } + + self.plants = maps\mp\_utility::getpersstat( "plants" ); + + if ( !isdefined( self.pers["defuses"] ) ) + { + maps\mp\_utility::initpersstat( "defuses" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "defuses", 0 ); + } + + self.defuses = maps\mp\_utility::getpersstat( "defuses" ); + + if ( !isdefined( self.pers["destructions"] ) ) + { + maps\mp\_utility::initpersstat( "destructions" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "destructions", 0 ); + } + + self.destructions = maps\mp\_utility::getpersstat( "destructions" ); + + if ( !isdefined( self.pers["confirmed"] ) ) + { + maps\mp\_utility::initpersstat( "confirmed" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "confirmed", 0 ); + } + + self.confirmed = maps\mp\_utility::getpersstat( "confirmed" ); + + if ( !isdefined( self.pers["denied"] ) ) + { + maps\mp\_utility::initpersstat( "denied" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "denied", 0 ); + } + + self.denied = maps\mp\_utility::getpersstat( "denied" ); + + if ( !isdefined( self.pers["rescues"] ) ) + { + maps\mp\_utility::initpersstat( "rescues" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "rescues", 0 ); + } + + self.rescues = maps\mp\_utility::getpersstat( "rescues" ); + + if ( !isdefined( self.pers["killChains"] ) ) + { + maps\mp\_utility::initpersstat( "killChains" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killChains", 0 ); + } + + self.killchains = maps\mp\_utility::getpersstat( "killChains" ); + + if ( !isdefined( self.pers["killsAsSurvivor"] ) ) + { + maps\mp\_utility::initpersstat( "killsAsSurvivor" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killsAsSurvivor", 0 ); + } + + self.killsassurvivor = maps\mp\_utility::getpersstat( "killsAsSurvivor" ); + + if ( !isdefined( self.pers["killsAsInfected"] ) ) + { + maps\mp\_utility::initpersstat( "killsAsInfected" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killsAsInfected", 0 ); + } + + self.killsasinfected = maps\mp\_utility::getpersstat( "killsAsInfected" ); + + if ( !isdefined( self.pers["teamkills"] ) ) + maps\mp\_utility::initpersstat( "teamkills" ); + + if ( !isdefined( self.pers["extrascore0"] ) ) + maps\mp\_utility::initpersstat( "extrascore0" ); + + if ( !isdefined( self.pers["hordeKills"] ) ) + { + maps\mp\_utility::initpersstat( "hordeKills" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardKills", 0 ); + } + + if ( !isdefined( self.pers["hordeRevives"] ) ) + { + maps\mp\_utility::initpersstat( "hordeRevives" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardRevives", 0 ); + } + + if ( !isdefined( self.pers["hordeCrates"] ) ) + { + maps\mp\_utility::initpersstat( "hordeCrates" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardCrates", 0 ); + } + + if ( !isdefined( self.pers["hordeRound"] ) ) + { + maps\mp\_utility::initpersstat( "hordeRound" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "sguardWave", 0 ); + } + + if ( !isdefined( self.pers["hordeWeapon"] ) ) + { + maps\mp\_utility::initpersstat( "hordeWeapon" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "sguardWeaponLevel", 0 ); + } + + if ( !isdefined( self.pers["teamKillPunish"] ) ) + self.pers["teamKillPunish"] = 0; + + maps\mp\_utility::initpersstat( "longestStreak" ); + self.pers["lives"] = maps\mp\_utility::getgametypenumlives(); + maps\mp\gametypes\_persistence::statsetchild( "round", "killStreak", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "loss", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "win", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "scoreboardType", "none" ); + maps\mp\gametypes\_persistence::statsetchildbuffered( "round", "timePlayed", 0 ); +} + +addtoteamcount() +{ + level.teamcount[self.team]++; + + if ( !isdefined( level.teamlist ) ) + level.teamlist = []; + + if ( !isdefined( level.teamlist[self.team] ) ) + level.teamlist[self.team] = []; + + level.teamlist[self.team][level.teamlist[self.team].size] = self; + maps\mp\gametypes\_gamelogic::updategameevents(); +} + +removefromteamcount() +{ + level.teamcount[self.team]--; + + if ( isdefined( level.teamlist ) && isdefined( level.teamlist[self.team] ) ) + { + var_0 = []; + + foreach ( var_2 in level.teamlist[self.team] ) + { + if ( !isdefined( var_2 ) || var_2 == self ) + continue; + + var_0[var_0.size] = var_2; + } + + level.teamlist[self.team] = var_0; + } +} + +addtoalivecount() +{ + var_0 = self.team; + + if ( !( isdefined( self.alreadyaddedtoalivecount ) && self.alreadyaddedtoalivecount ) ) + { + level.hasspawned[var_0]++; + incrementalivecount( var_0 ); + } + + self.alreadyaddedtoalivecount = undefined; + + if ( level.alivecount["allies"] + level.alivecount["axis"] > level.maxplayercount ) + level.maxplayercount = level.alivecount["allies"] + level.alivecount["axis"]; +} + +incrementalivecount( var_0 ) +{ + level.alivecount[var_0]++; +} + +removefromalivecount( var_0 ) +{ + if ( maps\mp\_utility::is_aliens() ) + return; + + var_1 = self.team; + + if ( isdefined( self.switching_teams ) && self.switching_teams && isdefined( self.joining_team ) && self.joining_team == self.team ) + var_1 = self.leaving_team; + + if ( isdefined( var_0 ) ) + removeallfromlivescount(); + else if ( isdefined( self.switching_teams ) ) + self.pers["lives"]--; + + decrementalivecount( var_1 ); + return maps\mp\gametypes\_gamelogic::updategameevents(); +} + +decrementalivecount( var_0 ) +{ + level.alivecount[var_0]--; +} + +addtolivescount() +{ + level.livescount[self.team] += self.pers["lives"]; +} + +removefromlivescount() +{ + level.livescount[self.team]--; + level.livescount[self.team] = int( max( 0, level.livescount[self.team] ) ); +} + +removeallfromlivescount() +{ + level.livescount[self.team] -= self.pers["lives"]; + level.livescount[self.team] = int( max( 0, level.livescount[self.team] ) ); +} + +resetuidvarsonspawn() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsonconnect() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientdvar( "ui_eyes_on_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsonspectate() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientdvar( "ui_eyes_on_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsondeath() +{ + +} + +watchforslide() +{ + self endon( "death" ); + self endon( "disconnect" ); + + for (;;) + { + self waittill( "sprint_slide_begin" ); + self playfx( level._effect["slide_dust"], self geteye() ); + } +} diff --git a/iw6x/data/scripts/_team_balance.gsc b/iw6x/data/scripts/_team_balance.gsc new file mode 100644 index 0000000..6866a9c --- /dev/null +++ b/iw6x/data/scripts/_team_balance.gsc @@ -0,0 +1,23 @@ +init() +{ + // define onteamselection callback function used in balanceteams() + level.onteamselection = ::set_team; +} + +set_team(team) +{ + if (team != self.pers["team"]) + { + self.switching_teams = true; + self.joining_team = team; + self.leaving_team = self.pers["team"]; + } + + if (self.sessionstate == "playing") + { + self suicide(); + } + + maps\mp\gametypes\_menus::addtoteam(team); + maps\mp\gametypes\_menus::endrespawnnotify(); +} diff --git a/iw6x/data/sound/patch-3-music.flac b/iw6x/data/sound/patch-3-music.flac new file mode 100644 index 0000000..ad13711 Binary files /dev/null and b/iw6x/data/sound/patch-3-music.flac differ diff --git a/iw6x/data/ui_scripts/main_menu/__init__.lua b/iw6x/data/ui_scripts/main_menu/__init__.lua new file mode 100644 index 0000000..150cfc8 --- /dev/null +++ b/iw6x/data/ui_scripts/main_menu/__init__.lua @@ -0,0 +1,497 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +package.loaded["LUI.mp_menus.MPMainMenu"].main_menu_options_feeder = function( f17_arg0 ) + local f17_local0 = Engine.IsAliensMode() + local f17_local1 = SvS.IsSvS() + local f17_local2 = false + if Engine.GetDvarInt( "allow_online_squads" ) == 1 or not Engine.IsConsoleGame() then + f17_local2 = true + end + local f17_local3 = Engine.DoWeNeedCompatibilityPacks() + if f17_local1 then + local f17_local4 = f17_local2 + end + local f17_local5 = f17_local4 or not f17_local1 + local f17_local6 = {} + if Engine.AllowOnline() and f17_local5 then + local f17_local7, f17_local8 = nil + if f17_local1 then + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_SQUADS_CAPS" ) + f17_local7 = Engine.Localize( "@LUA_MENU_SQUADS_INTRO" ) + elseif f17_local0 then + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_CAPS" ) + f17_local7 = Engine.Localize( "@LUA_MENU_PLAY_EXTINCTION_ONLINE_DESC" ) + else + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_CAPS" ) + f17_local7 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_DESC" ) + end + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_0", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks, + properties = { + button_text = f17_local8, + button_action_func = LUI.mp_menus.MPMainMenu.xboxLiveButtonAction, + desc_text = f17_local7, + button_over_func = function ( f18_arg0, f18_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + end + if Engine.IsConsoleGame() then + local f17_local7 = "@LUA_MENU_SPLITSCREEN_CAPS" + if f17_local0 then + f17_local7 = "@LUA_MENU_LOCAL_CAPS" + elseif f17_local1 then + f17_local7 = "@LUA_MENU_LOCAL_CAPS" + end + local f17_local8 = #f17_local6 + 1 + local f17_local9 = { + type = "UIGenericButton", + id = "btn_MPMain_1", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks + } + local f17_local10 = { + button_text = Engine.Localize( f17_local7 ), + button_action_func = splitScreenButtonAction + } + local f17_local11 + if f17_local1 then + f17_local11 = Engine.Localize( "@LUA_MENU_SQUAD_LOCAL_PLAY_DESC" ) + if not f17_local11 then + + else + f17_local10.desc_text = f17_local11 + f17_local10.button_over_func = function ( f19_arg0, f19_arg1 ) + PersistentBackground.SetToDefault() + end + + f17_local9.properties = f17_local10 + f17_local6[f17_local8] = f17_local9 + if not f17_local1 then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_2", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks, + properties = { + button_text = Engine.Localize( "@PLATFORM_SYSTEM_LINK_CAPS" ), + button_action_func = LUI.mp_menus.MPMainMenu.systemLinkButtonAction, + desc_text = Engine.Localize( "@PLATFORM_SYSTEM_LINK_DESC" ), + button_over_func = function ( f20_arg0, f20_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + end + end + end + f17_local11 = Engine.Localize( "@LUA_MENU_SPLITSCREEN_DESC" ) + end + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_6", + properties = { + button_text = Engine.Localize( "@LUA_MENU_OPTIONS_CAPS" ), + button_action_func = LUI.mp_menus.MPMainMenu.optionsButtonAction, + desc_text = Engine.Localize( "@LUA_MENU_OPTIONS_DESC" ), + button_over_func = function ( f22_arg0, f22_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + f17_local6[#f17_local6 + 1] = { + type = "generic_separator", + id = "main_menu_spacer_id" + } + if not Engine.IsCoreMode() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_7", + properties = { + text = Engine.Localize( "@LUA_MENU_MULTIPLAYER_CAPS" ), + button_action_func = function ( f23_arg0, f23_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToCoreMode() + Engine.PlayMusic( CoD.Music.MainMPMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f24_arg0, f24_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.MPBackground ) + end, + desc_text = Engine.Localize( "@PLATFORM_PLAY_ONLINE_DESC" ) + } + } + end + if not SvS.IsSvS() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_8", + properties = { + button_text = Engine.Localize( "@LUA_MENU_SQUAD_MODE_CAP" ), + button_action_func = function ( f25_arg0, f25_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToSquadVsSquadMode() + Engine.PlayMusic( CoD.Music.MainSquadMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f26_arg0, f26_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.SvSBackground ) + end, + desc_text = Engine.Localize( "@LUA_MENU_SVS_MAIN_MENU_DESC" ) + } + } + end + if not Engine.IsAliensMode() and Engine.UnlockedAliens() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_9", + properties = { + button_text = Engine.Localize( "@LUA_MENU_ALIENS_CAPS" ), + button_action_func = function ( f27_arg0, f27_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToAliensMode() + Engine.PlayMusic( CoD.Music.MainExtinctMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f28_arg0, f28_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.AliensBackground ) + end, + desc_text = Engine.Localize( "@LUA_MENU_ALIENS_MAIN_MENU_DESC" ), + additional_handlers = { + menu_create = AddExtinctionGlowBackground + } + } + } + end + f17_local6[#f17_local6 + 1] = { + type = "button_desc_text", + id = "mp_menu_button_description_id", + properties = { + lines = SvS.IsSvS() and 8 or nil + } + } + return f17_local6 +end + +package.loaded["LUI.mp_menus.MPXboxLiveMenu"].XboxLiveOptionsFeeder = function( f29_arg0 ) + local f29_local0 = Engine.IsAliensMode() + local f29_local1 = SvS.IsSvS() + local f29_local2 = SvS.IsSvS() + if f29_local2 then + f29_local2 = SvS.GetCurrentSquadModeInfo() + end + local f29_local3 = {} + local f29_local4 = nil + if f29_local0 then + f29_local4 = Engine.Localize( "@LUA_MENU_STORE_CAPS" ) -- Orginally @LUA_MENU_PUBLIC_MATCH_CAPS but we need to use @LUA_MENU_STORE_CAPS + elseif f29_local1 then + f29_local4 = Engine.Localize( "@PLATFORM_FIND_GAME_CAPS" ) + else + f29_local4 = Engine.Localize( "@LUA_MENU_STORE_CAPS" ) -- Orginally @PLATFORM_FIND_GAME_CAPS but we need to use @LUA_MENU_STORE_CAPS + end + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "find_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = f29_local4, + button_action_func = FindMatchAction, + desc_text = SvS.IsSvS() and Engine.Localize( "@LUA_MENU_SQUADS_FIND_MATCH_DESC" ) or Engine.Localize( "@LUA_MENU_STORE_DESC" ), -- Orginally @PLATFORM_DESC_FIND_GAME but we need to use @LUA_MENU_STORE_DESC + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + if f29_local0 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "solo_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.shouldDisableSoloMatch(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_SOLO_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.SoloMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_SOLO_MATCH_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.shouldDisableSoloMatch, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "private_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_CUSTOM_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.PrivateMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_PRIVATE_MATCH" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + if not f29_local0 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "create_squad_button_id", + disabled = false, + properties = { + button_text = Engine.Localize( "@LUA_MENU_CREATE_A_CLASS_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.CreateSquadAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CREATE_A_CLASS" ), + additional_handlers = { + refresh_new_icons = function ( f30_arg0, f30_arg1 ) + if Cac.AnyUnseenMDLCItems( Engine.GetFirstActiveController(), NewIconsTable.CACItemTypes ) then + f30_arg0:processEvent( { + name = "show_new_icon" + } ) + end + end + } + } + } + else + f29_local3[#f29_local3 + 1] = LUI.mp_menus.AliensLoadout.GetAliensLoadoutButton() + end + local f29_local5 = { + type = "UIGenericButton", + id = "leaderboards_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_LEADERBOARDS_CAPS" ), + desc_text = Engine.Localize( "@LUA_MENU_DESC_LEADERBOARDS" ), + button_action_func = function ( f31_arg0, f31_arg1 ) + if Engine.IsUserAGuest( f31_arg1.controller ) then + LUI.FlowManager.RequestPopupMenu( f31_arg0, "popup_no_guest", true, f31_arg1.controller ) + else + LUI.FlowManager.RequestAddMenu( f31_arg0, "leaderboards", true, f31_arg1.controller ) + end + end + } + } + if f29_local1 and f29_local2.HasLeaderboard then + f29_local3[#f29_local3 + 1] = f29_local5 + end + if f29_local1 and f29_local2 and f29_local2.HasReports then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "squad_reports_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_SQUAD_REPORTS" ), + desc_text = Engine.Localize( "@LUA_MENU_SQUAD_REPORTS_DESC" ), + button_action_func = function ( f32_arg0, f32_arg1 ) + LUI.FlowManager.RequestAddMenu( f32_arg0, "squad_reports_menu", false, f32_arg1.controller, false, { + controller = f32_arg1.controller + } ) + end + } + } + end + if not f29_local0 and not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "operations_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_OPERATIONS_TITLE" ), + button_action_func = LUI.mp_menus.MPBarracks.BarrackOperationsAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CHALLENGES" ) + } + } + end + if not f29_local0 then + if not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "barracks_button_id", + disabled = false, + properties = { + button_text = Engine.Localize( "@LUA_MENU_BARRACKS_CAPS" ), + button_action_func = BarracksAction, + desc_text = Clan.IsEnabled() and Engine.Localize( "@LUA_MENU_DESC_BARRACKS" ) or Engine.Localize( "@LUA_MENU_DESC_BARRACKS_PRIVATE" ) + } + } + end + if not f29_local1 or f29_local2 ~= SvS.SquadModes.SquadVsSquad then + f29_local3[#f29_local3 + 1] = { + type = "generic_separator" + } + end + if not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "private_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_PRIVATE_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.PrivateMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_PRIVATE_MATCH" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + if f29_local1 then + if f29_local2 == SvS.SquadModes.SquadAssault then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "squad_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "LUA_MENU_CHALLENGE_FRIEND_CAPS" ), + button_action_func = function ( f35_arg0, f35_arg1 ) + if IsFirstTimeFlowRequired( f35_arg1.controller ) then + LUI.FlowManager.RequestAddMenu( f35_arg0, "cac_member_select_main", true, f35_arg1.controller, false, { + next_screen = "cac_edit_main", + squad_location = "squadMembers", + class_location = "loadouts", + findMatch = true + } ) + elseif CheckHasRequiredDLC( f35_arg0 ) then + LUI.FlowManager.RequestPopupMenu( f35_arg0, "popup_friends", true, f35_arg1.controller, false, { + challengeMode = true + } ) + end + end, + desc_text = Engine.Localize( "LUA_MENU_CHALLENGE_FRIEND_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + if f29_local2 and not f29_local2.RequiresMatchmaking then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "play_now_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "LUA_MENU_PLAY_NOW_CAPS" ), + button_action_func = function ( f36_arg0, f36_arg1 ) + f36_arg1.squadsPlayNow = true + FindMatchAction( f36_arg0, f36_arg1 ) + end, + desc_text = Engine.Localize( "LUA_MENU_PLAY_NOW_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + end + end + local f29_local6 = #f29_local3 + 1 + local f29_local7 = { + type = "button_desc_text", + id = "prelobby_description_id" + } + local f29_local8 = {} + local f29_local9 + if not (not SvS.IsSvS() or f29_local2 ~= SvS.SquadModes.SquadAssault) or Engine.IsAliensMode() or Engine.IsCoreMode() then + f29_local9 = 1 + if not f29_local9 then + + else + f29_local8.lines = f29_local9 + f29_local7.properties = f29_local8 + f29_local3[f29_local6] = f29_local7 + f29_local3[#f29_local3 + 1] = { + type = "UITimer", + id = "bnt_lock_tmr", + properties = { + event = "check_buttons", + interval = 500, + disposable = false, + broadcastToRoot = true + } + } + return f29_local3 + end + end + f29_local9 = nil +end + +function FindMatchAction( f5_arg0, f5_arg1 ) + if Lobby.EnteringLobby() == true then + LUI.FlowManager.RequestPopupMenu( f5_arg0, "popup_throttling", true, f5_arg1.controller, false, { + eventData = f5_arg1 + } ) + else + FindMatchAfterThrottleEvent( f5_arg0, f5_arg1 ) + end +end + +function FindMatchAfterThrottleEvent( f4_arg0, f4_arg1 ) + local f4_local0 = false + local f4_local1 = -1 + for f4_local2 = 0, Engine.GetMaxControllerCount() - 1, 1 do + if Engine.HasActiveLocalClient( f4_local2 ) and IsFirstTimeFlowRequired( f4_local2 ) then + f4_local0 = true + if f4_local1 < 0 then + f4_local1 = f4_local2 + end + end + end + if f4_local0 then + LUI.FlowManager.RequestAddMenu( f4_arg0, "cac_member_select_main", true, f4_local1, false, { + next_screen = "cac_edit_main", + squad_location = "squadMembers", + class_location = "loadouts", + findMatch = true + } ) + elseif not LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons() then + Engine.Exec( "xblive_privatematch 0" ) + if Engine.IsAliensMode() then + LUI.mp_menus.Aliens.AliensRunConfig( f4_arg1.controller ) + end + if LUI.mp_menus.MPXboxLiveMenu.CheckHasRequiredDLC( f4_arg0 ) then + if LUI.mp_menus.MPXboxLiveMenu.DisplayLowRepWarning( f4_arg0, f4_arg1 ) then + return + elseif SvS.IsSvS() then + local f4_local3 = SvS.GetCurrentSquadModeInfo() + local f4_local4, f4_local5 = SvS.GetPlaylistFromSquadMode( f4_local3 ) + local f4_local6 = false + if f4_arg1.squadsPlayNow then + f4_local6 = true + end + if not f4_arg1.squadsPlayNow and f4_local3.DynamicMatchmaking then + Playlist.DoAction( f4_local4, f4_local5, true, f4_local6 ) + else + Playlist.DoAction( f4_local4, f4_local5, false, f4_local6 ) + end + if Engine.GetDvarBool( "squad_match" ) then + Squad.StartMatch( f4_arg1.controller, true ) + Engine.SetDvarBool( "squad_find_match", true ) + end + LUI.FlowManager.RequestAddMenu( f4_arg0, "menu_xboxlive_lobby", false, f4_arg1.controller, false ) + else + LUI.FlowManager.RequestPopupMenu( f4_arg0, "menu_systemlink_join" ) -- open server list instead of playlist_main + end + end + end +end + +function BarracksAction( f9_arg0, f9_arg1 ) + LUI.FlowManager.RequestAddMenu( f9_arg0, "menu_stats", true, f9_arg1.controller ) -- custom stats menu +end + +-- Remove social button +LUI.MenuBuilder.m_definitions["online_friends_widget"] = function() + return { + type = "UIElement" + } +end diff --git a/iw6x/data/ui_scripts/server_filter/__init__.lua b/iw6x/data/ui_scripts/server_filter/__init__.lua new file mode 100644 index 0000000..c236356 --- /dev/null +++ b/iw6x/data/ui_scripts/server_filter/__init__.lua @@ -0,0 +1,436 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local Lobby = luiglobals.Lobby + +game:addlocalizedstring("LUA_MENU_SERVER_FILTER_POPUP_INSTR", "Change how the servers are filtered") + +function FiltersPopupClose(f1_arg0, f1_arg1) + local f1_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f1_arg0) + local f1_local1 = LUI.FlowManager.GetMenuScopedDataByMenuName("mp_leaderboard_main") + local f1_local2 = f1_local1.leaderboardType + if f1_local2 and f1_local2 ~= "" then + Leaderboards.OpenLeaderboard(f1_arg0, f1_local2, f1_local0.filterKey, f1_local1.filterDurationKey, f1_local1.isHardcore) + end +end + +function mp_server_filters_popup() + return { + type = "UIElement", + id = "mp_leaderboard_filters_popup_container_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + children = { + { + type = "UIImage", + id = "darken_bg", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + top = 0, + bottom = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + } + }, + { + type = "UIElement", + id = "mp_server_filters_popup_id", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = false, + rightAnchor = false, + top = -1 * Leaderboards.Layout.FilterHeight * 0.6, + width = Leaderboards.Layout.FilterWidth, + height = 170 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "server_filters_popup_title_bar_id", + properties = { + title_bar_text = Engine.Localize("@LUA_MENU_FILTER_CAPS"), + fill_alpha = 1 + } + }, + { + type = "generic_menu_background", + id = "server_filters_popup_background", + properties = { + fill_alpha = 1 + } + }, + { + type = "mp_server_filters_popup_page" + }, + { + type = "UIBindButton", + id = "filters_popup_back_button", + handlers = { + button_secondary = MBh.DoMultiple({ + MBh.LeaveMenu(), + FiltersPopupClose, + ForceRefreshServers + }) + } + } + } + } + } + } +end + +function ForceRefreshServers(f4_arg0, f4_arg1) + local f4_local0 = LUI.FlowManager.GetMenuScopedDataByMenuName("menu_systemlink_join") + f4_local0.serverCount = 0 + if f4_local0.serverList then + local f4_local1 = Lobby.RefreshServerList + local f4_local2 = f4_arg1.controller + if not f4_local2 then + f4_local2 = Engine.GetFirstActiveController() + end + f4_local1(f4_local2) + f4_local0.serverList:processEvent({ + name = "lose_focus", + immediate = true + }) + f4_local0.serverList:clearSavedState() + f4_local0.serverList:processEvent({ + name = "menu_refresh", + dispatchChildren = true + }) + end +end + +function OpenFiltersMenu(f36_arg0, f36_arg1) + LUI.FlowManager.RequestPopupMenu(f36_arg0, "mp_server_filters_popup", true, f36_arg1.controller, false, {}) +end + +LUI.MenuBuilder.registerDef("mp_server_filters_popup", mp_server_filters_popup) + +GameTypeRefCol = 0 +GameTypeNameCol = 1 +GameTypeDescCol = 2 +GameTypeImageCol = 3 + +function GetGametypes() + if Engine.IsCoreMode() then + return { "any", "dm", "war", "sd", "dom", "conf", "sr", "infect", "blitz", "grind", "cranked", "sotf", "sotf_ffa", + "horde", "gun", "grnd", "siege" } + end + return { "aliens" } +end + +function GetLocalizedStringFromGametype(gametype) + if gametype == "any" then + return string.upper(Engine.Localize("LUA_MENU_LB_FILTER_GROUP_ALL")) + end + local gametype_name = Engine.TableLookup("mp/gameTypesTable.csv", GameTypeRefCol, gametype, GameTypeNameCol) + if gametype_name ~= "" then + local token = "@" + local caps_token = "_CAPS" + localized = Engine.Localize(token .. gametype_name .. caps_token) + return localized + end + return "UNKNOWN" +end + +function GetMapnameFromID(id) + if id == "any" then + return string.upper(Engine.Localize("LUA_MENU_LB_FILTER_GROUP_ALL")) + end + + if id == "mp_descent_new" then + return Engine.Localize("@LUA_MENU_MAPNAME_DESCENT_CAPS") + elseif id == "mp_favela_iw6" then + return string.upper(Engine.Localize("@PRESENCE_MP_FAVELA_IW6")) + elseif id == "mp_conflict" then + return string.upper(Engine.Localize("@PRESENCE_MP_CONFLICT")) + elseif id == "mp_mine" then + return string.upper(Engine.Localize("@PRESENCE_MP_MINE")) + elseif id == "mp_shipment_ns" then + return string.upper(Engine.Localize("@PRESENCE_MP_SHIPMENT_NS")) + elseif id == "mp_zerosub" then + return string.upper(Engine.Localize("@PRESENCE_MP_ZEROSUB")) + elseif id == "mp_ca_red_river" then + return string.upper(Engine.Localize("@PRESENCE_MP_CA_RED_RIVER")) + elseif id == "mp_ca_rumble" then + return string.upper(Engine.Localize("@PRESENCE_MP_CA_RUMBLE")) + end + + if id == "mp_alien_town" then + return string.upper(Engine.Localize("@MPUI_ALIEN_TOWN")) + elseif id == "mp_alien_armory" then + return string.upper(Engine.Localize("@MPUI_ALIEN_ARMORY")) + elseif id == "mp_alien_beacon" then + return string.upper(Engine.Localize("@MPUI_ALIEN_BEACON")) + elseif id == "mp_alien_dlc3" then + return string.upper(Engine.Localize("@PRESENCE_MP_ALIEN_DLC3")) + elseif id == "mp_alien_last" then + return string.upper(Engine.Localize("@PRESENCE_MP_ALIEN_LAST")) + end + + return Engine.Localize("@LUA_MENU_MAPNAME_" .. id:sub(4) .. "_CAPS") +end + +function GetMaps() + if Engine.IsCoreMode() then + return { + "any", + "mp_prisonbreak", + "mp_dart", + "mp_lonestar", + "mp_frag", + "mp_snow", + "mp_fahrenheit", + "mp_hashima", + "mp_warhawk", + "mp_sovereign", + "mp_zebra", + "mp_skeleton", + "mp_chasm", + "mp_flooded", + "mp_strikezone", + "mp_descent_new", + "mp_ca_red_river", + "mp_ca_rumble", + "mp_swamp", + "mp_boneyard_ns", + "mp_dome_ns", + "mp_battery3", + "mp_ca_impact", + "mp_ca_behemoth", + "mp_dig", + "mp_zulu", + "mp_pirate", + "mp_favela_iw6", + "mp_zerosub", + "mp_conflict", + "mp_mine", + "mp_shipment_ns", + } + elseif Engine.IsAliensMode() then + return { + "any", + "mp_alien_town", + "mp_alien_armory", + "mp_alien_beacon", + "mp_alien_dlc3", + "mp_alien_last" + } + end + + return { "any" } +end + +function ServerFiltersPopupItems(f7_arg0) + + local rules = {} + if Engine.IsCoreMode() then + local gametype = { + type = "UIGenericButton", + id = "server_filters_gametype", + properties = { + style = GenericButtonSettings.Styles.GlassButton, + substyle = GenericButtonSettings.Styles.GlassButton.SubStyles.SubMenu, + variant = GenericButtonSettings.Variants.Select, + content_width = 258, + side = "left", + button_text = Engine.Localize("@LUA_MENU_MODE_CAPS"), + button_display_func = function(f8_arg0, f8_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f8_arg0) + if focusedElement.filterGametypeKey == nil then + focusedElement.filterGametypeKey = Engine.GetDvarString("ui_mapvote_entrya_gametype") + end + Engine.SetDvarString("ui_mapvote_entrya_gametype", focusedElement.filterGametypeKey) + return Engine.Localize(GetLocalizedStringFromGametype(focusedElement.filterGametypeKey)) + end, + button_left_func = function(f9_arg0, f9_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f9_arg0) + local keys = GetGametypes() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterGametypeKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI - 1 + if defaultKeysI < 1 then + focusedElement.filterGametypeKey = keys[#keys] + else + focusedElement.filterGametypeKey = keys[defaultKeysI] + end + end, + button_right_func = function(f10_arg0, f10_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f10_arg0) + local keys = GetGametypes() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterGametypeKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI + 1 + if #keys < defaultKeysI then + focusedElement.filterGametypeKey = keys[1] + else + focusedElement.filterGametypeKey = keys[defaultKeysI] + end + end + } + } + table.insert(rules, gametype) + end + + local maps = { + type = "UIGenericButton", + id = "server_filters_map", + properties = { + style = GenericButtonSettings.Styles.GlassButton, + substyle = GenericButtonSettings.Styles.GlassButton.SubStyles.SubMenu, + variant = GenericButtonSettings.Variants.Select, + content_width = 258, + side = "left", + button_text = Engine.Localize("@LUA_MENU_MAPS_CAPS"), + button_display_func = function(f8_arg0, f8_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f8_arg0) + if focusedElement.filterMapnameKey == nil then + focusedElement.filterMapnameKey = Engine.GetDvarString("ui_mapvote_entrya_mapname") + end + Engine.SetDvarString("ui_mapvote_entrya_mapname", focusedElement.filterMapnameKey) + return GetMapnameFromID(focusedElement.filterMapnameKey) + end, + button_left_func = function(f9_arg0, f9_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f9_arg0) + local keys = GetMaps() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterMapnameKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI - 1 + if defaultKeysI < 1 then + focusedElement.filterMapnameKey = keys[#keys] + else + focusedElement.filterMapnameKey = keys[defaultKeysI] + end + end, + button_right_func = function(f10_arg0, f10_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f10_arg0) + local keys = GetMaps() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterMapnameKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI + 1 + if #keys < defaultKeysI then + focusedElement.filterMapnameKey = keys[1] + else + focusedElement.filterMapnameKey = keys[defaultKeysI] + end + end + } + } + table.insert(rules, maps) + + return rules +end + +function mp_server_filters_popup_page() + return { + type = "UIElement", + id = "mp_server_filters_popup_page_id", + properties = {}, + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = AAR.Layout.TitleBarHeight + 1, + bottom = -1, + left = 1, + right = -1, + } + }, + children = { + { + type = "UIText", + id = "leaderboard_filters_instruction", + properties = { + text = Engine.Localize("@LUA_MENU_SERVER_FILTER_POPUP_INSTR") + }, + states = { + default = { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 10, + bottom = 10 + CoD.TextSettings.NormalFont.Height, + left = 75, + right = -75, + alignment = LUI.Alignment.Center, + font = CoD.TextSettings.NormalFont.Font, + red = Colors.white.r, + green = Colors.white.g, + blue = Colors.white.b + } + } + }, + { + type = "UIVerticalList", + id = "server_filters_popup_vlist", + states = { + default = { + topAnchor = false, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = -75, + bottom = 0, + left = 2, + right = -2, + spacing = 5 + } + }, + childrenFeeder = ServerFiltersPopupItems + } + } + } +end + +LUI.MenuBuilder.registerDef("mp_server_filters_popup_page", mp_server_filters_popup_page) diff --git a/iw6x/data/ui_scripts/server_list/__init__.lua b/iw6x/data/ui_scripts/server_list/__init__.lua new file mode 100644 index 0000000..9e8942c --- /dev/null +++ b/iw6x/data/ui_scripts/server_list/__init__.lua @@ -0,0 +1,636 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local Lobby = luiglobals.Lobby +local SystemLinkJoinMenu = LUI.mp_menus.SystemLinkJoinMenu + +local controller = nil +local server = nil + +COLUMN_0 = 0 +COLUMN_1 = 460 +COLUMN_2 = 660 +COLUMN_3 = 800 +COLUMN_4 = 985 +COLUMN_5 = 500 + +SystemLinkJoinMenu.UpdateGameList = function(f3_arg0, f3_arg1) + local f3_local0 = f3_arg1.controller + if not f3_local0 then + f3_local0 = Engine.GetFirstActiveController() + end + local f3_local1 = LUI.FlowManager.GetMenuScopedDataFromElement(f3_arg0) + Lobby.UpdateServerDisplayList(f3_local0) + local f3_local2 = Lobby.GetServerCount(f3_local0) + if f3_local2 ~= f3_local1.serverCount then + f3_local1.serverCount = f3_local2 + f3_arg0:processEvent({ + name = "menu_refresh", + immediate = true + }) + f3_arg0:processEvent({ + name = "gain_focus", + immediate = true + }) + end +end + +SystemLinkJoinMenu.RefreshServers = function(f4_arg0, f4_arg1) + local f4_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f4_arg0) + f4_local0.serverCount = 0 + if f4_local0.serverList then + local f4_local1 = Lobby.RefreshServerList + local f4_local2 = f4_arg1.controller + if not f4_local2 then + f4_local2 = Engine.GetFirstActiveController() + end + f4_local1(f4_local2) + f4_local0.serverList:processEvent({ + name = "lose_focus", + immediate = true + }) + f4_local0.serverList:clearSavedState() + f4_local0.serverList:processEvent({ + name = "menu_refresh", + dispatchChildren = true + }) + end +end + +function CreateColumnImage(id, shader, leftAnchor, rightAnchor, left, alpha) + return { + type = "UIImage", + id = id, + states = { + default = { + font = CoD.TextSettings.NormalFont.Font, + alignment = LUI.Alignment.right, + height = 20, + width = 20, + left = left, + red = Colors.cac_label_text.r, + green = Colors.cac_label_text.g, + blue = Colors.cac_label_text.b, + alpha = alpha, + material = RegisterMaterial(shader) + }, + }, + handlers = { + button_over = MBh.AnimateToState("over"), + button_up = MBh.AnimateToState("default"), + button_disable = MBh.AnimateToState("disabled") + } + } +end + +SystemLinkJoinMenu.CreateHeaderDef = function() + local header = { + type = "UIElement", + id = "header_row_id", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 2, + left = 2, + right = -2, + height = GenericTitleBarDims.TitleBarHeight, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + }, + } + + local columns = {} + table.insert(columns, SystemLinkJoinMenu.CreateRowBackground(SystemLinkJoinMenu.Colors.generic_menu_bg_color)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_id", false, COLUMN_1, COLUMN_2)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_2_id", true, COLUMN_3, -1)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("host_header", Engine.Localize("@MENU_HOST_NAME"), true, false, COLUMN_0, COLUMN_1)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("map_header", Engine.Localize("@MENU_MAP"), true, false, COLUMN_1, COLUMN_2)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("players_header", Engine.Localize("@MENU_NUMPLAYERS"), true, false, COLUMN_2, COLUMN_3)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("type_header", Engine.Localize("@MENU_TYPE1"), true, true, COLUMN_3, COLUMN_4)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("ping_header", Engine.Localize("@MENU_PING"), true, true, COLUMN_4, COLUMN_5)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnImage("protected_header", "icon_lock", true, true, COLUMN_5, 1)) + header.children = columns + return header +end + +SystemLinkJoinMenu.CreateRowDef = function(f6_arg0, f6_arg1, f6_arg2, f6_arg3) + local option = { + type = "UIButton", + id = "row_" .. f6_arg1, + disabled = f6_arg2, + focusable = not f6_arg2, + properties = { + button_height = GenericButtonDims.button_height + }, + states = { + default = { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = MBh.Property("button_height"), + left = 0, + right = 0 + } + }, + handlers = { + button_action = MBh.EmitEventToRoot({ + name = "select_game", + idx = f6_arg1 + }) + } + } + + local columns = {} + table.insert(columns, SystemLinkJoinMenu.CreateRowBackground(f6_arg3)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_id", false, COLUMN_1, COLUMN_2)) + local shade = SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_2_id", true, COLUMN_3, -1) + table.insert(columns, shade) + local hostname = SystemLinkJoinMenu.CreateColumnText("host_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Host), true, false, COLUMN_0, COLUMN_1) + table.insert(columns, hostname) + local mapname = SystemLinkJoinMenu.CreateColumnText("map_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Map), true, false, COLUMN_1, COLUMN_2) + table.insert(columns, mapname) + local players = SystemLinkJoinMenu.CreateColumnText("players_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Clients), true, false, COLUMN_2, COLUMN_3) + table.insert(columns, players) + local gametype = SystemLinkJoinMenu.CreateColumnText("type_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Game), true, true, COLUMN_3, COLUMN_4) + table.insert(columns, gametype) + local ping = SystemLinkJoinMenu.CreateColumnText("ping_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Ping), true, true, COLUMN_4, COLUMN_5) + table.insert(columns, ping) + local is_private = SystemLinkJoinMenu.CreateColumnImage("protected_header", "icon_lock", true, true, COLUMN_5, Lobby.GetServerData(f6_arg0, f6_arg1, 5) == "1" and 1 or 0) + table.insert(columns, is_private) + option.children = columns + return option +end + +SystemLinkJoinMenu.OnCreate = function(f1_arg0, f1_arg1) + local f1_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f1_arg0) + f1_local0.serverCount = 0 + f1_arg0:processEvent(LUI.ButtonHelperText.CommonEvents.addBackButton) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_action", + helper_text = Engine.Localize("@MENU_JOIN_GAME1"), + side = "left", + clickable = true + }) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_alt1", + helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), + side = "left", + clickable = true + }) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_alt2", + helper_text = Engine.Localize("@LUA_MENU_FILTER"), + side = "right", + clickable = true + }) + local f1_local1 = Lobby.BuildServerList + local f1_local2 = f1_arg1.controller + if not f1_local2 then + f1_local2 = Engine.GetFirstActiveController() + end + f1_local1(f1_local2) +end + +function ServerListBackground() + if Engine.IsAliensMode() then + return { + image = "frontend_aliens_art", + fill_color = { + r = 1, + g = 1, + b = 1 + }, + fill_alpha = 1 + } + end + + if Engine.IsCoreMode() then + return { + image = "white", + fill_color = { + r = 0.07, + g = 0.1, + b = 0.11 + }, + fill_alpha = 1 + } + end +end + +function JoinGame(f2_arg0, f2_arg1) + server = f2_arg1 + controller = server.controller + if not f2_local1 then + controller = Engine.GetFirstActiveController() + end + + local is_private = Lobby.GetServerData(controller, server.idx, 5) + if is_private == "1" then + LUI.FlowManager.RequestPopupMenu(server, "server_password_field", false, controller, false) + else + Lobby.JoinServer(controller, server.idx) + end +end + +SystemLinkJoinMenu.menu_systemlink_join = function() + if Engine.IsCoreMode() then + Engine.SetDvarString("ui_customModeName", "mp") + elseif Engine.IsAliensMode() then + Engine.SetDvarString("ui_customModeName", "aliens") + end + + if Engine.GetDvarString("ui_mapvote_entrya_gametype") == nil + or Engine.GetDvarString("ui_mapvote_entrya_gametype") then + Engine.SetDvarString("ui_mapvote_entrya_gametype", "any") + end + + if Engine.GetDvarString("ui_mapvote_entrya_mapname") == nil + or Engine.GetDvarString("ui_mapvote_entrya_mapname") == "" + or (string.match(Engine.GetDvarString("ui_mapvote_entrya_mapname"), "alien") == nil and Engine.IsAliensMode()) + or (string.match(Engine.GetDvarString("ui_mapvote_entrya_mapname"), "alien") == "alien" and Engine.IsCoreMode()) then + Engine.SetDvarString("ui_mapvote_entrya_mapname", "any") + end + + return { + type = "UIElement", + id = "menu_systemlink_join_root", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + handlers = { + menu_create = SystemLinkJoinMenu.OnCreate, + select_game = JoinGame + }, + children = { + { + type = "UIImage", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore, + }) + } + }, + { + type = "UIElement", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + left = 200, + right = -200, + height = 550 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "menu_systemlink_join_title_id", + properties = { + fill_alpha = 1, + font = CoD.TextSettings.BoldFont, + title_bar_text = Engine.Localize("@PLATFORM_SYSTEM_LINK_TITLE"), + title_bar_text_indent = GenericTitleBarDims.TitleBarLCapWidth, + title_bar_alignment = LUI.Alignment.Left + } + }, + { + type = "generic_menu_background", + id = "menu_systemlink_join_bg_id", + properties = { + fill_alpha = Swatches.Overlay.AlphaMore, + }, + children = { + SystemLinkJoinMenu.CreateHeaderDef(), + { + type = "UIVerticalList", + id = "menu_systemlink_join_game_list_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = GenericTitleBarDims.TitleBarHeight + 4, + bottom = 600, + left = 2, + right = -2 + } + }, + childrenFeeder = SystemLinkJoinMenu.LinkGamesFeeder, + handlers = { + update_game_list = SystemLinkJoinMenu.UpdateGameList, + menu_create = function(f12_arg0, f12_arg1) + local f12_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f12_arg0) + f12_local0.serverList = f12_arg0 + SystemLinkJoinMenu.RefreshServers(f12_arg0, f12_arg1) + end + + } + }, + { + type = "button_helper_text_main", + id = "online_vault_helper_text_id", + properties = { + left_inset = 10, + right_inset = -10, + top_margin = GenericFooterDims.TopMargin_WithoutBackground, + height = 42, + spacing = 12, + background_alpha = 0 + } + } + } + } + } + }, + { + type = "UITimer", + id = "menu_systemlink_join_update_timer", + properties = { + event = "update_game_list", + interval = 250, + disposable = false, + broadcastToRoot = true + } + }, + { + type = "UIBindButton", + id = "menu_systemlink_join_bind_button_id", + handlers = { + button_secondary = MBh.LeaveMenu(), + button_alt1 = SystemLinkJoinMenu.RefreshServers, + button_alt2 = OpenFiltersMenu + } + }, + } + } +end + + +LUI.MenuBuilder.m_definitions["menu_systemlink_join"] = function() + local menu = SystemLinkJoinMenu.menu_systemlink_join() + + local rows = menu.children[2].children[3].children + local header = rows[1] + + + -- Increase server list width + menu.children[2].states.default.left = 100 + menu.children[2].states.default.right = -100 + + menu.children[3].properties.interval = 10 -- 250 + + return menu +end + +ServerPaswordListFeeder = function() + return { + { + type = "UIVerticalList", + id = "password_field_items", + states = { + default = { + topAnchor = true, + leftAnchor = true, + bottomAnchor = false, + rightAnchor = true, + } + }, + children = { + { + type = "UIGenericButton", + id = "password_button_id", + properties = { + variant = GenericButtonSettings.Variants.Plain, + button_text = Engine.Localize("PATCH_MENU_CHANGE_PASSWORD_CAPS"), + button_display_func = function() + local f31_local0 = Engine.GetDvarString("password") + if f31_local0 then + f31_local0 = Engine.GetDvarString("password") ~= "" + end + local f31_local1 + if f31_local0 then + f31_local1 = Engine.Localize("PATCH_MENU_PASSWORD_SET") + if not f31_local1 then + + else + return f31_local1 + end + end + f31_local1 = Engine.Localize("MENU_NONE") + end, + button_action_func = function(f32_arg0, f32_arg1) + Engine.ExecNow("setfromdvar ui_password password") + Engine.OpenScreenKeyboard(f32_arg1.controller, Engine.Localize("MENU_PASSWORD"), Engine.GetDvarString("ui_password") or "", Lobby.PasswordLength, false, false, CoD.KeyboardInputTypes.Password) + end + }, + handlers = { + text_input_complete = function(f33_arg0, f33_arg1) + if f33_arg1.text then + Engine.SetDvarString("password", f33_arg1.text) + f33_arg0:processEvent({ + name = "content_refresh" + }) + end + end + } + }, + { + type = "UIGenericButton", + id = "connect_button_id", + properties = { + variant = GenericButtonSettings.Variants.Plain, + button_text = Engine.Localize("MENU_JOIN_GAME"), button_action_func = function() + Lobby.JoinServer(controller, server.idx) + end + } + + } + } + } + } +end + +password_field = function(f50_arg0, f50_arg1) + return { + type = "UIElement", + id = "server_popup_container_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + children = { + { + type = "UIImage", + id = "darken_bg", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + top = 0, + bottom = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + } + }, + { + type = "UIElement", + id = "mp_server_filters_popup_id", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = false, + rightAnchor = false, + top = -1 * Leaderboards.Layout.FilterHeight * 0.6, + width = Leaderboards.Layout.FilterWidth, + height = 145 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "server_filters_popup_title_bar_id", + properties = { + title_bar_text = Engine.Localize("@LUA_MENU_LOBBY_JOINING"), + fill_alpha = 1 + } + }, + { + type = "generic_menu_background", + id = "server_filters_popup_background", + properties = { + fill_alpha = 1 + } + }, + { + type = "UIElement", + id = "mp_server_password_popup_page_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = AAR.Layout.TitleBarHeight + 1, + bottom = -1, + left = 1, + right = -1, + } + }, + children = { + { + type = "generic_border", + properties = { + thickness = 2, + border_red = Colors.generic_menu_frame_color.r, + border_green = Colors.generic_menu_frame_color.g, + border_blue = Colors.generic_menu_frame_color.b + }, + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0, + alpha = 0.6 + } + } + }, + { + type = "UIVerticalList", + id = "server_filters_popup_vlist", + states = { + default = { + topAnchor = false, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = -90, + bottom = 0, + left = 0, + right = 0, + spacing = 5 + } + }, + childrenFeeder = ServerPaswordListFeeder + } + } + }, + { + type = "UIBindButton", + id = "filters_popup_back_button", + handlers = { + button_secondary = MBh.DoMultiple({ + MBh.LeaveMenu(), + FiltersPopupClose, + ForceRefreshServers + }) + } + } + } + } + } + } +end + +LUI.MenuBuilder.registerDef("server_password_field", password_field) diff --git a/iw6x/data/ui_scripts/stats/__init__.lua b/iw6x/data/ui_scripts/stats/__init__.lua new file mode 100644 index 0000000..af09c63 --- /dev/null +++ b/iw6x/data/ui_scripts/stats/__init__.lua @@ -0,0 +1,167 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +game:addlocalizedstring("LUA_MENU_UNLOCKALL", "UNLOCK ALL") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_DESC", + "Whether all items should be unlocked.") + +function UnlockAllAction( f1_arg0, f1_arg1 ) + Engine.Exec("unlockstats") +end + +function StatsButtonHelper( f2_arg0, f2_arg1 ) + f2_arg0:processEvent( LUI.ButtonHelperText.CommonEvents.addBackButton ) +end + +function BarrackPrestigeResetStatsAction( f3_arg0, f3_arg1 ) + LUI.FlowManager.RequestAddMenu( f3_arg0, "prestige_reset", true, f3_arg1.controller ) +end + +function menu_stats() + return { + type = "UIElement", + id = "menu_stats_root", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + handlers = { + menu_create = StatsButtonHelper, + }, + children = { + { + type = "generic_menu_title", + id = "stats_title_text_id", + properties = { + menu_title = Engine.Localize( "@LUA_MENU_BARRACKS_CAPS" ) + } + }, + { + type = "UIVerticalList", + id = "stats_options_vlist_id", + states = { + default = { + alignment = LUI.Alignment.Top, + leftAnchor = true, + rightAnchor = false, + topAnchor = true, + bottomAnchor = false, + left = GenericMenuDims.menu_left, + right = GenericMenuDims.menu_right, + top = GenericMenuDims.menu_top, + bottom = GenericMenuDims.menu_bottom + } + }, + childrenFeeder = StatsOptionsFeeder + }, + { + type = "button_helper_text_main", + id = "stats_button_helper_text_id" + }, + { + type = "UIBindButton", + id = "stats_bind_buttons_id", + handlers = { + button_secondary = MBh.LeaveMenu() + } + }, + } + } +end + +function StatsOptionsFeeder( f8_arg0 ) + local f8_local4 = {} + local f8_local0 = Engine.IsAliensMode() + local f8_local2 = Engine.InLobby() + local f8_local3 = f8_arg0.exclusiveController + f8_local4[#f8_local4 + 1] = { + type = "UIGenericButton", + id = "unlockall_items_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_UNLOCKALL" ), + button_action_func = UnlockAllAction, + desc_text = Engine.Localize( "@LUA_MENU_UNLOCKALL_DESC" ) + } + } + if not f8_local2 then + local f8_local5 = #f8_local4 + 1 + local f8_local6 = { + type = "UIGenericButton", + id = "reset_stats_button_id" + } + local f8_local7 + if Cac.GetPrestigeLevel( f8_local3, Cac.GetSquadLoc() ) == 10 then + f8_local7 = Engine.IsUserAGuest( f8_local3 ) + else + f8_local7 = true + end + f8_local6.disabled = f8_local7 + f8_local6.properties = { + button_text = Engine.Localize( "@LUA_MENU_MP_RESET_STATS_CAPS" ), + button_action_func = BarrackPrestigeResetStatsAction, + desc_text = Engine.Localize( "@LUA_MENU_MP_RESET_STATS_DESC" ) + } + f8_local6.handlers = { + element_refresh = function ( f12_arg0, f12_arg1 ) + local f12_local0 + if Cac.GetPrestigeLevel( f8_local3, Cac.GetSquadLoc() ) == 10 then + f12_local0 = Engine.IsUserAGuest( f8_local3 ) + else + f12_local0 = true + end + local f12_local1 = f12_arg0 + local f12_local2 = f12_arg0.processEvent + local f12_local3 = {} + local f12_local4 + if f12_local0 then + f12_local4 = "disable" + if not f12_local4 then + + else + f12_local3.name = f12_local4 + f12_local2( f12_local1, f12_local3 ) + end + end + f12_local4 = "enable" + end + } + f8_local4[f8_local5] = f8_local6 + end + f8_local4[#f8_local4 + 1] = { + type = "button_desc_text", + id = "stats_button_description_id" + } + return f8_local4 +end + +function stats_options_vlist() + return { + type = "UIVerticalList", + focusable = true, + states = { + default = { + alignment = LUI.Alignment.Top, + leftAnchor = true, + rightAnchor = false, + topAnchor = true, + bottomAnchor = false, + left = GenericMenuDims.menu_left, + right = GenericMenuDims.menu_right, + top = GenericMenuDims.menu_top, + bottom = GenericMenuDims.menu_bottom + } + } + } +end + +LUI.MenuBuilder.registerDef( "menu_stats", menu_stats ) +LUI.MenuBuilder.registerDef( "stats_options_vlist", stats_options_vlist ) diff --git a/iw6x/data/ui_scripts/team_select/__init__.lua b/iw6x/data/ui_scripts/team_select/__init__.lua new file mode 100644 index 0000000..f482e6b --- /dev/null +++ b/iw6x/data/ui_scripts/team_select/__init__.lua @@ -0,0 +1,101 @@ +if (game:issingleplayer()) then + return +end + +if (package.loaded["LUI.mp_hud.OptionsMenu"] == nil) then + return +end + +package.loaded["LUI.mp_hud.OptionsMenu"].options_def = function() + local f14_local0 = GameX.GetGameMode() + local f14_local1 = Engine.TableLookup( GameTypesTable.File, GameTypesTable.Cols.Ref, f14_local0, GameTypesTable.Cols.ClassChoice ) == "1" + + if not f14_local1 then + f14_local1 = GameX.UsesFakeLoadout() + end + + local f14_local2 = LUI.mp_hud.OptionsMenu.checkTeamChoice( f14_local0 ) + local f14_local3 = GameX.IsRankedMatch() + local f14_local4 = Engine.GetDvarBool( "splitscreen_ingame" ) + local f14_local5 = Game.GetOmnvar( "ui_team_selected" ) + local f14_local6 = Game.GetOmnvar( "ui_loadout_selected" ) + local f14_local7 = LUI.mp_hud.OptionsMenu.chooseClassCheck( f14_local3, f14_local5, f14_local2 ) + local self = LUI.UIVerticalList.new() + self.id = "pause_selections_Id" + + self:registerAnimationState("default", { + topAnchor = true, + leftAnchor = true, + bottomAnchor = false, + rightAnchor = false, + top = GenericMenuDims.menu_top, + left = GenericMenuDims.menu_left, + bottom = GenericMenuDims.menu_bottom, + right = GenericMenuDims.menu_right, + alignment = LUI.Alignment.Top + }) + + self:animateToState( "default", 0 ) + self:makeFocusable() + + if f14_local0 ~= "aliens" and false == CoD.IsFireTeamMode() and GameX.IsSpectatingNotOnTeam() == false and f14_local1 == true and f14_local7 == true and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_0", + properties = { + childNum = 1, + button_text = Engine.Localize( "@LUA_MENU_CHOOSE_CLASS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.chooseClassButtonAction + } + }) + end + + if f14_local0 ~= "aliens" and false == CoD.IsFireTeamMode() and f14_local2 == true and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_1", + properties = { + childNum = 2, + button_text = Engine.Localize( "@LUA_MENU_CHANGE_TEAM_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.changeTeamButtonAction + } + }) + end + + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_2", + disabledFunc = LUI.mp_hud.OptionsMenu.optionsLockedUpdate, + properties = { + childNum = 3, + button_text = Engine.Localize( "@LUA_MENU_OPTIONS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.optionsButtonAction + }, + handlers = { + refresh_options_button = LUI.mp_hud.OptionsMenu.refreshOptionDisable + } + }) + + if GameX.IsOnlineMatch() and (not Engine.IsAliensMode() or not Game.GetOmnvar( "ui_alien_is_solo" )) and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_3", + properties = { + childNum = 4, + button_text = Engine.Localize( "@LUA_MENU_MUTE_PLAYERS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.mutePlayersButtonAction + } + }) + end + + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_5", + properties = { + childNum = 6, + button_text = Engine.Localize( "@LUA_MENU_END_GAME_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.endGameButtonAction + } + }) + return self +end diff --git a/iw6x/iw6x.exe b/iw6x/iw6x.exe new file mode 100644 index 0000000..626143f Binary files /dev/null and b/iw6x/iw6x.exe differ diff --git a/launcher/IWX Launcher.exe b/launcher/IWX Launcher.exe new file mode 100644 index 0000000..edf487f Binary files /dev/null and b/launcher/IWX Launcher.exe differ diff --git a/localappdata/xlabs/data/cef/release/chrome_100_percent.pak b/localappdata/xlabs/data/cef/release/chrome_100_percent.pak new file mode 100644 index 0000000..c96d4eb Binary files /dev/null and b/localappdata/xlabs/data/cef/release/chrome_100_percent.pak differ diff --git a/localappdata/xlabs/data/cef/release/chrome_200_percent.pak b/localappdata/xlabs/data/cef/release/chrome_200_percent.pak new file mode 100644 index 0000000..cc80fd5 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/chrome_200_percent.pak differ diff --git a/localappdata/xlabs/data/cef/release/chrome_elf.dll b/localappdata/xlabs/data/cef/release/chrome_elf.dll new file mode 100644 index 0000000..cd73399 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/chrome_elf.dll differ diff --git a/localappdata/xlabs/data/cef/release/d3dcompiler_47.dll b/localappdata/xlabs/data/cef/release/d3dcompiler_47.dll new file mode 100644 index 0000000..e82d8c7 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/d3dcompiler_47.dll differ diff --git a/localappdata/xlabs/data/cef/release/icudtl.dat b/localappdata/xlabs/data/cef/release/icudtl.dat new file mode 100644 index 0000000..9e23f17 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/icudtl.dat differ diff --git a/localappdata/xlabs/data/cef/release/libEGL.dll b/localappdata/xlabs/data/cef/release/libEGL.dll new file mode 100644 index 0000000..eb3a592 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/libEGL.dll differ diff --git a/localappdata/xlabs/data/cef/release/libGLESv2.dll b/localappdata/xlabs/data/cef/release/libGLESv2.dll new file mode 100644 index 0000000..94a7cc0 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/libGLESv2.dll differ diff --git a/localappdata/xlabs/data/cef/release/libcef.dll b/localappdata/xlabs/data/cef/release/libcef.dll new file mode 100644 index 0000000..aada029 --- /dev/null +++ b/localappdata/xlabs/data/cef/release/libcef.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62ea61213fdbfa7a712ba65685d638dc394f11784ae41e637b71ca5e0c2879d1 +size 196779520 diff --git a/localappdata/xlabs/data/cef/release/locales/en-US.pak b/localappdata/xlabs/data/cef/release/locales/en-US.pak new file mode 100644 index 0000000..a693a19 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/locales/en-US.pak differ diff --git a/localappdata/xlabs/data/cef/release/resources.pak b/localappdata/xlabs/data/cef/release/resources.pak new file mode 100644 index 0000000..518e735 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/resources.pak differ diff --git a/localappdata/xlabs/data/cef/release/snapshot_blob.bin b/localappdata/xlabs/data/cef/release/snapshot_blob.bin new file mode 100644 index 0000000..9372a94 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/snapshot_blob.bin differ diff --git a/localappdata/xlabs/data/cef/release/v8_context_snapshot.bin b/localappdata/xlabs/data/cef/release/v8_context_snapshot.bin new file mode 100644 index 0000000..5806f84 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/v8_context_snapshot.bin differ diff --git a/localappdata/xlabs/data/cef/release/vk_swiftshader.dll b/localappdata/xlabs/data/cef/release/vk_swiftshader.dll new file mode 100644 index 0000000..c146ebc Binary files /dev/null and b/localappdata/xlabs/data/cef/release/vk_swiftshader.dll differ diff --git a/localappdata/xlabs/data/cef/release/vulkan-1.dll b/localappdata/xlabs/data/cef/release/vulkan-1.dll new file mode 100644 index 0000000..12df5d6 Binary files /dev/null and b/localappdata/xlabs/data/cef/release/vulkan-1.dll differ diff --git a/localappdata/xlabs/data/iw4x/iw4x-sp.exe b/localappdata/xlabs/data/iw4x/iw4x-sp.exe new file mode 100644 index 0000000..f35f3d5 Binary files /dev/null and b/localappdata/xlabs/data/iw4x/iw4x-sp.exe differ diff --git a/localappdata/xlabs/data/iw4x/iw4x.dll b/localappdata/xlabs/data/iw4x/iw4x.dll new file mode 100644 index 0000000..996fc3d Binary files /dev/null and b/localappdata/xlabs/data/iw4x/iw4x.dll differ diff --git a/localappdata/xlabs/data/iw6x/data/dw/entitlement_config_tu14.info b/localappdata/xlabs/data/iw6x/data/dw/entitlement_config_tu14.info new file mode 100644 index 0000000..1bae79a --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/dw/entitlement_config_tu14.info @@ -0,0 +1,228 @@ +version 7 + +// Entitlement ID Ranges +// 0 - 299 ??? +// 300 - 399 Clan Entitlements +// 400 - 599 ??? +// 600 - 699 Clan War Entitlements +// 700 - 799 Generic Elite Entitlements + +// Number of keys to read from the key archive +keys_to_read 16 + +// unlocks in game - type, key index, bit, name, payload... +unlock 0 0 600 //clan wars demon_skull_p +unlock 0 1 601 //clan wars dead_ninja_p +unlock 0 2 602 //clan wars mummy_p +unlock 0 3 603 //clan wars skull_bow_p +unlock 0 4 604 //clan wars cyclops_skull_p +unlock 0 5 605 //clan wars dead_gnome_p +unlock 0 6 606 //clan wars gold_grill_p +unlock 0 7 607 //clan wars pirate_skull_p +unlock 0 8 608 //clan wars gargoyle_p +unlock 0 9 609 //clan wars vulture_p +unlock 0 10 610 //clan wars warrior_mask_p +unlock 0 11 611 //clan wars yeti_p +unlock 0 12 612 //clan wars dead_owl_p +unlock 0 13 613 //clan wars money_bags_p +unlock 0 14 614 //clan wars injured_octopus_p +unlock 0 15 615 //clan wars hotdog_p +unlock 0 16 616 //clan wars crab_p +unlock 0 17 617 //clan wars angry_robot_p +unlock 0 18 618 //clan wars triangle_dot_ret +unlock 0 19 619 //clan wars gold_chain_emb +unlock 0 20 620 //clan wars wing_emb +unlock 0 21 621 //clan wars brass_knuck_emb +unlock 0 22 622 //clan wars ninja_emb +unlock 0 25 623 //clan wars reaper head +unlock 0 26 624 //clan wars merc head +unlock 0 27 625 //clan wars body +unlock 0 28 460 //clan wars diamond division reticle +unlock 0 29 401 //clan wars diamond division camo +unlock 0 30 627 //clan wars diamond division assassin head +unlock 0 31 626 //clan wars diamond division savage head +unlock 0 32 628 //clan wars diamond division body + +unlock 3 0 700 //Download the mobile app +unlock 3 1 701 //Founder Skull + +unlock 3 4 500 //NEVERSOFT +unlock 3 3 501 //IW +unlock 3 5 502 //RAVEN +unlock 3 7 503 //HIGH_MOON +unlock 3 6 504 //BEACHHEAD + +unlock 13 0 209 //monster beast patch +unlock 13 2 210 //monster beast playercard +unlock 13 1 211 //monster viper patch +unlock 13 3 212 //monster viper playercard + +unlock 13 4 216 //riley / classic ghost head + +unlock 13 30 217 //watcher patch +unlock 13 31 213 //federation patch +unlock 13 32 215 //into the deep patch +unlock 13 33 214 //no man's land patch + +//Platform Unlocks +platform 200 255161 //team leader head +platform 201 255161 //team leader playercard +platform 202 255161 //team leader patch +platform 403 255161 //team leader camo +platform 451 255161 //team leader reticle + +platform 200 255160 //team leader head +platform 201 255160 //team leader playercard +platform 202 255160 //team leader patch +platform 403 255160 //team leader camo +platform 451 255160 //team leader reticle + +platform 206 255162 //insignia playercard +platform 205 255162 //insignia patch + +platform 216 255165 //classic ghost character + +platform 213 255167 //federation patch +platform 214 255168 //no mans land patch +platform 215 255169 //into the deep patch + +platform 207 255163 //digital hardened patch +platform 208 255163 //digital hardened playercard + +platform 217 255166 //Steam Patch - The Watcher + +platform 222 268100 //festive playercard +platform 221 268100 //festive patch +platform 410 268100 //festive camo +platform 453 268100 //festive reticle + +platform 550 268101 //wolf + +platform 551 277670 //extra slots + +platform 552 277671 // hero character - elias +platform 553 277672 // hero character - hesh +platform 554 277673 // hero character - merrick +platform 555 277674 // hero character - keegan +platform 556 277675 // hero character - price + +platform 557 281343 // Hazmat character +platform 558 281340 // Makarov Legend Pack +platform 559 281342 // Rorke Character +platform 560 281341 // Zakhaev Character + +platform 561 286632 // Soap Legend Pack +platform 562 286633 // Extinction Squad +platform 563 286634 // TF141 + +platform 490 277676 // Personalization pack 1 - Ducky +platform 491 277677 // Personalization pack 2 - Blood +platform 492 277678 // Personalization pack 3 - Inferno +platform 493 277679 // Personalization pack 4 - Kittens + +platform 494 281344 // Personalization pack 5 +platform 495 281345 // Personalization pack 6 +platform 496 281346 // Personalization pack 7 +platform 497 281347 // Personalization pack 8 +platform 498 286630 // Personalization pack 9 +platform 499 286631 // Personalization pack 10 + +platform 510 295430 // Personalization pack 11 +platform 511 295431 // Personalization pack 12 +platform 512 295432 // Personalization pack 13 +platform 513 295433 // Personalization pack 14 +platform 515 295434 // Personalization pack 15 +platform 516 295435 // Personalization pack 16 + +platform 517 295439 // Personalization pack 17 +platform 518 295440 // Personalization pack 18 +platform 519 301111 // Personalization pack 19 +platform 520 301112 // Personalization pack 20 +platform 521 301113 // Personalization pack 21 +platform 522 301114 // Personalization pack 22 +platform 523 301110 // Personalization pack Flags + +platform 564 295436 // Spectrum Character +platform 565 295437 // Astronaut Character +platform 566 295438 // Resistance Squad + +platform 567 309870 // Bluntforce Character +platform 568 309871 // Inferno Character +platform 569 309872 // Bling Character + +platform 480 259250 //dlc gun 1 +platform 480 301116 //dlc gun 1 +platform 481 259250 //dlc gun 1 +platform 481 301116 //dlc gun 1 + +platform 482 259251 //Ripper from Devastation +platform 482 255161 //Ripper from Season Pass +platform 482 301115 //Ripper from mDLC + +//Clan Entitlements - ID 300 - 399 - type, bit, entitlement id +clan 0 300 +clan 0 301 +clan 1 302 +clan 2 303 +clan 3 304 +clan 3 305 +clan 3 306 +clan 4 307 +clan 4 308 +clan 4 309 +clan 5 310 +clan 5 311 +clan 6 312 +clan 7 313 +clan 8 314 +clan 8 315 +clan 8 316 +clan 9 317 +clan 10 318 +clan 10 319 +clan 10 320 +clan 10 321 +clan 10 322 +clan 11 323 +clan 12 324 +clan 13 325 +clan 13 326 +clan 13 327 +clan 13 328 +clan 13 329 +clan 14 330 +clan 15 331 +clan 15 332 +clan 15 333 +clan 16 334 +clan 16 335 +clan 16 336 +clan 16 337 +clan 16 338 +clan 17 339 +clan 18 340 +clan 19 341 +clan 19 342 +clan 19 343 +clan 19 344 +clan 20 345 +clan 20 346 +clan 21 347 +clan 21 348 +clan 21 349 +clan 22 350 +clan 23 351 +clan 24 352 +clan 25 353 +clan 26 354 +clan 26 355 +clan 26 356 +clan 26 357 +clan 27 358 + +//Clan Level Challenges - type, required level, challenge id +clanlevelchallenge 23 ch_cam_clan_02 // Kiss of Death Camo + +//Clan War Challenges - type, key index, bit offset, challenge id +entitlementchallenge 0 18 ch_ret_clan // clan wars reticle - Triad +entitlementchallenge 0 24 ch_cam_clan_01 // clan wars camo - Body Count diff --git a/localappdata/xlabs/data/iw6x/data/dw/mm.cfg b/localappdata/xlabs/data/iw6x/data/dw/mm.cfg new file mode 100644 index 0000000..bbb75d7 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/dw/mm.cfg @@ -0,0 +1,2 @@ +VERSION 5 +XX 0 D100 0 P50 0 G5 4 F 6 H 8 P75 16 P100 16 S 24 P120 32 P150 40 P-1 10 M192 20 M48 \ No newline at end of file diff --git a/localappdata/xlabs/data/iw6x/data/dw/newsfeed.txt b/localappdata/xlabs/data/iw6x/data/dw/newsfeed.txt new file mode 100644 index 0000000..28de37c --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/dw/newsfeed.txt @@ -0,0 +1,162 @@ +article 1 +header "FLAGS OF THE WORLD PACK" +body "Show your national pride with individual patches, playercards, and backgrounds for England, France, Germany, Italy, Spain, Mexico, USA, Brazil, Australia, Japan, UK, Russia, Netherlands, Portugal, Colombia, Argentina, Canada, Ireland, and Sweden. + +Plus, go international in any firefight with a unique reticle and flags of the world weapon camo. + +Available now. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_pers_pack_flags.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack40 +localJPEGImage + +article 2 +header "CALL OF DUTY APP" +body "The Call of Duty App is everything you need to keep track of your Ghosts experience on the go. + +Get unique info on Clan Wars: A brand new game mode that connects directly to Call of Duty®: Ghosts multiplayer, where clans compete against each other for additional XP and in-game content. + +Communicate via the Rally Up and Clan Chat features, to keep in touch with your friends and Clan members." +type news +image img_sf_generic_news2 +imagewidth 320 +imageheight 320 + +article 3 +header "PLAY HOW YOU WANT WITH EXTRA LOADOUT SLOTS" +body "You can increase the number of loadout slots from 6 to 10, so you can take even more options into battle. Never get caught with the wrong gear and give yourself great flexibility by creating different loadouts for different situations. + +Top Tip - Set up different characters for different game modes, that way you can select the right man for the job. + +Another Top Tip - With all the extra loadouts, set up variations of your favorite loadout so you’re always ready for the unexpected. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_extra_slots.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack2 +localJPEGImage + +article 4 +header "DROP ZONE IS BACK!" +body "We are bringing this fan favorite mode from Call of Duty: Modern Warfare 3 to Call of Duty: Ghosts Multiplayer. + +Fight to take control of the Drop Zone marked with a red smoke grenade, a location where Care Packages are regularly delivered by air drops. + +This mode gives you multiple chances to change the game with awesome killstreaks like the Gryphon, Juggernaut, or the earth shattering Loki. + +Control the Drop Zone, collect killstreaks, and wreak havoc on the opposing team!" +type news +image img_squadmode_03 +imagewidth 320 +imageheight 176 + +article 5 +header "THE REAL ORIGINS OF EXTINCTION" +body "Find out the origins of the Extinction story by collecting hidden intel items in Episode 1: Nightfall. + +Find out the real story of Dr. Cross, Archer and discover more secrets from Project Nightfall. + +Episode 1: Nightfall is part of DLC 1: Onslaught, available now. + +Visit the in-game store to find out more." +type item +image bg_large_073 +imagewidth 320 +imageheight 320 +data dlc3 + +article 6 +header "NEW CUSTOMIZATION CONTENT" +body "New content is being released all the time. Personalize your look and your loadout with customization items. + +- Special Characters: Customize your look head-to-toe in Multiplayer, Squads and Extinction. + +- Personalization Packs: Uniquely themed weapon camo, reticle, patch, playercard and background. + +- Legend Packs: A Special Character and themed Personalization Pack for a legendary figure in Call of Duty lore. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_pers_pack_07.jpg +imagewidth 320 +imageheight 160 +data mdlc_pack17 +localJPEGImage + +article 7 +header "NEW TO EXTINCTION - THE ARMORY" +body "Spend Teeth in the Armory to purchase upgrades for classes and equipment. + +Earn Teeth by completing Extinction missions. Bonus Teeth are awarded for completing with a relic, completing in Hardcore mode, or helping other players complete a mission for the first time. + +You can also earn teeth by killing aliens in both Extinction and Chaos Mode. + +Upgrades include the Weapon Specialist's Infinite Ammo Ability and the Medic's Energy Field, instantly heal and revive anyone within its perimeter!" +type news +image img_sf_extinction_armory +imagewidth 320 +imageheight 320 + +article 8 +header "CAN YOU SURVIVE THE CHAOS?" +body "Extinction's Chaos Mode is an all-new, adrenaline pumping game type that pits 1-4 players against a never ending alien onslaught. + +Keep the combo meter filled by damaging aliens, collecting weaponry or upgrades, and making use of your abilities. Combos provide players with an ever-expanding set of perks such as Fast Health Regen, Gas Mask, and Stopping Power. + +Special bonus drops provide new ability upgrades including the Tank Class Skill and the Venom-X that further your arsenal and overall score potential. + +The aliens are ready, are you?" +type news +image img_sf_extinction_chaos +imagewidth 320 +imageheight 320 + +article 9 +header "WHAT'S GOING ON WITH YOUR CLAN?" +body "Check out what your Clan is up to in-game via Clan Details inside the Barracks. See what's going on with other players' Clans by checking out View Clan when you select them in the lobby. + +Get even more details on your Clan via the Call of Duty App, available now on the App Store, Google Play and Windows Store. + +Not in a Clan? Create one now via the Barracks and invite your friends straight from the game." +type news +image img_squadmode_02 +imagewidth 320 +imageheight 176 + +article 10 +header "DRILL INSTRUCTOR VOICE PACK" +body "Multiplayer returns to boot camp with the all-new Drill Instructor Voice Pack voiced by the one and only R. Lee Ermey, aka The Gunny. + +Swap out your in-game alerts with ones that will get you back into top combat shape. + +Now, drop down and give me twenty! + +Available now. + +Visit the in-game store to find out more." +type item +image ui_mp/ingamestore/img_store_drill_sergeant.jpg +imagewidth 320 +imageheight 160 +data dlc10 +localJPEGImage + +article 11 +header "TRY REINFORCE" +body "Reinforce is a new game mode where you annihilate the enemy team or capture points to win a match. + +You only respawn if a teammate captures a point, so be careful out there! + +This new game mode is now live in our Multiplayer playlist. + +Enjoy!" +type news +image bg_large_045 +imagewidth 320 +imageheight 320 \ No newline at end of file diff --git a/localappdata/xlabs/data/iw6x/data/dw/playlists_tu14.aggr b/localappdata/xlabs/data/iw6x/data/dw/playlists_tu14.aggr new file mode 100644 index 0000000..0e3e8eb Binary files /dev/null and b/localappdata/xlabs/data/iw6x/data/dw/playlists_tu14.aggr differ diff --git a/localappdata/xlabs/data/iw6x/data/dw/social_tu14.cfg b/localappdata/xlabs/data/iw6x/data/dw/social_tu14.cfg new file mode 100644 index 0000000..bbb75d7 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/dw/social_tu14.cfg @@ -0,0 +1,2 @@ +VERSION 5 +XX 0 D100 0 P50 0 G5 4 F 6 H 8 P75 16 P100 16 S 24 P120 32 P150 40 P-1 10 M192 20 M48 \ No newline at end of file diff --git a/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_damage.gsc b/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_damage.gsc new file mode 100644 index 0000000..b7318f3 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_damage.gsc @@ -0,0 +1,3302 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +isswitchingteams() +{ + if ( isdefined( self.switching_teams ) ) + return 1; + + return 0; +} + +isteamswitchbalanced() +{ + var_0 = maps\mp\gametypes\_teams::countplayers(); + var_0[self.leaving_team]--; + var_0[self.joining_team]++; + return var_0[self.joining_team] - var_0[self.leaving_team] < 2; +} + +isfriendlyfire( var_0, var_1 ) +{ + if ( !level.teambased ) + return 0; + + if ( !isdefined( var_1 ) ) + return 0; + + if ( !isplayer( var_1 ) && !isdefined( var_1.team ) ) + return 0; + + if ( var_0.team != var_1.team ) + return 0; + + if ( var_0 == var_1 ) + return 0; + + return 1; +} + +killedself( var_0 ) +{ + if ( !isplayer( var_0 ) ) + return 0; + + if ( var_0 != self ) + return 0; + + return 1; +} + +handleteamchangedeath() +{ + if ( !level.teambased ) + return; + + if ( self.joining_team == "spectator" || !isteamswitchbalanced() ) + { + self thread [[ level.onxpevent ]]( "suicide" ); + maps\mp\_utility::incpersstat( "suicides", 1 ); + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + } + + if ( isdefined( level.onteamchangedeath ) ) + [[ level.onteamchangedeath ]]( self ); +} + +handleworlddeath( var_0, var_1, var_2, var_3 ) +{ + if ( !isdefined( var_0 ) ) + return; + + if ( !isdefined( var_0.team ) ) + { + handlesuicidedeath( var_2, var_3 ); + return; + } + + if ( level.teambased && var_0.team != self.team || !level.teambased ) + { + if ( isdefined( level.onnormaldeath ) && ( isplayer( var_0 ) || isagent( var_0 ) ) && var_0.team != "spectator" ) + [[ level.onnormaldeath ]]( self, var_0, var_1 ); + } +} + +handlesuicidedeath( var_0, var_1 ) +{ + self thread [[ level.onxpevent ]]( "suicide" ); + maps\mp\_utility::incpersstat( "suicides", 1 ); + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + + if ( !maps\mp\_utility::matchmakinggame() ) + maps\mp\_utility::incplayerstat( "suicides", 1 ); + + var_2 = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "suicidepointloss" ); + maps\mp\gametypes\_gamescore::_setplayerscore( self, maps\mp\gametypes\_gamescore::_getplayerscore( self ) - var_2 ); + + if ( var_0 == "MOD_SUICIDE" && var_1 == "none" && isdefined( self.throwinggrenade ) ) + self.lastgrenadesuicidetime = gettime(); + + if ( isdefined( level.onsuicidedeath ) ) + [[ level.onsuicidedeath ]]( self ); + + if ( isdefined( self.friendlydamage ) ) + self iprintlnbold( &"MP_FRIENDLY_FIRE_WILL_NOT" ); +} + +handlefriendlyfiredeath( var_0 ) +{ + var_0 thread [[ level.onxpevent ]]( "teamkill" ); + var_0.pers["teamkills"] += 1.0; + var_0.teamkillsthisround++; + + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "team", "teamkillpointloss" ) ) + { + var_1 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ); + maps\mp\gametypes\_gamescore::_setplayerscore( var_0, maps\mp\gametypes\_gamescore::_getplayerscore( var_0 ) - var_1 ); + } + + if ( level.maxallowedteamkills < 0 ) + return; + + if ( level.ingraceperiod ) + { + var_2 = 1; + var_0.pers["teamkills"] += level.maxallowedteamkills; + } + else if ( var_0.pers["teamkills"] > 1 && maps\mp\_utility::gettimepassed() < level.graceperiod * 1000 + 8000 + var_0.pers["teamkills"] * 1000 ) + { + var_2 = 1; + var_0.pers["teamkills"] += level.maxallowedteamkills; + } + else + var_2 = var_0 maps\mp\gametypes\_playerlogic::teamkilldelay(); + + if ( var_2 > 0 ) + { + var_0.pers["teamKillPunish"] = 1; + var_0 maps\mp\_utility::_suicide(); + } +} + +handlenormaldeath( var_0, var_1, var_2, var_3, var_4 ) +{ + var_1 thread maps\mp\_events::killedplayer( var_0, self, var_3, var_4 ); + + if ( var_4 == "MOD_HEAD_SHOT" ) + { + var_1 maps\mp\_utility::incpersstat( "headshots", 1 ); + var_1.headshots = var_1 maps\mp\_utility::getpersstat( "headshots" ); + var_1 maps\mp\_utility::incplayerstat( "headshots", 1 ); + + if ( isdefined( var_1.laststand ) ) + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ) * 2; + else + var_5 = undefined; + + var_1 playlocalsound( "bullet_impact_headshot_plr" ); + self playsound( "bullet_impact_headshot" ); + } + else if ( isdefined( var_1.laststand ) ) + var_5 = maps\mp\gametypes\_rank::getscoreinfovalue( "kill" ) * 2; + else + var_5 = undefined; + + var_6 = var_1; + + if ( isdefined( var_1.commanding_bot ) ) + var_6 = var_1.commanding_bot; + + var_7 = 0; + + if ( issquadsmode() ) + var_7 = 1; + + var_6 maps\mp\_utility::incpersstat( "kills", 1, var_7 ); + var_6.kills = var_6 maps\mp\_utility::getpersstat( "kills" ); + var_6 maps\mp\_utility::updatepersratio( "kdRatio", "kills", "deaths" ); + var_6 maps\mp\gametypes\_persistence::statsetchild( "round", "kills", var_6.kills ); + var_6 maps\mp\_utility::incplayerstat( "kills", 1 ); + + if ( isflankkill( self, var_1 ) ) + { + var_6 maps\mp\_utility::incplayerstat( "flankkills", 1 ); + maps\mp\_utility::incplayerstat( "flankdeaths", 1 ); + } + + var_8 = var_1.pers["cur_kill_streak"]; + + if ( isalive( var_1 ) || var_1.streaktype == "support" ) + { + if ( var_4 == "MOD_MELEE" && !var_1 maps\mp\_utility::isjuggernaut() || var_1 maps\mp\_utility::killshouldaddtokillstreak( var_3 ) ) + var_1 registerkill( var_3, 1 ); + + var_1 maps\mp\_utility::setplayerstatifgreater( "killstreak", var_1.pers["cur_kill_streak"] ); + + if ( var_1.pers["cur_kill_streak"] > var_1 maps\mp\_utility::getpersstat( "longestStreak" ) ) + var_1 maps\mp\_utility::setpersstat( "longestStreak", var_1.pers["cur_kill_streak"] ); + } + + var_1.pers["cur_death_streak"] = 0; + var_1 thread maps\mp\gametypes\_rank::giverankxp( "kill", var_5, var_3, var_4, undefined, self ); + + if ( var_1.pers["cur_kill_streak"] > var_1 maps\mp\gametypes\_persistence::statgetchild( "round", "killStreak" ) ) + var_1 maps\mp\gametypes\_persistence::statsetchild( "round", "killStreak", var_1.pers["cur_kill_streak"] ); + + if ( var_1 maps\mp\_utility::rankingenabled() ) + { + if ( var_1.pers["cur_kill_streak"] > var_1.kill_streak ) + { + if ( !issquadsmode() ) + var_1 maps\mp\gametypes\_persistence::statset( "killStreak", var_1.pers["cur_kill_streak"] ); + + var_1.kill_streak = var_1.pers["cur_kill_streak"]; + } + } + + maps\mp\gametypes\_gamescore::giveplayerscore( "kill", var_1, self ); + var_9 = maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "deathpointloss" ); + maps\mp\gametypes\_gamescore::_setplayerscore( self, maps\mp\gametypes\_gamescore::_getplayerscore( self ) - var_9 ); + + if ( isdefined( level.ac130player ) && level.ac130player == var_1 ) + level notify( "ai_killed", self ); + + if ( isdefined( var_1.odin ) ) + level notify( "odin_killed_player", self ); + + level notify( "player_got_killstreak_" + var_1.pers["cur_kill_streak"], var_1 ); + var_1 notify( "got_killstreak", var_1.pers["cur_kill_streak"] ); + var_1 notify( "killed_enemy", self, var_3, var_4 ); + + if ( isdefined( self.motionsensormarkedby ) ) + { + if ( self.motionsensormarkedby != var_1 ) + self.motionsensormarkedby thread maps\mp\gametypes\_weapons::motionsensor_processtaggedassist( self ); + + self.motionsensormarkedby = undefined; + } + + if ( isdefined( level.onnormaldeath ) && var_1.pers["team"] != "spectator" ) + [[ level.onnormaldeath ]]( self, var_1, var_0 ); + + if ( !level.teambased ) + { + self.attackers = []; + return; + } + + level thread maps\mp\gametypes\_battlechatter_mp::saylocalsounddelayed( var_1, "kill", 0.75 ); + + if ( isdefined( self.lastattackedshieldplayer ) && isdefined( self.lastattackedshieldtime ) && self.lastattackedshieldplayer != var_1 ) + { + if ( gettime() - self.lastattackedshieldtime < 2500 ) + { + self.lastattackedshieldplayer thread maps\mp\gametypes\_gamescore::processshieldassist( self ); + + if ( self.lastattackedshieldplayer maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + self.lastattackedshieldplayer.pers["assistsToKill"]++; + + if ( !( self.lastattackedshieldplayer.pers["assistsToKill"] % 2 ) ) + { + self.lastattackedshieldplayer maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + self.lastattackedshieldplayer maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.lastattackedshieldplayer.pers["cur_kill_streak"]++; + } + } + else + self.lastattackedshieldplayer.pers["assistsToKill"] = 0; + } + else if ( isalive( self.lastattackedshieldplayer ) && gettime() - self.lastattackedshieldtime < 5000 ) + { + var_10 = vectornormalize( anglestoforward( self.angles ) ); + var_11 = vectornormalize( self.lastattackedshieldplayer.origin - self.origin ); + + if ( vectordot( var_11, var_10 ) > 0.925 ) + { + self.lastattackedshieldplayer thread maps\mp\gametypes\_gamescore::processshieldassist( self ); + + if ( self.lastattackedshieldplayer maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + self.lastattackedshieldplayer.pers["assistsToKill"]++; + + if ( !( self.lastattackedshieldplayer.pers["assistsToKill"] % 2 ) ) + { + self.lastattackedshieldplayer maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + self.lastattackedshieldplayer maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.lastattackedshieldplayer.pers["cur_kill_streak"]++; + } + } + else + self.lastattackedshieldplayer.pers["assistsToKill"] = 0; + } + } + } + + if ( isdefined( self.attackers ) ) + { + foreach ( var_13 in self.attackers ) + { + if ( !isdefined( maps\mp\_utility::_validateattacker( var_13 ) ) ) + continue; + + if ( var_13 == var_1 ) + continue; + + if ( self == var_13 ) + continue; + + if ( isdefined( level.assists_disabled ) ) + continue; + + var_13 thread maps\mp\gametypes\_gamescore::processassist( self ); + + if ( var_13 maps\mp\_utility::_hasperk( "specialty_assists" ) ) + { + var_13.pers["assistsToKill"]++; + + if ( !( var_13.pers["assistsToKill"] % 2 ) ) + { + var_13 maps\mp\gametypes\_missions::processchallenge( "ch_hardlineassists" ); + var_13 registerkill( var_3, 0 ); + } + + continue; + } + + var_13.pers["assistsToKill"] = 0; + } + + self.attackers = []; + } +} + +isplayerweapon( var_0 ) +{ + if ( weaponclass( var_0 ) == "non-player" ) + return 0; + + if ( weaponclass( var_0 ) == "turret" ) + return 0; + + if ( weaponinventorytype( var_0 ) == "primary" || weaponinventorytype( var_0 ) == "altmode" ) + return 1; + + return 0; +} + +waitskipkillcambuttonduringdeathtimer() +{ + self endon( "disconnect" ); + self endon( "killcam_death_done_waiting" ); + self notifyonplayercommand( "death_respawn", "+usereload" ); + self notifyonplayercommand( "death_respawn", "+activate" ); + self waittill( "death_respawn" ); + self notify( "killcam_death_button_cancel" ); +} + +waitskipkillcamduringdeathtimer( var_0 ) +{ + self endon( "disconnect" ); + self endon( "killcam_death_button_cancel" ); + wait(var_0); + self notify( "killcam_death_done_waiting" ); +} + +skipkillcamduringdeathtimer( var_0 ) +{ + self endon( "disconnect" ); + + if ( level.showingfinalkillcam ) + return 0; + + if ( !isai( self ) ) + { + thread waitskipkillcambuttonduringdeathtimer(); + thread waitskipkillcamduringdeathtimer( var_0 ); + var_1 = common_scripts\utility::waittill_any_return( "killcam_death_done_waiting", "killcam_death_button_cancel" ); + + if ( var_1 == "killcam_death_done_waiting" ) + return 0; + else + return 1; + } + + return 0; +} + +callback_playerkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 ) +{ + playerkilled_internal( var_0, var_1, self, var_2, var_3, var_4, var_5, var_6, var_7, var_8, 0 ); +} + +queueshieldforremoval( var_0 ) +{ + var_1 = 5; + + if ( !isdefined( level.shieldtrasharray ) ) + level.shieldtrasharray = []; + + if ( level.shieldtrasharray.size >= var_1 ) + { + var_2 = level.shieldtrasharray.size - 1; + level.shieldtrasharray[0] delete(); + + for ( var_3 = 0; var_3 < var_2; var_3++ ) + level.shieldtrasharray[var_3] = level.shieldtrasharray[var_3 + 1]; + + level.shieldtrasharray[var_2] = undefined; + } + + level.shieldtrasharray[level.shieldtrasharray.size] = var_0; +} + +launchshield( var_0, var_1 ) +{ + if ( isdefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped ) + { + if ( isdefined( self.riotshieldmodel ) ) + maps\mp\_utility::riotshield_detach( 1 ); + else if ( isdefined( self.riotshieldmodelstowed ) ) + maps\mp\_utility::riotshield_detach( 0 ); + } +} + +playerkilled_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + var_2 endon( "spawned" ); + var_2 notify( "killed_player" ); + var_2 maps\mp\gametypes\_playerlogic::resetuidvarsondeath(); + var_2.abilitychosen = 0; + var_2.perkoutlined = 0; + + if ( maps\mp\_utility::gamehasneutralcrateowner( level.gametype ) ) + { + if ( var_2 != var_1 && var_4 == "MOD_CRUSH" ) + { + var_0 = var_2; + var_1 = var_2; + var_4 = "MOD_SUICIDE"; + var_5 = "none"; + var_7 = "none"; + var_2.attackers = []; + } + } + + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + + if ( isdefined( var_1 ) ) + var_1.assistedsuicide = undefined; + + if ( !isdefined( var_2.idflags ) ) + { + if ( var_4 == "MOD_SUICIDE" ) + var_2.idflags = 0; + else if ( var_4 == "MOD_GRENADE" ) + { + if ( ( issubstr( var_5, "frag_grenade" ) || issubstr( var_5, "thermobaric_grenade" ) || issubstr( var_5, "mortar_shell" ) ) && var_3 == 100000 ) + var_2.idflags = 0; + else if ( var_5 == "nuke_mp" ) + var_2.idflags = 0; + else if ( level.friendlyfire >= 2 ) + var_2.idflags = 0; + else + { + + } + } + } + + if ( isdefined( var_2.hasriotshieldequipped ) && var_2.hasriotshieldequipped ) + var_2 launchshield( var_3, var_4 ); + + var_2 maps\mp\_utility::riotshield_clear(); + maps\mp\gametypes\_weapons::recordtogglescopestates(); + + if ( !var_10 ) + { + if ( isdefined( var_2.endgame ) ) + maps\mp\_utility::restorebasevisionset( 2 ); + else + { + maps\mp\_utility::restorebasevisionset( 0 ); + var_2 thermalvisionoff(); + } + } + else + { + var_2.fauxdead = 1; + self notify( "death" ); + } + + if ( game["state"] == "postgame" ) + return; + + maps\mp\perks\_perks::updateactiveperks( var_0, var_1, var_2, var_3, var_4 ); + var_11 = 0; + + if ( !isplayer( var_0 ) && isdefined( var_0.primaryweapon ) ) + var_12 = var_0.primaryweapon; + else if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_12 = var_1 getcurrentprimaryweapon(); + else if ( issubstr( var_5, "alt_" ) ) + var_12 = getsubstr( var_5, 4, var_5.size ); + else + var_12 = undefined; + + if ( isdefined( var_2.uselaststandparams ) || isdefined( var_2.laststandparams ) && var_4 == "MOD_SUICIDE" ) + { + var_2 ensurelaststandparamsvalidity(); + var_2.uselaststandparams = undefined; + var_0 = var_2.laststandparams.einflictor; + var_1 = var_2.laststandparams.attacker; + var_3 = var_2.laststandparams.idamage; + var_4 = var_2.laststandparams.smeansofdeath; + var_5 = var_2.laststandparams.sweapon; + var_12 = var_2.laststandparams.sprimaryweapon; + var_6 = var_2.laststandparams.vdir; + var_7 = var_2.laststandparams.shitloc; + var_11 = ( gettime() - var_2.laststandparams.laststandstarttime ) / 1000; + var_2.laststandparams = undefined; + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + } + + if ( ( !isdefined( var_1 ) || var_1.classname == "trigger_hurt" || var_1.classname == "worldspawn" || var_1 == var_2 ) && isdefined( self.attackers ) ) + { + var_13 = undefined; + + foreach ( var_15 in self.attackers ) + { + if ( !isdefined( maps\mp\_utility::_validateattacker( var_15 ) ) ) + continue; + + if ( !isdefined( var_2.attackerdata[var_15.guid].damage ) ) + continue; + + if ( var_15 == var_2 || level.teambased && var_15.team == var_2.team ) + continue; + + if ( var_2.attackerdata[var_15.guid].lasttimedamaged + 2500 < gettime() && ( var_1 != var_2 && ( isdefined( var_2.laststand ) && var_2.laststand ) ) ) + continue; + + if ( var_2.attackerdata[var_15.guid].damage > 1 && !isdefined( var_13 ) ) + { + var_13 = var_15; + continue; + } + + if ( isdefined( var_13 ) && var_2.attackerdata[var_15.guid].damage > var_2.attackerdata[var_13.guid].damage ) + var_13 = var_15; + } + + if ( isdefined( var_13 ) ) + { + var_1 = var_13; + var_1.assistedsuicide = 1; + var_5 = var_2.attackerdata[var_13.guid].weapon; + var_6 = var_2.attackerdata[var_13.guid].vdir; + var_7 = var_2.attackerdata[var_13.guid].shitloc; + var_8 = var_2.attackerdata[var_13.guid].psoffsettime; + var_4 = var_2.attackerdata[var_13.guid].smeansofdeath; + var_3 = var_2.attackerdata[var_13.guid].damage; + var_12 = var_2.attackerdata[var_13.guid].sprimaryweapon; + var_0 = var_1; + } + } + else if ( isdefined( var_1 ) ) + var_1.assistedsuicide = undefined; + + if ( maps\mp\_utility::isheadshot( var_5, var_7, var_4, var_1 ) ) + var_4 = "MOD_HEAD_SHOT"; + else if ( !isdefined( var_2.nuked ) ) + { + if ( isdefined( level.custom_death_sound ) ) + [[ level.custom_death_sound ]]( var_2, var_4, var_0 ); + else if ( var_4 != "MOD_MELEE" ) + var_2 maps\mp\_utility::playdeathsound(); + } + + if ( isdefined( level.custom_death_effect ) ) + [[ level.custom_death_effect ]]( var_2, var_4, var_0 ); + + var_17 = isfriendlyfire( var_2, var_1 ); + + if ( isdefined( var_1 ) ) + { + if ( var_1.code_classname == "script_vehicle" && isdefined( var_1.owner ) ) + var_1 = var_1.owner; + + if ( var_1.code_classname == "misc_turret" && isdefined( var_1.owner ) ) + { + if ( isdefined( var_1.vehicle ) ) + var_1.vehicle notify( "killedPlayer", var_2 ); + + var_1 = var_1.owner; + } + + if ( isagent( var_1 ) ) + { + var_5 = "agent_mp"; + var_4 = "MOD_RIFLE_BULLET"; + + if ( isdefined( var_1.agent_type ) ) + { + if ( var_1.agent_type == "dog" ) + var_5 = "guard_dog_mp"; + else if ( var_1.agent_type == "squadmate" ) + var_5 = "agent_support_mp"; + else if ( var_1.agent_type == "pirate" ) + var_5 = "pirate_agent_mp"; + else if ( var_1.agent_type == "wolf" ) + var_5 = "killstreak_wolfpack_mp"; + else if ( var_1.agent_type == "beastmen" ) + var_5 = "beast_agent_mp"; + } + + if ( isdefined( var_1.owner ) ) + var_1 = var_1.owner; + } + + if ( var_1.code_classname == "script_model" && isdefined( var_1.owner ) ) + { + var_1 = var_1.owner; + + if ( !isfriendlyfire( var_2, var_1 ) && var_1 != var_2 ) + var_1 notify( "crushed_enemy" ); + } + } + + if ( var_4 != "MOD_SUICIDE" && ( maps\mp\_utility::isaigameparticipant( var_2 ) || maps\mp\_utility::isaigameparticipant( var_1 ) ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["get_attacker_ent"] ) ) + { + var_18 = [[ level.bot_funcs["get_attacker_ent"] ]]( var_1, var_0 ); + + if ( isdefined( var_18 ) ) + { + if ( maps\mp\_utility::isaigameparticipant( var_2 ) ) + var_2 botmemoryevent( "death", var_5, var_18.origin, var_2.origin, var_18 ); + + if ( maps\mp\_utility::isaigameparticipant( var_1 ) ) + { + var_19 = 1; + + if ( var_18.classname == "script_vehicle" && isdefined( var_18.helitype ) || var_18.classname == "rocket" || var_18.classname == "misc_turret" ) + var_19 = 0; + + if ( var_19 ) + var_1 botmemoryevent( "kill", var_5, var_18.origin, var_2.origin, var_2 ); + } + } + } + + var_2 maps\mp\gametypes\_weapons::dropscavengerfordeath( var_1 ); + var_2 [[ level.weapondropfunction ]]( var_1, var_4 ); + + if ( !var_10 ) + var_2 maps\mp\_utility::updatesessionstate( "dead", "hud_status_dead" ); + + var_20 = isdefined( var_2.fauxdead ) && var_2.fauxdead && isdefined( var_2.switching_teams ) && var_2.switching_teams; + + if ( !var_20 ) + var_2 maps\mp\gametypes\_playerlogic::removefromalivecount(); + + if ( !isdefined( var_2.switching_teams ) ) + { + var_21 = var_2; + + if ( isdefined( var_2.commanding_bot ) ) + var_21 = var_2.commanding_bot; + + if ( isdefined( level.ishorde ) ) + var_21.deaths++; + else + { + var_22 = 0; + + if ( issquadsmode() ) + var_22 = 1; + + var_21 maps\mp\_utility::incpersstat( "deaths", 1, var_22 ); + var_21.deaths = var_21 maps\mp\_utility::getpersstat( "deaths" ); + var_21 maps\mp\_utility::updatepersratio( "kdRatio", "kills", "deaths" ); + var_21 maps\mp\gametypes\_persistence::statsetchild( "round", "deaths", var_21.deaths ); + var_21 maps\mp\_utility::incplayerstat( "deaths", 1 ); + } + } + + if ( isdefined( var_1 ) && isplayer( var_1 ) ) + var_1 checkkillsteal( var_2 ); + + obituary( var_2, var_1, var_5, var_4 ); + var_23 = 0; + var_24 = var_2 maps\mp\_matchdata::logplayerlife(); + var_2 logprintplayerdeath( var_24, var_1, var_3, var_4, var_5, var_12, var_7 ); + var_2 maps\mp\_matchdata::logplayerdeath( var_24, var_1, var_3, var_4, var_5, var_12, var_7 ); + + if ( isplayer( var_1 ) ) + { + if ( var_4 == "MOD_MELEE" ) + { + if ( maps\mp\gametypes\_weapons::isriotshield( var_5 ) ) + { + var_1 maps\mp\_utility::incplayerstat( "shieldkills", 1 ); + + if ( !maps\mp\_utility::matchmakinggame() ) + var_2 maps\mp\_utility::incplayerstat( "shielddeaths", 1 ); + } + else + var_1 maps\mp\_utility::incplayerstat( "knifekills", 1 ); + + addattacker( var_2, var_1, var_0, var_5, var_3, ( 0, 0, 0 ), var_6, var_7, var_8, var_4 ); + } + } + + if ( var_2 isswitchingteams() ) + handleteamchangedeath(); + else if ( !isplayer( var_1 ) || isplayer( var_1 ) && var_4 == "MOD_FALLING" ) + { + handleworlddeath( var_1, var_24, var_4, var_7 ); + + if ( isagent( var_1 ) ) + var_23 = 1; + } + else if ( var_1 == var_2 ) + handlesuicidedeath( var_4, var_7 ); + else if ( var_17 ) + { + if ( !( isdefined( var_2.nuked ) || var_5 == "bomb_site_mp" ) ) + handlefriendlyfiredeath( var_1 ); + } + else + { + if ( var_4 == "MOD_GRENADE" && var_0 == var_1 ) + addattacker( var_2, var_1, var_0, var_5, var_3, ( 0, 0, 0 ), var_6, var_7, var_8, var_4 ); + + var_23 = 1; + + if ( isai( var_2 ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["should_do_killcam"] ) ) + var_23 = var_2 [[ level.bot_funcs["should_do_killcam"] ]](); + + if ( isdefined( level.disable_killcam ) && level.disable_killcam ) + var_23 = 0; + + handlenormaldeath( var_24, var_1, var_0, var_5, var_4 ); + var_2 thread maps\mp\gametypes\_missions::playerkilled( var_0, var_1, var_3, var_4, var_5, var_12, var_7, var_1.modifiers ); + var_2.pers["cur_death_streak"]++; + + if ( isplayer( var_1 ) && var_2 maps\mp\_utility::isjuggernaut() ) + { + if ( isdefined( var_2.isjuggernautmaniac ) && var_2.isjuggernautmaniac ) + { + var_1 thread maps\mp\_utility::teamplayercardsplash( "callout_killed_maniac", var_1 ); + + if ( var_4 == "MOD_MELEE" ) + var_1 maps\mp\gametypes\_missions::processchallenge( "ch_thisisaknife" ); + } + else if ( isdefined( var_2.isjuggernautlevelcustom ) && var_2.isjuggernautlevelcustom ) + var_1 thread maps\mp\_utility::teamplayercardsplash( level.mapcustomjuggkilledsplash, var_1 ); + else + var_1 thread maps\mp\_utility::teamplayercardsplash( "callout_killed_juggernaut", var_1 ); + } + } + + var_25 = 0; + var_26 = undefined; + + if ( isdefined( self.previousprimary ) ) + { + var_25 = 1; + var_26 = self.previousprimary; + self.previousprimary = undefined; + } + + if ( isplayer( var_1 ) && var_1 != self && ( !level.teambased || level.teambased && self.team != var_1.team ) ) + { + if ( var_25 && isdefined( var_26 ) ) + var_27 = var_26; + else + var_27 = self.lastdroppableweapon; + + var_27 = maps\mp\_utility::weaponmap( var_27 ); + thread maps\mp\gametypes\_gamelogic::trackleaderboarddeathstats( var_27, var_4 ); + var_1 thread maps\mp\gametypes\_gamelogic::trackattackerleaderboarddeathstats( var_5, var_4 ); + } + + if ( isdefined( var_1 ) && isdefined( var_2 ) ) + bbprint( "kills", "attackername %s attackerteam %s attackerx %f attackery %f attackerz %f attackerweapon %s victimx %f victimy %f victimz %f victimname %s victimteam %s damage %i damagetype %s damagelocation %s attackerisbot %i victimisbot %i timesincespawn %f", var_1.name, var_1.team, var_1.origin[0], var_1.origin[1], var_1.origin[2], var_5, var_2.origin[0], var_2.origin[1], var_2.origin[2], var_2.name, var_2.team, var_3, var_4, var_7, isai( var_1 ), isai( var_2 ), ( gettime() - var_2.lastspawntime ) / 1000 ); + + var_2.wasswitchingteamsforonplayerkilled = undefined; + + if ( isdefined( var_2.switching_teams ) ) + var_2.wasswitchingteamsforonplayerkilled = 1; + + var_2 resetplayervariables(); + var_2.lastattacker = var_1; + var_2.lastdeathpos = var_2.origin; + var_2.deathtime = gettime(); + var_2.wantsafespawn = 0; + var_2.revived = 0; + var_2.sameshotdamage = 0; + + if ( maps\mp\killstreaks\_killstreaks::streaktyperesetsondeath( var_2.streaktype ) ) + var_2 maps\mp\killstreaks\_killstreaks::resetadrenaline(); + + var_28 = undefined; + + if ( maps\mp\_utility::isrocketcorpse() ) + { + var_23 = 1; + var_10 = 0; + var_28 = self.killcament; + self waittill( "final_rocket_corpse_death" ); + } + else + { + if ( var_10 ) + { + var_23 = 0; + var_9 = var_2 playerforcedeathanim( var_0, var_4, var_5, var_7, var_6 ); + } + + var_2.body = var_2 cloneplayer( var_9 ); + var_2.body.targetname = "player_corpse"; + + if ( var_10 ) + var_2 playerhide(); + + if ( var_2 isonladder() || var_2 ismantling() || !var_2 isonground() || isdefined( var_2.nuked ) || isdefined( var_2.customdeath ) ) + { + var_29 = 0; + + if ( var_4 == "MOD_MELEE" ) + { + if ( isdefined( var_2.isplanting ) && var_2.isplanting || isdefined( var_2.nuked ) ) + var_29 = 1; + } + + if ( !var_29 ) + { + var_2.body startragdoll(); + var_2 notify( "start_instant_ragdoll", var_4, var_0 ); + } + } + + if ( !isdefined( var_2.switching_teams ) ) + { + if ( isdefined( var_1 ) && isplayer( var_1 ) && !var_1 maps\mp\_utility::_hasperk( "specialty_silentkill" ) ) + thread maps\mp\gametypes\_deathicons::adddeathicon( var_2.body, var_2, var_2.team, 5.0 ); + } + + thread delaystartragdoll( var_2.body, var_7, var_6, var_5, var_0, var_4 ); + } + + var_2 thread [[ level.onplayerkilled ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_24 ); + + if ( isai( var_2 ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["on_killed"] ) ) + var_2 thread [[ level.bot_funcs["on_killed"] ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_24 ); + + if ( maps\mp\_utility::isgameparticipant( var_1 ) ) + var_30 = var_1 getentitynumber(); + else + var_30 = -1; + + if ( !isdefined( var_28 ) ) + var_28 = var_2 getkillcamentity( var_1, var_0, var_5 ); + + var_31 = -1; + var_32 = 0; + + if ( isdefined( var_28 ) ) + { + var_31 = var_28 getentitynumber(); + var_32 = var_28.birthtime; + + if ( !isdefined( var_32 ) ) + var_32 = 0; + } + + if ( ( !isdefined( level.disable_killcam ) || !level.disable_killcam ) && var_4 != "MOD_SUICIDE" && !( !isdefined( var_1 ) || var_1.classname == "trigger_hurt" || var_1.classname == "worldspawn" || var_1 == var_2 ) ) + recordfinalkillcam( 5.0, var_2, var_1, var_30, var_0, var_31, var_32, var_5, var_11, var_8, var_4 ); + + var_2 setcommonplayerdata( "killCamHowKilled", 0 ); + + switch ( var_4 ) + { + case "MOD_HEAD_SHOT": + var_2 setcommonplayerdata( "killCamHowKilled", 1 ); + break; + default: + break; + } + + var_33 = undefined; + + if ( var_23 ) + { + var_2 maps\mp\gametypes\_killcam::prekillcamnotify( var_0, var_1 ); + + if ( isdefined( var_0 ) && isagent( var_0 ) ) + { + var_33 = spawnstruct(); + var_33.agent_type = var_0.agent_type; + var_33.lastspawntime = var_0.lastspawntime; + } + } + + if ( !var_10 ) + { + self.respawntimerstarttime = gettime() + 1000; + var_34 = maps\mp\gametypes\_playerlogic::timeuntilspawn( 1 ); + + if ( var_34 < 1 ) + var_34 = 1; + + var_2 thread maps\mp\gametypes\_playerlogic::predictabouttospawnplayerovertime( var_34 ); + wait 1.0; + + if ( var_23 ) + var_23 = !skipkillcamduringdeathtimer( 0.5 ); + + var_2 notify( "death_delay_finished" ); + } + + var_35 = ( gettime() - var_2.deathtime ) / 1000; + self.respawntimerstarttime = gettime(); + var_23 = var_23 && !var_2 maps\mp\gametypes\_battlebuddy::canbuddyspawn(); + + if ( !( isdefined( var_2.cancelkillcam ) && var_2.cancelkillcam ) && var_23 && level.killcam && game["state"] == "playing" && !var_2 maps\mp\_utility::isusingremote() && !level.showingfinalkillcam ) + { + var_36 = !( maps\mp\_utility::getgametypenumlives() && !var_2.pers["lives"] ); + var_34 = maps\mp\gametypes\_playerlogic::timeuntilspawn( 1 ); + var_37 = var_36 && var_34 <= 0; + + if ( !var_36 ) + { + var_34 = -1; + level notify( "player_eliminated", var_2 ); + } + + var_2 maps\mp\gametypes\_killcam::killcam( var_0, var_33, var_30, var_31, var_32, var_5, var_35 + var_11, var_8, var_34, maps\mp\gametypes\_gamelogic::timeuntilroundend(), var_1, var_2, var_4 ); + } + + if ( game["state"] != "playing" ) + { + if ( !level.showingfinalkillcam ) + { + var_2 maps\mp\_utility::updatesessionstate( "dead" ); + var_2 maps\mp\_utility::clearkillcamstate(); + } + + return; + } + + var_38 = maps\mp\_utility::getgametypenumlives(); + var_39 = self.pers["lives"]; + + if ( self == var_2 && isdefined( var_2.battlebuddy ) && maps\mp\_utility::isreallyalive( var_2.battlebuddy ) && ( !maps\mp\_utility::getgametypenumlives() || self.pers["lives"] ) && !var_2 maps\mp\_utility::isusingremote() ) + maps\mp\gametypes\_battlebuddy::waitforplayerrespawnchoice(); + + if ( maps\mp\_utility::isvalidclass( var_2.class ) ) + var_2 thread maps\mp\gametypes\_playerlogic::spawnclient(); +} + +checkforcebleedout() +{ + if ( level.diehardmode != 1 ) + return 0; + + if ( !maps\mp\_utility::getgametypenumlives() ) + return 0; + + if ( level.livescount[self.team] > 0 ) + return 0; + + foreach ( var_1 in level.players ) + { + if ( !isalive( var_1 ) ) + continue; + + if ( var_1.team != self.team ) + continue; + + if ( var_1 == self ) + continue; + + if ( !var_1.inlaststand ) + return 0; + } + + foreach ( var_1 in level.players ) + { + if ( !isalive( var_1 ) ) + continue; + + if ( var_1.team != self.team ) + continue; + + if ( var_1.inlaststand && var_1 != self ) + var_1 laststandbleedout( 0 ); + } + + return 1; +} + +checkkillsteal( var_0 ) +{ + if ( maps\mp\_utility::matchmakinggame() ) + return; + + var_1 = 0; + var_2 = undefined; + + if ( isdefined( var_0.attackerdata ) && var_0.attackerdata.size > 1 ) + { + foreach ( var_4 in var_0.attackerdata ) + { + if ( var_4.damage > var_1 ) + { + var_1 = var_4.damage; + var_2 = var_4.attackerent; + } + } + + if ( isdefined( var_2 ) && var_2 != self ) + maps\mp\_utility::incplayerstat( "killsteals", 1 ); + } +} + +initfinalkillcam() +{ + level.finalkillcam_delay = []; + level.finalkillcam_victim = []; + level.finalkillcam_attacker = []; + level.finalkillcam_attackernum = []; + level.finalkillcam_inflictor = []; + level.finalkillcam_inflictor_agent_type = []; + level.finalkillcam_inflictor_lastspawntime = []; + level.finalkillcam_killcamentityindex = []; + level.finalkillcam_killcamentitystarttime = []; + level.finalkillcam_sweapon = []; + level.finalkillcam_deathtimeoffset = []; + level.finalkillcam_psoffsettime = []; + level.finalkillcam_timerecorded = []; + level.finalkillcam_timegameended = []; + level.finalkillcam_smeansofdeath = []; + + if ( level.multiteambased ) + { + foreach ( var_1 in level.teamnamelist ) + { + level.finalkillcam_delay[var_1] = undefined; + level.finalkillcam_victim[var_1] = undefined; + level.finalkillcam_attacker[var_1] = undefined; + level.finalkillcam_attackernum[var_1] = undefined; + level.finalkillcam_inflictor[var_1] = undefined; + level.finalkillcam_inflictor_agent_type[var_1] = undefined; + level.finalkillcam_inflictor_lastspawntime[var_1] = undefined; + level.finalkillcam_killcamentityindex[var_1] = undefined; + level.finalkillcam_killcamentitystarttime[var_1] = undefined; + level.finalkillcam_sweapon[var_1] = undefined; + level.finalkillcam_deathtimeoffset[var_1] = undefined; + level.finalkillcam_psoffsettime[var_1] = undefined; + level.finalkillcam_timerecorded[var_1] = undefined; + level.finalkillcam_timegameended[var_1] = undefined; + level.finalkillcam_smeansofdeath[var_1] = undefined; + } + } + else + { + level.finalkillcam_delay["axis"] = undefined; + level.finalkillcam_victim["axis"] = undefined; + level.finalkillcam_attacker["axis"] = undefined; + level.finalkillcam_attackernum["axis"] = undefined; + level.finalkillcam_inflictor["axis"] = undefined; + level.finalkillcam_inflictor_agent_type["axis"] = undefined; + level.finalkillcam_inflictor_lastspawntime["axis"] = undefined; + level.finalkillcam_killcamentityindex["axis"] = undefined; + level.finalkillcam_killcamentitystarttime["axis"] = undefined; + level.finalkillcam_sweapon["axis"] = undefined; + level.finalkillcam_deathtimeoffset["axis"] = undefined; + level.finalkillcam_psoffsettime["axis"] = undefined; + level.finalkillcam_timerecorded["axis"] = undefined; + level.finalkillcam_timegameended["axis"] = undefined; + level.finalkillcam_smeansofdeath["axis"] = undefined; + level.finalkillcam_delay["allies"] = undefined; + level.finalkillcam_victim["allies"] = undefined; + level.finalkillcam_attacker["allies"] = undefined; + level.finalkillcam_attackernum["allies"] = undefined; + level.finalkillcam_inflictor["allies"] = undefined; + level.finalkillcam_inflictor_agent_type["allies"] = undefined; + level.finalkillcam_inflictor_lastspawntime["allies"] = undefined; + level.finalkillcam_killcamentityindex["allies"] = undefined; + level.finalkillcam_killcamentitystarttime["allies"] = undefined; + level.finalkillcam_sweapon["allies"] = undefined; + level.finalkillcam_deathtimeoffset["allies"] = undefined; + level.finalkillcam_psoffsettime["allies"] = undefined; + level.finalkillcam_timerecorded["allies"] = undefined; + level.finalkillcam_timegameended["allies"] = undefined; + level.finalkillcam_smeansofdeath["allies"] = undefined; + } + + level.finalkillcam_delay["none"] = undefined; + level.finalkillcam_victim["none"] = undefined; + level.finalkillcam_attacker["none"] = undefined; + level.finalkillcam_attackernum["none"] = undefined; + level.finalkillcam_inflictor["none"] = undefined; + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + level.finalkillcam_killcamentityindex["none"] = undefined; + level.finalkillcam_killcamentitystarttime["none"] = undefined; + level.finalkillcam_sweapon["none"] = undefined; + level.finalkillcam_deathtimeoffset["none"] = undefined; + level.finalkillcam_psoffsettime["none"] = undefined; + level.finalkillcam_timerecorded["none"] = undefined; + level.finalkillcam_timegameended["none"] = undefined; + level.finalkillcam_smeansofdeath["none"] = undefined; + level.finalkillcam_winner = undefined; +} + +recordfinalkillcam( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + if ( level.teambased && isdefined( var_2.team ) ) + { + level.finalkillcam_delay[var_2.team] = var_0; + level.finalkillcam_victim[var_2.team] = var_1; + level.finalkillcam_attacker[var_2.team] = var_2; + level.finalkillcam_attackernum[var_2.team] = var_3; + level.finalkillcam_inflictor[var_2.team] = var_4; + level.finalkillcam_killcamentityindex[var_2.team] = var_5; + level.finalkillcam_killcamentitystarttime[var_2.team] = var_6; + level.finalkillcam_sweapon[var_2.team] = var_7; + level.finalkillcam_deathtimeoffset[var_2.team] = var_8; + level.finalkillcam_psoffsettime[var_2.team] = var_9; + level.finalkillcam_timerecorded[var_2.team] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended[var_2.team] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_smeansofdeath[var_2.team] = var_10; + + if ( isdefined( var_4 ) && isagent( var_4 ) ) + { + level.finalkillcam_inflictor_agent_type[var_2.team] = var_4.agent_type; + level.finalkillcam_inflictor_lastspawntime[var_2.team] = var_4.lastspawntime; + } + else + { + level.finalkillcam_inflictor_agent_type[var_2.team] = undefined; + level.finalkillcam_inflictor_lastspawntime[var_2.team] = undefined; + } + } + + level.finalkillcam_delay["none"] = var_0; + level.finalkillcam_victim["none"] = var_1; + level.finalkillcam_attacker["none"] = var_2; + level.finalkillcam_attackernum["none"] = var_3; + level.finalkillcam_inflictor["none"] = var_4; + level.finalkillcam_killcamentityindex["none"] = var_5; + level.finalkillcam_killcamentitystarttime["none"] = var_6; + level.finalkillcam_sweapon["none"] = var_7; + level.finalkillcam_deathtimeoffset["none"] = var_8; + level.finalkillcam_psoffsettime["none"] = var_9; + level.finalkillcam_timerecorded["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_timegameended["none"] = maps\mp\_utility::getsecondspassed(); + level.finalkillcam_smeansofdeath["none"] = var_10; + + if ( isdefined( var_4 ) && isagent( var_4 ) ) + { + level.finalkillcam_inflictor_agent_type["none"] = var_4.agent_type; + level.finalkillcam_inflictor_lastspawntime["none"] = var_4.lastspawntime; + } + else + { + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + } +} + +erasefinalkillcam() +{ + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + level.finalkillcam_delay[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_victim[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_attacker[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_attackernum[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor_agent_type[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_inflictor_lastspawntime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_killcamentityindex[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_killcamentitystarttime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_sweapon[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_deathtimeoffset[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_psoffsettime[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_timerecorded[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_timegameended[level.teamnamelist[var_0]] = undefined; + level.finalkillcam_smeansofdeath[level.teamnamelist[var_0]] = undefined; + } + } + else + { + level.finalkillcam_delay["axis"] = undefined; + level.finalkillcam_victim["axis"] = undefined; + level.finalkillcam_attacker["axis"] = undefined; + level.finalkillcam_attackernum["axis"] = undefined; + level.finalkillcam_inflictor["axis"] = undefined; + level.finalkillcam_inflictor_agent_type["axis"] = undefined; + level.finalkillcam_inflictor_lastspawntime["axis"] = undefined; + level.finalkillcam_killcamentityindex["axis"] = undefined; + level.finalkillcam_killcamentitystarttime["axis"] = undefined; + level.finalkillcam_sweapon["axis"] = undefined; + level.finalkillcam_deathtimeoffset["axis"] = undefined; + level.finalkillcam_psoffsettime["axis"] = undefined; + level.finalkillcam_timerecorded["axis"] = undefined; + level.finalkillcam_timegameended["axis"] = undefined; + level.finalkillcam_smeansofdeath["axis"] = undefined; + level.finalkillcam_delay["allies"] = undefined; + level.finalkillcam_victim["allies"] = undefined; + level.finalkillcam_attacker["allies"] = undefined; + level.finalkillcam_attackernum["allies"] = undefined; + level.finalkillcam_inflictor["allies"] = undefined; + level.finalkillcam_inflictor_agent_type["allies"] = undefined; + level.finalkillcam_inflictor_lastspawntime["allies"] = undefined; + level.finalkillcam_killcamentityindex["allies"] = undefined; + level.finalkillcam_killcamentitystarttime["allies"] = undefined; + level.finalkillcam_sweapon["allies"] = undefined; + level.finalkillcam_deathtimeoffset["allies"] = undefined; + level.finalkillcam_psoffsettime["allies"] = undefined; + level.finalkillcam_timerecorded["allies"] = undefined; + level.finalkillcam_timegameended["allies"] = undefined; + level.finalkillcam_smeansofdeath["allies"] = undefined; + } + + level.finalkillcam_delay["none"] = undefined; + level.finalkillcam_victim["none"] = undefined; + level.finalkillcam_attacker["none"] = undefined; + level.finalkillcam_attackernum["none"] = undefined; + level.finalkillcam_inflictor["none"] = undefined; + level.finalkillcam_inflictor_agent_type["none"] = undefined; + level.finalkillcam_inflictor_lastspawntime["none"] = undefined; + level.finalkillcam_killcamentityindex["none"] = undefined; + level.finalkillcam_killcamentitystarttime["none"] = undefined; + level.finalkillcam_sweapon["none"] = undefined; + level.finalkillcam_deathtimeoffset["none"] = undefined; + level.finalkillcam_psoffsettime["none"] = undefined; + level.finalkillcam_timerecorded["none"] = undefined; + level.finalkillcam_timegameended["none"] = undefined; + level.finalkillcam_smeansofdeath["none"] = undefined; + level.finalkillcam_winner = undefined; +} + +dofinalkillcam() +{ + level waittill( "round_end_finished" ); + level.showingfinalkillcam = 1; + var_0 = "none"; + + if ( isdefined( level.finalkillcam_winner ) ) + var_0 = level.finalkillcam_winner; + + var_1 = level.finalkillcam_delay[var_0]; + var_2 = level.finalkillcam_victim[var_0]; + var_3 = level.finalkillcam_attacker[var_0]; + var_4 = level.finalkillcam_attackernum[var_0]; + var_5 = level.finalkillcam_inflictor[var_0]; + var_6 = level.finalkillcam_inflictor_agent_type[var_0]; + var_7 = level.finalkillcam_inflictor_lastspawntime[var_0]; + var_8 = level.finalkillcam_killcamentityindex[var_0]; + var_9 = level.finalkillcam_killcamentitystarttime[var_0]; + var_10 = level.finalkillcam_sweapon[var_0]; + var_11 = level.finalkillcam_deathtimeoffset[var_0]; + var_12 = level.finalkillcam_psoffsettime[var_0]; + var_13 = level.finalkillcam_timerecorded[var_0]; + var_14 = level.finalkillcam_timegameended[var_0]; + var_15 = level.finalkillcam_smeansofdeath[var_0]; + + if ( !isdefined( var_2 ) || !isdefined( var_3 ) ) + { + level.showingfinalkillcam = 0; + level notify( "final_killcam_done" ); + return; + } + + var_16 = 15; + var_17 = var_14 - var_13; + + if ( var_17 > var_16 ) + { + level.showingfinalkillcam = 0; + level notify( "final_killcam_done" ); + return; + } + + if ( isdefined( var_3 ) ) + { + var_3.finalkill = 1; + var_18 = "none"; + + if ( level.teambased ) + var_18 = var_3.team; + + if ( isdefined( level.finalkillcam_attacker[var_18] ) && level.finalkillcam_attacker[var_18] == var_3 ) + maps\mp\gametypes\_missions::processfinalkillchallenges( var_3, var_2 ); + } + + var_19 = spawnstruct(); + var_19.agent_type = var_6; + var_19.lastspawntime = var_7; + var_20 = ( gettime() - var_2.deathtime ) / 1000; + + foreach ( var_22 in level.players ) + { + var_22 maps\mp\_utility::restorebasevisionset( 0 ); + var_22.killcamentitylookat = var_2 getentitynumber(); + var_22 thread maps\mp\gametypes\_killcam::killcam( var_5, var_19, var_4, var_8, var_9, var_10, var_20 + var_11, var_12, 0, 12, var_3, var_2, var_15 ); + } + + wait 0.1; + + while ( anyplayersinkillcam() ) + wait 0.05; + + level notify( "final_killcam_done" ); + level.showingfinalkillcam = 0; +} + +anyplayersinkillcam() +{ + foreach ( var_1 in level.players ) + { + if ( isdefined( var_1.killcam ) ) + return 1; + } + + return 0; +} + +resetplayervariables() +{ + self.killedplayerscurrent = []; + self.ch_extremecrueltycomplete = 0; + self.switching_teams = undefined; + self.joining_team = undefined; + self.leaving_team = undefined; + self.pers["cur_kill_streak"] = 0; + self.pers["cur_kill_streak_for_nuke"] = 0; + maps\mp\gametypes\_gameobjects::detachusemodels(); +} + +getkillcamentity( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_0 ) || !isdefined( var_1 ) || var_0 == var_1 && !isagent( var_0 ) ) + return undefined; + + switch ( var_2 ) + { + case "trophy_mp": + case "bomb_site_mp": + case "proximity_explosive_mp": + case "heli_pilot_turret_mp": + case "sentry_minigun_mp": + case "hashima_missiles_mp": + return var_1.killcament; + case "remote_tank_projectile_mp": + case "hind_bomb_mp": + case "hind_missile_mp": + case "aamissile_projectile_mp": + if ( isdefined( var_1.vehicle_fired_from ) && isdefined( var_1.vehicle_fired_from.killcament ) ) + return var_1.vehicle_fired_from.killcament; + else if ( isdefined( var_1.vehicle_fired_from ) ) + return var_1.vehicle_fired_from; + + break; + case "sam_projectile_mp": + if ( isdefined( var_1.samturret ) && isdefined( var_1.samturret.killcament ) ) + return var_1.samturret.killcament; + + break; + case "ims_projectile_mp": + if ( isdefined( var_0 ) && isdefined( var_0.imskillcament ) ) + return var_0.imskillcament; + + break; + case "ball_drone_gun_mp": + case "ball_drone_projectile_mp": + if ( isplayer( var_0 ) && isdefined( var_0.balldrone ) && isdefined( var_0.balldrone.turret ) && isdefined( var_0.balldrone.turret.killcament ) ) + return var_0.balldrone.turret.killcament; + + break; + case "none": + case "artillery_mp": + if ( isdefined( var_1.targetname ) && var_1.targetname == "care_package" || isdefined( var_1.killcament ) && ( var_1.classname == "script_brushmodel" || var_1.classname == "trigger_multiple" || var_1.classname == "script_model" ) ) + return var_1.killcament; + + break; + case "ac130_105mm_mp": + case "ac130_40mm_mp": + case "remotemissile_projectile_mp": + case "ac130_25mm_mp": + case "osprey_player_minigun_mp": + case "ugv_turret_mp": + case "remote_turret_mp": + return undefined; + } + + if ( maps\mp\_utility::isdestructibleweapon( var_2 ) || maps\mp\_utility::isbombsiteweapon( var_2 ) ) + { + if ( isdefined( var_1.killcament ) && !var_0 attackerinremotekillstreak() ) + return var_1.killcament; + else + return undefined; + } + + return var_1; +} + +attackerinremotekillstreak() +{ + if ( !isdefined( self ) ) + return 0; + + if ( isdefined( level.ac130player ) && self == level.ac130player ) + return 1; + + if ( isdefined( level.chopper ) && isdefined( level.chopper.gunner ) && self == level.chopper.gunner ) + return 1; + + if ( isdefined( level.remote_mortar ) && isdefined( level.remote_mortar.owner ) && self == level.remote_mortar.owner ) + return 1; + + if ( isdefined( self.using_remote_turret ) && self.using_remote_turret ) + return 1; + + if ( isdefined( self.using_remote_tank ) && self.using_remote_tank ) + return 1; + else if ( isdefined( self.using_remote_a10 ) ) + return 1; + + return 0; +} + +hitlocdebug( var_0, var_1, var_2, var_3, var_4 ) +{ + var_5 = []; + var_5[0] = 2; + var_5[1] = 3; + var_5[2] = 5; + var_5[3] = 7; + + if ( !getdvarint( "scr_hitloc_debug" ) ) + return; + + if ( !isdefined( var_0.hitlocinited ) ) + { + for ( var_6 = 0; var_6 < 6; var_6++ ) + var_0 setclientdvar( "ui_hitloc_" + var_6, "" ); + + var_0.hitlocinited = 1; + } + + if ( level.splitscreen || !isplayer( var_0 ) ) + return; + + var_7 = 6; + + if ( !isdefined( var_0.damageinfo ) ) + { + var_0.damageinfo = []; + + for ( var_6 = 0; var_6 < var_7; var_6++ ) + { + var_0.damageinfo[var_6] = spawnstruct(); + var_0.damageinfo[var_6].damage = 0; + var_0.damageinfo[var_6].hitloc = ""; + var_0.damageinfo[var_6].bp = 0; + var_0.damageinfo[var_6].jugg = 0; + var_0.damageinfo[var_6].colorindex = 0; + } + + var_0.damageinfocolorindex = 0; + var_0.damageinfovictim = undefined; + } + + for ( var_6 = var_7 - 1; var_6 > 0; var_6-- ) + { + var_0.damageinfo[var_6].damage = var_0.damageinfo[var_6 - 1].damage; + var_0.damageinfo[var_6].hitloc = var_0.damageinfo[var_6 - 1].hitloc; + var_0.damageinfo[var_6].bp = var_0.damageinfo[var_6 - 1].bp; + var_0.damageinfo[var_6].jugg = var_0.damageinfo[var_6 - 1].jugg; + var_0.damageinfo[var_6].colorindex = var_0.damageinfo[var_6 - 1].colorindex; + } + + var_0.damageinfo[0].damage = var_2; + var_0.damageinfo[0].hitloc = var_3; + var_0.damageinfo[0].bp = var_4 & level.idflags_penetration; + var_0.damageinfo[0].jugg = var_1 maps\mp\_utility::isjuggernaut(); + + if ( isdefined( var_0.damageinfovictim ) && var_0.damageinfovictim != var_1 ) + { + var_0.damageinfocolorindex++; + + if ( var_0.damageinfocolorindex == var_5.size ) + var_0.damageinfocolorindex = 0; + } + + var_0.damageinfovictim = var_1; + var_0.damageinfo[0].colorindex = var_0.damageinfocolorindex; + + for ( var_6 = 0; var_6 < var_7; var_6++ ) + { + var_8 = "^" + var_5[var_0.damageinfo[var_6].colorindex]; + + if ( var_0.damageinfo[var_6].hitloc != "" ) + { + var_9 = var_8 + var_0.damageinfo[var_6].hitloc; + + if ( var_0.damageinfo[var_6].bp ) + var_9 += " (BP)"; + + if ( var_0.damageinfo[var_6].jugg ) + var_9 += " (Jugg)"; + + var_0 setclientdvar( "ui_hitloc_" + var_6, var_9 ); + } + + var_0 setclientdvar( "ui_hitloc_damage_" + var_6, var_8 + var_0.damageinfo[var_6].damage ); + } +} + +giverecentshieldxp() +{ + self endon( "death" ); + self endon( "disconnect" ); + self notify( "giveRecentShieldXP" ); + self endon( "giveRecentShieldXP" ); + self.recentshieldxp++; + wait 20.0; + self.recentshieldxp = 0; +} + +updateinflictorstat( var_0, var_1, var_2 ) +{ + if ( !isdefined( var_0 ) || !isdefined( var_0.alreadyhit ) || !var_0.alreadyhit || !maps\mp\_utility::issinglehitweapon( var_2 ) ) + maps\mp\gametypes\_gamelogic::setinflictorstat( var_0, var_1, var_2 ); + + if ( isdefined( var_0 ) ) + var_0.alreadyhit = 1; +} + +callback_playerdamage_internal( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + var_1 = maps\mp\_utility::_validateattacker( var_1 ); + var_11 = getdvar( "g_gametype" ); + + if ( isdefined( var_5 ) && var_5 == "MOD_CRUSH" && isdefined( var_0 ) && isdefined( var_0.classname ) && var_0.classname == "script_vehicle" ) + return "crushed"; + + if ( !maps\mp\_utility::isreallyalive( var_2 ) ) + return "!isReallyAlive( victim )"; + + if ( var_6 == "hind_bomb_mp" || var_6 == "hind_missile_mp" ) + { + if ( isdefined( var_1 ) && var_2 == var_1 ) + return 0; + } + + if ( isdefined( var_1 ) && var_1.classname == "script_origin" && isdefined( var_1.type ) && var_1.type == "soft_landing" ) + return "soft_landing"; + + if ( var_6 == "killstreak_emp_mp" ) + return "sWeapon == killstreak_emp_mp"; + + if ( var_6 == "bouncingbetty_mp" && !maps\mp\gametypes\_weapons::minedamageheightpassed( var_0, var_2 ) ) + return "mineDamageHeightPassed"; + + if ( var_6 == "bouncingbetty_mp" && ( var_2 getstance() == "crouch" || var_2 getstance() == "prone" ) ) + var_3 = int( var_3 / 2 ); + + if ( var_6 == "emp_grenade_mp" && var_5 != "MOD_IMPACT" ) + var_2 notify( "emp_damage", var_1 ); + + if ( isdefined( level.hostmigrationtimer ) ) + return "level.hostMigrationTimer"; + + if ( var_5 == "MOD_FALLING" ) + var_2 thread emitfalldamage( var_3 ); + + if ( var_5 == "MOD_EXPLOSIVE_BULLET" && var_3 != 1 ) + { + var_3 *= getdvarfloat( "scr_explBulletMod" ); + var_3 = int( var_3 ); + } + + if ( isdefined( var_1 ) && var_1.classname == "worldspawn" ) + var_1 = undefined; + + if ( isdefined( var_1 ) && isdefined( var_1.gunner ) ) + var_1 = var_1.gunner; + + if ( isdefined( var_0 ) && isdefined( var_0.damagedby ) ) + var_1 = var_0.damagedby; + + var_12 = isdefined( var_1 ) && !isdefined( var_1.gunner ) && ( var_1.classname == "script_vehicle" || var_1.classname == "misc_turret" || var_1.classname == "script_model" ); + var_13 = maps\mp\_utility::attackerishittingteam( var_2, var_1 ); + var_14 = isdefined( var_1 ) && isdefined( var_0 ) && isdefined( var_2 ) && isplayer( var_1 ) && var_1 == var_0 && var_1 == var_2 && !isdefined( var_0.poison ); + + if ( var_14 ) + return "attackerIsInflictorVictim"; + + var_15 = 0.0; + + if ( var_4 & level.idflags_stun ) + { + var_15 = 0.0; + var_3 = 0.0; + } + else if ( var_9 == "shield" ) + { + if ( var_13 && level.friendlyfire == 0 ) + return "attackerIsHittingTeammate"; + + if ( var_5 == "MOD_PISTOL_BULLET" || var_5 == "MOD_RIFLE_BULLET" || var_5 == "MOD_EXPLOSIVE_BULLET" && !var_13 ) + { + if ( isplayer( var_1 ) ) + { + if ( isdefined( var_2.owner ) ) + var_2 = var_2.owner; + + var_1.lastattackedshieldplayer = var_2; + var_1.lastattackedshieldtime = gettime(); + } + + var_2 notify( "shield_blocked" ); + + if ( maps\mp\_utility::isenvironmentweapon( var_6 ) ) + var_16 = 25; + else + var_16 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + var_2.shielddamage += var_16; + + if ( !maps\mp\_utility::isenvironmentweapon( var_6 ) || common_scripts\utility::cointoss() ) + var_2.shieldbullethits++; + + if ( var_2.shieldbullethits >= level.riotshieldxpbullets ) + { + if ( self.recentshieldxp > 4 ) + var_17 = int( 50 / self.recentshieldxp ); + else + var_17 = 50; + + var_2 thread maps\mp\gametypes\_rank::giverankxp( "shield_damage", var_17 ); + var_2 thread giverecentshieldxp(); + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_damage", var_2.shielddamage ); + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_bullet_hits", var_2.shieldbullethits ); + var_2.shielddamage = 0; + var_2.shieldbullethits = 0; + } + } + + if ( var_4 & level.idflags_shield_explosive_impact ) + { + if ( !var_13 ) + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_explosive_hits", 1 ); + + var_9 = "none"; + + if ( !( var_4 & level.idflags_shield_explosive_impact_huge ) ) + var_3 *= 0.0; + } + else if ( var_4 & level.idflags_shield_explosive_splash ) + { + if ( isdefined( var_0 ) && isdefined( var_0.stuckenemyentity ) && var_0.stuckenemyentity == var_2 ) + var_3 = 151; + + var_2 thread maps\mp\gametypes\_missions::genericchallenge( "shield_explosive_hits", 1 ); + var_9 = "none"; + } + else + return "hit shield"; + } + else if ( var_5 == "MOD_MELEE" && maps\mp\gametypes\_weapons::isriotshield( var_6 ) ) + { + if ( !( var_13 && level.friendlyfire == 0 ) ) + { + var_15 = 0.0; + var_2 stunplayer( 0.0 ); + } + } + + if ( isdefined( var_0 ) && isdefined( var_0.stuckenemyentity ) && var_0.stuckenemyentity == var_2 ) + var_3 = 151; + + if ( !var_13 ) + { + if ( maps\mp\_utility::_hasperk( "specialty_moredamage" ) ) + maps\mp\_utility::_unsetperk( "specialty_moredamage" ); + + if ( maps\mp\_utility::isbulletdamage( var_5 ) && var_1 maps\mp\_utility::_hasperk( "specialty_deadeye" ) ) + var_1 maps\mp\perks\_perkfunctions::setdeadeyeinternal(); + + var_3 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9, var_0 ); + + if ( isplayer( var_1 ) && ( var_6 == "smoke_grenade_mp" || var_6 == "throwingknife_mp" ) ) + var_1 thread maps\mp\gametypes\_gamelogic::threadedsetweaponstatbyname( var_6, 1, "hits" ); + } + + if ( isdefined( level.modifyplayerdamage ) ) + var_3 = [[ level.modifyplayerdamage ]]( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + if ( !var_3 ) + return "!iDamage"; + + var_2.idflags = var_4; + var_2.idflagstime = gettime(); + + if ( game["state"] == "postgame" ) + return "game[ state ] == postgame"; + + if ( var_2.sessionteam == "spectator" ) + return "victim.sessionteam == spectator"; + + if ( isdefined( var_2.candocombat ) && !var_2.candocombat ) + return "!victim.canDoCombat"; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_1.candocombat ) && !var_1.candocombat ) + return "!eAttacker.canDoCombat"; + + if ( var_12 && var_13 ) + { + if ( var_5 == "MOD_CRUSH" ) + { + var_2 maps\mp\_utility::_suicide(); + return "suicide crush"; + } + + if ( !level.friendlyfire ) + return "!level.friendlyfire"; + } + + if ( isai( self ) ) + self [[ level.bot_funcs["on_damaged"] ]]( var_1, var_3, var_5, var_6, var_0, var_9 ); + + if ( !isdefined( var_8 ) ) + var_4 |= level.idflags_no_knockback; + + var_18 = 0; + + if ( var_2.health == var_2.maxhealth && ( !isdefined( var_2.laststand ) || !var_2.laststand ) || !isdefined( var_2.attackers ) && !isdefined( var_2.laststand ) ) + var_2 resetattackerlist_internal(); + + if ( maps\mp\_utility::isheadshot( var_6, var_9, var_5, var_1 ) ) + var_5 = "MOD_HEAD_SHOT"; + + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "game", "onlyheadshots" ) ) + { + if ( var_5 == "MOD_PISTOL_BULLET" || var_5 == "MOD_RIFLE_BULLET" || var_5 == "MOD_EXPLOSIVE_BULLET" ) + return "getTweakableValue( game, onlyheadshots )"; + else if ( var_5 == "MOD_HEAD_SHOT" ) + { + if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_3 = 75; + else + var_3 = 150; + } + } + + if ( var_6 == "destructible_toy" && isdefined( var_0 ) ) + var_6 = "destructible_car"; + + if ( gettime() < var_2.spawntime + level.killstreakspawnshield ) + { + var_19 = int( max( var_2.health / 4, 1 ) ); + + if ( var_3 >= var_19 && maps\mp\_utility::iskillstreakweapon( var_6 ) && var_5 != "MOD_MELEE" ) + var_3 = var_19; + } + + if ( !( var_4 & level.idflags_no_protection ) ) + { + if ( !level.teambased && var_12 && isdefined( var_1.owner ) && var_1.owner == var_2 ) + { + if ( var_5 == "MOD_CRUSH" ) + var_2 maps\mp\_utility::_suicide(); + + return "ffa suicide"; + } + + if ( ( issubstr( var_5, "MOD_GRENADE" ) || issubstr( var_5, "MOD_EXPLOSIVE" ) || issubstr( var_5, "MOD_PROJECTILE" ) ) && isdefined( var_0 ) && isdefined( var_1 ) ) + { + if ( var_2 != var_1 && var_0.classname == "grenade" && var_2.lastspawntime + 3500 > gettime() && isdefined( var_2.lastspawnpoint ) && distance( var_0.origin, var_2.lastspawnpoint.origin ) < 500 ) + return "spawnkill grenade protection"; + + var_2.explosiveinfo = []; + var_2.explosiveinfo["damageTime"] = gettime(); + var_2.explosiveinfo["damageId"] = var_0 getentitynumber(); + var_2.explosiveinfo["returnToSender"] = 0; + var_2.explosiveinfo["counterKill"] = 0; + var_2.explosiveinfo["chainKill"] = 0; + var_2.explosiveinfo["cookedKill"] = 0; + var_2.explosiveinfo["throwbackKill"] = 0; + var_2.explosiveinfo["suicideGrenadeKill"] = 0; + var_2.explosiveinfo["weapon"] = var_6; + var_20 = issubstr( var_6, "frag_" ); + + if ( var_1 != var_2 ) + { + if ( ( issubstr( var_6, "c4_" ) || issubstr( var_6, "proximity_explosive_" ) || issubstr( var_6, "claymore_" ) ) && isdefined( var_0.owner ) ) + { + var_2.explosiveinfo["returnToSender"] = var_0.owner == var_2; + var_2.explosiveinfo["counterKill"] = isdefined( var_0.wasdamaged ); + var_2.explosiveinfo["chainKill"] = isdefined( var_0.waschained ); + var_2.explosiveinfo["bulletPenetrationKill"] = isdefined( var_0.wasdamagedfrombulletpenetration ); + var_2.explosiveinfo["cookedKill"] = 0; + } + + if ( isdefined( var_1.lastgrenadesuicidetime ) && var_1.lastgrenadesuicidetime >= gettime() - 50 && var_20 ) + var_2.explosiveinfo["suicideGrenadeKill"] = 1; + } + + if ( var_20 ) + { + var_2.explosiveinfo["cookedKill"] = isdefined( var_0.iscooked ); + var_2.explosiveinfo["throwbackKill"] = isdefined( var_0.threwback ); + } + + var_2.explosiveinfo["stickKill"] = isdefined( var_0.isstuck ) && var_0.isstuck == "enemy"; + var_2.explosiveinfo["stickFriendlyKill"] = isdefined( var_0.isstuck ) && var_0.isstuck == "friendly"; + + if ( isplayer( var_1 ) && var_1 != self && var_11 != "aliens" ) + updateinflictorstat( var_0, var_1, var_6 ); + } + + if ( issubstr( var_5, "MOD_IMPACT" ) && var_6 == "iw6_rgm_mp" ) + { + if ( isplayer( var_1 ) && var_1 != self && var_11 != "aliens" ) + updateinflictorstat( var_0, var_1, var_6 ); + } + + if ( isplayer( var_1 ) && isdefined( var_1.pers["participation"] ) ) + var_1.pers["participation"]++; + else if ( isplayer( var_1 ) ) + var_1.pers["participation"] = 1; + + var_21 = var_2.health / var_2.maxhealth; + + if ( var_13 ) + { + if ( !maps\mp\_utility::matchmakinggame() && isplayer( var_1 ) ) + var_1 maps\mp\_utility::incplayerstat( "mostff", 1 ); + + if ( level.friendlyfire == 0 || !isplayer( var_1 ) && level.friendlyfire != 1 || var_6 == "bomb_site_mp" ) + { + if ( var_6 == "artillery_mp" || var_6 == "stealth_bomb_mp" ) + var_2 damageshellshockandrumble( var_0, var_6, var_5, var_3, var_4, var_1 ); + + return "friendly fire"; + } + else if ( level.friendlyfire == 1 ) + { + if ( var_3 < 1 ) + var_3 = 1; + + if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_3 = maps\mp\perks\_perks::cac_modified_damage( var_2, var_1, var_3, var_5, var_6, var_7, var_8, var_9 ); + + var_2.lastdamagewasfromenemy = 0; + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + } + else if ( level.friendlyfire == 2 && maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_3 = int( var_3 * 0.5 ); + + if ( var_3 < 1 ) + var_3 = 1; + + var_1.lastdamagewasfromenemy = 0; + var_1.friendlydamage = 1; + var_1 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + var_1.friendlydamage = undefined; + } + else if ( level.friendlyfire == 3 && maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_3 = int( var_3 * 0.5 ); + + if ( var_3 < 1 ) + var_3 = 1; + + var_2.lastdamagewasfromenemy = 0; + var_1.lastdamagewasfromenemy = 0; + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + + if ( maps\mp\_utility::isreallyalive( var_1 ) ) + { + var_1.friendlydamage = 1; + var_1 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + var_1.friendlydamage = undefined; + } + } + + var_18 = 1; + } + else + { + if ( var_3 < 1 ) + var_3 = 1; + + if ( isdefined( var_1 ) && isplayer( var_1 ) ) + addattacker( var_2, var_1, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + + if ( isdefined( var_1 ) && !isplayer( var_1 ) && isdefined( var_1.owner ) && ( !isdefined( var_1.scrambled ) || !var_1.scrambled ) ) + addattacker( var_2, var_1.owner, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + else if ( isdefined( var_1 ) && !isplayer( var_1 ) && isdefined( var_1.secondowner ) && isdefined( var_1.scrambled ) && var_1.scrambled ) + addattacker( var_2, var_1.secondowner, var_0, var_6, var_3, var_7, var_8, var_9, var_10, var_5 ); + + if ( var_5 == "MOD_EXPLOSIVE" || var_5 == "MOD_GRENADE_SPLASH" && var_3 < var_2.health ) + var_2 notify( "survived_explosion", var_1 ); + + if ( isdefined( var_1 ) ) + level.lastlegitimateattacker = var_1; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_6 ) ) + var_1 thread maps\mp\gametypes\_weapons::checkhit( var_6, var_2 ); + + if ( isdefined( var_1 ) && isplayer( var_1 ) && isdefined( var_6 ) && var_1 != var_2 ) + { + var_1 thread maps\mp\_events::damagedplayer( self, var_3, var_6 ); + var_2.attackerposition = var_1.origin; + } + else + var_2.attackerposition = undefined; + + if ( issubstr( var_5, "MOD_GRENADE" ) && isdefined( var_0.iscooked ) ) + var_2.wascooked = gettime(); + else + var_2.wascooked = undefined; + + var_2.lastdamagewasfromenemy = isdefined( var_1 ) && var_1 != var_2; + + if ( var_2.lastdamagewasfromenemy ) + { + var_22 = gettime(); + var_1.damagedplayers[var_2.guid] = var_22; + var_2.lastdamagedtime = var_22; + } + + var_2 finishplayerdamagewrapper( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_15 ); + + if ( isdefined( level.ac130player ) && isdefined( var_1 ) && level.ac130player == var_1 ) + level notify( "ai_pain", var_2 ); + + var_2 thread maps\mp\gametypes\_missions::playerdamaged( var_0, var_1, var_3, var_5, var_6, var_9 ); + } + + if ( var_12 && isdefined( var_1.gunner ) ) + var_23 = var_1.gunner; + else + var_23 = var_1; + + if ( isdefined( var_23 ) && var_23 != var_2 && var_3 > 0 && ( !isdefined( var_9 ) || var_9 != "shield" ) ) + { + var_24 = !maps\mp\_utility::isreallyalive( var_2 ) || isagent( var_2 ) && var_3 >= var_2.health; + + if ( var_4 & level.idflags_stun ) + var_25 = "stun"; + else if ( isexplosivedamagemod( var_5 ) && ( isdefined( var_2.thermodebuffed ) && var_2.thermodebuffed ) ) + var_25 = common_scripts\utility::ter_op( var_24, "thermodebuff_kill", "thermobaric_debuff" ); + else if ( isexplosivedamagemod( var_5 ) && var_2 maps\mp\_utility::_hasperk( "_specialty_blastshield" ) && !maps\mp\_utility::weaponignoresblastshield( var_6 ) ) + var_25 = common_scripts\utility::ter_op( var_24, "hitkillblast", "hitblastshield" ); + else if ( var_2 maps\mp\_utility::_hasperk( "specialty_combathigh" ) ) + var_25 = "hitendgame"; + else if ( isdefined( var_2.lightarmorhp ) && var_5 != "MOD_HEAD_SHOT" && !maps\mp\_utility::isfmjdamage( var_6, var_5, var_1 ) ) + var_25 = "hitlightarmor"; + else if ( maps\mp\perks\_perkfunctions::hasheavyarmor( var_2 ) ) + var_25 = "hitlightarmor"; + else if ( var_2 maps\mp\_utility::isjuggernaut() ) + var_25 = common_scripts\utility::ter_op( var_24, "hitkilljugg", "hitjuggernaut" ); + else if ( var_2 maps\mp\_utility::_hasperk( "specialty_moreHealth" ) ) + var_25 = "hitmorehealth"; + else if ( var_23 maps\mp\_utility::_hasperk( "specialty_moredamage" ) ) + { + var_25 = common_scripts\utility::ter_op( var_24, "hitdeadeyekill", "hitcritical" ); + var_23 maps\mp\_utility::_unsetperk( "specialty_moredamage" ); + } + else if ( !shouldweaponfeedback( var_6 ) ) + var_25 = "none"; + else + var_25 = common_scripts\utility::ter_op( var_24, "hitkill", "standard" ); + + var_23 thread maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_25 ); + } + + maps\mp\gametypes\_gamelogic::sethasdonecombat( var_2, 1 ); + } + + if ( isdefined( var_1 ) && var_1 != var_2 && !var_18 ) + level.usestartspawns = 0; + + if ( var_3 > 10 && isdefined( var_0 ) && !var_2 maps\mp\_utility::isusingremote() && isplayer( var_2 ) ) + { + var_2 thread maps\mp\gametypes\_shellshock::bloodeffect( var_0.origin ); + + if ( isplayer( var_0 ) && var_5 == "MOD_MELEE" ) + var_0 thread maps\mp\gametypes\_shellshock::bloodmeleeeffect(); + } + + if ( var_2.sessionstate != "dead" ) + { + var_23 = var_2 getentitynumber(); + var_24 = var_2.name; + var_25 = var_2.pers["team"]; + var_26 = var_2.guid; + var_27 = ""; + + if ( isplayer( var_1 ) ) + { + var_28 = var_1 getentitynumber(); + var_29 = var_1.guid; + var_30 = var_1.name; + var_27 = var_1.pers["team"]; + } + else + { + var_28 = -1; + var_29 = ""; + var_30 = ""; + var_27 = "world"; + } + + logprint( "D;" + var_26 + ";" + var_23 + ";" + var_25 + ";" + var_24 + ";" + var_29 + ";" + var_28 + ";" + var_27 + ";" + var_30 + ";" + var_6 + ";" + var_3 + ";" + var_5 + ";" + var_9 + "\n" ); + } + + hitlocdebug( var_1, var_2, var_3, var_9, var_4 ); + + if ( isdefined( var_1 ) && var_1 != var_2 ) + { + if ( isplayer( var_1 ) ) + var_1 maps\mp\_utility::incplayerstat( "damagedone", var_3 ); + + var_2 maps\mp\_utility::incplayerstat( "damagetaken", var_3 ); + } + + if ( isagent( self ) ) + self [[ maps\mp\agents\_agent_utility::agentfunc( "on_damaged_finished" ) ]]( var_0, var_1, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + + return "finished"; +} + +shouldweaponfeedback( var_0 ) +{ + switch ( var_0 ) + { + case "artillery_mp": + case "stealth_bomb_mp": + return 0; + } + + return 1; +} + +checkvictimstutter( var_0, var_1, var_2, var_3, var_4 ) +{ + if ( var_4 == "MOD_PISTOL_BULLET" || var_4 == "MOD_RIFLE_BULLET" || var_4 == "MOD_HEAD_SHOT" ) + { + if ( distance( var_0.origin, var_1.origin ) > 256 ) + return; + + var_5 = var_0 getvelocity(); + + if ( lengthsquared( var_5 ) < 10 ) + return; + + var_6 = maps\mp\_utility::findisfacing( var_0, var_1, 25 ); + + if ( var_6 ) + var_0 thread stutterstep(); + } +} + +stutterstep( var_0 ) +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); + self.instutter = 1; + self.movespeedscaler = 0.05; + maps\mp\gametypes\_weapons::updatemovespeedscale(); + wait 0.5; + self.movespeedscaler = 1; + + if ( maps\mp\_utility::_hasperk( "specialty_lightweight" ) ) + self.movespeedscaler = maps\mp\_utility::lightweightscalar(); + + maps\mp\gametypes\_weapons::updatemovespeedscale(); + self.instutter = 0; +} + +addattacker( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + if ( !isdefined( var_0.attackerdata ) ) + var_0.attackerdata = []; + + if ( !isdefined( var_0.attackerdata[var_1.guid] ) ) + { + var_0.attackers[var_1.guid] = var_1; + var_0.attackerdata[var_1.guid] = spawnstruct(); + var_0.attackerdata[var_1.guid].damage = 0; + var_0.attackerdata[var_1.guid].attackerent = var_1; + var_0.attackerdata[var_1.guid].firsttimedamaged = gettime(); + } + + if ( maps\mp\gametypes\_weapons::isprimaryweapon( var_3 ) && !maps\mp\gametypes\_weapons::issidearm( var_3 ) ) + var_0.attackerdata[var_1.guid].isprimary = 1; + + var_0.attackerdata[var_1.guid].damage += var_4; + var_0.attackerdata[var_1.guid].weapon = var_3; + var_0.attackerdata[var_1.guid].vpoint = var_5; + var_0.attackerdata[var_1.guid].vdir = var_6; + var_0.attackerdata[var_1.guid].shitloc = var_7; + var_0.attackerdata[var_1.guid].psoffsettime = var_8; + var_0.attackerdata[var_1.guid].smeansofdeath = var_9; + var_0.attackerdata[var_1.guid].attackerent = var_1; + var_0.attackerdata[var_1.guid].lasttimedamaged = gettime(); + + if ( isdefined( var_2 ) && !isplayer( var_2 ) && isdefined( var_2.primaryweapon ) ) + var_0.attackerdata[var_1.guid].sprimaryweapon = var_2.primaryweapon; + else if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_0.attackerdata[var_1.guid].sprimaryweapon = var_1 getcurrentprimaryweapon(); + else + var_0.attackerdata[var_1.guid].sprimaryweapon = undefined; +} + +resetattackerlist( var_0 ) +{ + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); + wait 1.75; + resetattackerlist_internal(); +} + +resetattackerlist_internal() +{ + self.attackers = []; + self.attackerdata = []; +} + +callback_playerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + var_10 = callback_playerdamage_internal( var_0, var_1, self, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); +} + +finishplayerdamagewrapper( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ) +{ + if ( maps\mp\_utility::isusingremote() && var_2 >= self.health && !( var_3 & level.idflags_stun ) && allowfauxdeath() || maps\mp\_utility::isrocketcorpse() ) + { + if ( !isdefined( var_7 ) ) + var_7 = ( 0, 0, 0 ); + + if ( !isdefined( var_1 ) && !isdefined( var_0 ) ) + { + var_1 = self; + var_0 = var_1; + } + + playerkilled_internal( var_0, var_1, self, var_2, var_4, var_5, var_7, var_8, var_9, 0, 1 ); + } + else + { + if ( !callback_killingblow( var_0, var_1, var_2 - var_2 * var_10, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) ) + return; + + if ( !isalive( self ) ) + return; + + if ( isplayer( self ) ) + self finishplayerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10 ); + } + + if ( var_4 == "MOD_EXPLOSIVE_BULLET" && !maps\mp\_utility::is_aliens() ) + self shellshock( "damage_mp", getdvarfloat( "scr_csmode" ) ); + + damageshellshockandrumble( var_0, var_5, var_4, var_2, var_3, var_1 ); +} + +allowfauxdeath() +{ + if ( !isdefined( level.allowfauxdeath ) ) + level.allowfauxdeath = 1; + + return level.allowfauxdeath; +} + +callback_playerlaststand( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 ) +{ + var_9 = spawnstruct(); + var_9.einflictor = var_0; + var_9.attacker = var_1; + var_9.idamage = var_2; + var_9.attackerposition = var_1.origin; + + if ( var_1 == self ) + var_9.smeansofdeath = "MOD_SUICIDE"; + else + var_9.smeansofdeath = var_3; + + var_9.sweapon = var_4; + + if ( isdefined( var_1 ) && isplayer( var_1 ) && var_1 getcurrentprimaryweapon() != "none" ) + var_9.sprimaryweapon = var_1 getcurrentprimaryweapon(); + else + var_9.sprimaryweapon = undefined; + + var_9.vdir = var_5; + var_9.shitloc = var_6; + var_9.laststandstarttime = gettime(); + var_10 = maydolaststand( var_4, var_3, var_6 ); + + if ( isdefined( self.endgame ) ) + var_10 = 0; + + if ( level.teambased && isdefined( var_1.team ) && var_1.team == self.team ) + var_10 = 0; + + if ( level.diehardmode ) + { + if ( level.teamcount[self.team] <= 1 ) + var_10 = 0; + else if ( maps\mp\_utility::isteaminlaststand() ) + { + var_10 = 0; + maps\mp\_utility::killteaminlaststand( self.team ); + } + } + + if ( !var_10 ) + { + self.laststandparams = var_9; + self.uselaststandparams = 1; + maps\mp\_utility::_suicide(); + } + else + { + self.inlaststand = 1; + var_11 = spawnstruct(); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) ) + { + var_11.titletext = game["strings"]["final_stand"]; + var_11.iconname = "specialty_finalstand"; + } + else if ( maps\mp\_utility::_hasperk( "specialty_c4death" ) ) + { + var_11.titletext = game["strings"]["c4_death"]; + var_11.iconname = "specialty_c4death"; + } + else + { + var_11.titletext = game["strings"]["last_stand"]; + var_11.iconname = "specialty_finalstand"; + } + + var_11.glowcolor = ( 1, 0, 0 ); + var_11.sound = "mp_last_stand"; + var_11.duration = 2.0; + self.health = 1; + thread maps\mp\gametypes\_hud_message::notifymessage( var_11 ); + var_12 = "frag_grenade_mp"; + + if ( isdefined( level.ac130player ) && isdefined( var_1 ) && level.ac130player == var_1 ) + level notify( "ai_crawling", self ); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) ) + { + self.laststandparams = var_9; + self.infinalstand = 1; + var_13 = self getweaponslistexclusives(); + + foreach ( var_15 in var_13 ) + self takeweapon( var_15 ); + + common_scripts\utility::_disableusability(); + thread enablelaststandweapons(); + thread laststandtimer( 20, 1 ); + } + else if ( maps\mp\_utility::_hasperk( "specialty_c4death" ) ) + { + self.previousprimary = self.lastdroppableweapon; + self.laststandparams = var_9; + self takeallweapons(); + self giveweapon( "c4death_mp", 0, 0 ); + self switchtoweapon( "c4death_mp" ); + common_scripts\utility::_disableusability(); + self.inc4death = 1; + thread laststandtimer( 20, 0 ); + thread detonateonuse(); + thread detonateondeath(); + } + else + { + if ( level.diehardmode ) + { + var_1 maps\mp\gametypes\_rank::giverankxp( "kill", 100, var_4, var_3 ); + self.laststandparams = var_9; + common_scripts\utility::_disableweapon(); + thread laststandtimer( 20, 0 ); + common_scripts\utility::_disableusability(); + return; + } + + self.laststandparams = var_9; + var_17 = undefined; + var_18 = self getweaponslistprimaries(); + + foreach ( var_15 in var_18 ) + { + if ( maps\mp\gametypes\_weapons::issidearm( var_15 ) ) + var_17 = var_15; + } + + if ( !isdefined( var_17 ) ) + { + var_17 = "iw6_p226_mp"; + maps\mp\_utility::_giveweapon( var_17 ); + } + + self givemaxammo( var_17 ); + self disableweaponswitch(); + common_scripts\utility::_disableusability(); + + if ( !maps\mp\_utility::_hasperk( "specialty_laststandoffhand" ) ) + self disableoffhandweapons(); + + self switchtoweapon( var_17 ); + thread laststandtimer( 10, 0 ); + } + } +} + +dieaftertime( var_0 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + wait(var_0); + self.uselaststandparams = 1; + maps\mp\_utility::_suicide(); +} + +detonateonuse() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + self waittill( "detonate" ); + self.uselaststandparams = 1; + c4deathdetonate(); +} + +detonateondeath() +{ + self endon( "detonate" ); + self endon( "disconnect" ); + self endon( "joined_team" ); + level endon( "game_ended" ); + self waittill( "death" ); + c4deathdetonate(); +} + +c4deathdetonate() +{ + self playsound( "detpack_explo_default" ); + radiusdamage( self.origin, 312, 100, 100, self ); + + if ( isalive( self ) ) + maps\mp\_utility::_suicide(); +} + +enablelaststandweapons() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + maps\mp\_utility::freezecontrolswrapper( 1 ); + wait 0.3; + maps\mp\_utility::freezecontrolswrapper( 0 ); +} + +laststandtimer( var_0, var_1 ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "revive" ); + level endon( "game_ended" ); + level notify( "player_last_stand" ); + thread laststandwaittilldeath(); + self.laststand = 1; + + if ( !var_1 && ( !isdefined( self.inc4death ) || !self.inc4death ) ) + { + thread laststandallowsuicide(); + maps\mp\_utility::setlowermessage( "last_stand", &"PLATFORM_COWARDS_WAY_OUT", undefined, undefined, undefined, undefined, undefined, undefined, 1 ); + thread laststandkeepoverlay(); + } + + if ( level.diehardmode == 1 && level.diehardmode != 2 ) + { + var_2 = spawn( "script_model", self.origin ); + var_2 setmodel( "tag_origin" ); + var_2 setcursorhint( "HINT_NOICON" ); + var_2 sethintstring( &"PLATFORM_REVIVE" ); + var_2 revivesetup( self ); + var_2 endon( "death" ); + var_3 = newteamhudelem( self.team ); + var_3 setshader( "waypoint_revive", 8, 8 ); + var_3 setwaypoint( 1, 1 ); + var_3 settargetent( self ); + var_3 thread destroyonreviveentdeath( var_2 ); + var_3.color = ( 0.33, 0.75, 0.24 ); + maps\mp\_utility::playdeathsound(); + + if ( var_1 ) + { + wait(var_0); + + if ( self.infinalstand ) + thread laststandbleedout( var_1, var_2 ); + } + + return; + } + else if ( level.diehardmode == 2 ) + { + thread laststandkeepoverlay(); + var_2 = spawn( "script_model", self.origin ); + var_2 setmodel( "tag_origin" ); + var_2 setcursorhint( "HINT_NOICON" ); + var_2 sethintstring( &"PLATFORM_REVIVE" ); + var_2 revivesetup( self ); + var_2 endon( "death" ); + var_3 = newteamhudelem( self.team ); + var_3 setshader( "waypoint_revive", 8, 8 ); + var_3 setwaypoint( 1, 1 ); + var_3 settargetent( self ); + var_3 thread destroyonreviveentdeath( var_2 ); + var_3.color = ( 0.33, 0.75, 0.24 ); + maps\mp\_utility::playdeathsound(); + + if ( var_1 ) + { + wait(var_0); + + if ( self.infinalstand ) + thread laststandbleedout( var_1, var_2 ); + } + + wait(var_0 / 3); + var_3.color = ( 1, 0.64, 0 ); + + while ( var_2.inuse ) + wait 0.05; + + maps\mp\_utility::playdeathsound(); + wait(var_0 / 3); + var_3.color = ( 1, 0, 0 ); + + while ( var_2.inuse ) + wait 0.05; + + maps\mp\_utility::playdeathsound(); + wait(var_0 / 3); + + while ( var_2.inuse ) + wait 0.05; + + wait 0.05; + thread laststandbleedout( var_1 ); + return; + } + + thread laststandkeepoverlay(); + wait(var_0); + thread laststandbleedout( var_1 ); +} + +maxhealthoverlay( var_0, var_1 ) +{ + self endon( "stop_maxHealthOverlay" ); + self endon( "revive" ); + self endon( "death" ); + + for (;;) + { + self.health -= 1; + self.maxhealth = var_0; + wait 0.05; + self.maxhealth = 50; + self.health += 1; + wait 0.5; + } +} + +laststandbleedout( var_0, var_1 ) +{ + if ( var_0 ) + { + self.laststand = undefined; + self.infinalstand = 0; + self notify( "revive" ); + maps\mp\_utility::clearlowermessage( "last_stand" ); + maps\mp\gametypes\_playerlogic::laststandrespawnplayer(); + + if ( isdefined( var_1 ) ) + var_1 delete(); + } + else + { + self.uselaststandparams = 1; + self.beingrevived = 0; + maps\mp\_utility::_suicide(); + } +} + +laststandallowsuicide() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "game_ended" ); + self endon( "revive" ); + + for (;;) + { + if ( self usebuttonpressed() ) + { + var_0 = gettime(); + + while ( self usebuttonpressed() ) + { + wait 0.05; + + if ( gettime() - var_0 > 700 ) + break; + } + + if ( gettime() - var_0 > 700 ) + break; + } + + wait 0.05; + } + + thread laststandbleedout( 0 ); +} + +laststandkeepoverlay() +{ + level endon( "game_ended" ); + self endon( "death" ); + self endon( "disconnect" ); + self endon( "revive" ); + + while ( !level.gameended ) + { + self.health = 2; + wait 0.05; + self.health = 1; + wait 0.5; + } + + self.health = self.maxhealth; +} + +laststandwaittilldeath() +{ + self endon( "disconnect" ); + self endon( "revive" ); + level endon( "game_ended" ); + self waittill( "death" ); + maps\mp\_utility::clearlowermessage( "last_stand" ); + self.laststand = undefined; +} + +maydolaststand( var_0, var_1, var_2 ) +{ + if ( var_1 == "MOD_TRIGGER_HURT" ) + return 0; + + if ( var_1 != "MOD_PISTOL_BULLET" && var_1 != "MOD_RIFLE_BULLET" && var_1 != "MOD_FALLING" && var_1 != "MOD_EXPLOSIVE_BULLET" ) + return 0; + + if ( var_1 == "MOD_IMPACT" && maps\mp\gametypes\_weapons::isthrowingknife( var_0 ) ) + return 0; + + if ( var_1 == "MOD_IMPACT" && ( var_0 == "m79_mp" || issubstr( var_0, "gl_" ) ) ) + return 0; + + if ( maps\mp\_utility::isheadshot( var_0, var_2, var_1 ) ) + return 0; + + if ( maps\mp\_utility::isusingremote() ) + return 0; + + return 1; +} + +ensurelaststandparamsvalidity() +{ + if ( !isdefined( self.laststandparams.attacker ) ) + self.laststandparams.attacker = self; +} + +gethitlocheight( var_0 ) +{ + switch ( var_0 ) + { + case "head": + case "helmet": + case "neck": + return 60; + case "gun": + case "torso_upper": + case "right_arm_upper": + case "left_arm_upper": + case "right_arm_lower": + case "left_arm_lower": + case "right_hand": + case "left_hand": + return 48; + case "torso_lower": + return 40; + case "right_leg_upper": + case "left_leg_upper": + return 32; + case "right_leg_lower": + case "left_leg_lower": + return 10; + case "right_foot": + case "left_foot": + return 5; + } + + return 48; +} + +delaystartragdoll( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + if ( isdefined( var_0 ) ) + { + var_6 = var_0 getcorpseanim(); + + if ( animhasnotetrack( var_6, "ignore_ragdoll" ) ) + return; + } + + if ( isdefined( level.noragdollents ) && level.noragdollents.size ) + { + foreach ( var_8 in level.noragdollents ) + { + if ( distancesquared( var_0.origin, var_8.origin ) < 65536 ) + return; + } + } + + wait 0.2; + + if ( !isdefined( var_0 ) ) + return; + + if ( var_0 isragdoll() ) + return; + + var_6 = var_0 getcorpseanim(); + var_10 = 0.35; + + if ( animhasnotetrack( var_6, "start_ragdoll" ) ) + { + var_11 = getnotetracktimes( var_6, "start_ragdoll" ); + + if ( isdefined( var_11 ) ) + var_10 = var_11[0]; + } + + var_12 = var_10 * getanimlength( var_6 ); + wait(var_12); + + if ( isdefined( var_0 ) ) + var_0 startragdoll(); +} + +getmostkilledby() +{ + var_0 = ""; + var_1 = 0; + var_2 = getarraykeys( self.killedby ); + + for ( var_3 = 0; var_3 < var_2.size; var_3++ ) + { + var_4 = var_2[var_3]; + + if ( self.killedby[var_4] <= var_1 ) + continue; + + var_1 = self.killedby[var_4]; + var_5 = var_4; + } + + return var_0; +} + +getmostkilled() +{ + var_0 = ""; + var_1 = 0; + var_2 = getarraykeys( self.killedplayers ); + + for ( var_3 = 0; var_3 < var_2.size; var_3++ ) + { + var_4 = var_2[var_3]; + + if ( self.killedplayers[var_4] <= var_1 ) + continue; + + var_1 = self.killedplayers[var_4]; + var_0 = var_4; + } + + return var_0; +} + +damageshellshockandrumble( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + thread maps\mp\gametypes\_weapons::onweapondamage( var_0, var_1, var_2, var_3, var_5 ); + + if ( !isai( self ) ) + self playrumbleonentity( "damage_heavy" ); +} + +revivesetup( var_0 ) +{ + var_1 = var_0.team; + self linkto( var_0, "tag_origin" ); + self.owner = var_0; + self.inuse = 0; + self makeusable(); + updateusablebyteam( var_1 ); + thread trackteamchanges( var_1 ); + thread revivetriggerthink( var_1 ); + thread deleteonreviveordeathordisconnect(); +} + +deleteonreviveordeathordisconnect() +{ + self endon( "death" ); + self.owner common_scripts\utility::waittill_any( "death", "disconnect" ); + self delete(); +} + +updateusablebyteam( var_0 ) +{ + foreach ( var_2 in level.players ) + { + if ( var_0 == var_2.team && var_2 != self.owner ) + { + self enableplayeruse( var_2 ); + continue; + } + + self disableplayeruse( var_2 ); + } +} + +trackteamchanges( var_0 ) +{ + self endon( "death" ); + + for (;;) + { + level waittill( "joined_team" ); + updateusablebyteam( var_0 ); + } +} + +tracklaststandchanges( var_0 ) +{ + self endon( "death" ); + + for (;;) + { + level waittill( "player_last_stand" ); + updateusablebyteam( var_0 ); + } +} + +revivetriggerthink( var_0 ) +{ + self endon( "death" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "trigger", var_1 ); + self.owner.beingrevived = 1; + + if ( isdefined( var_1.beingrevived ) && var_1.beingrevived ) + { + self.owner.beingrevived = 0; + continue; + } + + self makeunusable(); + self.owner maps\mp\_utility::freezecontrolswrapper( 1 ); + var_2 = useholdthink( var_1 ); + self.owner.beingrevived = 0; + + if ( !isalive( self.owner ) ) + { + self delete(); + return; + } + + self.owner maps\mp\_utility::freezecontrolswrapper( 0 ); + + if ( var_2 ) + { + var_1 thread maps\mp\gametypes\_hud_message::splashnotifydelayed( "reviver", maps\mp\gametypes\_rank::getscoreinfovalue( "reviver" ) ); + var_1 thread maps\mp\gametypes\_rank::giverankxp( "reviver" ); + self.owner.laststand = undefined; + self.owner maps\mp\_utility::clearlowermessage( "last_stand" ); + self.owner.movespeedscaler = 1; + + if ( self.owner maps\mp\_utility::_hasperk( "specialty_lightweight" ) ) + self.owner.movespeedscaler = maps\mp\_utility::lightweightscalar(); + + self.owner common_scripts\utility::_enableweapon(); + self.owner.maxhealth = 100; + self.owner maps\mp\gametypes\_weapons::updatemovespeedscale(); + self.owner maps\mp\gametypes\_playerlogic::laststandrespawnplayer(); + self.owner maps\mp\_utility::giveperk( "specialty_pistoldeath", 0 ); + self.owner.beingrevived = 0; + self delete(); + return; + } + + self makeusable(); + updateusablebyteam( var_0 ); + } +} + +useholdthink( var_0, var_1 ) +{ + var_2 = 3000; + var_3 = spawn( "script_origin", self.origin ); + var_3 hide(); + var_0 playerlinkto( var_3 ); + var_0 playerlinkedoffsetenable(); + var_0 common_scripts\utility::_disableweapon(); + self.curprogress = 0; + self.inuse = 1; + self.userate = 0; + + if ( isdefined( var_1 ) ) + self.usetime = var_1; + else + self.usetime = var_2; + + var_4 = useholdthinkloop( var_0 ); + self.inuse = 0; + var_3 delete(); + + if ( isdefined( var_0 ) && maps\mp\_utility::isreallyalive( var_0 ) ) + { + var_0 unlink(); + var_0 common_scripts\utility::_enableweapon(); + } + + if ( isdefined( var_4 ) && var_4 ) + { + self.owner thread maps\mp\gametypes\_hud_message::playercardsplashnotify( "revived", var_0 ); + self.owner.inlaststand = 0; + return 1; + } + + return 0; +} + +useholdthinkloop( var_0 ) +{ + level endon( "game_ended" ); + self.owner endon( "death" ); + self.owner endon( "disconnect" ); + + while ( maps\mp\_utility::isreallyalive( var_0 ) && var_0 usebuttonpressed() && self.curprogress < self.usetime && ( !isdefined( var_0.laststand ) || !var_0.laststand ) ) + { + self.curprogress += 50 * self.userate; + self.userate = 1; + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 1 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 1 ); + + if ( self.curprogress >= self.usetime ) + { + self.inuse = 0; + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + return maps\mp\_utility::isreallyalive( var_0 ); + } + + wait 0.05; + } + + var_0 maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + self.owner maps\mp\gametypes\_gameobjects::updateuiprogress( self, 0 ); + return 0; +} + +callback_killingblow( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) +{ + if ( isdefined( self.lastdamagewasfromenemy ) && self.lastdamagewasfromenemy && var_2 >= self.health && isdefined( self.combathigh ) && self.combathigh == "specialty_endgame" ) + { + maps\mp\_utility::giveperk( "specialty_endgame", 0 ); + return 0; + } + + return 1; +} + +emitfalldamage( var_0 ) +{ + physicsexplosionsphere( self.origin, 64, 64, 1 ); + var_1 = []; + + for ( var_2 = 0; var_2 < 360; var_2 += 30 ) + { + var_3 = cos( var_2 ) * 16; + var_4 = sin( var_2 ) * 16; + var_5 = bullettrace( self.origin + ( var_3, var_4, 4 ), self.origin + ( var_3, var_4, -6 ), 1, self ); + + if ( isdefined( var_5["entity"] ) && isdefined( var_5["entity"].targetname ) && ( var_5["entity"].targetname == "destructible_vehicle" || var_5["entity"].targetname == "destructible_toy" ) ) + var_1[var_1.size] = var_5["entity"]; + } + + if ( var_1.size ) + { + var_6 = spawn( "script_origin", self.origin ); + var_6 hide(); + var_6.type = "soft_landing"; + var_6.destructibles = var_1; + radiusdamage( self.origin, 64, 100, 100, var_6 ); + wait 0.1; + var_6 delete(); + } +} + +isflankkill( var_0, var_1 ) +{ + var_2 = anglestoforward( var_0.angles ); + var_2 = ( var_2[0], var_2[1], 0 ); + var_2 = vectornormalize( var_2 ); + var_3 = var_0.origin - var_1.origin; + var_3 = ( var_3[0], var_3[1], 0 ); + var_3 = vectornormalize( var_3 ); + var_4 = vectordot( var_2, var_3 ); + + if ( var_4 > 0 ) + return 1; + else + return 0; +} + +logprintplayerdeath( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + var_7 = self getentitynumber(); + var_8 = self.name; + var_9 = self.team; + var_10 = self.guid; + + if ( isplayer( var_1 ) ) + { + var_11 = var_1.guid; + var_12 = var_1.name; + var_13 = var_1.team; + var_14 = var_1 getentitynumber(); + var_15 = var_1 getxuid() + "(" + var_12 + ")"; + } + else + { + var_11 = ""; + var_12 = ""; + var_13 = "world"; + var_14 = -1; + var_15 = "none"; + } + + logprint( "k;" + var_10 + ";" + var_7 + ";" + var_9 + ";" + var_8 + ";" + var_11 + ";" + var_14 + ";" + var_13 + ";" + var_12 + ";" + var_4 + ";" + var_2 + ";" + var_3 + ";" + var_6 + "\n" ); +} + +destroyonreviveentdeath( var_0 ) +{ + var_0 waittill( "death" ); + self destroy(); +} + +gamemodemodifyplayerdamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 ) +{ + if ( isdefined( var_1 ) && isplayer( var_1 ) && isalive( var_1 ) ) + { + if ( level.matchrules_damagemultiplier ) + var_2 *= level.matchrules_damagemultiplier; + + if ( level.matchrules_vampirism ) + var_1.health = int( min( float( var_1.maxhealth ), float( var_1.health + 20 ) ) ); + } + + return var_2; +} + +registerkill( var_0, var_1 ) +{ + thread maps\mp\killstreaks\_killstreaks::giveadrenaline( "kill" ); + self.pers["cur_kill_streak"]++; + + if ( var_1 ) + self notify( "kill_streak_increased" ); + + var_2 = !maps\mp\_utility::iskillstreakweapon( var_0 ); + + if ( var_2 ) + self.pers["cur_kill_streak_for_nuke"]++; + + var_3 = 25; + + if ( maps\mp\_utility::_hasperk( "specialty_hardline" ) ) + var_3--; + + if ( var_2 && self.pers["cur_kill_streak_for_nuke"] == var_3 && !maps\mp\_utility::isanymlgmatch() ) + { + if ( !isdefined( level.supportnuke ) || level.supportnuke ) + giveultimatekillstreak( var_3 ); + } +} + +giveultimatekillstreak( var_0 ) +{ + thread maps\mp\killstreaks\_killstreaks::givekillstreak( "nuke", 0, 1, self ); + thread maps\mp\gametypes\_hud_message::killstreaksplashnotify( "nuke", var_0 ); +} + +monitordamage( var_0, var_1, var_2, var_3, var_4, var_5 ) +{ + self endon( "death" ); + level endon( "game_ended" ); + + if ( !isdefined( var_5 ) ) + var_5 = 0; + + self setcandamage( 1 ); + self.health = 999999; + self.maxhealth = var_0; + self.damagetaken = 0; + + if ( !isdefined( var_4 ) ) + var_4 = 0; + + for ( var_6 = 1; var_6; var_6 = monitordamageoneshot( var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14, var_15, var_16, var_1, var_2, var_3, var_4 ) ) + { + self waittill( "damage", var_7, var_8, var_9, var_10, var_11, var_12, var_13, var_14, var_15, var_16 ); + + if ( var_5 ) + self playrumbleonentity( "damage_light" ); + + if ( isdefined( self.helitype ) && self.helitype == "littlebird" ) + { + if ( !isdefined( self.attackers ) ) + self.attackers = []; + + var_17 = ""; + + if ( isdefined( var_8 ) && isplayer( var_8 ) ) + var_17 = var_8 maps\mp\_utility::getuniqueid(); + + if ( isdefined( self.attackers[var_17] ) ) + self.attackers[var_17] += var_7; + else + self.attackers[var_17] = var_7; + } + } +} + +monitordamageoneshot( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11, var_12, var_13 ) +{ + if ( !isdefined( self ) ) + return 0; + + if ( isdefined( var_1 ) && !maps\mp\_utility::isgameparticipant( var_1 ) && !isdefined( var_1.allowmonitoreddamage ) ) + return 1; + + if ( maps\mp\_utility::is_aliens() || isdefined( var_1 ) && !maps\mp\gametypes\_weapons::friendlyfirecheck( self.owner, var_1 ) ) + return 1; + + var_14 = var_0; + + if ( isdefined( var_9 ) ) + { + switch ( var_9 ) + { + case "flash_grenade_mp": + case "smoke_grenade_mp": + case "smoke_grenadejugg_mp": + case "concussion_grenade_mp": + return 1; + } + + if ( !isdefined( var_12 ) ) + var_12 = ::modifydamage; + + var_14 = [[ var_12 ]]( var_1, var_9, var_4, var_0 ); + } + + if ( var_14 < 0 ) + return 1; + + self.wasdamaged = 1; + self.damagetaken += var_14; + + if ( isdefined( var_8 ) && var_8 & level.idflags_penetration ) + self.wasdamagedfrombulletpenetration = 1; + + if ( var_13 ) + maps\mp\killstreaks\_killstreaks::killstreakhit( var_1, var_9, self ); + + if ( isdefined( var_1 ) ) + { + if ( isplayer( var_1 ) ) + { + if ( self.damagetaken >= self.maxhealth ) + var_10 = "hitkill"; + + var_1 maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_10 ); + } + else if ( isdefined( var_1.owner ) && isplayer( var_1.owner ) ) + var_1.owner maps\mp\gametypes\_damagefeedback::updatedamagefeedback( var_10 ); + } + + if ( self.damagetaken >= self.maxhealth ) + { + self thread [[ var_11 ]]( var_1, var_9, var_4, var_0 ); + return 0; + } + + return 1; +} + +modifydamage( var_0, var_1, var_2, var_3 ) +{ + var_4 = var_3; + var_4 = handleempdamage( var_1, var_2, var_4 ); + var_4 = handlemissiledamage( var_1, var_2, var_4 ); + var_4 = handlegrenadedamage( var_1, var_2, var_4 ); + var_4 = handleapdamage( var_1, var_2, var_4, var_0 ); + return var_4; +} + +handlemissiledamage( var_0, var_1, var_2 ) +{ + var_3 = var_2; + + switch ( var_0 ) + { + case "bomb_site_mp": + case "iw6_maawschild_mp": + case "iw6_maawshoming_mp": + case "iw6_maaws_mp": + case "iw6_panzerfaust3_mp": + case "drone_hive_projectile_mp": + case "odin_projectile_large_rod_mp": + case "odin_projectile_small_rod_mp": + case "aamissile_projectile_mp": + case "ac130_105mm_mp": + case "ac130_40mm_mp": + case "maverick_projectile_mp": + self.largeprojectiledamage = 1; + var_3 = self.maxhealth + 1; + break; + case "remote_tank_projectile_mp": + case "switch_blade_child_mp": + case "hind_bomb_mp": + case "hind_missile_mp": + self.largeprojectiledamage = 0; + var_3 = self.maxhealth + 1; + break; + case "heli_pilot_turret_mp": + case "a10_30mm_turret_mp": + self.largeprojectiledamage = 0; + var_3 *= 2; + break; + case "sam_projectile_mp": + self.largeprojectiledamage = 1; + var_3 = var_2; + break; + } + + return var_3; +} + +handlegrenadedamage( var_0, var_1, var_2 ) +{ + if ( isexplosivedamagemod( var_1 ) ) + { + switch ( var_0 ) + { + case "mortar_shell_mp": + case "c4_mp": + case "proximity_explosive_mp": + case "iw6_rgm_mp": + var_2 *= 3; + break; + case "frag_grenade_mp": + case "semtex_mp": + case "semtexproj_mp": + case "iw6_mk32_mp": + var_2 *= 4; + break; + default: + if ( maps\mp\_utility::isstrstart( var_0, "alt_" ) ) + var_2 *= 3; + + break; + } + } + + return var_2; +} + +handlemeleedamage( var_0, var_1, var_2 ) +{ + if ( var_1 == "MOD_MELEE" ) + return self.maxhealth + 1; + + return var_2; +} + +handleempdamage( var_0, var_1, var_2 ) +{ + if ( var_0 == "emp_grenade_mp" && var_1 == "MOD_GRENADE_SPLASH" ) + { + self notify( "emp_damage", var_0.owner, 8.0 ); + return 0; + } + + return var_2; +} + +handleapdamage( var_0, var_1, var_2, var_3 ) +{ + if ( var_1 == "MOD_RIFLE_BULLET" || var_1 == "MOD_PISTOL_BULLET" ) + { + if ( var_3 maps\mp\_utility::_hasperk( "specialty_armorpiercing" ) || maps\mp\_utility::isfmjdamage( var_0, var_1, var_3 ) ) + return var_2 * level.armorpiercingmod; + } + + return var_2; +} + +onkillstreakkilled( var_0, var_1, var_2, var_3, var_4, var_5, var_6 ) +{ + var_7 = 0; + var_8 = undefined; + + if ( isdefined( var_0 ) && isdefined( self.owner ) ) + { + if ( isdefined( var_0.owner ) && isplayer( var_0.owner ) ) + var_0 = var_0.owner; + + if ( self.owner maps\mp\_utility::isenemy( var_0 ) ) + var_8 = var_0; + } + + if ( isdefined( var_8 ) ) + { + var_8 notify( "destroyed_killstreak", var_1 ); + var_9 = 100; + + if ( isdefined( var_4 ) ) + { + var_9 = maps\mp\gametypes\_rank::getscoreinfovalue( var_4 ); + var_8 thread maps\mp\gametypes\_rank::xpeventpopup( var_4 ); + } + + var_8 thread maps\mp\gametypes\_rank::giverankxp( "kill", var_9, var_1, var_2 ); + + if ( isdefined( var_6 ) ) + thread maps\mp\_utility::teamplayercardsplash( var_6, var_8 ); + + thread maps\mp\gametypes\_missions::killstreakkilled( self.owner, self, undefined, var_8, var_3, var_2, var_1 ); + var_7 = 1; + } + + if ( isdefined( self.owner ) && isdefined( var_5 ) ) + self.owner thread maps\mp\_utility::leaderdialogonplayer( var_5, undefined, undefined, self.origin ); + + self notify( "death" ); + return var_7; +} diff --git a/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_menus.gsc b/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_menus.gsc new file mode 100644 index 0000000..13180b7 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_menus.gsc @@ -0,0 +1,727 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +init() +{ + if ( !isdefined( game["gamestarted"] ) ) + { + game["menu_team"] = "team_marinesopfor"; + + if ( level.multiteambased ) + game["menu_team"] = "team_mt_options"; + + if ( maps\mp\_utility::bot_is_fireteam_mode() ) + { + level.fireteam_menu = "class_commander_" + level.gametype; + game["menu_class"] = level.fireteam_menu; + game["menu_class_allies"] = level.fireteam_menu; + game["menu_class_axis"] = level.fireteam_menu; + } + else + { + game["menu_class"] = "class"; + game["menu_class_allies"] = "class_marines"; + game["menu_class_axis"] = "class_opfor"; + } + + game["menu_changeclass_allies"] = "changeclass_marines"; + game["menu_changeclass_axis"] = "changeclass_opfor"; + + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + var_1 = "menu_class_" + level.teamnamelist[var_0]; + var_2 = "menu_changeclass_" + level.teamnamelist[var_0]; + game[var_1] = game["menu_class_allies"]; + game[var_2] = "changeclass_marines"; + } + } + + game["menu_changeclass"] = "changeclass"; + + if ( level.console ) + { + game["menu_controls"] = "ingame_controls"; + + if ( level.splitscreen ) + { + if ( level.multiteambased ) + { + for ( var_0 = 0; var_0 < level.teamnamelist.size; var_0++ ) + { + var_1 = "menu_class_" + level.teamnamelist[var_0]; + var_2 = "menu_changeclass_" + level.teamnamelist[var_0]; + game[var_1] += "_splitscreen"; + game[var_2] += "_splitscreen"; + } + } + + game["menu_team"] += "_splitscreen"; + game["menu_class_allies"] += "_splitscreen"; + game["menu_class_axis"] += "_splitscreen"; + game["menu_changeclass_allies"] += "_splitscreen"; + game["menu_changeclass_axis"] += "_splitscreen"; + game["menu_controls"] += "_splitscreen"; + game["menu_changeclass_defaults_splitscreen"] = "changeclass_splitscreen_defaults"; + game["menu_changeclass_custom_splitscreen"] = "changeclass_splitscreen_custom"; + precachemenu( game["menu_changeclass_defaults_splitscreen"] ); + precachemenu( game["menu_changeclass_custom_splitscreen"] ); + } + + precachemenu( game["menu_controls"] ); + } + + precachemenu( game["menu_team"] ); + precachemenu( game["menu_class_allies"] ); + precachemenu( game["menu_class_axis"] ); + precachemenu( game["menu_changeclass"] ); + precachemenu( game["menu_changeclass_allies"] ); + precachemenu( game["menu_changeclass_axis"] ); + precachemenu( game["menu_class"] ); + precachestring( &"MP_HOST_ENDED_GAME" ); + precachestring( &"MP_HOST_ENDGAME_RESPONSE" ); + } + + level thread onplayerconnect(); +} + +onplayerconnect() +{ + for (;;) + { + level waittill( "connected", var_0 ); + var_0 thread watchforclasschange(); + var_0 thread watchforteamchange(); + var_0 thread watchforleavegame(); + var_0 thread connectedmenus(); + } +} + +connectedmenus() +{ + +} + +getclasschoice( var_0 ) +{ + if ( var_0 > 10 ) + { + if ( var_0 > 10 && var_0 < 17 ) + { + var_0 -= 10; + var_0 = "axis_recipe" + var_0; + } + else if ( var_0 > 16 && var_0 < 23 ) + { + var_0 -= 16; + var_0 = "allies_recipe" + var_0; + } + } + else + var_0 = "custom" + var_0; + + return var_0; +} + +watchforclasschange() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "class_select" ) + continue; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) && self ismlgspectator() ) + { + self setclientomnvar( "ui_options_menu", 0 ); + continue; + } + + var_2 = isai( self ) || issubstr( self.name, "tcBot" ); + + if ( !var_2 ) + { + if ( !isai( self ) && "" + var_1 != "callback" ) + self setclientomnvar( "ui_loadout_selected", var_1 ); + } + + if ( isdefined( self.waitingtoselectclass ) && self.waitingtoselectclass ) + continue; + + if ( !maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() ) + continue; + + if ( "" + var_1 != "callback" ) + { + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] ) + { + self.pers["class"] = var_1; + self.class = var_1; + } + else + { + var_3 = var_1 + 1; + var_3 = getclasschoice( var_3 ); + + if ( !isdefined( self.pers["class"] ) || var_3 == self.pers["class"] ) + continue; + + self.pers["class"] = var_3; + self.class = var_3; + + if ( level.ingraceperiod && !self.hasdonecombat ) + { + maps\mp\gametypes\_class::setclass( self.pers["class"] ); + self.tag_stowed_back = undefined; + self._id_7E62 = undefined; + maps\mp\gametypes\_class::giveloadout( self.pers["team"], self.pers["class"] ); + } + else if ( isalive( self ) ) + self iprintlnbold( game["strings"]["change_class"] ); + } + + continue; + } + + menuclass( "callback" ); + } +} + +watchforleavegame() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "end_game" ) + continue; + + if ( maps\mp\_utility::is_aliens() ) + { + [[ level.forceendgame_alien ]](); + continue; + } + + level thread maps\mp\gametypes\_gamelogic::forceend( var_1 ); + } +} + +watchforteamchange() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + for (;;) + { + self waittill( "luinotifyserver", var_0, var_1 ); + + if ( var_0 != "team_select" ) + continue; + + if ( maps\mp\_utility::matchmakinggame() && !getdvarint( "force_ranking" ) ) + continue; + + if ( var_1 != 3 ) + thread showloadoutmenu(); + + if ( var_1 == 3 ) + { + self setclientomnvar( "ui_spectator_selected", 1 ); + self setclientomnvar( "ui_loadout_selected", -1 ); + self.spectating_actively = 1; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) ) + { + self setmlgspectator( 1 ); + self.pers["mlgSpectator"] = 1; + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 1 ); + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + self setclientomnvar( "ui_options_menu", 2 ); + } + } + else + { + self setclientomnvar( "ui_spectator_selected", -1 ); + self.spectating_actively = 0; + + if ( getdvarint( "systemlink" ) && getdvarint( "xblive_competitionmatch" ) ) + { + self setmlgspectator( 0 ); + self.pers["mlgSpectator"] = 0; + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 0 ); + } + } + + self setclientomnvar( "ui_team_selected", var_1 ); + + if ( var_1 == 0 ) + var_1 = "axis"; + else if ( var_1 == 1 ) + var_1 = "allies"; + else if ( var_1 == 2 ) + var_1 = "random"; + else + var_1 = "spectator"; + + if ( isdefined( self.pers["team"] ) && var_1 == self.pers["team"] ) + { + self notify( "selected_same_team" ); + continue; + } + + self setclientomnvar( "ui_loadout_selected", -1 ); + + if ( var_1 == "axis" ) + { + thread setteam( "axis" ); + continue; + } + + if ( var_1 == "allies" ) + { + thread setteam( "allies" ); + continue; + } + + if ( var_1 == "random" ) + { + thread autoassign(); + continue; + } + + if ( var_1 == "spectator" ) + thread setspectator(); + } +} + +showloadoutmenu() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + common_scripts\utility::waittill_any( "joined_team", "selected_same_team" ); + self setclientomnvar( "ui_options_menu", 2 ); +} + +autoassign() +{ + if ( maps\mp\_utility::is_aliens() || level.gametype == "infect" ) + thread setteam( "allies" ); + else if ( ( getdvarint( "squad_match" ) == 1 || getdvarint( "squad_vs_squad" ) == 1 || getdvarint( "squad_use_hosts_squad" ) == 1 ) && isdefined( self.bot_team ) ) + thread setteam( self.bot_team ); + else if ( !isdefined( self.team ) ) + { + if ( self ismlgspectator() ) + thread setspectator(); + else if ( level.teamcount["axis"] < level.teamcount["allies"] ) + thread setteam( "axis" ); + else if ( level.teamcount["allies"] < level.teamcount["axis"] ) + thread setteam( "allies" ); + else if ( getteamscore( "allies" ) > getteamscore( "axis" ) ) + thread setteam( "axis" ); + else + thread setteam( "allies" ); + } + else + { + if ( self ismlgspectator() ) + { + thread setspectator(); + return; + } + + if ( level.teamcount["axis"] < level.teamcount["allies"] && self.team != "axis" ) + { + thread setteam( "axis" ); + return; + } + + if ( level.teamcount["allies"] < level.teamcount["axis"] && self.team != "allies" ) + { + thread setteam( "allies" ); + return; + } + + if ( level.teamcount["allies"] == level.teamcount["axis"] ) + { + if ( getteamscore( "allies" ) > getteamscore( "axis" ) && self.team != "axis" ) + thread setteam( "axis" ); + else if ( self.team != "allies" ) + thread setteam( "allies" ); + } + } +} + +setteam( var_0 ) +{ + self endon( "disconnect" ); + + if ( !isai( self ) && level.teambased && !maps\mp\gametypes\_teams::getjointeampermissions( var_0 ) ) + return; + + if ( level.ingraceperiod && !self.hasdonecombat ) + self.hasspawned = 0; + + if ( self.sessionstate == "playing" ) + { + self.switching_teams = 1; + self.joining_team = var_0; + self.leaving_team = self.pers["team"]; + } + + addtoteam( var_0 ); + + if ( self.sessionstate == "playing" ) + self suicide(); + + waitforclassselect(); + endrespawnnotify(); + + if ( self.sessionstate == "spectator" ) + { + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + { + if ( isdefined( self.waitingtospawnamortize ) && self.waitingtospawnamortize ) + return; + + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + self notify( "okToSpawn" ); +} + +setspectator() +{ + if ( isdefined( self.pers["team"] ) && self.pers["team"] == "spectator" ) + return; + + if ( isalive( self ) ) + { + self.switching_teams = 1; + self.joining_team = "spectator"; + self.leaving_team = self.pers["team"]; + self suicide(); + } + + self notify( "becameSpectator" ); + addtoteam( "spectator" ); + self.pers["class"] = undefined; + self.class = undefined; + thread maps\mp\gametypes\_playerlogic::spawnspectator(); +} + +waitforclassselect() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self.waitingtoselectclass = 1; + + for (;;) + { + if ( level.gametype == "infect" ) + { + bypassclasschoice(); + break; + } + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self waittill( "luinotifyserver", var_0, var_1 ); + else + { + bypassclasschoice(); + break; + } + + if ( var_0 != "class_select" ) + continue; + + if ( self.team == "spectator" ) + continue; + + if ( "" + var_1 != "callback" ) + { + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] ) + { + self.pers["class"] = var_1; + self.class = var_1; + } + else + { + var_1 += 1; + self.pers["class"] = getclasschoice( var_1 ); + self.class = getclasschoice( var_1 ); + } + + self.waitingtoselectclass = 0; + } + else + { + self.waitingtoselectclass = 0; + menuclass( "callback" ); + } + + break; + } +} + +beginclasschoice( var_0 ) +{ + var_1 = self.pers["team"]; + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + { + self setclientomnvar( "ui_options_menu", 2 ); + + if ( !self ismlgspectator() ) + waitforclassselect(); + + endrespawnnotify(); + + if ( self.sessionstate == "spectator" ) + { + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + { + if ( isdefined( self.waitingtospawnamortize ) && self.waitingtospawnamortize ) + return; + + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + self.connecttime = gettime(); + self notify( "okToSpawn" ); + } + else + thread bypassclasschoice(); + + if ( !isalive( self ) ) + thread maps\mp\gametypes\_playerlogic::predictabouttospawnplayerovertime( 0.1 ); +} + +bypassclasschoice() +{ + self.selectedclass = 1; + self.waitingtoselectclass = 0; + + if ( isdefined( level.bypassclasschoicefunc ) ) + { + var_0 = self [[ level.bypassclasschoicefunc ]](); + self.class = var_0; + } + else + self.class = "class0"; +} + +beginteamchoice() +{ + self setclientomnvar( "ui_options_menu", 1 ); +} + +showmainmenuforteam() +{ + var_0 = self.pers["team"]; + self openpopupmenu( game["menu_class_" + var_0] ); +} + +menuspectator() +{ + if ( isdefined( self.pers["team"] ) && self.pers["team"] == "spectator" ) + return; + + if ( isalive( self ) ) + { + self.switching_teams = 1; + self.joining_team = "spectator"; + self.leaving_team = self.pers["team"]; + self suicide(); + } + + addtoteam( "spectator" ); + self.pers["class"] = undefined; + self.class = undefined; + thread maps\mp\gametypes\_playerlogic::spawnspectator(); +} + +menuclass( var_0 ) +{ + if ( var_0 == "demolitions_mp,0" && self getrankedplayerdata( "featureNew", "demolitions" ) ) + self setrankedplayerdata( "featureNew", "demolitions", 0 ); + + if ( var_0 == "sniper_mp,0" && self getrankedplayerdata( "featureNew", "sniper" ) ) + self setrankedplayerdata( "featureNew", "sniper", 0 ); + + var_1 = self.pers["team"]; + var_2 = maps\mp\gametypes\_class::getclasschoice( var_0 ); + var_3 = maps\mp\gametypes\_class::getweaponchoice( var_0 ); + + if ( var_2 == "restricted" ) + { + beginclasschoice(); + return; + } + + if ( isdefined( self.pers["class"] ) && self.pers["class"] == var_2 && ( isdefined( self.pers["primary"] ) && self.pers["primary"] == var_3 ) ) + return; + + if ( self.sessionstate == "playing" ) + { + if ( isdefined( self.pers["lastClass"] ) && isdefined( self.pers["class"] ) ) + { + self.pers["lastClass"] = self.pers["class"]; + self.lastclass = self.pers["lastClass"]; + } + + self.pers["class"] = var_2; + self.class = var_2; + self.pers["primary"] = var_3; + + if ( game["state"] == "postgame" ) + return; + + if ( level.ingraceperiod && !self.hasdonecombat ) + { + maps\mp\gametypes\_class::setclass( self.pers["class"] ); + self.tag_stowed_back = undefined; + self._id_7E62 = undefined; + maps\mp\gametypes\_class::giveloadout( self.pers["team"], self.pers["class"] ); + } + else + self iprintlnbold( game["strings"]["change_class"] ); + } + else + { + if ( isdefined( self.pers["lastClass"] ) && isdefined( self.pers["class"] ) ) + { + self.pers["lastClass"] = self.pers["class"]; + self.lastclass = self.pers["lastClass"]; + } + + self.pers["class"] = var_2; + self.class = var_2; + self.pers["primary"] = var_3; + + if ( game["state"] == "postgame" ) + return; + + if ( game["state"] == "playing" && !maps\mp\_utility::isinkillcam() ) + thread maps\mp\gametypes\_playerlogic::spawnclient(); + } + + thread maps\mp\gametypes\_spectating::setspectatepermissions(); +} + +update_wargame_after_migration() +{ + foreach ( var_1 in level.players ) + { + if ( !isai( var_1 ) && var_1 ishost() ) + level.wargame_client = var_1; + } +} + +addtoteam( var_0, var_1, var_2 ) +{ + if ( isdefined( self.team ) ) + { + maps\mp\gametypes\_playerlogic::removefromteamcount(); + + if ( isdefined( var_2 ) && var_2 ) + maps\mp\gametypes\_playerlogic::decrementalivecount( self.team ); + } + + self.pers["team"] = var_0; + self.team = var_0; + + if ( getdvar( "squad_vs_squad" ) == "1" ) + { + if ( !isai( self ) ) + { + if ( var_0 == "allies" ) + { + if ( !isdefined( level.squad_vs_squad_allies_client ) ) + level.squad_vs_squad_allies_client = self; + } + else if ( var_0 == "axis" ) + { + if ( !isdefined( level.squad_vs_squad_axis_client ) ) + level.squad_vs_squad_axis_client = self; + } + } + } + + if ( getdvar( "squad_match" ) == "1" ) + { + if ( !isai( self ) && self ishost() ) + { + if ( !isdefined( level.squad_match_client ) ) + level.squad_match_client = self; + } + } + + if ( getdvar( "squad_use_hosts_squad" ) == "1" ) + { + if ( !isai( self ) && self ishost() ) + { + if ( !isdefined( level.wargame_client ) ) + level.wargame_client = self; + } + } + + // session team is readonly in ranked matches if "teambased" is set on the playlist + if ( level.teambased ) + self.sessionteam = var_0; + else if ( var_0 == "spectator" ) + self.sessionteam = "spectator"; + else + self.sessionteam = "none"; + + if ( game["state"] != "postgame" ) + { + maps\mp\gametypes\_playerlogic::addtoteamcount(); + + if ( isdefined( var_2 ) && var_2 ) + maps\mp\gametypes\_playerlogic::incrementalivecount( self.team ); + } + + maps\mp\_utility::updateobjectivetext(); + + if ( isdefined( var_1 ) && var_1 ) + waittillframeend; + + maps\mp\_utility::updatemainmenu(); + + if ( var_0 == "spectator" ) + { + self notify( "joined_spectators" ); + level notify( "joined_team", self ); + } + else + { + self notify( "joined_team" ); + level notify( "joined_team", self ); + } +} + +endrespawnnotify() +{ + self.waitingtospawn = 0; + self notify( "end_respawn" ); +} diff --git a/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_playerlogic.gsc b/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_playerlogic.gsc new file mode 100644 index 0000000..a1906e6 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/maps/mp/gametypes/_playerlogic.gsc @@ -0,0 +1,1902 @@ +// IW6 GSC SOURCE +// Dumped by https://github.com/xensik/gsc-tool + +timeuntilwavespawn( var_0 ) +{ + if ( !self.hasspawned ) + return 0; + + var_1 = gettime() + var_0 * 1000; + var_2 = level.lastwave[self.pers["team"]]; + var_3 = level.wavedelay[self.pers["team"]] * 1000; + var_4 = ( var_1 - var_2 ) / var_3; + var_5 = ceil( var_4 ); + var_6 = var_2 + var_5 * var_3; + + if ( isdefined( self.respawntimerstarttime ) ) + { + var_7 = ( gettime() - self.respawntimerstarttime ) / 1000.0; + + if ( self.respawntimerstarttime < var_2 ) + return 0; + } + + if ( isdefined( self.wavespawnindex ) ) + var_6 += 50 * self.wavespawnindex; + + return ( var_6 - gettime() ) / 1000; +} + +teamkilldelay() +{ + var_0 = self.pers["teamkills"]; + + if ( level.maxallowedteamkills < 0 || var_0 <= level.maxallowedteamkills ) + return 0; + + var_1 = var_0 - level.maxallowedteamkills; + return maps\mp\gametypes\_tweakables::gettweakablevalue( "team", "teamkillspawndelay" ) * var_1; +} + +timeuntilspawn( var_0 ) +{ + if ( level.ingraceperiod && !self.hasspawned || level.gameended ) + return 0; + + var_1 = 0; + + if ( self.hasspawned ) + { + var_2 = self [[ level.onrespawndelay ]](); + + if ( isdefined( var_2 ) ) + var_1 = var_2; + else + var_1 = getdvarint( "scr_" + level.gametype + "_playerrespawndelay" ); + + if ( var_0 && isdefined( self.pers["teamKillPunish"] ) && self.pers["teamKillPunish"] ) + var_1 += teamkilldelay(); + + if ( isdefined( self.respawntimerstarttime ) ) + { + var_3 = ( gettime() - self.respawntimerstarttime ) / 1000.0; + var_1 -= var_3; + + if ( var_1 < 0 ) + var_1 = 0; + } + + if ( isdefined( self.setspawnpoint ) ) + var_1 += level.tispawndelay; + } + + var_4 = getdvarint( "scr_" + level.gametype + "_waverespawndelay" ) > 0; + + if ( var_4 ) + return timeuntilwavespawn( var_1 ); + + return var_1; +} + +mayspawn() +{ + if ( maps\mp\_utility::getgametypenumlives() || isdefined( level.disablespawning ) ) + { + if ( isdefined( level.disablespawning ) && level.disablespawning ) + return 0; + + if ( isdefined( self.pers["teamKillPunish"] ) && self.pers["teamKillPunish"] ) + return 0; + + if ( self.pers["lives"] <= 0 && maps\mp\_utility::gamehasstarted() ) + return 0; + else if ( maps\mp\_utility::gamehasstarted() ) + { + if ( !level.ingraceperiod && !self.hasspawned && ( isdefined( level.allowlatecomers ) && !level.allowlatecomers ) ) + { + if ( isdefined( self.siegelatecomer ) && !self.siegelatecomer ) + return 1; + + return 0; + } + } + } + + return 1; +} + +spawnclient() +{ + self endon( "becameSpectator" ); + + if ( isdefined( self.waitingtoselectclass ) && self.waitingtoselectclass ) + self waittill( "okToSpawn" ); + + if ( isdefined( self.addtoteam ) ) + { + maps\mp\gametypes\_menus::addtoteam( self.addtoteam ); + self.addtoteam = undefined; + } + + if ( !mayspawn() ) + { + wait 0.05; + var_0 = self.origin; + var_1 = self.angles; + self notify( "attempted_spawn" ); + var_2 = self.pers["teamKillPunish"]; + + if ( isdefined( var_2 ) && var_2 ) + { + self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 ); + maps\mp\_utility::setlowermessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT" ); + + if ( !self.hasspawned && self.pers["teamkills"] <= level.maxallowedteamkills ) + self.pers["teamKillPunish"] = 0; + } + else if ( maps\mp\_utility::isroundbased() && !maps\mp\_utility::islastround() ) + { + if ( isdefined( self.tagavailable ) && self.tagavailable ) + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_tag_wait"] ); + else if ( level.gametype == "siege" ) + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_flag_wait"] ); + else + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["spawn_next_round"] ); + + thread removespawnmessageshortly( 3.0 ); + } + + if ( self.sessionstate != "spectator" ) + var_0 += ( 0, 0, 60 ); + + thread spawnspectator( var_0, var_1 ); + return; + } + + if ( self.waitingtospawn ) + return; + + self.waitingtospawn = 1; + waitandspawnclient(); + + if ( isdefined( self ) ) + self.waitingtospawn = 0; +} + +waitandspawnclient() +{ + self endon( "disconnect" ); + self endon( "end_respawn" ); + level endon( "game_ended" ); + self notify( "attempted_spawn" ); + var_0 = 0; + var_1 = self.pers["teamKillPunish"]; + + if ( isdefined( var_1 ) && var_1 ) + { + var_2 = teamkilldelay(); + + if ( var_2 > 0 ) + { + maps\mp\_utility::setlowermessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT", var_2, 1, 1 ); + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + var_0 = 1; + wait(var_2); + maps\mp\_utility::clearlowermessage( "friendly_fire" ); + self.respawntimerstarttime = gettime(); + } + + self.pers["teamKillPunish"] = 0; + } + else if ( !maps\mp\_utility::is_aliens() && teamkilldelay() ) + self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 ); + + if ( maps\mp\_utility::isusingremote() ) + { + self.spawningafterremotedeath = 1; + self.deathposition = self.origin; + self waittill( "stopped_using_remote" ); + } + + if ( !isdefined( self.wavespawnindex ) && isdefined( level.waveplayerspawnindex[self.team] ) ) + { + self.wavespawnindex = level.waveplayerspawnindex[self.team]; + level.waveplayerspawnindex[self.team]++; + } + + var_3 = timeuntilspawn( 0 ); + thread predictabouttospawnplayerovertime( var_3 ); + + if ( var_3 > 0 ) + { + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["waiting_to_spawn"], var_3, 1, 1 ); + + if ( !var_0 ) + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + + var_0 = 1; + maps\mp\_utility::waitfortimeornotify( var_3, "force_spawn" ); + self notify( "stop_wait_safe_spawn_button" ); + } + + if ( needsbuttontorespawn() ) + { + maps\mp\_utility::setlowermessage( "spawn_info", game["strings"]["press_to_spawn"], undefined, undefined, undefined, undefined, undefined, undefined, 1 ); + + if ( !var_0 ) + thread respawn_asspectator( self.origin + ( 0, 0, 60 ), self.angles ); + + var_0 = 1; + waitrespawnbutton(); + } + + self.waitingtospawn = 0; + maps\mp\_utility::clearlowermessage( "spawn_info" ); + self.wavespawnindex = undefined; + thread spawnplayer(); +} + +needsbuttontorespawn() +{ + if ( maps\mp\gametypes\_tweakables::gettweakablevalue( "player", "forcerespawn" ) != 0 ) + return 0; + + if ( !self.hasspawned ) + return 0; + + var_0 = getdvarint( "scr_" + level.gametype + "_waverespawndelay" ) > 0; + + if ( var_0 ) + return 0; + + if ( self.wantsafespawn ) + return 0; + + return 1; +} + +waitrespawnbutton() +{ + self endon( "disconnect" ); + self endon( "end_respawn" ); + + for (;;) + { + if ( self usebuttonpressed() ) + break; + + wait 0.05; + } +} + +removespawnmessageshortly( var_0 ) +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + waittillframeend; + self endon( "end_respawn" ); + wait(var_0); + maps\mp\_utility::clearlowermessage( "spawn_info" ); +} + +laststandrespawnplayer() +{ + self laststandrevive(); + + if ( maps\mp\_utility::_hasperk( "specialty_finalstand" ) && !level.diehardmode ) + maps\mp\_utility::_unsetperk( "specialty_finalstand" ); + + if ( level.diehardmode ) + self.headicon = ""; + + self setstance( "crouch" ); + self.revived = 1; + self notify( "revive" ); + + if ( isdefined( self.standardmaxhealth ) ) + self.maxhealth = self.standardmaxhealth; + + self.health = self.maxhealth; + common_scripts\utility::_enableusability(); + + if ( game["state"] == "postgame" ) + maps\mp\gametypes\_gamelogic::freezeplayerforroundend(); +} + +getdeathspawnpoint() +{ + var_0 = spawn( "script_origin", self.origin ); + var_0 hide(); + var_0.angles = self.angles; + return var_0; +} + +showspawnnotifies() +{ + if ( isdefined( game["defcon"] ) ) + thread maps\mp\gametypes\_hud_message::defconsplashnotify( game["defcon"], 0 ); + + if ( !maps\mp\_utility::is_aliens() && maps\mp\_utility::isrested() ) + thread maps\mp\gametypes\_hud_message::splashnotify( "rested" ); +} + +predictabouttospawnplayerovertime( var_0 ) +{ + if ( !0 ) + return; + + self endon( "disconnect" ); + self endon( "spawned" ); + self endon( "used_predicted_spawnpoint" ); + self notify( "predicting_about_to_spawn_player" ); + self endon( "predicting_about_to_spawn_player" ); + + if ( var_0 <= 0 ) + return; + + if ( var_0 > 1.0 ) + wait(var_0 - 1.0); + + predictabouttospawnplayer(); + self predictstreampos( self.predictedspawnpoint.origin + ( 0, 0, 60 ), self.predictedspawnpoint.angles ); + self.predictedspawnpointtime = gettime(); + + for ( var_1 = 0; var_1 < 30; var_1++ ) + { + wait 0.4; + var_2 = self.predictedspawnpoint; + predictabouttospawnplayer(); + + if ( self.predictedspawnpoint != var_2 ) + { + self predictstreampos( self.predictedspawnpoint.origin + ( 0, 0, 60 ), self.predictedspawnpoint.angles ); + self.predictedspawnpointtime = gettime(); + } + } +} + +predictabouttospawnplayer() +{ + if ( timeuntilspawn( 1 ) > 1.0 ) + { + self.predictedspawnpoint = getspectatepoint(); + return; + } + + if ( isdefined( self.setspawnpoint ) ) + { + self.predictedspawnpoint = self.setspawnpoint; + return; + } + + var_0 = self [[ level.getspawnpoint ]](); + self.predictedspawnpoint = var_0; +} + +checkpredictedspawnpointcorrectness( var_0 ) +{ + self notify( "used_predicted_spawnpoint" ); + self.predictedspawnpoint = undefined; +} + +percentage( var_0, var_1 ) +{ + return var_0 + " (" + int( var_0 / var_1 * 100 ) + "%)"; +} + +printpredictedspawnpointcorrectness() +{ + +} + +getspawnorigin( var_0 ) +{ + if ( !positionwouldtelefrag( var_0.origin ) ) + return var_0.origin; + + if ( !isdefined( var_0.alternates ) ) + return var_0.origin; + + foreach ( var_2 in var_0.alternates ) + { + if ( !positionwouldtelefrag( var_2 ) ) + return var_2; + } + + return var_0.origin; +} + +tivalidationcheck() +{ + if ( !isdefined( self.setspawnpoint ) ) + return 0; + + var_0 = getentarray( "care_package", "targetname" ); + + foreach ( var_2 in var_0 ) + { + if ( distance( var_2.origin, self.setspawnpoint.playerspawnpos ) > 64 ) + continue; + + if ( isdefined( var_2.owner ) ) + maps\mp\gametypes\_hud_message::playercardsplashnotify( "destroyed_insertion", var_2.owner ); + + maps\mp\perks\_perkfunctions::deleteti( self.setspawnpoint ); + return 0; + } + + if ( !bullettracepassed( self.setspawnpoint.origin + ( 0, 0, 60 ), self.setspawnpoint.origin, 0, self.setspawnpoint ) ) + return 0; + + var_4 = self.setspawnpoint.origin + ( 0, 0, 1 ); + var_5 = playerphysicstrace( var_4, self.setspawnpoint.origin + ( 0, 0, -16 ) ); + + if ( var_4[2] == var_5[2] ) + return 0; + + return 1; +} + +spawningclientthisframereset() +{ + self notify( "spawningClientThisFrameReset" ); + self endon( "spawningClientThisFrameReset" ); + wait 0.05; + level.numplayerswaitingtospawn--; +} + +spawnplayer( var_0 ) +{ + self endon( "disconnect" ); + self endon( "joined_spectators" ); + self notify( "spawned" ); + self notify( "end_respawn" ); + self notify( "started_spawnPlayer" ); + + if ( !isdefined( var_0 ) ) + var_0 = 0; + + var_1 = undefined; + self.ti_spawn = 0; + self setclientomnvar( "ui_options_menu", 0 ); + self setclientomnvar( "ui_hud_shake", 0 ); + self.lastkillsplash = undefined; + + if ( !level.ingraceperiod && !self.hasdonecombat ) + { + level.numplayerswaitingtospawn++; + + if ( level.numplayerswaitingtospawn > 1 ) + { + self.waitingtospawnamortize = 1; + wait(0.05 * ( level.numplayerswaitingtospawn - 1 )); + } + + thread spawningclientthisframereset(); + self.waitingtospawnamortize = 0; + } + + // // Returning false we use default character model and prevent a 5 second respawn delay. (Github issue #109) + if ( !self hasloadedcustomizationplayerview( self ) ) + self.waitingtospawnamortize = 0; + + if ( isdefined( self.forcespawnorigin ) ) + { + var_2 = self.forcespawnorigin; + self.forcespawnorigin = undefined; + + if ( isdefined( self.forcespawnangles ) ) + { + var_3 = self.forcespawnangles; + self.forcespawnangles = undefined; + } + else + var_3 = ( 0, randomfloatrange( 0, 360 ), 0 ); + } + else if ( isdefined( self.setspawnpoint ) && ( isdefined( self.setspawnpoint.notti ) || tivalidationcheck() ) ) + { + var_1 = self.setspawnpoint; + + if ( !isdefined( self.setspawnpoint.notti ) ) + { + self.ti_spawn = 1; + self playlocalsound( "tactical_spawn" ); + + if ( level.multiteambased ) + { + foreach ( var_5 in level.teamnamelist ) + { + if ( var_5 != self.team ) + self playsoundtoteam( "tactical_spawn", var_5 ); + } + } + else if ( level.teambased ) + self playsoundtoteam( "tactical_spawn", level.otherteam[self.team] ); + else + self playsound( "tactical_spawn" ); + } + + foreach ( var_8 in level.ugvs ) + { + if ( distancesquared( var_8.origin, var_1.playerspawnpos ) < 1024 ) + var_8 notify( "damage", 5000, var_8.owner, ( 0, 0, 0 ), ( 0, 0, 0 ), "MOD_EXPLOSIVE", "", "", "", undefined, "killstreak_emp_mp" ); + } + + var_2 = self.setspawnpoint.playerspawnpos; + var_3 = self.setspawnpoint.angles; + + if ( isdefined( self.setspawnpoint.enemytrigger ) ) + self.setspawnpoint.enemytrigger delete(); + + self.setspawnpoint delete(); + var_1 = undefined; + } + else if ( isdefined( self.isspawningonbattlebuddy ) && isdefined( self.battlebuddy ) ) + { + var_2 = undefined; + var_3 = undefined; + var_10 = maps\mp\gametypes\_battlebuddy::checkbuddyspawn(); + + if ( var_10.status == 0 ) + { + var_2 = var_10.origin; + var_3 = var_10.angles; + } + else + { + var_1 = self [[ level.getspawnpoint ]](); + var_2 = var_1.origin; + var_3 = var_1.angles; + } + + maps\mp\gametypes\_battlebuddy::cleanupbuddyspawn(); + self setclientomnvar( "cam_scene_name", "battle_spawn" ); + self setclientomnvar( "cam_scene_lead", self.battlebuddy getentitynumber() ); + self setclientomnvar( "cam_scene_support", self getentitynumber() ); + } + else if ( isdefined( self.helispawning ) && ( !isdefined( self.firstspawn ) || isdefined( self.firstspawn ) && self.firstspawn ) && level.prematchperiod > 0 && self.team == "allies" ) + { + while ( !isdefined( level.allieschopper ) ) + wait 0.1; + + var_2 = level.allieschopper.origin; + var_3 = level.allieschopper.angles; + self.firstspawn = 0; + } + else if ( isdefined( self.helispawning ) && ( !isdefined( self.firstspawn ) || isdefined( self.firstspawn ) && self.firstspawn ) && level.prematchperiod > 0 && self.team == "axis" ) + { + while ( !isdefined( level.axischopper ) ) + wait 0.1; + + var_2 = level.axischopper.origin; + var_3 = level.axischopper.angles; + self.firstspawn = 0; + } + else + { + var_1 = self [[ level.getspawnpoint ]](); + var_2 = var_1.origin; + var_3 = var_1.angles; + } + + setspawnvariables(); + var_11 = self.hasspawned; + self.fauxdead = undefined; + + if ( !var_0 ) + { + self.killsthislife = []; + self.killsthislifeperweapon = []; + maps\mp\_utility::updatesessionstate( "playing" ); + maps\mp\_utility::clearkillcamstate(); + self.cancelkillcam = undefined; + self.maxhealth = maps\mp\gametypes\_tweakables::gettweakablevalue( "player", "maxhealth" ); + self.health = self.maxhealth; + self.friendlydamage = undefined; + self.hasspawned = 1; + self.spawntime = gettime(); + self.wasti = !isdefined( var_1 ); + self.afk = 0; + self.damagedplayers = []; + self.killstreakscaler = 1; + self.xpscaler = 1; + self.objectivescaler = 1; + self.clampedhealth = undefined; + self.shielddamage = 0; + self.shieldbullethits = 0; + self.recentshieldxp = 0; + } + + self.movespeedscaler = 1; + self.inlaststand = 0; + self.laststand = undefined; + self.infinalstand = undefined; + self.inc4death = undefined; + self.disabledweapon = 0; + self.disabledweaponswitch = 0; + self.disabledoffhandweapons = 0; + common_scripts\utility::resetusability(); + + if ( !var_0 ) + { + self.avoidkillstreakonspawntimer = 5.0; + + if ( !maps\mp\_utility::is_aliens() ) + { + var_12 = self.pers["lives"]; + + if ( var_12 == maps\mp\_utility::getgametypenumlives() ) + addtolivescount(); + + if ( var_12 ) + self.pers["lives"]--; + } + + addtoalivecount(); + + if ( !var_11 || maps\mp\_utility::gamehasstarted() || maps\mp\_utility::gamehasstarted() && level.ingraceperiod && self.hasdonecombat ) + removefromlivescount(); + + if ( !self.wasaliveatmatchstart ) + { + var_13 = 20; + + if ( maps\mp\_utility::gettimelimit() > 0 && var_13 < maps\mp\_utility::gettimelimit() * 60 / 4 ) + var_13 = maps\mp\_utility::gettimelimit() * 60 / 4; + + if ( level.ingraceperiod || maps\mp\_utility::gettimepassed() < var_13 * 1000 ) + self.wasaliveatmatchstart = 1; + } + } + + self setdepthoffield( 0, 0, 512, 512, 4, 0 ); + + if ( level.console ) + self setclientdvar( "cg_fov", "65" ); + + resetuidvarsonspawn(); + + if ( isdefined( var_1 ) ) + { + maps\mp\gametypes\_spawnlogic::finalizespawnpointchoice( var_1 ); + var_2 = getspawnorigin( var_1 ); + var_3 = var_1.angles; + } + else if ( !isdefined( self.faux_spawn_infected ) ) + self.lastspawntime = gettime(); + + self.spawnpos = var_2; + self spawn( var_2, var_3 ); + + if ( var_0 && isdefined( self.faux_spawn_stance ) ) + { + self setstance( self.faux_spawn_stance ); + self.faux_spawn_stance = undefined; + } + + if ( isai( self ) ) + maps\mp\_utility::freezecontrolswrapper( 1 ); + + [[ level.onspawnplayer ]](); + + if ( isdefined( var_1 ) ) + checkpredictedspawnpointcorrectness( var_1.origin ); + + if ( !var_0 ) + { + maps\mp\gametypes\_missions::playerspawned(); + + if ( isai( self ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["player_spawned"] ) ) + self [[ level.bot_funcs["player_spawned"] ]](); + + if ( !isai( self ) ) + thread watchforslide(); + } + + maps\mp\gametypes\_class::setclass( self.class ); + + if ( isdefined( level.custom_giveloadout ) ) + self [[ level.custom_giveloadout ]]( var_0 ); + else + maps\mp\gametypes\_class::giveloadout( self.team, self.class ); + + if ( isdefined( game["roundsPlayed"] ) && game["roundsPlayed"] > 0 ) + { + if ( !isdefined( self.classrefreshed ) || !self.classrefreshed ) + { + if ( isdefined( self.class_num ) ) + { + self setclientomnvar( "ui_loadout_selected", self.class_num ); + self.classrefreshed = 1; + } + } + } + + if ( getdvarint( "camera_thirdPerson" ) ) + maps\mp\_utility::setthirdpersondof( 1 ); + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) ) + maps\mp\_utility::freezecontrolswrapper( 1 ); + else + maps\mp\_utility::freezecontrolswrapper( 0 ); + + if ( !maps\mp\_utility::gameflag( "prematch_done" ) || !var_11 && game["state"] == "playing" ) + { + if ( !maps\mp\_utility::is_aliens() ) + { + if ( game["status"] == "overtime" ) + thread maps\mp\gametypes\_hud_message::oldnotifymessage( game["strings"]["overtime"], game["strings"]["overtime_hint"], undefined, ( 1, 0, 0 ), "mp_last_stand" ); + } + + thread showspawnnotifies(); + } + + if ( maps\mp\_utility::getintproperty( "scr_showperksonspawn", 1 ) == 1 && game["state"] != "postgame" ) + { + if ( !maps\mp\_utility::is_aliens() ) + self setclientomnvar( "ui_spawn_abilities_show", 1 ); + } + + waittillframeend; + self.spawningafterremotedeath = undefined; + self notify( "spawned_player" ); + level notify( "player_spawned", self ); + + if ( game["state"] == "postgame" ) + maps\mp\gametypes\_gamelogic::freezeplayerforroundend(); +} + +spawnspectator( var_0, var_1 ) +{ + self notify( "spawned" ); + self notify( "end_respawn" ); + self notify( "joined_spectators" ); + in_spawnspectator( var_0, var_1 ); +} + +respawn_asspectator( var_0, var_1 ) +{ + in_spawnspectator( var_0, var_1 ); +} + +in_spawnspectator( var_0, var_1 ) +{ + setspawnvariables(); + var_2 = self.pers["team"]; + + if ( isdefined( var_2 ) && var_2 == "spectator" && !level.gameended ) + maps\mp\_utility::clearlowermessage( "spawn_info" ); + + maps\mp\_utility::updatesessionstate( "spectator" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + resetuidvarsonspectate(); + + if ( isdefined( var_2 ) && var_2 == "spectator" ) + self.statusicon = ""; + else + self.statusicon = "hud_status_dead"; + + maps\mp\gametypes\_spectating::setspectatepermissions(); + onspawnspectator( var_0, var_1 ); + + if ( level.teambased && !level.splitscreen && !self issplitscreenplayer() ) + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); +} + +getplayerfromclientnum( var_0 ) +{ + if ( var_0 < 0 ) + return undefined; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + if ( level.players[var_1] getentitynumber() == var_0 ) + return level.players[var_1]; + } + + return undefined; +} + +onspawnspectator( var_0, var_1 ) +{ + if ( isdefined( var_0 ) && isdefined( var_1 ) ) + { + self setspectatedefaults( var_0, var_1 ); + self spawn( var_0, var_1 ); + checkpredictedspawnpointcorrectness( var_0 ); + return; + } + + var_2 = getspectatepoint(); + + if ( !maps\mp\_utility::is_aliens() ) + { + var_3 = getentarray( "mp_mlg_camera", "classname" ); + + if ( isdefined( var_3 ) && var_3.size ) + { + for ( var_4 = 0; var_4 < var_3.size && var_4 < 4; var_4++ ) + { + self setmlgcameradefaults( var_4, var_3[var_4].origin, var_3[var_4].angles ); + level.cameramapobjs[var_4].origin = var_3[var_4].origin; + level.cameramapobjs[var_4].angles = var_3[var_4].angles; + } + } + else if ( isdefined( level.camera3pos ) ) + { + var_5 = tolower( getdvar( "mapname" ) ); + + if ( var_5 == "mp_strikezone" && isdefined( level.teleport_zone_current ) && level.teleport_zone_current != "start" ) + { + self setmlgcameradefaults( 0, level.camera5pos, level.camera5ang ); + level.cameramapobjs[0].origin = level.camera5pos; + level.cameramapobjs[0].angles = level.camera5ang; + self setmlgcameradefaults( 1, level.camera6pos, level.camera6ang ); + level.cameramapobjs[1].origin = level.camera6pos; + level.cameramapobjs[1].angles = level.camera6ang; + self setmlgcameradefaults( 2, level.camera7pos, level.camera7ang ); + level.cameramapobjs[2].origin = level.camera7pos; + level.cameramapobjs[2].angles = level.camera7ang; + self setmlgcameradefaults( 3, level.camera8pos, level.camera8ang ); + level.cameramapobjs[3].origin = level.camera8pos; + level.cameramapobjs[3].angles = level.camera8ang; + } + else + { + self setmlgcameradefaults( 0, level.camera1pos, level.camera1ang ); + level.cameramapobjs[0].origin = level.camera1pos; + level.cameramapobjs[0].angles = level.camera1ang; + self setmlgcameradefaults( 1, level.camera2pos, level.camera2ang ); + level.cameramapobjs[1].origin = level.camera2pos; + level.cameramapobjs[1].angles = level.camera2ang; + self setmlgcameradefaults( 2, level.camera3pos, level.camera3ang ); + level.cameramapobjs[2].origin = level.camera3pos; + level.cameramapobjs[2].angles = level.camera3ang; + self setmlgcameradefaults( 3, level.camera4pos, level.camera4ang ); + level.cameramapobjs[3].origin = level.camera4pos; + level.cameramapobjs[3].angles = level.camera4ang; + } + } + else + { + for ( var_4 = 0; var_4 < 4; var_4++ ) + self setmlgcameradefaults( var_4, var_2.origin, var_2.angles ); + } + } + + self setspectatedefaults( var_2.origin, var_2.angles ); + self spawn( var_2.origin, var_2.angles ); + checkpredictedspawnpointcorrectness( var_2.origin ); +} + +getspectatepoint() +{ + var_0 = getentarray( "mp_global_intermission", "classname" ); + var_1 = maps\mp\gametypes\_spawnlogic::getspawnpoint_random( var_0 ); + return var_1; +} + +spawnintermission() +{ + self endon( "disconnect" ); + self notify( "spawned" ); + self notify( "end_respawn" ); + setspawnvariables(); + maps\mp\_utility::clearlowermessages(); + maps\mp\_utility::freezecontrolswrapper( 1 ); + self setclientdvar( "cg_everyoneHearsEveryone", 1 ); + var_0 = self.pers["postGameChallenges"]; + + if ( !maps\mp\_utility::is_aliens() && level.rankedmatch && ( self.postgamepromotion || isdefined( var_0 ) && var_0 ) ) + { + if ( self.postgamepromotion ) + self playlocalsound( "mp_level_up" ); + else if ( isdefined( var_0 ) ) + self playlocalsound( "mp_challenge_complete" ); + + if ( self.postgamepromotion > level.postgamenotifies ) + level.postgamenotifies = 1; + + if ( isdefined( var_0 ) && var_0 > level.postgamenotifies ) + level.postgamenotifies = var_0; + + var_1 = 7.0; + + if ( isdefined( var_0 ) ) + var_1 = 4.0 + min( var_0, 3 ); + + while ( var_1 ) + { + wait 0.25; + var_1 -= 0.25; + } + } + + if ( isdefined( level.finalkillcam_winner ) && level.finalkillcam_winner != "none" && isdefined( level.match_end_delay ) && maps\mp\_utility::waslastround() ) + wait(level.match_end_delay); + + maps\mp\_utility::updatesessionstate( "intermission" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + var_2 = getentarray( "mp_global_intermission", "classname" ); + var_2 = maps\mp\gametypes\_spawnscoring::checkdynamicspawns( var_2 ); + var_3 = var_2[0]; + + if ( !isdefined( level.custom_ending ) ) + { + self spawn( var_3.origin, var_3.angles ); + checkpredictedspawnpointcorrectness( var_3.origin ); + self setdepthoffield( 0, 128, 512, 4000, 6, 1.8 ); + } + else + level notify( "scoreboard_displaying" ); +} + +spawnendofgame() +{ + if ( 1 ) + { + if ( isdefined( level.custom_ending ) && maps\mp\_utility::waslastround() ) + level notify( "start_custom_ending" ); + + maps\mp\_utility::freezecontrolswrapper( 1 ); + spawnspectator(); + maps\mp\_utility::freezecontrolswrapper( 1 ); + return; + } + + self notify( "spawned" ); + self notify( "end_respawn" ); + setspawnvariables(); + maps\mp\_utility::clearlowermessages(); + self setclientdvar( "cg_everyoneHearsEveryone", 1 ); + maps\mp\_utility::updatesessionstate( "dead" ); + maps\mp\_utility::clearkillcamstate(); + self.friendlydamage = undefined; + var_0 = getspectatepoint(); + spawnspectator( var_0.origin, var_0.angles ); + checkpredictedspawnpointcorrectness( var_0.origin ); + maps\mp\_utility::freezecontrolswrapper( 1 ); + self setdepthoffield( 0, 0, 512, 512, 4, 0 ); +} + +setspawnvariables() +{ + self stopshellshock(); + self stoprumble( "damage_heavy" ); + self.deathposition = undefined; +} + +notifyconnecting() +{ + waittillframeend; + + if ( isdefined( self ) ) + level notify( "connecting", self ); +} + +callback_playerdisconnect( var_0 ) +{ + if ( !isdefined( self.connected ) ) + return; + + var_1 = getmatchdata( "gameLength" ); + var_1 += int( maps\mp\_utility::getsecondspassed() ); + setmatchdata( "players", self.clientid, "disconnectTime", var_1 ); + setmatchdata( "players", self.clientid, "disconnectReason", var_0 ); + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + maps\mp\_matchdata::logfinalstats(); + + if ( isdefined( self.pers["confirmed"] ) ) + maps\mp\_matchdata::logkillsconfirmed(); + + if ( isdefined( self.pers["denied"] ) ) + maps\mp\_matchdata::logkillsdenied(); + + removeplayerondisconnect(); + maps\mp\gametypes\_spawnlogic::removefromparticipantsarray(); + maps\mp\gametypes\_spawnlogic::removefromcharactersarray(); + var_2 = self getentitynumber(); + + if ( !level.teambased ) + game["roundsWon"][self.guid] = undefined; + + if ( level.splitscreen ) + { + var_3 = level.players; + + if ( var_3.size <= 1 ) + level thread maps\mp\gametypes\_gamelogic::forceend(); + } + + if ( isdefined( self.score ) && isdefined( self.pers["team"] ) ) + { + var_4 = self.score; + + if ( maps\mp\_utility::getminutespassed() ) + var_4 = self.score / maps\mp\_utility::getminutespassed(); + + setplayerteamrank( self, self.clientid, int( var_4 ) ); + } + + var_5 = self getentitynumber(); + var_6 = self.guid; + logprint( "Q;" + var_6 + ";" + var_5 + ";" + self.name + "\n" ); + thread maps\mp\_events::disconnected(); + + if ( level.gameended ) + maps\mp\gametypes\_gamescore::removedisconnectedplayerfromplacement(); + + if ( isdefined( self.team ) ) + removefromteamcount(); + + if ( self.sessionstate == "playing" && !( isdefined( self.fauxdead ) && self.fauxdead ) ) + removefromalivecount( 1 ); + else if ( self.sessionstate == "spectator" || self.sessionstate == "dead" ) + level thread maps\mp\gametypes\_gamelogic::updategameevents(); +} + +removeplayerondisconnect() +{ + var_0 = 0; + + for ( var_1 = 0; var_1 < level.players.size; var_1++ ) + { + if ( level.players[var_1] == self ) + { + for ( var_0 = 1; var_1 < level.players.size - 1; var_1++ ) + level.players[var_1] = level.players[var_1 + 1]; + + level.players[var_1] = undefined; + break; + } + } +} + +initclientdvarssplitscreenspecific() +{ + if ( level.splitscreen || self issplitscreenplayer() ) + { + self setclientdvars( "cg_hudGrenadeIconHeight", "37.5", "cg_hudGrenadeIconWidth", "37.5", "cg_hudGrenadeIconOffset", "75", "cg_hudGrenadePointerHeight", "18", "cg_hudGrenadePointerWidth", "37.5", "cg_hudGrenadePointerPivot", "18 40.5", "cg_fovscale", "0.75" ); + setdvar( "r_materialBloomHQScriptMasterEnable", 0 ); + } + else + self setclientdvars( "cg_hudGrenadeIconHeight", "25", "cg_hudGrenadeIconWidth", "25", "cg_hudGrenadeIconOffset", "50", "cg_hudGrenadePointerHeight", "12", "cg_hudGrenadePointerWidth", "25", "cg_hudGrenadePointerPivot", "12 27", "cg_fovscale", "1" ); +} + +initclientdvars() +{ + setdvar( "cg_drawTalk", 1 ); + setdvar( "cg_drawCrosshair", 1 ); + setdvar( "cg_drawCrosshairNames", 1 ); + setdvar( "cg_hudGrenadeIconMaxRangeFrag", 250 ); + + if ( level.hardcoremode ) + { + setdvar( "cg_drawTalk", 3 ); + setdvar( "cg_drawCrosshair", 0 ); + setdvar( "cg_drawCrosshairNames", 1 ); + setdvar( "cg_hudGrenadeIconMaxRangeFrag", 0 ); + } + + if ( isdefined( level.alwaysdrawfriendlynames ) && level.alwaysdrawfriendlynames ) + setdvar( "cg_drawFriendlyNamesAlways", 1 ); + else + setdvar( "cg_drawFriendlyNamesAlways", 0 ); + + self setclientdvars( "cg_drawSpectatorMessages", 1, "cg_scoreboardPingGraph", 1 ); + initclientdvarssplitscreenspecific(); + + if ( maps\mp\_utility::getgametypenumlives() ) + self setclientdvars( "cg_deadChatWithDead", 1, "cg_deadChatWithTeam", 0, "cg_deadHearTeamLiving", 0, "cg_deadHearAllLiving", 0 ); + else + self setclientdvars( "cg_deadChatWithDead", 0, "cg_deadChatWithTeam", 1, "cg_deadHearTeamLiving", 1, "cg_deadHearAllLiving", 0 ); + + if ( level.teambased ) + self setclientdvars( "cg_everyonehearseveryone", 0 ); + + self setclientdvar( "ui_altscene", 0 ); + + if ( getdvarint( "scr_hitloc_debug" ) ) + { + for ( var_0 = 0; var_0 < 6; var_0++ ) + self setclientdvar( "ui_hitloc_" + var_0, "" ); + + self.hitlocinited = 1; + } +} + +getlowestavailableclientid() +{ + var_0 = 0; + + for ( var_1 = 0; var_1 < 30; var_1++ ) + { + foreach ( var_3 in level.players ) + { + if ( !isdefined( var_3 ) ) + continue; + + if ( var_3.clientid == var_1 ) + { + var_0 = 1; + break; + } + + var_0 = 0; + } + + if ( !var_0 ) + return var_1; + } +} + +setupsavedactionslots() +{ + self.saved_actionslotdata = []; + + for ( var_0 = 1; var_0 <= 4; var_0++ ) + { + self.saved_actionslotdata[var_0] = spawnstruct(); + self.saved_actionslotdata[var_0].type = ""; + self.saved_actionslotdata[var_0].item = undefined; + } + + if ( !level.console ) + { + for ( var_0 = 5; var_0 <= 8; var_0++ ) + { + self.saved_actionslotdata[var_0] = spawnstruct(); + self.saved_actionslotdata[var_0].type = ""; + self.saved_actionslotdata[var_0].item = undefined; + } + } +} + +callback_playerconnect() +{ + thread notifyconnecting(); + self.statusicon = "hud_status_connecting"; + self waittill( "begin" ); + self.statusicon = ""; + self.connecttime = undefined; + level notify( "connected", self ); + self.connected = 1; + + if ( self ishost() ) + level.player = self; + + if ( !level.splitscreen && !isdefined( self.pers["score"] ) ) + iprintln( &"MP_CONNECTED", self ); + + self.usingonlinedataoffline = self isusingonlinedataoffline(); + initclientdvars(); + + if ( !maps\mp\_utility::is_aliens() ) + initplayerstats(); + + if ( getdvar( "r_reflectionProbeGenerate" ) == "1" ) + level waittill( "eternity" ); + + self.guid = maps\mp\_utility::getuniqueid(); + var_0 = 0; + + if ( !isdefined( self.pers["clientid"] ) ) + { + if ( game["clientid"] >= 30 ) + self.pers["clientid"] = getlowestavailableclientid(); + else + self.pers["clientid"] = game["clientid"]; + + if ( game["clientid"] < 30 ) + game["clientid"]++; + + var_0 = 1; + } + + if ( var_0 ) + maps\mp\killstreaks\_killstreaks::resetadrenaline(); + + self.clientid = self.pers["clientid"]; + self.pers["teamKillPunish"] = 0; + logprint( "J;" + self.guid + ";" + self getentitynumber() + ";" + self.name + "\n" ); + + if ( game["clientid"] <= 30 && game["clientid"] != getmatchdata( "playerCount" ) ) + { + var_1 = 0; + var_2 = 0; + + if ( !isai( self ) && maps\mp\_utility::matchmakinggame() ) + self registerparty( self.clientid ); + + setmatchdata( "playerCount", game["clientid"] ); + setmatchdata( "players", self.clientid, "playerID", "xuid", self getxuid() ); + setmatchdata( "players", self.clientid, "playerID", "ucdIDHigh", self getucdidhigh() ); + setmatchdata( "players", self.clientid, "playerID", "ucdIDLow", self getucdidlow() ); + setmatchdata( "players", self.clientid, "playerID", "clanIDHigh", self getclanidhigh() ); + setmatchdata( "players", self.clientid, "playerID", "clanIDLow", self getclanidlow() ); + setmatchdata( "players", self.clientid, "gamertag", self.name ); + var_2 = self getcommonplayerdata( "connectionIDChunkLow", 0 ); + var_1 = self getcommonplayerdata( "connectionIDChunkHigh", 0 ); + setmatchdata( "players", self.clientid, "connectionIDChunkLow", var_2 ); + setmatchdata( "players", self.clientid, "connectionIDChunkHigh", var_1 ); + setmatchclientip( self, self.clientid ); + var_3 = getmatchdata( "gameLength" ); + var_3 += int( maps\mp\_utility::getsecondspassed() ); + setmatchdata( "players", self.clientid, "joinType", self getjointype() ); + setmatchdata( "players", self.clientid, "connectTime", var_3 ); + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + maps\mp\_matchdata::loginitialstats(); + + if ( isdefined( self.pers["isBot"] ) && self.pers["isBot"] || isai( self ) ) + var_4 = 1; + else + var_4 = 0; + + if ( maps\mp\_utility::matchmakinggame() && maps\mp\_utility::allowteamchoice() && !var_4 ) + setmatchdata( "players", self.clientid, "team", self.sessionteam ); + } + + if ( !level.teambased ) + game["roundsWon"][self.guid] = 0; + + self.leaderdialogqueue = []; + self.leaderdialoglocqueue = []; + self.leaderdialogactive = ""; + self.leaderdialoggroups = []; + self.leaderdialoggroup = ""; + + if ( !isdefined( self.pers["cur_kill_streak"] ) ) + self.pers["cur_kill_streak"] = 0; + + if ( !isdefined( self.pers["cur_death_streak"] ) ) + self.pers["cur_death_streak"] = 0; + + if ( !isdefined( self.pers["assistsToKill"] ) ) + self.pers["assistsToKill"] = 0; + + if ( !isdefined( self.pers["cur_kill_streak_for_nuke"] ) ) + self.pers["cur_kill_streak_for_nuke"] = 0; + + if ( !isdefined( self.pers["objectivePointStreak"] ) ) + self.pers["objectivePointStreak"] = 0; + + if ( maps\mp\_utility::rankingenabled() && !maps\mp\_utility::is_aliens() ) + self.kill_streak = maps\mp\gametypes\_persistence::statget( "killStreak" ); + + self.lastgrenadesuicidetime = -1; + self.teamkillsthisround = 0; + self.hasspawned = 0; + self.waitingtospawn = 0; + self.wantsafespawn = 0; + self.wasaliveatmatchstart = 0; + self.movespeedscaler = 1; + self.killstreakscaler = 1; + self.xpscaler = 1; + self.objectivescaler = 1; + self.issniper = 0; + + if ( !maps\mp\_utility::is_aliens() ) + setrestxpgoal(); + + setupsavedactionslots(); + thread maps\mp\_flashgrenades::monitorflash(); + resetuidvarsonconnect(); + waittillframeend; + level.players[level.players.size] = self; + maps\mp\gametypes\_spawnlogic::addtoparticipantsarray(); + maps\mp\gametypes\_spawnlogic::addtocharactersarray(); + + if ( level.teambased ) + self updatescores(); + + if ( game["state"] == "postgame" ) + { + self.connectedpostgame = 1; + self setclientdvars( "cg_drawSpectatorMessages", 0 ); + spawnintermission(); + } + else + { + if ( isai( self ) && isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["think"] ) ) + self thread [[ level.bot_funcs["think"] ]](); + + level endon( "game_ended" ); + + if ( isdefined( level.hostmigrationtimer ) ) + thread maps\mp\gametypes\_hostmigration::hostmigrationtimerthink(); + + if ( isdefined( level.onplayerconnectaudioinit ) ) + [[ level.onplayerconnectaudioinit ]](); + + if ( maps\mp\_utility::bot_is_fireteam_mode() && !isai( self ) ) + { + thread spawnspectator(); + self setclientomnvar( "ui_options_menu", 0 ); + } + else if ( !isdefined( self.pers["team"] ) ) + { + if ( maps\mp\_utility::matchmakinggame() && self.sessionteam != "none" ) + { + thread spawnspectator(); + thread maps\mp\gametypes\_menus::setteam( self.sessionteam ); + + if ( maps\mp\_utility::allowclasschoice() || maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self setclientomnvar( "ui_options_menu", 2 ); + + thread kickifdontspawn(); + return; + } + else if ( issquadsmode() && getdvarint( "onlinegame" ) == 0 && level.gametype != "horde" && isbot( self ) == 0 ) + { + thread spawnspectator(); + thread maps\mp\gametypes\_menus::setteam( "allies" ); + self setclientomnvar( "ui_options_menu", 2 ); + } + else if ( maps\mp\_utility::allowteamchoice() && isbot( self ) == 0 ) + { + maps\mp\gametypes\_menus::menuspectator(); + self setclientomnvar( "ui_options_menu", 1 ); + } + else + { + thread spawnspectator(); + maps\mp\gametypes\_menus::autoassign(); + + if ( maps\mp\_utility::showfakeloadout() && !isai( self ) ) + self setclientomnvar( "ui_options_menu", 2 ); + + if ( maps\mp\_utility::matchmakinggame() ) + thread kickifdontspawn(); + + return; + } + } + else + { + maps\mp\gametypes\_menus::addtoteam( self.pers["team"], 1 ); + + if ( maps\mp\_utility::isvalidclass( self.pers["class"] ) ) + { + thread spawnclient(); + return; + } + + thread spawnspectator(); + + if ( self.pers["team"] == "spectator" ) + { + if ( isdefined( self.pers["mlgSpectator"] ) && self.pers["mlgSpectator"] ) + { + self setmlgspectator( 1 ); + thread maps\mp\gametypes\_spectating::setmlgcamvisibility( 1 ); + thread maps\mp\gametypes\_spectating::setspectatepermissions(); + } + + if ( maps\mp\_utility::allowteamchoice() ) + { + maps\mp\gametypes\_menus::beginteamchoice(); + return; + } + + self [[ level.autoassign ]](); + return; + return; + } + + maps\mp\gametypes\_menus::beginclasschoice(); + } + } +} + +callback_playermigrated() +{ + if ( isdefined( self.connected ) && self.connected ) + { + maps\mp\_utility::updateobjectivetext(); + maps\mp\_utility::updatemainmenu(); + + if ( level.teambased ) + self updatescores(); + } + + if ( self ishost() ) + initclientdvarssplitscreenspecific(); + + var_0 = 0; + + foreach ( var_2 in level.players ) + { + if ( !isdefined( var_2.pers["isBot"] ) || var_2.pers["isBot"] == 0 ) + var_0++; + } + + if ( !isdefined( self.pers["isBot"] ) || self.pers["isBot"] == 0 ) + { + level.hostmigrationreturnedplayercount++; + + if ( level.hostmigrationreturnedplayercount >= var_0 * 2 / 3 ) + level notify( "hostmigration_enoughplayers" ); + } +} + +addlevelstoexperience( var_0, var_1 ) +{ + var_2 = maps\mp\gametypes\_rank::getrankforxp( var_0 ); + var_3 = maps\mp\gametypes\_rank::getrankinfominxp( var_2 ); + var_4 = maps\mp\gametypes\_rank::getrankinfomaxxp( var_2 ); + var_2 += ( var_0 - var_3 ) / ( var_4 - var_3 ); + var_2 += var_1; + + if ( var_2 < 0 ) + { + var_2 = 0; + var_5 = 0.0; + } + else if ( var_2 >= level.maxrank + 1.0 ) + { + var_2 = level.maxrank; + var_5 = 1.0; + } + else + { + var_5 = var_2 - floor( var_2 ); + var_2 = int( floor( var_2 ) ); + } + + var_3 = maps\mp\gametypes\_rank::getrankinfominxp( var_2 ); + var_4 = maps\mp\gametypes\_rank::getrankinfomaxxp( var_2 ); + return int( var_5 * ( var_4 - var_3 ) ) + var_3; +} + +getrestxpcap( var_0 ) +{ + var_1 = getdvarfloat( "scr_restxp_cap" ); + return addlevelstoexperience( var_0, var_1 ); +} + +setrestxpgoal() +{ + if ( !maps\mp\_utility::rankingenabled() ) + return; + + if ( !getdvarint( "scr_restxp_enable" ) ) + { + self setrankedplayerdata( "restXPGoal", 0 ); + return; + } + + var_0 = self getrestedtime(); + var_1 = var_0 / 3600; + var_2 = self getrankedplayerdata( "experience" ); + var_3 = getdvarfloat( "scr_restxp_minRestTime" ); + var_4 = getdvarfloat( "scr_restxp_levelsPerDay" ) / 24.0; + var_5 = getrestxpcap( var_2 ); + var_6 = self getrankedplayerdata( "restXPGoal" ); + + if ( var_6 < var_2 ) + var_6 = var_2; + + var_7 = var_6; + var_8 = 0; + + if ( var_1 > var_3 ) + { + var_8 = var_4 * var_1; + var_6 = addlevelstoexperience( var_6, var_8 ); + } + + var_9 = ""; + + if ( var_6 >= var_5 ) + { + var_6 = var_5; + var_9 = " (hit cap)"; + } + + self setrankedplayerdata( "restXPGoal", var_6 ); +} + +forcespawn() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "spawned" ); + wait 60.0; + + if ( self.hasspawned ) + return; + + if ( self.pers["team"] == "spectator" ) + return; + + if ( !maps\mp\_utility::isvalidclass( self.pers["class"] ) ) + { + self.pers["class"] = "CLASS_CUSTOM1"; + self.class = self.pers["class"]; + } + + thread spawnclient(); +} + +kickifdontspawn() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "spawned" ); + self endon( "attempted_spawn" ); + var_0 = getdvarfloat( "scr_kick_time", 90 ); + var_1 = getdvarfloat( "scr_kick_mintime", 45 ); + var_2 = getdvarfloat( "scr_kick_hosttime", 120 ); + var_3 = gettime(); + + if ( self ishost() ) + kickwait( var_2 ); + else + kickwait( var_0 ); + + var_4 = ( gettime() - var_3 ) / 1000; + + if ( var_4 < var_0 - 0.1 && var_4 < var_1 ) + return; + + if ( self.hasspawned ) + return; + + if ( self.pers["team"] == "spectator" ) + return; + + kick( self getentitynumber(), "EXE_PLAYERKICKED_INACTIVE" ); + level thread maps\mp\gametypes\_gamelogic::updategameevents(); +} + +kickwait( var_0 ) +{ + level endon( "game_ended" ); + maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_0 ); +} + +initplayerstats() +{ + maps\mp\gametypes\_persistence::initbufferedstats(); + self.pers["lives"] = maps\mp\_utility::getgametypenumlives(); + + if ( !isdefined( self.pers["deaths"] ) ) + { + maps\mp\_utility::initpersstat( "deaths" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "deaths", 0 ); + } + + self.deaths = maps\mp\_utility::getpersstat( "deaths" ); + + if ( !isdefined( self.pers["score"] ) ) + { + maps\mp\_utility::initpersstat( "score" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "score", 0 ); + } + + self.score = maps\mp\_utility::getpersstat( "score" ); + + if ( !isdefined( self.pers["suicides"] ) ) + maps\mp\_utility::initpersstat( "suicides" ); + + self.suicides = maps\mp\_utility::getpersstat( "suicides" ); + + if ( !isdefined( self.pers["kills"] ) ) + { + maps\mp\_utility::initpersstat( "kills" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "kills", 0 ); + } + + self.kills = maps\mp\_utility::getpersstat( "kills" ); + + if ( !isdefined( self.pers["headshots"] ) ) + maps\mp\_utility::initpersstat( "headshots" ); + + self.headshots = maps\mp\_utility::getpersstat( "headshots" ); + + if ( !isdefined( self.pers["assists"] ) ) + { + maps\mp\_utility::initpersstat( "assists" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "assists", 0 ); + } + + self.assists = maps\mp\_utility::getpersstat( "assists" ); + + if ( !isdefined( self.pers["captures"] ) ) + { + maps\mp\_utility::initpersstat( "captures" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "captures", 0 ); + } + + self.captures = maps\mp\_utility::getpersstat( "captures" ); + + if ( !isdefined( self.pers["returns"] ) ) + { + maps\mp\_utility::initpersstat( "returns" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "returns", 0 ); + } + + self.returns = maps\mp\_utility::getpersstat( "returns" ); + + if ( !isdefined( self.pers["defends"] ) ) + { + maps\mp\_utility::initpersstat( "defends" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "defends", 0 ); + } + + self.defends = maps\mp\_utility::getpersstat( "defends" ); + + if ( !isdefined( self.pers["plants"] ) ) + { + maps\mp\_utility::initpersstat( "plants" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "plants", 0 ); + } + + self.plants = maps\mp\_utility::getpersstat( "plants" ); + + if ( !isdefined( self.pers["defuses"] ) ) + { + maps\mp\_utility::initpersstat( "defuses" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "defuses", 0 ); + } + + self.defuses = maps\mp\_utility::getpersstat( "defuses" ); + + if ( !isdefined( self.pers["destructions"] ) ) + { + maps\mp\_utility::initpersstat( "destructions" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "destructions", 0 ); + } + + self.destructions = maps\mp\_utility::getpersstat( "destructions" ); + + if ( !isdefined( self.pers["confirmed"] ) ) + { + maps\mp\_utility::initpersstat( "confirmed" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "confirmed", 0 ); + } + + self.confirmed = maps\mp\_utility::getpersstat( "confirmed" ); + + if ( !isdefined( self.pers["denied"] ) ) + { + maps\mp\_utility::initpersstat( "denied" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "denied", 0 ); + } + + self.denied = maps\mp\_utility::getpersstat( "denied" ); + + if ( !isdefined( self.pers["rescues"] ) ) + { + maps\mp\_utility::initpersstat( "rescues" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "rescues", 0 ); + } + + self.rescues = maps\mp\_utility::getpersstat( "rescues" ); + + if ( !isdefined( self.pers["killChains"] ) ) + { + maps\mp\_utility::initpersstat( "killChains" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killChains", 0 ); + } + + self.killchains = maps\mp\_utility::getpersstat( "killChains" ); + + if ( !isdefined( self.pers["killsAsSurvivor"] ) ) + { + maps\mp\_utility::initpersstat( "killsAsSurvivor" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killsAsSurvivor", 0 ); + } + + self.killsassurvivor = maps\mp\_utility::getpersstat( "killsAsSurvivor" ); + + if ( !isdefined( self.pers["killsAsInfected"] ) ) + { + maps\mp\_utility::initpersstat( "killsAsInfected" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "killsAsInfected", 0 ); + } + + self.killsasinfected = maps\mp\_utility::getpersstat( "killsAsInfected" ); + + if ( !isdefined( self.pers["teamkills"] ) ) + maps\mp\_utility::initpersstat( "teamkills" ); + + if ( !isdefined( self.pers["extrascore0"] ) ) + maps\mp\_utility::initpersstat( "extrascore0" ); + + if ( !isdefined( self.pers["hordeKills"] ) ) + { + maps\mp\_utility::initpersstat( "hordeKills" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardKills", 0 ); + } + + if ( !isdefined( self.pers["hordeRevives"] ) ) + { + maps\mp\_utility::initpersstat( "hordeRevives" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardRevives", 0 ); + } + + if ( !isdefined( self.pers["hordeCrates"] ) ) + { + maps\mp\_utility::initpersstat( "hordeCrates" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "squardCrates", 0 ); + } + + if ( !isdefined( self.pers["hordeRound"] ) ) + { + maps\mp\_utility::initpersstat( "hordeRound" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "sguardWave", 0 ); + } + + if ( !isdefined( self.pers["hordeWeapon"] ) ) + { + maps\mp\_utility::initpersstat( "hordeWeapon" ); + maps\mp\gametypes\_persistence::statsetchild( "round", "sguardWeaponLevel", 0 ); + } + + if ( !isdefined( self.pers["teamKillPunish"] ) ) + self.pers["teamKillPunish"] = 0; + + maps\mp\_utility::initpersstat( "longestStreak" ); + self.pers["lives"] = maps\mp\_utility::getgametypenumlives(); + maps\mp\gametypes\_persistence::statsetchild( "round", "killStreak", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "loss", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "win", 0 ); + maps\mp\gametypes\_persistence::statsetchild( "round", "scoreboardType", "none" ); + maps\mp\gametypes\_persistence::statsetchildbuffered( "round", "timePlayed", 0 ); +} + +addtoteamcount() +{ + level.teamcount[self.team]++; + + if ( !isdefined( level.teamlist ) ) + level.teamlist = []; + + if ( !isdefined( level.teamlist[self.team] ) ) + level.teamlist[self.team] = []; + + level.teamlist[self.team][level.teamlist[self.team].size] = self; + maps\mp\gametypes\_gamelogic::updategameevents(); +} + +removefromteamcount() +{ + level.teamcount[self.team]--; + + if ( isdefined( level.teamlist ) && isdefined( level.teamlist[self.team] ) ) + { + var_0 = []; + + foreach ( var_2 in level.teamlist[self.team] ) + { + if ( !isdefined( var_2 ) || var_2 == self ) + continue; + + var_0[var_0.size] = var_2; + } + + level.teamlist[self.team] = var_0; + } +} + +addtoalivecount() +{ + var_0 = self.team; + + if ( !( isdefined( self.alreadyaddedtoalivecount ) && self.alreadyaddedtoalivecount ) ) + { + level.hasspawned[var_0]++; + incrementalivecount( var_0 ); + } + + self.alreadyaddedtoalivecount = undefined; + + if ( level.alivecount["allies"] + level.alivecount["axis"] > level.maxplayercount ) + level.maxplayercount = level.alivecount["allies"] + level.alivecount["axis"]; +} + +incrementalivecount( var_0 ) +{ + level.alivecount[var_0]++; +} + +removefromalivecount( var_0 ) +{ + if ( maps\mp\_utility::is_aliens() ) + return; + + var_1 = self.team; + + if ( isdefined( self.switching_teams ) && self.switching_teams && isdefined( self.joining_team ) && self.joining_team == self.team ) + var_1 = self.leaving_team; + + if ( isdefined( var_0 ) ) + removeallfromlivescount(); + else if ( isdefined( self.switching_teams ) ) + self.pers["lives"]--; + + decrementalivecount( var_1 ); + return maps\mp\gametypes\_gamelogic::updategameevents(); +} + +decrementalivecount( var_0 ) +{ + level.alivecount[var_0]--; +} + +addtolivescount() +{ + level.livescount[self.team] += self.pers["lives"]; +} + +removefromlivescount() +{ + level.livescount[self.team]--; + level.livescount[self.team] = int( max( 0, level.livescount[self.team] ) ); +} + +removeallfromlivescount() +{ + level.livescount[self.team] -= self.pers["lives"]; + level.livescount[self.team] = int( max( 0, level.livescount[self.team] ) ); +} + +resetuidvarsonspawn() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsonconnect() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientdvar( "ui_eyes_on_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsonspectate() +{ + self setclientomnvar( "ui_carrying_bomb", 0 ); + self setclientomnvar( "ui_dom_securing", 0 ); + self setclientomnvar( "ui_securing", 0 ); + self setclientomnvar( "ui_bomb_planting_defusing", 0 ); + self setclientomnvar( "ui_light_armor", 0 ); + self setclientomnvar( "ui_killcam_end_milliseconds", 0 ); + self setclientdvar( "ui_juiced_end_milliseconds", 0 ); + self setclientdvar( "ui_eyes_on_end_milliseconds", 0 ); + self setclientomnvar( "ui_cranked_bomb_timer_end_milliseconds", 0 ); +} + +resetuidvarsondeath() +{ + +} + +watchforslide() +{ + self endon( "death" ); + self endon( "disconnect" ); + + for (;;) + { + self waittill( "sprint_slide_begin" ); + self playfx( level._effect["slide_dust"], self geteye() ); + } +} diff --git a/localappdata/xlabs/data/iw6x/data/scripts/_team_balance.gsc b/localappdata/xlabs/data/iw6x/data/scripts/_team_balance.gsc new file mode 100644 index 0000000..6866a9c --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/scripts/_team_balance.gsc @@ -0,0 +1,23 @@ +init() +{ + // define onteamselection callback function used in balanceteams() + level.onteamselection = ::set_team; +} + +set_team(team) +{ + if (team != self.pers["team"]) + { + self.switching_teams = true; + self.joining_team = team; + self.leaving_team = self.pers["team"]; + } + + if (self.sessionstate == "playing") + { + self suicide(); + } + + maps\mp\gametypes\_menus::addtoteam(team); + maps\mp\gametypes\_menus::endrespawnnotify(); +} diff --git a/localappdata/xlabs/data/iw6x/data/sound/patch-3-music.flac b/localappdata/xlabs/data/iw6x/data/sound/patch-3-music.flac new file mode 100644 index 0000000..ad13711 Binary files /dev/null and b/localappdata/xlabs/data/iw6x/data/sound/patch-3-music.flac differ diff --git a/localappdata/xlabs/data/iw6x/data/ui_scripts/main_menu/__init__.lua b/localappdata/xlabs/data/iw6x/data/ui_scripts/main_menu/__init__.lua new file mode 100644 index 0000000..150cfc8 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/ui_scripts/main_menu/__init__.lua @@ -0,0 +1,497 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +package.loaded["LUI.mp_menus.MPMainMenu"].main_menu_options_feeder = function( f17_arg0 ) + local f17_local0 = Engine.IsAliensMode() + local f17_local1 = SvS.IsSvS() + local f17_local2 = false + if Engine.GetDvarInt( "allow_online_squads" ) == 1 or not Engine.IsConsoleGame() then + f17_local2 = true + end + local f17_local3 = Engine.DoWeNeedCompatibilityPacks() + if f17_local1 then + local f17_local4 = f17_local2 + end + local f17_local5 = f17_local4 or not f17_local1 + local f17_local6 = {} + if Engine.AllowOnline() and f17_local5 then + local f17_local7, f17_local8 = nil + if f17_local1 then + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_SQUADS_CAPS" ) + f17_local7 = Engine.Localize( "@LUA_MENU_SQUADS_INTRO" ) + elseif f17_local0 then + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_CAPS" ) + f17_local7 = Engine.Localize( "@LUA_MENU_PLAY_EXTINCTION_ONLINE_DESC" ) + else + f17_local8 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_CAPS" ) + f17_local7 = Engine.Localize( "@PLATFORM_PLAY_ONLINE_DESC" ) + end + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_0", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks, + properties = { + button_text = f17_local8, + button_action_func = LUI.mp_menus.MPMainMenu.xboxLiveButtonAction, + desc_text = f17_local7, + button_over_func = function ( f18_arg0, f18_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + end + if Engine.IsConsoleGame() then + local f17_local7 = "@LUA_MENU_SPLITSCREEN_CAPS" + if f17_local0 then + f17_local7 = "@LUA_MENU_LOCAL_CAPS" + elseif f17_local1 then + f17_local7 = "@LUA_MENU_LOCAL_CAPS" + end + local f17_local8 = #f17_local6 + 1 + local f17_local9 = { + type = "UIGenericButton", + id = "btn_MPMain_1", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks + } + local f17_local10 = { + button_text = Engine.Localize( f17_local7 ), + button_action_func = splitScreenButtonAction + } + local f17_local11 + if f17_local1 then + f17_local11 = Engine.Localize( "@LUA_MENU_SQUAD_LOCAL_PLAY_DESC" ) + if not f17_local11 then + + else + f17_local10.desc_text = f17_local11 + f17_local10.button_over_func = function ( f19_arg0, f19_arg1 ) + PersistentBackground.SetToDefault() + end + + f17_local9.properties = f17_local10 + f17_local6[f17_local8] = f17_local9 + if not f17_local1 then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_2", + disabled = f17_local3, + disabledFunc = Engine.DoWeNeedCompatibilityPacks, + properties = { + button_text = Engine.Localize( "@PLATFORM_SYSTEM_LINK_CAPS" ), + button_action_func = LUI.mp_menus.MPMainMenu.systemLinkButtonAction, + desc_text = Engine.Localize( "@PLATFORM_SYSTEM_LINK_DESC" ), + button_over_func = function ( f20_arg0, f20_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + end + end + end + f17_local11 = Engine.Localize( "@LUA_MENU_SPLITSCREEN_DESC" ) + end + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_6", + properties = { + button_text = Engine.Localize( "@LUA_MENU_OPTIONS_CAPS" ), + button_action_func = LUI.mp_menus.MPMainMenu.optionsButtonAction, + desc_text = Engine.Localize( "@LUA_MENU_OPTIONS_DESC" ), + button_over_func = function ( f22_arg0, f22_arg1 ) + PersistentBackground.SetToDefault() + end + } + } + f17_local6[#f17_local6 + 1] = { + type = "generic_separator", + id = "main_menu_spacer_id" + } + if not Engine.IsCoreMode() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_7", + properties = { + text = Engine.Localize( "@LUA_MENU_MULTIPLAYER_CAPS" ), + button_action_func = function ( f23_arg0, f23_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToCoreMode() + Engine.PlayMusic( CoD.Music.MainMPMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f24_arg0, f24_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.MPBackground ) + end, + desc_text = Engine.Localize( "@PLATFORM_PLAY_ONLINE_DESC" ) + } + } + end + if not SvS.IsSvS() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_8", + properties = { + button_text = Engine.Localize( "@LUA_MENU_SQUAD_MODE_CAP" ), + button_action_func = function ( f25_arg0, f25_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToSquadVsSquadMode() + Engine.PlayMusic( CoD.Music.MainSquadMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f26_arg0, f26_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.SvSBackground ) + end, + desc_text = Engine.Localize( "@LUA_MENU_SVS_MAIN_MENU_DESC" ) + } + } + end + if not Engine.IsAliensMode() and Engine.UnlockedAliens() then + f17_local6[#f17_local6 + 1] = { + type = "UIGenericButton", + id = "btn_MPMain_9", + properties = { + button_text = Engine.Localize( "@LUA_MENU_ALIENS_CAPS" ), + button_action_func = function ( f27_arg0, f27_arg1 ) + Engine.StopMusic( 200 ) + Engine.SwitchToAliensMode() + Engine.PlayMusic( CoD.Music.MainExtinctMusic ) + Engine.SetActiveMenu( ActiveMenus.None ) + Engine.SetActiveMenu( ActiveMenus.Main ) + end, + button_over_func = function ( f28_arg0, f28_arg1 ) + PersistentBackground.Set( PersistentBackground.Variants.AliensBackground ) + end, + desc_text = Engine.Localize( "@LUA_MENU_ALIENS_MAIN_MENU_DESC" ), + additional_handlers = { + menu_create = AddExtinctionGlowBackground + } + } + } + end + f17_local6[#f17_local6 + 1] = { + type = "button_desc_text", + id = "mp_menu_button_description_id", + properties = { + lines = SvS.IsSvS() and 8 or nil + } + } + return f17_local6 +end + +package.loaded["LUI.mp_menus.MPXboxLiveMenu"].XboxLiveOptionsFeeder = function( f29_arg0 ) + local f29_local0 = Engine.IsAliensMode() + local f29_local1 = SvS.IsSvS() + local f29_local2 = SvS.IsSvS() + if f29_local2 then + f29_local2 = SvS.GetCurrentSquadModeInfo() + end + local f29_local3 = {} + local f29_local4 = nil + if f29_local0 then + f29_local4 = Engine.Localize( "@LUA_MENU_STORE_CAPS" ) -- Orginally @LUA_MENU_PUBLIC_MATCH_CAPS but we need to use @LUA_MENU_STORE_CAPS + elseif f29_local1 then + f29_local4 = Engine.Localize( "@PLATFORM_FIND_GAME_CAPS" ) + else + f29_local4 = Engine.Localize( "@LUA_MENU_STORE_CAPS" ) -- Orginally @PLATFORM_FIND_GAME_CAPS but we need to use @LUA_MENU_STORE_CAPS + end + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "find_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = f29_local4, + button_action_func = FindMatchAction, + desc_text = SvS.IsSvS() and Engine.Localize( "@LUA_MENU_SQUADS_FIND_MATCH_DESC" ) or Engine.Localize( "@LUA_MENU_STORE_DESC" ), -- Orginally @PLATFORM_DESC_FIND_GAME but we need to use @LUA_MENU_STORE_DESC + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + if f29_local0 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "solo_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.shouldDisableSoloMatch(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_SOLO_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.SoloMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_SOLO_MATCH_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.shouldDisableSoloMatch, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "private_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_CUSTOM_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.PrivateMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_PRIVATE_MATCH" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + if not f29_local0 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "create_squad_button_id", + disabled = false, + properties = { + button_text = Engine.Localize( "@LUA_MENU_CREATE_A_CLASS_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.CreateSquadAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CREATE_A_CLASS" ), + additional_handlers = { + refresh_new_icons = function ( f30_arg0, f30_arg1 ) + if Cac.AnyUnseenMDLCItems( Engine.GetFirstActiveController(), NewIconsTable.CACItemTypes ) then + f30_arg0:processEvent( { + name = "show_new_icon" + } ) + end + end + } + } + } + else + f29_local3[#f29_local3 + 1] = LUI.mp_menus.AliensLoadout.GetAliensLoadoutButton() + end + local f29_local5 = { + type = "UIGenericButton", + id = "leaderboards_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_LEADERBOARDS_CAPS" ), + desc_text = Engine.Localize( "@LUA_MENU_DESC_LEADERBOARDS" ), + button_action_func = function ( f31_arg0, f31_arg1 ) + if Engine.IsUserAGuest( f31_arg1.controller ) then + LUI.FlowManager.RequestPopupMenu( f31_arg0, "popup_no_guest", true, f31_arg1.controller ) + else + LUI.FlowManager.RequestAddMenu( f31_arg0, "leaderboards", true, f31_arg1.controller ) + end + end + } + } + if f29_local1 and f29_local2.HasLeaderboard then + f29_local3[#f29_local3 + 1] = f29_local5 + end + if f29_local1 and f29_local2 and f29_local2.HasReports then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "squad_reports_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_SQUAD_REPORTS" ), + desc_text = Engine.Localize( "@LUA_MENU_SQUAD_REPORTS_DESC" ), + button_action_func = function ( f32_arg0, f32_arg1 ) + LUI.FlowManager.RequestAddMenu( f32_arg0, "squad_reports_menu", false, f32_arg1.controller, false, { + controller = f32_arg1.controller + } ) + end + } + } + end + if not f29_local0 and not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "operations_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_OPERATIONS_TITLE" ), + button_action_func = LUI.mp_menus.MPBarracks.BarrackOperationsAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_CHALLENGES" ) + } + } + end + if not f29_local0 then + if not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "barracks_button_id", + disabled = false, + properties = { + button_text = Engine.Localize( "@LUA_MENU_BARRACKS_CAPS" ), + button_action_func = BarracksAction, + desc_text = Clan.IsEnabled() and Engine.Localize( "@LUA_MENU_DESC_BARRACKS" ) or Engine.Localize( "@LUA_MENU_DESC_BARRACKS_PRIVATE" ) + } + } + end + if not f29_local1 or f29_local2 ~= SvS.SquadModes.SquadVsSquad then + f29_local3[#f29_local3 + 1] = { + type = "generic_separator" + } + end + if not f29_local1 then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "private_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "@LUA_MENU_PRIVATE_MATCH_CAPS" ), + button_action_func = LUI.mp_menus.MPXboxLiveMenu.PrivateMatchAction, + desc_text = Engine.Localize( "@LUA_MENU_DESC_PRIVATE_MATCH" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + if f29_local1 then + if f29_local2 == SvS.SquadModes.SquadAssault then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "squad_match_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "LUA_MENU_CHALLENGE_FRIEND_CAPS" ), + button_action_func = function ( f35_arg0, f35_arg1 ) + if IsFirstTimeFlowRequired( f35_arg1.controller ) then + LUI.FlowManager.RequestAddMenu( f35_arg0, "cac_member_select_main", true, f35_arg1.controller, false, { + next_screen = "cac_edit_main", + squad_location = "squadMembers", + class_location = "loadouts", + findMatch = true + } ) + elseif CheckHasRequiredDLC( f35_arg0 ) then + LUI.FlowManager.RequestPopupMenu( f35_arg0, "popup_friends", true, f35_arg1.controller, false, { + challengeMode = true + } ) + end + end, + desc_text = Engine.Localize( "LUA_MENU_CHALLENGE_FRIEND_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + if f29_local2 and not f29_local2.RequiresMatchmaking then + f29_local3[#f29_local3 + 1] = { + type = "UIGenericButton", + id = "play_now_button_id", + disabled = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons(), + properties = { + button_text = Engine.Localize( "LUA_MENU_PLAY_NOW_CAPS" ), + button_action_func = function ( f36_arg0, f36_arg1 ) + f36_arg1.squadsPlayNow = true + FindMatchAction( f36_arg0, f36_arg1 ) + end, + desc_text = Engine.Localize( "LUA_MENU_PLAY_NOW_DESC" ), + disabledFunc = LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons, + additional_handlers = { + check_buttons = LUI.mp_menus.MPLivePrivateLobby.RefreshButtonDisable + } + } + } + end + end + end + local f29_local6 = #f29_local3 + 1 + local f29_local7 = { + type = "button_desc_text", + id = "prelobby_description_id" + } + local f29_local8 = {} + local f29_local9 + if not (not SvS.IsSvS() or f29_local2 ~= SvS.SquadModes.SquadAssault) or Engine.IsAliensMode() or Engine.IsCoreMode() then + f29_local9 = 1 + if not f29_local9 then + + else + f29_local8.lines = f29_local9 + f29_local7.properties = f29_local8 + f29_local3[f29_local6] = f29_local7 + f29_local3[#f29_local3 + 1] = { + type = "UITimer", + id = "bnt_lock_tmr", + properties = { + event = "check_buttons", + interval = 500, + disposable = false, + broadcastToRoot = true + } + } + return f29_local3 + end + end + f29_local9 = nil +end + +function FindMatchAction( f5_arg0, f5_arg1 ) + if Lobby.EnteringLobby() == true then + LUI.FlowManager.RequestPopupMenu( f5_arg0, "popup_throttling", true, f5_arg1.controller, false, { + eventData = f5_arg1 + } ) + else + FindMatchAfterThrottleEvent( f5_arg0, f5_arg1 ) + end +end + +function FindMatchAfterThrottleEvent( f4_arg0, f4_arg1 ) + local f4_local0 = false + local f4_local1 = -1 + for f4_local2 = 0, Engine.GetMaxControllerCount() - 1, 1 do + if Engine.HasActiveLocalClient( f4_local2 ) and IsFirstTimeFlowRequired( f4_local2 ) then + f4_local0 = true + if f4_local1 < 0 then + f4_local1 = f4_local2 + end + end + end + if f4_local0 then + LUI.FlowManager.RequestAddMenu( f4_arg0, "cac_member_select_main", true, f4_local1, false, { + next_screen = "cac_edit_main", + squad_location = "squadMembers", + class_location = "loadouts", + findMatch = true + } ) + elseif not LUI.mp_menus.MPXboxLiveMenu.disableCreateGameButtons() then + Engine.Exec( "xblive_privatematch 0" ) + if Engine.IsAliensMode() then + LUI.mp_menus.Aliens.AliensRunConfig( f4_arg1.controller ) + end + if LUI.mp_menus.MPXboxLiveMenu.CheckHasRequiredDLC( f4_arg0 ) then + if LUI.mp_menus.MPXboxLiveMenu.DisplayLowRepWarning( f4_arg0, f4_arg1 ) then + return + elseif SvS.IsSvS() then + local f4_local3 = SvS.GetCurrentSquadModeInfo() + local f4_local4, f4_local5 = SvS.GetPlaylistFromSquadMode( f4_local3 ) + local f4_local6 = false + if f4_arg1.squadsPlayNow then + f4_local6 = true + end + if not f4_arg1.squadsPlayNow and f4_local3.DynamicMatchmaking then + Playlist.DoAction( f4_local4, f4_local5, true, f4_local6 ) + else + Playlist.DoAction( f4_local4, f4_local5, false, f4_local6 ) + end + if Engine.GetDvarBool( "squad_match" ) then + Squad.StartMatch( f4_arg1.controller, true ) + Engine.SetDvarBool( "squad_find_match", true ) + end + LUI.FlowManager.RequestAddMenu( f4_arg0, "menu_xboxlive_lobby", false, f4_arg1.controller, false ) + else + LUI.FlowManager.RequestPopupMenu( f4_arg0, "menu_systemlink_join" ) -- open server list instead of playlist_main + end + end + end +end + +function BarracksAction( f9_arg0, f9_arg1 ) + LUI.FlowManager.RequestAddMenu( f9_arg0, "menu_stats", true, f9_arg1.controller ) -- custom stats menu +end + +-- Remove social button +LUI.MenuBuilder.m_definitions["online_friends_widget"] = function() + return { + type = "UIElement" + } +end diff --git a/localappdata/xlabs/data/iw6x/data/ui_scripts/server_filter/__init__.lua b/localappdata/xlabs/data/iw6x/data/ui_scripts/server_filter/__init__.lua new file mode 100644 index 0000000..c236356 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/ui_scripts/server_filter/__init__.lua @@ -0,0 +1,436 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local Lobby = luiglobals.Lobby + +game:addlocalizedstring("LUA_MENU_SERVER_FILTER_POPUP_INSTR", "Change how the servers are filtered") + +function FiltersPopupClose(f1_arg0, f1_arg1) + local f1_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f1_arg0) + local f1_local1 = LUI.FlowManager.GetMenuScopedDataByMenuName("mp_leaderboard_main") + local f1_local2 = f1_local1.leaderboardType + if f1_local2 and f1_local2 ~= "" then + Leaderboards.OpenLeaderboard(f1_arg0, f1_local2, f1_local0.filterKey, f1_local1.filterDurationKey, f1_local1.isHardcore) + end +end + +function mp_server_filters_popup() + return { + type = "UIElement", + id = "mp_leaderboard_filters_popup_container_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + children = { + { + type = "UIImage", + id = "darken_bg", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + top = 0, + bottom = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + } + }, + { + type = "UIElement", + id = "mp_server_filters_popup_id", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = false, + rightAnchor = false, + top = -1 * Leaderboards.Layout.FilterHeight * 0.6, + width = Leaderboards.Layout.FilterWidth, + height = 170 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "server_filters_popup_title_bar_id", + properties = { + title_bar_text = Engine.Localize("@LUA_MENU_FILTER_CAPS"), + fill_alpha = 1 + } + }, + { + type = "generic_menu_background", + id = "server_filters_popup_background", + properties = { + fill_alpha = 1 + } + }, + { + type = "mp_server_filters_popup_page" + }, + { + type = "UIBindButton", + id = "filters_popup_back_button", + handlers = { + button_secondary = MBh.DoMultiple({ + MBh.LeaveMenu(), + FiltersPopupClose, + ForceRefreshServers + }) + } + } + } + } + } + } +end + +function ForceRefreshServers(f4_arg0, f4_arg1) + local f4_local0 = LUI.FlowManager.GetMenuScopedDataByMenuName("menu_systemlink_join") + f4_local0.serverCount = 0 + if f4_local0.serverList then + local f4_local1 = Lobby.RefreshServerList + local f4_local2 = f4_arg1.controller + if not f4_local2 then + f4_local2 = Engine.GetFirstActiveController() + end + f4_local1(f4_local2) + f4_local0.serverList:processEvent({ + name = "lose_focus", + immediate = true + }) + f4_local0.serverList:clearSavedState() + f4_local0.serverList:processEvent({ + name = "menu_refresh", + dispatchChildren = true + }) + end +end + +function OpenFiltersMenu(f36_arg0, f36_arg1) + LUI.FlowManager.RequestPopupMenu(f36_arg0, "mp_server_filters_popup", true, f36_arg1.controller, false, {}) +end + +LUI.MenuBuilder.registerDef("mp_server_filters_popup", mp_server_filters_popup) + +GameTypeRefCol = 0 +GameTypeNameCol = 1 +GameTypeDescCol = 2 +GameTypeImageCol = 3 + +function GetGametypes() + if Engine.IsCoreMode() then + return { "any", "dm", "war", "sd", "dom", "conf", "sr", "infect", "blitz", "grind", "cranked", "sotf", "sotf_ffa", + "horde", "gun", "grnd", "siege" } + end + return { "aliens" } +end + +function GetLocalizedStringFromGametype(gametype) + if gametype == "any" then + return string.upper(Engine.Localize("LUA_MENU_LB_FILTER_GROUP_ALL")) + end + local gametype_name = Engine.TableLookup("mp/gameTypesTable.csv", GameTypeRefCol, gametype, GameTypeNameCol) + if gametype_name ~= "" then + local token = "@" + local caps_token = "_CAPS" + localized = Engine.Localize(token .. gametype_name .. caps_token) + return localized + end + return "UNKNOWN" +end + +function GetMapnameFromID(id) + if id == "any" then + return string.upper(Engine.Localize("LUA_MENU_LB_FILTER_GROUP_ALL")) + end + + if id == "mp_descent_new" then + return Engine.Localize("@LUA_MENU_MAPNAME_DESCENT_CAPS") + elseif id == "mp_favela_iw6" then + return string.upper(Engine.Localize("@PRESENCE_MP_FAVELA_IW6")) + elseif id == "mp_conflict" then + return string.upper(Engine.Localize("@PRESENCE_MP_CONFLICT")) + elseif id == "mp_mine" then + return string.upper(Engine.Localize("@PRESENCE_MP_MINE")) + elseif id == "mp_shipment_ns" then + return string.upper(Engine.Localize("@PRESENCE_MP_SHIPMENT_NS")) + elseif id == "mp_zerosub" then + return string.upper(Engine.Localize("@PRESENCE_MP_ZEROSUB")) + elseif id == "mp_ca_red_river" then + return string.upper(Engine.Localize("@PRESENCE_MP_CA_RED_RIVER")) + elseif id == "mp_ca_rumble" then + return string.upper(Engine.Localize("@PRESENCE_MP_CA_RUMBLE")) + end + + if id == "mp_alien_town" then + return string.upper(Engine.Localize("@MPUI_ALIEN_TOWN")) + elseif id == "mp_alien_armory" then + return string.upper(Engine.Localize("@MPUI_ALIEN_ARMORY")) + elseif id == "mp_alien_beacon" then + return string.upper(Engine.Localize("@MPUI_ALIEN_BEACON")) + elseif id == "mp_alien_dlc3" then + return string.upper(Engine.Localize("@PRESENCE_MP_ALIEN_DLC3")) + elseif id == "mp_alien_last" then + return string.upper(Engine.Localize("@PRESENCE_MP_ALIEN_LAST")) + end + + return Engine.Localize("@LUA_MENU_MAPNAME_" .. id:sub(4) .. "_CAPS") +end + +function GetMaps() + if Engine.IsCoreMode() then + return { + "any", + "mp_prisonbreak", + "mp_dart", + "mp_lonestar", + "mp_frag", + "mp_snow", + "mp_fahrenheit", + "mp_hashima", + "mp_warhawk", + "mp_sovereign", + "mp_zebra", + "mp_skeleton", + "mp_chasm", + "mp_flooded", + "mp_strikezone", + "mp_descent_new", + "mp_ca_red_river", + "mp_ca_rumble", + "mp_swamp", + "mp_boneyard_ns", + "mp_dome_ns", + "mp_battery3", + "mp_ca_impact", + "mp_ca_behemoth", + "mp_dig", + "mp_zulu", + "mp_pirate", + "mp_favela_iw6", + "mp_zerosub", + "mp_conflict", + "mp_mine", + "mp_shipment_ns", + } + elseif Engine.IsAliensMode() then + return { + "any", + "mp_alien_town", + "mp_alien_armory", + "mp_alien_beacon", + "mp_alien_dlc3", + "mp_alien_last" + } + end + + return { "any" } +end + +function ServerFiltersPopupItems(f7_arg0) + + local rules = {} + if Engine.IsCoreMode() then + local gametype = { + type = "UIGenericButton", + id = "server_filters_gametype", + properties = { + style = GenericButtonSettings.Styles.GlassButton, + substyle = GenericButtonSettings.Styles.GlassButton.SubStyles.SubMenu, + variant = GenericButtonSettings.Variants.Select, + content_width = 258, + side = "left", + button_text = Engine.Localize("@LUA_MENU_MODE_CAPS"), + button_display_func = function(f8_arg0, f8_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f8_arg0) + if focusedElement.filterGametypeKey == nil then + focusedElement.filterGametypeKey = Engine.GetDvarString("ui_mapvote_entrya_gametype") + end + Engine.SetDvarString("ui_mapvote_entrya_gametype", focusedElement.filterGametypeKey) + return Engine.Localize(GetLocalizedStringFromGametype(focusedElement.filterGametypeKey)) + end, + button_left_func = function(f9_arg0, f9_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f9_arg0) + local keys = GetGametypes() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterGametypeKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI - 1 + if defaultKeysI < 1 then + focusedElement.filterGametypeKey = keys[#keys] + else + focusedElement.filterGametypeKey = keys[defaultKeysI] + end + end, + button_right_func = function(f10_arg0, f10_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f10_arg0) + local keys = GetGametypes() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterGametypeKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI + 1 + if #keys < defaultKeysI then + focusedElement.filterGametypeKey = keys[1] + else + focusedElement.filterGametypeKey = keys[defaultKeysI] + end + end + } + } + table.insert(rules, gametype) + end + + local maps = { + type = "UIGenericButton", + id = "server_filters_map", + properties = { + style = GenericButtonSettings.Styles.GlassButton, + substyle = GenericButtonSettings.Styles.GlassButton.SubStyles.SubMenu, + variant = GenericButtonSettings.Variants.Select, + content_width = 258, + side = "left", + button_text = Engine.Localize("@LUA_MENU_MAPS_CAPS"), + button_display_func = function(f8_arg0, f8_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f8_arg0) + if focusedElement.filterMapnameKey == nil then + focusedElement.filterMapnameKey = Engine.GetDvarString("ui_mapvote_entrya_mapname") + end + Engine.SetDvarString("ui_mapvote_entrya_mapname", focusedElement.filterMapnameKey) + return GetMapnameFromID(focusedElement.filterMapnameKey) + end, + button_left_func = function(f9_arg0, f9_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f9_arg0) + local keys = GetMaps() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterMapnameKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI - 1 + if defaultKeysI < 1 then + focusedElement.filterMapnameKey = keys[#keys] + else + focusedElement.filterMapnameKey = keys[defaultKeysI] + end + end, + button_right_func = function(f10_arg0, f10_arg1) + local focusedElement = LUI.FlowManager.GetMenuScopedDataFromElement(f10_arg0) + local keys = GetMaps() + local defaultKeysI = 1 + for i = 1, #keys, 1 do + if keys[i] == focusedElement.filterMapnameKey then + defaultKeysI = i + break + end + end + defaultKeysI = defaultKeysI + 1 + if #keys < defaultKeysI then + focusedElement.filterMapnameKey = keys[1] + else + focusedElement.filterMapnameKey = keys[defaultKeysI] + end + end + } + } + table.insert(rules, maps) + + return rules +end + +function mp_server_filters_popup_page() + return { + type = "UIElement", + id = "mp_server_filters_popup_page_id", + properties = {}, + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = AAR.Layout.TitleBarHeight + 1, + bottom = -1, + left = 1, + right = -1, + } + }, + children = { + { + type = "UIText", + id = "leaderboard_filters_instruction", + properties = { + text = Engine.Localize("@LUA_MENU_SERVER_FILTER_POPUP_INSTR") + }, + states = { + default = { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 10, + bottom = 10 + CoD.TextSettings.NormalFont.Height, + left = 75, + right = -75, + alignment = LUI.Alignment.Center, + font = CoD.TextSettings.NormalFont.Font, + red = Colors.white.r, + green = Colors.white.g, + blue = Colors.white.b + } + } + }, + { + type = "UIVerticalList", + id = "server_filters_popup_vlist", + states = { + default = { + topAnchor = false, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = -75, + bottom = 0, + left = 2, + right = -2, + spacing = 5 + } + }, + childrenFeeder = ServerFiltersPopupItems + } + } + } +end + +LUI.MenuBuilder.registerDef("mp_server_filters_popup_page", mp_server_filters_popup_page) diff --git a/localappdata/xlabs/data/iw6x/data/ui_scripts/server_list/__init__.lua b/localappdata/xlabs/data/iw6x/data/ui_scripts/server_list/__init__.lua new file mode 100644 index 0000000..9e8942c --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/ui_scripts/server_list/__init__.lua @@ -0,0 +1,636 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +local Lobby = luiglobals.Lobby +local SystemLinkJoinMenu = LUI.mp_menus.SystemLinkJoinMenu + +local controller = nil +local server = nil + +COLUMN_0 = 0 +COLUMN_1 = 460 +COLUMN_2 = 660 +COLUMN_3 = 800 +COLUMN_4 = 985 +COLUMN_5 = 500 + +SystemLinkJoinMenu.UpdateGameList = function(f3_arg0, f3_arg1) + local f3_local0 = f3_arg1.controller + if not f3_local0 then + f3_local0 = Engine.GetFirstActiveController() + end + local f3_local1 = LUI.FlowManager.GetMenuScopedDataFromElement(f3_arg0) + Lobby.UpdateServerDisplayList(f3_local0) + local f3_local2 = Lobby.GetServerCount(f3_local0) + if f3_local2 ~= f3_local1.serverCount then + f3_local1.serverCount = f3_local2 + f3_arg0:processEvent({ + name = "menu_refresh", + immediate = true + }) + f3_arg0:processEvent({ + name = "gain_focus", + immediate = true + }) + end +end + +SystemLinkJoinMenu.RefreshServers = function(f4_arg0, f4_arg1) + local f4_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f4_arg0) + f4_local0.serverCount = 0 + if f4_local0.serverList then + local f4_local1 = Lobby.RefreshServerList + local f4_local2 = f4_arg1.controller + if not f4_local2 then + f4_local2 = Engine.GetFirstActiveController() + end + f4_local1(f4_local2) + f4_local0.serverList:processEvent({ + name = "lose_focus", + immediate = true + }) + f4_local0.serverList:clearSavedState() + f4_local0.serverList:processEvent({ + name = "menu_refresh", + dispatchChildren = true + }) + end +end + +function CreateColumnImage(id, shader, leftAnchor, rightAnchor, left, alpha) + return { + type = "UIImage", + id = id, + states = { + default = { + font = CoD.TextSettings.NormalFont.Font, + alignment = LUI.Alignment.right, + height = 20, + width = 20, + left = left, + red = Colors.cac_label_text.r, + green = Colors.cac_label_text.g, + blue = Colors.cac_label_text.b, + alpha = alpha, + material = RegisterMaterial(shader) + }, + }, + handlers = { + button_over = MBh.AnimateToState("over"), + button_up = MBh.AnimateToState("default"), + button_disable = MBh.AnimateToState("disabled") + } + } +end + +SystemLinkJoinMenu.CreateHeaderDef = function() + local header = { + type = "UIElement", + id = "header_row_id", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 2, + left = 2, + right = -2, + height = GenericTitleBarDims.TitleBarHeight, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + }, + } + + local columns = {} + table.insert(columns, SystemLinkJoinMenu.CreateRowBackground(SystemLinkJoinMenu.Colors.generic_menu_bg_color)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_id", false, COLUMN_1, COLUMN_2)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_2_id", true, COLUMN_3, -1)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("host_header", Engine.Localize("@MENU_HOST_NAME"), true, false, COLUMN_0, COLUMN_1)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("map_header", Engine.Localize("@MENU_MAP"), true, false, COLUMN_1, COLUMN_2)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("players_header", Engine.Localize("@MENU_NUMPLAYERS"), true, false, COLUMN_2, COLUMN_3)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("type_header", Engine.Localize("@MENU_TYPE1"), true, true, COLUMN_3, COLUMN_4)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnText("ping_header", Engine.Localize("@MENU_PING"), true, true, COLUMN_4, COLUMN_5)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnImage("protected_header", "icon_lock", true, true, COLUMN_5, 1)) + header.children = columns + return header +end + +SystemLinkJoinMenu.CreateRowDef = function(f6_arg0, f6_arg1, f6_arg2, f6_arg3) + local option = { + type = "UIButton", + id = "row_" .. f6_arg1, + disabled = f6_arg2, + focusable = not f6_arg2, + properties = { + button_height = GenericButtonDims.button_height + }, + states = { + default = { + topAnchor = true, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = MBh.Property("button_height"), + left = 0, + right = 0 + } + }, + handlers = { + button_action = MBh.EmitEventToRoot({ + name = "select_game", + idx = f6_arg1 + }) + } + } + + local columns = {} + table.insert(columns, SystemLinkJoinMenu.CreateRowBackground(f6_arg3)) + table.insert(columns, SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_id", false, COLUMN_1, COLUMN_2)) + local shade = SystemLinkJoinMenu.CreateColumnShade("column_shade_rect_2_id", true, COLUMN_3, -1) + table.insert(columns, shade) + local hostname = SystemLinkJoinMenu.CreateColumnText("host_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Host), true, false, COLUMN_0, COLUMN_1) + table.insert(columns, hostname) + local mapname = SystemLinkJoinMenu.CreateColumnText("map_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Map), true, false, COLUMN_1, COLUMN_2) + table.insert(columns, mapname) + local players = SystemLinkJoinMenu.CreateColumnText("players_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Clients), true, false, COLUMN_2, COLUMN_3) + table.insert(columns, players) + local gametype = SystemLinkJoinMenu.CreateColumnText("type_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Game), true, true, COLUMN_3, COLUMN_4) + table.insert(columns, gametype) + local ping = SystemLinkJoinMenu.CreateColumnText("ping_text", Lobby.GetServerData(f6_arg0, f6_arg1, SystemLinkJoinMenu.GameDataColumn.Ping), true, true, COLUMN_4, COLUMN_5) + table.insert(columns, ping) + local is_private = SystemLinkJoinMenu.CreateColumnImage("protected_header", "icon_lock", true, true, COLUMN_5, Lobby.GetServerData(f6_arg0, f6_arg1, 5) == "1" and 1 or 0) + table.insert(columns, is_private) + option.children = columns + return option +end + +SystemLinkJoinMenu.OnCreate = function(f1_arg0, f1_arg1) + local f1_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f1_arg0) + f1_local0.serverCount = 0 + f1_arg0:processEvent(LUI.ButtonHelperText.CommonEvents.addBackButton) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_action", + helper_text = Engine.Localize("@MENU_JOIN_GAME1"), + side = "left", + clickable = true + }) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_alt1", + helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), + side = "left", + clickable = true + }) + f1_arg0:processEvent({ + name = "add_button_helper_text", + button_ref = "button_alt2", + helper_text = Engine.Localize("@LUA_MENU_FILTER"), + side = "right", + clickable = true + }) + local f1_local1 = Lobby.BuildServerList + local f1_local2 = f1_arg1.controller + if not f1_local2 then + f1_local2 = Engine.GetFirstActiveController() + end + f1_local1(f1_local2) +end + +function ServerListBackground() + if Engine.IsAliensMode() then + return { + image = "frontend_aliens_art", + fill_color = { + r = 1, + g = 1, + b = 1 + }, + fill_alpha = 1 + } + end + + if Engine.IsCoreMode() then + return { + image = "white", + fill_color = { + r = 0.07, + g = 0.1, + b = 0.11 + }, + fill_alpha = 1 + } + end +end + +function JoinGame(f2_arg0, f2_arg1) + server = f2_arg1 + controller = server.controller + if not f2_local1 then + controller = Engine.GetFirstActiveController() + end + + local is_private = Lobby.GetServerData(controller, server.idx, 5) + if is_private == "1" then + LUI.FlowManager.RequestPopupMenu(server, "server_password_field", false, controller, false) + else + Lobby.JoinServer(controller, server.idx) + end +end + +SystemLinkJoinMenu.menu_systemlink_join = function() + if Engine.IsCoreMode() then + Engine.SetDvarString("ui_customModeName", "mp") + elseif Engine.IsAliensMode() then + Engine.SetDvarString("ui_customModeName", "aliens") + end + + if Engine.GetDvarString("ui_mapvote_entrya_gametype") == nil + or Engine.GetDvarString("ui_mapvote_entrya_gametype") then + Engine.SetDvarString("ui_mapvote_entrya_gametype", "any") + end + + if Engine.GetDvarString("ui_mapvote_entrya_mapname") == nil + or Engine.GetDvarString("ui_mapvote_entrya_mapname") == "" + or (string.match(Engine.GetDvarString("ui_mapvote_entrya_mapname"), "alien") == nil and Engine.IsAliensMode()) + or (string.match(Engine.GetDvarString("ui_mapvote_entrya_mapname"), "alien") == "alien" and Engine.IsCoreMode()) then + Engine.SetDvarString("ui_mapvote_entrya_mapname", "any") + end + + return { + type = "UIElement", + id = "menu_systemlink_join_root", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + handlers = { + menu_create = SystemLinkJoinMenu.OnCreate, + select_game = JoinGame + }, + children = { + { + type = "UIImage", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore, + }) + } + }, + { + type = "UIElement", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = true, + rightAnchor = true, + left = 200, + right = -200, + height = 550 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "menu_systemlink_join_title_id", + properties = { + fill_alpha = 1, + font = CoD.TextSettings.BoldFont, + title_bar_text = Engine.Localize("@PLATFORM_SYSTEM_LINK_TITLE"), + title_bar_text_indent = GenericTitleBarDims.TitleBarLCapWidth, + title_bar_alignment = LUI.Alignment.Left + } + }, + { + type = "generic_menu_background", + id = "menu_systemlink_join_bg_id", + properties = { + fill_alpha = Swatches.Overlay.AlphaMore, + }, + children = { + SystemLinkJoinMenu.CreateHeaderDef(), + { + type = "UIVerticalList", + id = "menu_systemlink_join_game_list_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = GenericTitleBarDims.TitleBarHeight + 4, + bottom = 600, + left = 2, + right = -2 + } + }, + childrenFeeder = SystemLinkJoinMenu.LinkGamesFeeder, + handlers = { + update_game_list = SystemLinkJoinMenu.UpdateGameList, + menu_create = function(f12_arg0, f12_arg1) + local f12_local0 = LUI.FlowManager.GetMenuScopedDataFromElement(f12_arg0) + f12_local0.serverList = f12_arg0 + SystemLinkJoinMenu.RefreshServers(f12_arg0, f12_arg1) + end + + } + }, + { + type = "button_helper_text_main", + id = "online_vault_helper_text_id", + properties = { + left_inset = 10, + right_inset = -10, + top_margin = GenericFooterDims.TopMargin_WithoutBackground, + height = 42, + spacing = 12, + background_alpha = 0 + } + } + } + } + } + }, + { + type = "UITimer", + id = "menu_systemlink_join_update_timer", + properties = { + event = "update_game_list", + interval = 250, + disposable = false, + broadcastToRoot = true + } + }, + { + type = "UIBindButton", + id = "menu_systemlink_join_bind_button_id", + handlers = { + button_secondary = MBh.LeaveMenu(), + button_alt1 = SystemLinkJoinMenu.RefreshServers, + button_alt2 = OpenFiltersMenu + } + }, + } + } +end + + +LUI.MenuBuilder.m_definitions["menu_systemlink_join"] = function() + local menu = SystemLinkJoinMenu.menu_systemlink_join() + + local rows = menu.children[2].children[3].children + local header = rows[1] + + + -- Increase server list width + menu.children[2].states.default.left = 100 + menu.children[2].states.default.right = -100 + + menu.children[3].properties.interval = 10 -- 250 + + return menu +end + +ServerPaswordListFeeder = function() + return { + { + type = "UIVerticalList", + id = "password_field_items", + states = { + default = { + topAnchor = true, + leftAnchor = true, + bottomAnchor = false, + rightAnchor = true, + } + }, + children = { + { + type = "UIGenericButton", + id = "password_button_id", + properties = { + variant = GenericButtonSettings.Variants.Plain, + button_text = Engine.Localize("PATCH_MENU_CHANGE_PASSWORD_CAPS"), + button_display_func = function() + local f31_local0 = Engine.GetDvarString("password") + if f31_local0 then + f31_local0 = Engine.GetDvarString("password") ~= "" + end + local f31_local1 + if f31_local0 then + f31_local1 = Engine.Localize("PATCH_MENU_PASSWORD_SET") + if not f31_local1 then + + else + return f31_local1 + end + end + f31_local1 = Engine.Localize("MENU_NONE") + end, + button_action_func = function(f32_arg0, f32_arg1) + Engine.ExecNow("setfromdvar ui_password password") + Engine.OpenScreenKeyboard(f32_arg1.controller, Engine.Localize("MENU_PASSWORD"), Engine.GetDvarString("ui_password") or "", Lobby.PasswordLength, false, false, CoD.KeyboardInputTypes.Password) + end + }, + handlers = { + text_input_complete = function(f33_arg0, f33_arg1) + if f33_arg1.text then + Engine.SetDvarString("password", f33_arg1.text) + f33_arg0:processEvent({ + name = "content_refresh" + }) + end + end + } + }, + { + type = "UIGenericButton", + id = "connect_button_id", + properties = { + variant = GenericButtonSettings.Variants.Plain, + button_text = Engine.Localize("MENU_JOIN_GAME"), button_action_func = function() + Lobby.JoinServer(controller, server.idx) + end + } + + } + } + } + } +end + +password_field = function(f50_arg0, f50_arg1) + return { + type = "UIElement", + id = "server_popup_container_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + children = { + { + type = "UIImage", + id = "darken_bg", + states = { + default = CoD.ColorizeState(Swatches.Overlay.Color, { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + top = 0, + bottom = 0, + material = RegisterMaterial("white"), + alpha = Swatches.Overlay.AlphaMore + }) + } + }, + { + type = "UIElement", + id = "mp_server_filters_popup_id", + states = { + default = { + topAnchor = false, + bottomAnchor = false, + leftAnchor = false, + rightAnchor = false, + top = -1 * Leaderboards.Layout.FilterHeight * 0.6, + width = Leaderboards.Layout.FilterWidth, + height = 145 + } + }, + children = { + { + type = "generic_drop_shadow", + properties = { + offset_shadow = 0 + } + }, + { + type = "generic_menu_titlebar", + id = "server_filters_popup_title_bar_id", + properties = { + title_bar_text = Engine.Localize("@LUA_MENU_LOBBY_JOINING"), + fill_alpha = 1 + } + }, + { + type = "generic_menu_background", + id = "server_filters_popup_background", + properties = { + fill_alpha = 1 + } + }, + { + type = "UIElement", + id = "mp_server_password_popup_page_id", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = AAR.Layout.TitleBarHeight + 1, + bottom = -1, + left = 1, + right = -1, + } + }, + children = { + { + type = "generic_border", + properties = { + thickness = 2, + border_red = Colors.generic_menu_frame_color.r, + border_green = Colors.generic_menu_frame_color.g, + border_blue = Colors.generic_menu_frame_color.b + }, + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0, + alpha = 0.6 + } + } + }, + { + type = "UIVerticalList", + id = "server_filters_popup_vlist", + states = { + default = { + topAnchor = false, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = -90, + bottom = 0, + left = 0, + right = 0, + spacing = 5 + } + }, + childrenFeeder = ServerPaswordListFeeder + } + } + }, + { + type = "UIBindButton", + id = "filters_popup_back_button", + handlers = { + button_secondary = MBh.DoMultiple({ + MBh.LeaveMenu(), + FiltersPopupClose, + ForceRefreshServers + }) + } + } + } + } + } + } +end + +LUI.MenuBuilder.registerDef("server_password_field", password_field) diff --git a/localappdata/xlabs/data/iw6x/data/ui_scripts/stats/__init__.lua b/localappdata/xlabs/data/iw6x/data/ui_scripts/stats/__init__.lua new file mode 100644 index 0000000..af09c63 --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/ui_scripts/stats/__init__.lua @@ -0,0 +1,167 @@ +if (game:issingleplayer() or not Engine.InFrontend()) then + return +end + +game:addlocalizedstring("LUA_MENU_UNLOCKALL", "UNLOCK ALL") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_DESC", + "Whether all items should be unlocked.") + +function UnlockAllAction( f1_arg0, f1_arg1 ) + Engine.Exec("unlockstats") +end + +function StatsButtonHelper( f2_arg0, f2_arg1 ) + f2_arg0:processEvent( LUI.ButtonHelperText.CommonEvents.addBackButton ) +end + +function BarrackPrestigeResetStatsAction( f3_arg0, f3_arg1 ) + LUI.FlowManager.RequestAddMenu( f3_arg0, "prestige_reset", true, f3_arg1.controller ) +end + +function menu_stats() + return { + type = "UIElement", + id = "menu_stats_root", + states = { + default = { + topAnchor = true, + bottomAnchor = true, + leftAnchor = true, + rightAnchor = true, + top = 0, + bottom = 0, + left = 0, + right = 0 + } + }, + handlers = { + menu_create = StatsButtonHelper, + }, + children = { + { + type = "generic_menu_title", + id = "stats_title_text_id", + properties = { + menu_title = Engine.Localize( "@LUA_MENU_BARRACKS_CAPS" ) + } + }, + { + type = "UIVerticalList", + id = "stats_options_vlist_id", + states = { + default = { + alignment = LUI.Alignment.Top, + leftAnchor = true, + rightAnchor = false, + topAnchor = true, + bottomAnchor = false, + left = GenericMenuDims.menu_left, + right = GenericMenuDims.menu_right, + top = GenericMenuDims.menu_top, + bottom = GenericMenuDims.menu_bottom + } + }, + childrenFeeder = StatsOptionsFeeder + }, + { + type = "button_helper_text_main", + id = "stats_button_helper_text_id" + }, + { + type = "UIBindButton", + id = "stats_bind_buttons_id", + handlers = { + button_secondary = MBh.LeaveMenu() + } + }, + } + } +end + +function StatsOptionsFeeder( f8_arg0 ) + local f8_local4 = {} + local f8_local0 = Engine.IsAliensMode() + local f8_local2 = Engine.InLobby() + local f8_local3 = f8_arg0.exclusiveController + f8_local4[#f8_local4 + 1] = { + type = "UIGenericButton", + id = "unlockall_items_button_id", + properties = { + button_text = Engine.Localize( "@LUA_MENU_UNLOCKALL" ), + button_action_func = UnlockAllAction, + desc_text = Engine.Localize( "@LUA_MENU_UNLOCKALL_DESC" ) + } + } + if not f8_local2 then + local f8_local5 = #f8_local4 + 1 + local f8_local6 = { + type = "UIGenericButton", + id = "reset_stats_button_id" + } + local f8_local7 + if Cac.GetPrestigeLevel( f8_local3, Cac.GetSquadLoc() ) == 10 then + f8_local7 = Engine.IsUserAGuest( f8_local3 ) + else + f8_local7 = true + end + f8_local6.disabled = f8_local7 + f8_local6.properties = { + button_text = Engine.Localize( "@LUA_MENU_MP_RESET_STATS_CAPS" ), + button_action_func = BarrackPrestigeResetStatsAction, + desc_text = Engine.Localize( "@LUA_MENU_MP_RESET_STATS_DESC" ) + } + f8_local6.handlers = { + element_refresh = function ( f12_arg0, f12_arg1 ) + local f12_local0 + if Cac.GetPrestigeLevel( f8_local3, Cac.GetSquadLoc() ) == 10 then + f12_local0 = Engine.IsUserAGuest( f8_local3 ) + else + f12_local0 = true + end + local f12_local1 = f12_arg0 + local f12_local2 = f12_arg0.processEvent + local f12_local3 = {} + local f12_local4 + if f12_local0 then + f12_local4 = "disable" + if not f12_local4 then + + else + f12_local3.name = f12_local4 + f12_local2( f12_local1, f12_local3 ) + end + end + f12_local4 = "enable" + end + } + f8_local4[f8_local5] = f8_local6 + end + f8_local4[#f8_local4 + 1] = { + type = "button_desc_text", + id = "stats_button_description_id" + } + return f8_local4 +end + +function stats_options_vlist() + return { + type = "UIVerticalList", + focusable = true, + states = { + default = { + alignment = LUI.Alignment.Top, + leftAnchor = true, + rightAnchor = false, + topAnchor = true, + bottomAnchor = false, + left = GenericMenuDims.menu_left, + right = GenericMenuDims.menu_right, + top = GenericMenuDims.menu_top, + bottom = GenericMenuDims.menu_bottom + } + } + } +end + +LUI.MenuBuilder.registerDef( "menu_stats", menu_stats ) +LUI.MenuBuilder.registerDef( "stats_options_vlist", stats_options_vlist ) diff --git a/localappdata/xlabs/data/iw6x/data/ui_scripts/team_select/__init__.lua b/localappdata/xlabs/data/iw6x/data/ui_scripts/team_select/__init__.lua new file mode 100644 index 0000000..f482e6b --- /dev/null +++ b/localappdata/xlabs/data/iw6x/data/ui_scripts/team_select/__init__.lua @@ -0,0 +1,101 @@ +if (game:issingleplayer()) then + return +end + +if (package.loaded["LUI.mp_hud.OptionsMenu"] == nil) then + return +end + +package.loaded["LUI.mp_hud.OptionsMenu"].options_def = function() + local f14_local0 = GameX.GetGameMode() + local f14_local1 = Engine.TableLookup( GameTypesTable.File, GameTypesTable.Cols.Ref, f14_local0, GameTypesTable.Cols.ClassChoice ) == "1" + + if not f14_local1 then + f14_local1 = GameX.UsesFakeLoadout() + end + + local f14_local2 = LUI.mp_hud.OptionsMenu.checkTeamChoice( f14_local0 ) + local f14_local3 = GameX.IsRankedMatch() + local f14_local4 = Engine.GetDvarBool( "splitscreen_ingame" ) + local f14_local5 = Game.GetOmnvar( "ui_team_selected" ) + local f14_local6 = Game.GetOmnvar( "ui_loadout_selected" ) + local f14_local7 = LUI.mp_hud.OptionsMenu.chooseClassCheck( f14_local3, f14_local5, f14_local2 ) + local self = LUI.UIVerticalList.new() + self.id = "pause_selections_Id" + + self:registerAnimationState("default", { + topAnchor = true, + leftAnchor = true, + bottomAnchor = false, + rightAnchor = false, + top = GenericMenuDims.menu_top, + left = GenericMenuDims.menu_left, + bottom = GenericMenuDims.menu_bottom, + right = GenericMenuDims.menu_right, + alignment = LUI.Alignment.Top + }) + + self:animateToState( "default", 0 ) + self:makeFocusable() + + if f14_local0 ~= "aliens" and false == CoD.IsFireTeamMode() and GameX.IsSpectatingNotOnTeam() == false and f14_local1 == true and f14_local7 == true and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_0", + properties = { + childNum = 1, + button_text = Engine.Localize( "@LUA_MENU_CHOOSE_CLASS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.chooseClassButtonAction + } + }) + end + + if f14_local0 ~= "aliens" and false == CoD.IsFireTeamMode() and f14_local2 == true and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_1", + properties = { + childNum = 2, + button_text = Engine.Localize( "@LUA_MENU_CHANGE_TEAM_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.changeTeamButtonAction + } + }) + end + + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_2", + disabledFunc = LUI.mp_hud.OptionsMenu.optionsLockedUpdate, + properties = { + childNum = 3, + button_text = Engine.Localize( "@LUA_MENU_OPTIONS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.optionsButtonAction + }, + handlers = { + refresh_options_button = LUI.mp_hud.OptionsMenu.refreshOptionDisable + } + }) + + if GameX.IsOnlineMatch() and (not Engine.IsAliensMode() or not Game.GetOmnvar( "ui_alien_is_solo" )) and not MLG.IsMLGSpectator() then + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_3", + properties = { + childNum = 4, + button_text = Engine.Localize( "@LUA_MENU_MUTE_PLAYERS_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.mutePlayersButtonAction + } + }) + end + + LUI.MenuBuilder.BuildAddChild(self, { + type = "UIGenericButton", + id = "btn_MPPause_5", + properties = { + childNum = 6, + button_text = Engine.Localize( "@LUA_MENU_END_GAME_CAPS" ), + button_action_func = LUI.mp_hud.OptionsMenu.endGameButtonAction + } + }) + return self +end diff --git a/localappdata/xlabs/data/iw6x/iw6x.exe b/localappdata/xlabs/data/iw6x/iw6x.exe new file mode 100644 index 0000000..626143f Binary files /dev/null and b/localappdata/xlabs/data/iw6x/iw6x.exe differ diff --git a/localappdata/xlabs/data/launcher-ui/css/main.css b/localappdata/xlabs/data/launcher-ui/css/main.css new file mode 100644 index 0000000..1aaeae5 --- /dev/null +++ b/localappdata/xlabs/data/launcher-ui/css/main.css @@ -0,0 +1,359 @@ +html, +body { + margin: 0; + font-family: 'Segoe UI Emoji', Tahoma, Geneva, Verdana, sans-serif; + width: 100%; + height: 100%; + user-select: none; + background: #333; + color: #bbb; +} + +body { + display: flex; + flex-flow: column; +} + +img { + -webkit-user-drag: none; +} + +#controls { + z-index: 1000; +} + +#container { + z-index: 100; +} + +#background { + position: fixed; + top: -100px; + left: -100px; + right: -100px; + bottom: -100px; + background: linear-gradient( 135deg, rgba(6, 10, 15, 1) 32%, rgba(26, 43, 65, 1) 50%, rgba(79, 109, 148, 1) 59%, rgba(157, 174, 182, 1) 65%, rgba(65, 82, 91, 1) 78%, rgba(42, 55, 63, 1) 89%, rgba(14, 14, 14, 1) 100%); + filter: blur(50px); + box-shadow: inset 0px 0px 84px 223px rgb(51 51 51 / 50%); + display: none; +} + +.container { + border-radius: 10px; + padding: 20px; + margin: 15px; + display: inline-block; + min-width: 50px; + min-height: 25px; + box-shadow: 0 9px 19px rgba(0, 0, 0, 0.15), 0 15px 12px rgba(0, 0, 0, 0.15); + background: #222; +} + +img.container { + padding: 0px; +} + +.card { + padding: 0px; + display: flex; + flex-flow: column; + transition: box-shadow 0.1s linear; + background: #333; +} + +.a.card:hover { + box-shadow: 0 2px 19px rgba(0, 17, 255, 0), 0 11px 40px rgba(51, 146, 255, 0); + cursor: pointer; +} + +.card>.title { + border-top-left-radius: 10px; + border-top-right-radius: 10px; + padding: 20px; + display: block; + flex: 0 1 auto; + background: #222; +} + +.card>.content { + padding: 20px; + flex: 1 1 auto; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} + +.card>.content.img { + padding: 0px; + background-size: cover; + background-position: center center; +} + +#container { + flex: 1 1 auto; + display: flex; + width: 100%; + height: 100%; + overflow: hidden; +} + +#navigation { + flex: 0 1 auto; + height: 100%; + max-height: 100%; + display: inline-block; + box-shadow: 0 19px 38px rgba(0, 0, 0, 0.03), 0 15px 12px rgba(0, 0, 0, 0.03); + padding: 20px; + text-align: center; + background: #222; +} + +#navigation>.separator { + width: calc(100% + 40px); + height: 1px; + display: block; + margin-left: -20px; + margin-right: -20px; + z-index: 0; + position: relative; + background: #333; +} + +#navigation>.element { + z-index: 1; + position: relative; + margin: auto; + margin-bottom: 20px; + margin-top: 20px; + border-radius: 15px; + display: block; + width: 7vw; + height: 7vw; + transition: box-shadow 0.1s linear; + box-shadow: 0 9px 19px rgba(0, 0, 0, 0.2), 0 15px 12px rgba(0, 0, 0, 0.2); +} + +#navigation>.element:hover { + cursor: pointer; +} + +#navigation>.element:first-of-type { + margin-top: 0px; +} + +#navigation>#settings.element { + background: #333; +} + +#navigation>#settings.element>img { + filter: invert(8%) sepia(8%) saturate(0%) hue-rotate(347deg) brightness(94%) contrast(100%); + width: 100%; +} + +#navigation>.element.active { + box-shadow: 0 2px 19px rgba(0, 17, 255, 0), 0 11px 40px rgba(51, 146, 255, 0); +} + +#content { + flex: 1 1 auto; + display: flex; + padding: 15px; +} + +#controls { + z-index: 99999; + flex: 0 1 auto; + -webkit-user-select: none; + -webkit-app-region: drag; + -moz-user-select: none; + user-select: none; + padding: 5px; + text-align: center; + background: #222; + border-bottom: 1px solid #333; +} + +#controls>.title { + position: absolute; + left: 0; + right: 0; + pointer-events: none; +} + +#controls>span.button { + width: 12px; + height: 12px; + border-radius: 50%; + float: right; + -webkit-app-region: no-drag; + opacity: 0.6; + transition: opacity 0.1s linear; + border: 5px solid #222; +} + +#controls>span.button:hover { + opacity: 1; +} + +#minimize-button { + background: rgb(255, 217, 0); +} + +#close-button { + background: rgb(255, 61, 61); +} + +#message-box { + background: rgba(0, 0, 0, 0.4); + position: fixed; + z-index: 9999; + top: 0; + left: 0; + right: 0; + bottom: 0; + opacity: 0; + pointer-events: none; + transition: opacity 0.1s linear; +} + +#message-box.visible { + pointer-events: all; + opacity: 1; +} + +#message-box>.container { + position: absolute; + left: 50%; + top: 45%; + transform: translate(-50%, -50%); + min-width: 300px; + background: #333; +} + +#message-box .mb-buttons { + display: block; + text-align: right; + margin-top: 15px; + padding-top: 15px; + border-top: 1px solid #222; +} + +#vignette { + position: fixed; + top: 0; + left: 0; + right: 1px; + bottom: 1px; + z-index: 999999; + border-radius: 8px; + pointer-events: none; + box-shadow: inset 0 0 2px rgb(255, 255, 255, 0.2); +} + +button { + padding: 10px; + margin: 5px; + border-radius: 5px; + transition: box-shadow 0.1s linear; + color: #bbb; + background: #222; + border: 1px solid rgb(51 51 51 / 50%); +} + +button:hover { + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.07), 0 3px 6px rgba(0, 0, 0, 0.13); +} + +input[type="text"] { + padding: 10px; + margin: 5px; + border-radius: 5px; + transition: border 0.1s linear; + outline: 0; + width: 250px; + color: #bbb; + background: #222; + border: 1px solid #222; +} + +input[type="text"]:focus { + border: 1px solid rgba(187, 187, 187, 0.3); +} + +.input { + margin: 5px; +} + +.two-grid { + display: flex; +} + +.two-grid>* { + display: inline-flex; + align-items: center; +} + +.two-grid>:first-child { + text-align: left; + flex: 0 1 auto; +} + +.two-grid>:last-child { + text-align: right; + margin-left: auto; + justify-content: flex-end; + flex: 1 1 auto; +} + +input[type="radio"] { + position: relative; + margin: 5px; + margin-right: 7px; + cursor: pointer; +} + +input[type="radio"]::before { + content: ''; + width: 22px; + height: 22px; + display: block; + border-radius: 50%; + left: -5px; + top: -4px; + position: absolute; + border: 1px solid rgba(0, 0, 0, 0.08); + transition: box-shadow 0.1s linear; + background: #222; +} + +input[type="radio"]::after { + content: ''; + width: 12px; + height: 12px; + display: block; + border-radius: 50%; + left: 1px; + top: 2px; + position: absolute; + background: #222; +} + +input[type="radio"]:checked { + display: inline; +} + +input[type="radio"]:checked::after { + background: rgb(0, 135, 193); +} + +input[type="radio"]:hover::before { + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.07), 0 3px 6px rgba(0, 0, 0, 0.13); +} + +::selection { + color: white; + background: rgb(0, 135, 193); +} + +#dark-mode-toggle { + --dark-mode-toggle-icon-size: 1.25rem; +} \ No newline at end of file diff --git a/localappdata/xlabs/data/launcher-ui/img/cog.png b/localappdata/xlabs/data/launcher-ui/img/cog.png new file mode 100644 index 0000000..7e8c652 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/cog.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/iw4x-mp.png b/localappdata/xlabs/data/launcher-ui/img/iw4x-mp.png new file mode 100644 index 0000000..e5efc1e Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/iw4x-mp.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/iw4x-sp.png b/localappdata/xlabs/data/launcher-ui/img/iw4x-sp.png new file mode 100644 index 0000000..efc1d1d Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/iw4x-sp.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/iw4x.png b/localappdata/xlabs/data/launcher-ui/img/iw4x.png new file mode 100644 index 0000000..8a18941 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/iw4x.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/iw6x-mp.png b/localappdata/xlabs/data/launcher-ui/img/iw6x-mp.png new file mode 100644 index 0000000..721308d Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/iw6x-mp.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/iw6x-sp.png b/localappdata/xlabs/data/launcher-ui/img/iw6x-sp.png new file mode 100644 index 0000000..781fca6 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/iw6x-sp.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/iw6x.png b/localappdata/xlabs/data/launcher-ui/img/iw6x.png new file mode 100644 index 0000000..8f7f18f Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/iw6x.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/s1x-mp.png b/localappdata/xlabs/data/launcher-ui/img/s1x-mp.png new file mode 100644 index 0000000..5972474 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/s1x-mp.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/s1x-sp.png b/localappdata/xlabs/data/launcher-ui/img/s1x-sp.png new file mode 100644 index 0000000..f214fe2 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/s1x-sp.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/s1x-survival.png b/localappdata/xlabs/data/launcher-ui/img/s1x-survival.png new file mode 100644 index 0000000..8147067 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/s1x-survival.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/s1x-zm.png b/localappdata/xlabs/data/launcher-ui/img/s1x-zm.png new file mode 100644 index 0000000..6b1e808 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/s1x-zm.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/s1x.png b/localappdata/xlabs/data/launcher-ui/img/s1x.png new file mode 100644 index 0000000..127eed8 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/s1x.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/splash-1.png b/localappdata/xlabs/data/launcher-ui/img/splash-1.png new file mode 100644 index 0000000..956aa9f Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/splash-1.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/splash-2.png b/localappdata/xlabs/data/launcher-ui/img/splash-2.png new file mode 100644 index 0000000..210e338 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/splash-2.png differ diff --git a/localappdata/xlabs/data/launcher-ui/img/xlabs.png b/localappdata/xlabs/data/launcher-ui/img/xlabs.png new file mode 100644 index 0000000..52f4463 Binary files /dev/null and b/localappdata/xlabs/data/launcher-ui/img/xlabs.png differ diff --git a/localappdata/xlabs/data/launcher-ui/js/command.js b/localappdata/xlabs/data/launcher-ui/js/command.js new file mode 100644 index 0000000..df086bd --- /dev/null +++ b/localappdata/xlabs/data/launcher-ui/js/command.js @@ -0,0 +1,16 @@ +window.executeCommand = function(command, data) { + + var object = { + command: command, + data: data || null, + } + + return fetch("/command", { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(object) + }).then(data => data.json()); +}; \ No newline at end of file diff --git a/localappdata/xlabs/data/launcher-ui/js/main.js b/localappdata/xlabs/data/launcher-ui/js/main.js new file mode 100644 index 0000000..e7bd7a5 --- /dev/null +++ b/localappdata/xlabs/data/launcher-ui/js/main.js @@ -0,0 +1,132 @@ +window.addEventListener("load", initialize); +window.channel = window.executeCommand("get-channel"); + +function sleep(milliseconds) { + return new Promise(resolve => { + setTimeout(resolve, milliseconds); + }); +} + +function makeSleep(milliseconds) { + return () => sleep(milliseconds); +} + +function waitForAllImages() { + return new Promise(resolve => { + function waitForAllImagesInternal() { + const images = document.querySelectorAll('img'); + + for (var i = 0; i < images.length; ++i) { + if (!images[i].complete) { + window.requestAnimationFrame(waitForAllImagesInternal); + return; + } + } + + resolve(); + } + + waitForAllImagesInternal(); + }); +} + +function addStyleElement(css) { + var head = document.head || document.getElementsByTagName('head')[0], + style = document.createElement('style'); + + head.appendChild(style); + + style.type = 'text/css'; + if (style.styleSheet) { + // This is required for IE8 and below. + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } +} + +function getOtherChannel(channel) { + if (channel == "main") { + return "dev"; + } + return "main"; +} + +function adjustChannelElements() { + window.channel.then(channel => { + addStyleElement(`.channel-${getOtherChannel(channel)}{display: none;}`); + }); +} + +function initialize() { + initializeNavigation() // + .then(() => waitForAllImages()) // + .then(makeSleep(300)) + .then(() => window.executeCommand("show")); + + document.querySelector("#minimize-button").onclick = () => { + window.executeCommand("minimize"); + }; + + document.querySelector("#close-button").onclick = () => { + window.executeCommand("close"); + }; + + adjustChannelElements(); +} + +window.showSettings = function() { + document.querySelector("#navigation>#settings.element").click(); +} + +function initializeNavigation() { + var elements = document.querySelectorAll("#navigation>.element"); + elements.forEach(e => { + e.addEventListener("click", handleNavigationClick); + }); + + return loadInitialPage(); +} + +function removeActiveElement() { + var element = document.querySelector("#navigation>.element.active"); + if (element) { + element.classList.remove("active"); + } +} + +function handleNavigationClick(e) { + const el = this; + if (el.classList.contains("active")) { + return; + } + + removeActiveElement(); + el.classList.add("active"); + loadNavigationPage(el.id); +} + +function loadInitialPage() { + const el = document.querySelector("#navigation>.element.active"); + return loadNavigationPage(el.id); +} + +function setInnerHTML(elm, html) { + elm.innerHTML = html; + Array.from(elm.querySelectorAll("script")).forEach(oldScript => { + const newScript = document.createElement("script"); + Array.from(oldScript.attributes) + .forEach(attr => newScript.setAttribute(attr.name, attr.value)); + newScript.appendChild(document.createTextNode(oldScript.innerHTML)); + oldScript.parentNode.replaceChild(newScript, oldScript); + }); +} + +function loadNavigationPage(page) { + var content = document.querySelector("#content"); + return fetch(`./pages/${page}.html`).then(data => { + return data.text() + }).then(text => { + setInnerHTML(content, text); + }); +} \ No newline at end of file diff --git a/localappdata/xlabs/data/launcher-ui/js/message-box.js b/localappdata/xlabs/data/launcher-ui/js/message-box.js new file mode 100644 index 0000000..da97b80 --- /dev/null +++ b/localappdata/xlabs/data/launcher-ui/js/message-box.js @@ -0,0 +1,47 @@ +function constructMessageBox(title, message, buttons) { + title = title || "Error"; + nessage = message || ""; + buttons = buttons || ["Ok"]; + + return new Promise((resolve, reject) => { + try{ + const messageBox = document.querySelector("#message-box"); + + const resolveInternal = function() { + messageBox.classList.remove("visible"); + return resolve.apply(this, arguments); + }; + + const titleElement = messageBox.querySelector(".mb-title"); + titleElement.innerHTML = title; + + const contentElement = messageBox.querySelector(".mb-content"); + contentElement.innerHTML = message; + + const buttonElement = messageBox.querySelector(".mb-buttons"); + buttonElement.textContent = ""; + + messageBox.classList.add("visible"); + + buttons.forEach((value, index) => { + + var button = document.createElement("button"); + button.innerHTML = value; + button.onclick = resolveInternal.bind(this, index); + buttonElement.appendChild(button); + }); + } + catch(e) { + reject(e); + } + }); +} + +window.showMessageBox = function() { + window.lastBox = window.lastBox || Promise.resolve(); + + const newBox = window.lastBox.then(() => constructMessageBox.apply(this, arguments)); + window.lastBox = newBox; + + return newBox; +}; diff --git a/localappdata/xlabs/data/launcher-ui/main.html b/localappdata/xlabs/data/launcher-ui/main.html new file mode 100644 index 0000000..143fee7 --- /dev/null +++ b/localappdata/xlabs/data/launcher-ui/main.html @@ -0,0 +1,53 @@ + + + + +Welcome to the new X Labs launcher! 🥳
The launcher is still a work-in-progress.
But once it is complete, it will unify all games in one place.
+ + Advanced Warfare Installation + + + + + + + +
+ ++ + Ghosts Installation + + + + + + + +
+ ++ + Modern Warfare 2 Installation + + + + + + + +
+ ++ + Update Channel + + + + + + + + + + + +
+ + +