This commit is contained in:
2025-11-16 21:44:07 +01:00
commit 3a6f9681b6
34 changed files with 16767 additions and 0 deletions

29
LICENSE Normal file
View File

@@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2026, AlterWare
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

7
README.md Normal file
View File

@@ -0,0 +1,7 @@
# T7 Rawfiles
This repo contains the T7 Rawfiles for T7x.
Contributions are welcome! Please follow the guidelines below:
- Sign [AlterWare CLA](https://alterware.dev/cla) and send a pull request or email your patch at patches@alterware.dev
- Make sure that PRs have only one commit, and deal with one issue only

View File

@@ -0,0 +1,26 @@
gametype_setting timelimit 5
gametype_setting scorelimit 0
gametype_setting roundscorelimit 1
gametype_setting roundwinlimit 2
gametype_setting roundlimit 2
gametype_setting preroundperiod 10
gametype_setting teamCount 2
gametype_setting shutdownDamage 3
gametype_setting bootTime 5
gametype_setting rebootTime 15
gametype_setting rebootPlayers 0
gametype_setting movePlayers 1
gametype_setting robotSpeed 1
gametype_setting robotShield 0
gametype_setting scoreHeroPowerGainFactor 0.788 //Score earned towards Hero Weapons and Abilities are multiplied by this factor
gametype_setting scoreHeroPowerTimeFactor 0.788
gametype_setting spawntraptriggertime 5
gametype_setting disableVehicleSpawners 1
gametype_setting gameAdvertisementRuleTimeLeft 3.5
gametype_setting gameAdvertisementRuleRound 3

BIN
data/launcher/bigboiii.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

146
data/launcher/main.html Normal file
View File

@@ -0,0 +1,146 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>T7x</title>
<style>
* {
user-select: none;
-ms-user-select: none;
cursor: default;
box-sizing: border-box;
}
html,
body {
-ms-overflow-style: none;
margin: 0;
padding: 0;
font-family: "Segoe UI Light", "Segoe UI", "Lucida Sans", Arial,
sans-serif;
font-style: normal;
font-weight: lighter;
display: flex;
min-height: 100vh;
flex-direction: column;
background: black;
}
body {
background: transparent;
}
.background-container {
inset: 0;
position: fixed;
z-index: -1;
}
.background-container:before {
background: #000;
background: url(./bigboiii.jpg);
background-position: 50%;
background-repeat: no-repeat;
background-size: cover;
content: "";
height: 100%;
opacity: 0.25;
position: fixed;
top: 0;
width: 100%;
}
.background-container:after {
background-image: url(./noise.jpg);
background-repeat: repeat;
content: "";
height: 100%;
mix-blend-mode: overlay;
opacity: 0.025;
position: fixed;
top: 0;
width: 100%;
}
body {
height: 100%;
width: 100%;
}
.content {
width: 100%;
text-align: center;
padding-top: 30px;
}
div.button {
margin: 5px 10px;
display: inline-block;
border: 1px solid #44413f;
color: rgba(244, 240, 235, 0.776);
cursor: pointer;
background-color: rgb(42, 40, 39);
width: 120px;
text-align: center;
padding: 0.5rem;
border-radius: 0.5rem;
transition: all 0.1s linear;
font-size: 1rem;
font-weight: normal;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
div.button:hover {
background-color: rgb(48, 45, 44);
border: 1px solid #4a4745;
}
h1,
h1 * {
font-size: 3rem;
font-weight: bold;
color: white;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
</style>
</head>
<body>
<div class="background-container"></div>
<div class="content">
<h1>
<span style="color: #f97316">B</span
><span style="color: #ec511c">O</span
><span style="color: #e53f21">I</span
><span style="color: #e23623">I</span
><span style="color: #dc2626">I</span>
</h1>
<div class="button" onclick="window.external.runGame()">Play</div>
<div class="button" onclick="window.external.openUrl('https://bo3.eu')">
About
</div>
</div>
<script>
window.onload = function () {};
document.onkeydown = fkey;
document.onkeypress = fkey;
document.onkeyup = fkey;
function fkey(e) {
e = e || window.event;
location.reload();
}
</script>
</body>
</html>

BIN
data/launcher/noise.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,854 @@
#using scripts\shared\array_shared;
#using scripts\shared\rank_shared;
#insert scripts\shared\shared.gsh;
#insert scripts\shared\statstable_shared.gsh;
#using scripts\mp\killstreaks\_killstreaks;
#using scripts\mp\bots\_bot;
#define BOT_ALLOCATION_MAX 100
#define BOT_ALLOCATION_UNLOCK_MAX 3
#define BOT_RANK_ALL_OPTIONS_AVAILABLE 20
#define BOT_RANK_OPTIONS_MULTIPLIER 4
#namespace bot_loadout;
// Item Whitelist
//========================================
function in_whitelist( itemName )
{
if ( !isdefined( itemName ) )
return false;
switch( itemName )
{
// Secondaries
case "WEAPON_KNIFE_LOADOUT":
case "WEAPON_PISTOL_STANDARD":
case "WEAPON_PISTOL_BURST":
case "WEAPON_PISTOL_FULLAUTO":
case "WEAPON_LAUNCHER_STANDARD":
case "WEAPON_LAUNCHER_LOCKONLY":
// Primaries
case "WEAPON_SMG_STANDARD":
case "WEAPON_SMG_BURST":
case "WEAPON_SMG_FASTFIRE":
case "WEAPON_SMG_LONGRANGE":
case "WEAPON_SMG_VERSATILE":
case "WEAPON_SMG_CAPACITY":
case "WEAPON_AR_STANDARD":
case "WEAPON_AR_ACCURATE":
case "WEAPON_AR_CQB":
case "WEAPON_AR_DAMAGE":
case "WEAPON_AR_FASTBURST":
case "WEAPON_AR_LONGBURST":
case "WEAPON_AR_MARKSMAN":
case "WEAPON_LMG_CQB":
case "WEAPON_LMG_HEAVY":
case "WEAPON_LMG_LIGHT":
case "WEAPON_LMG_SLOWFIRE":
case "WEAPON_SNIPER_FASTBOLT":
case "WEAPON_SNIPER_FASTSEMI":
case "WEAPON_SNIPER_POWERBOLT":
case "WEAPON_SNIPER_CHARGESHOT":
case "WEAPON_SHOTGUN_FULLAUTO":
case "WEAPON_SHOTGUN_PRECISION":
case "WEAPON_SHOTGUN_PUMP":
case "WEAPON_SHOTGUN_SEMIAUTO":
// Lethals
case "WEAPON_FRAGGRENADE":
case "WEAPON_HATCHET":
case "WEAPON_STICKY_GRENADE":
case "WEAPON_SATCHEL_CHARGE":
case "WEAPON_BOUNCINGBETTY":
case "WEAPON_INCENDIARY_GRENADE":
// Tacticals
case "WEAPON_WILLY_PETE":
case "WEAPON_STUN_GRENADE":
case "WEAPON_EMPGRENADE":
case "WEAPON_FLASHBANG":
case "WEAPON_PROXIMITY_GRENADE":
case "WEAPON_PDA_HACK":
case "WEAPON_TROPHY_SYSTEM":
// Killstreaks
//case "KILLSTREAK_RCBOMB":
case "KILLSTREAK_RECON":
case "KILLSTREAK_COUNTER_UAV":
//case "KILLSTREAK_SUPPLY_DROP":
//case "KILLSTREAK_MICROWAVE_TURRET":
case "KILLSTREAK_REMOTE_MISSILE":
//case "KILLSTREAK_PLANEMORTAR":
//case "KILLSTREAK_AUTO_TURRET":
case "KILLSTREAK_AI_TANK_DROP":
//case "KILLSTREAK_HELICOPTER_COMLINK":
case "KILLSTREAK_SATELLITE":
//case "KILLSTREAK_EMP":
//case "KILLSTREAK_HELICOPTER_GUNNER":
case "KILLSTREAK_RAPS":
//case "KILLSTREAK_DRONE_STRIKE":
//case "KILLSTREAK_DART":
case "KILLSTREAK_SENTINEL":
// TU Something Weapons
case "WEAPON_MELEE_KNUCKLES":
case "WEAPON_MELEE_BUTTERFLY":
case "WEAPON_MELEE_WRENCH":
// TU 6 Weapons
case "WEAPON_PISTOL_SHOTGUN":
case "WEAPON_AR_GARAND":
case "WEAPON_SPECIAL_CROSSBOW":
case "WEAPON_MELEE_CROWBAR":
case "WEAPON_MELEE_SWORD":
case "WEAPON_MELEE_BOXING":
case "WEAPON_SMG_AK74U":
case "WEAPON_SMG_MP40":
case "WEAPON_SMG_RECHAMBER":
case "WEAPON_SMG_NAILGUN":
case "WEAPON_AR_AN94":
case "WEAPON_AR_FAMAS":
case "WEAPON_SMG_MSMC":
case "WEAPON_LMG_INFINITE":
case "WEAPON_AR_PULSE":
case "WEAPON_AR_M16":
case "WEAPON_SMG_PPSH":
case "WEAPON_LAUNCHER_EX41":
case "WEAPON_SHOTGUN_OLYMPIA":
case "WEAPON_SNIPER_QUICKSCOPE":
case "WEAPON_SNIPER_DOUBLE":
case "WEAPON_SMG_STEN":
case "WEAPON_AR_GALIL":
case "WEAPON_LMG_RPK":
case "WEAPON_AR_M14":
case "WEAPON_SHOTGUN_ENERGY":
case "WEAPON_SPECIAL_CROSSBOW_DW":
case "WEAPON_AR_PEACEKEEPER":
case "WEAPON_MELEE_CHAINSAW":
case "WEAPON_SPECIAL_KNIFE_BALLISTIC":
case "WEAPON_MELEE_CRESCENT":
case "WEAPON_SPECIAL_DISCGUN":
return true;
}
return false;
}
// Classes
//========================================
function build_classes()
{
primaryWeapons = self get_available_items( undefined, "primary" );
secondaryWeapons = self get_available_items( undefined, "secondary" );
lethals = self get_available_items( undefined, "primarygadget" );
tacticals = self get_available_items( undefined, "secondarygadget" );
if ( IS_TRUE( level.perksEnabled ) )
{
specialties1 = self get_available_items( undefined, "specialty1" );
specialties2 = self get_available_items( undefined, "specialty2" );
specialties3 = self get_available_items( undefined, "specialty3" );
}
foreach( className, classValue in level.classMap )
{
if ( !isSubstr( className, "custom" ) )
{
continue;
}
classIndex = int( className[className.size-1] );
pickedItems = [];
pick_item( pickedItems, primaryWeapons );
if ( RandomInt( 100 ) < 95 ) // 5% chance to be a boxer for Scronce
{
pick_item( pickedItems, secondaryWeapons );
}
// Shuffle these selections around a bit so the classes don't all look the same when the allocation is low
otherItems = Array ( lethals, tacticals, specialties1, specialties2, specialties3 );
otherItems = array::randomize( otherItems );
for ( i = 0; i < otherItems.size; i ++ )
{
pick_item( pickedItems, otherItems[i] );
}
// Add items up to the max allocation
for ( i = 0; i < pickedItems.size && i < level.maxAllocation; i++ )
{
self BotClassAddItem( classIndex, pickedItems[i] );
}
// TODO: Pick primary/secondary attachments, extra perks, extra lethal, extra tactical, overkill
/*
primaryWeapon = self GetLoadoutWeapon( classIndex, "primary" );
if ( primaryWeapon != level.weaponNone && primaryWeapon.supportedAttachments.size )
{
attachment = array::random( primaryWeapon.supportedAttachments );
self BotClassAddAttachment( classIndex, primaryWeapon, attachment, "primary" );
}
secondaryWeapon = self GetLoadoutWeapon( classIndex, "secondary" );
if ( secondaryWeapon != level.weaponNone && secondaryWeapon.supportedAttachments.size )
{
attachment = array::random( secondaryWeapon.supportedAttachments );
self BotClassAddAttachment( classIndex, secondaryWeapon, attachment, "secondary" );
}
*/
}
}
function pick_item( &pickedItems, items )
{
if ( !isdefined( items ) || items.size <= 0 )
{
return;
}
pickedItems[pickedItems.size] = array::random( items );
}
function pick_classes()
{
self.loadoutClasses = [];
self.launcherClassCount = 0;
foreach( className, classValue in level.classMap )
{
if ( isSubstr( className, "custom" ) )
{
if ( level.disableCAC )
{
continue;
}
classIndex = int( className[className.size-1] );
}
else
{
// Things bots could use better in the default classes:
// C4, Trophy System, Lock on only launcher
classIndex = level.classToClassNum[ classValue ];
}
primary = self GetLoadoutWeapon( classIndex, "primary" );
secondary = self GetLoadoutWeapon( classIndex, "secondary" );
botClass = SpawnStruct();
botClass.name = className;
botClass.index = classIndex;
botClass.value = classValue;
botClass.primary = primary;
botClass.secondary = secondary;
if ( botClass.secondary.isRocketLauncher )
{
self.launcherClassCount++;
}
self.loadoutClasses[ self.loadoutClasses.size ] = botClass;
}
}
function get_current_class()
{
currValue = self.pers["class"];
if ( !isdefined( currValue ) )
{
return undefined;
}
foreach( botClass in self.loadoutClasses )
{
if ( botClass.value == currValue )
{
return botClass;
}
}
return undefined;
}
// Specialists
//========================================
function pick_hero_gadget()
{
if ( RandomInt( 2 ) < 1 || !self pick_hero_ability() )
{
self pick_hero_weapon();
}
}
function pick_hero_weapon()
{
heroWeaponRef = self GetHeroWeaponName();
if ( IsItemRestricted( heroWeaponRef ) )
{
return false;
}
heroWeaponName = self get_item_name( heroWeaponRef );
self BotClassAddItem( 0, heroWeaponName );
return true;
}
function pick_hero_ability()
{
heroAbilityRef = self GetHeroAbilityName();
if ( IsItemRestricted( heroAbilityRef ) )
{
return false;
}
heroAbilityName = self get_item_name( heroAbilityRef );
self BotClassAddItem( 0, heroAbilityName );
return true;
}
// Killstreaks
//========================================
function pick_killstreaks()
{
killstreaks = array::randomize( self get_available_items( "killstreak" ) );
for( i = 0; i < 3 && i < killstreaks.size; i++ )
{
self BotClassAddItem( 0, killstreaks[i] );
}
}
// Get Items
//========================================
function get_available_items( filterGroup, filterSlot )
{
// Get unlocked and unrestricted items
items = [];
for( i = 0; i < STATS_TABLE_MAX_ITEMS; i++ )
{
row = tableLookupRowNum( level.statsTableID, STATS_TABLE_COL_NUMBERING, i );
if ( row < 0 )
{
continue;
}
name = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NAME );
if ( name == "" || !in_whitelist( name ) )
{
continue;
}
allocation = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_ALLOCATION ) );
if ( allocation < 0 )
{
continue;
}
ref = tableLookupColumnForRow( level.statsTableId, row, STATS_TABLE_COL_REFERENCE );
if ( IsItemRestricted( ref ) )
{
continue;
}
number = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NUMBERING ) );
/*
if ( SessionModeIsPrivate() && self IsItemLocked( number ) )
{
continue;
}
*/
if ( isdefined( filterGroup ) )
{
group = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_GROUP );
if ( group != filterGroup )
{
continue;
}
}
if ( isdefined( filterSlot ) )
{
slot = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_SLOT );
if ( slot != filterSlot )
{
continue;
}
}
items[items.size] = name;
}
return items;
}
function get_item_name( itemReference )
{
for( i = 0; i < STATS_TABLE_MAX_ITEMS; i++ )
{
row = tableLookupRowNum( level.statsTableID, STATS_TABLE_COL_NUMBERING, i );
if ( row < 0 )
{
continue;
}
reference = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_REFERENCE );
if ( reference != itemReference )
{
continue;
}
name = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NAME );
return name;
}
return undefined;
}
// Not in use
function init()
{
level endon( "game_ended" );
level.bot_banned_killstreaks = Array ( "KILLSTREAK_RCBOMB",
"KILLSTREAK_QRDRONE",
/* "KILLSTREAK_REMOTE_MISSILE",*/
"KILLSTREAK_REMOTE_MORTAR",
"KILLSTREAK_HELICOPTER_GUNNER" );
for ( ;; )
{
level waittill( "connected", player );
if ( !player IsTestClient() )
{
continue;
}
player thread on_bot_connect();
}
}
function on_bot_connect()
{
self endon( "disconnect" );
if ( isdefined( self.pers[ "bot_loadout" ] ) )
{
return;
}
wait( 0.10 );
if ( self GetEntityNumber() % 2 == 0 )
{
WAIT_SERVER_FRAME;
}
self bot::set_rank();
self BotSetRandomCharacterCustomization();
max_allocation = BOT_ALLOCATION_MAX;
/*
if ( SessionModeIsPrivate() )
{
for ( i = 1; i <= BOT_ALLOCATION_UNLOCK_MAX; i++ )
{
if ( self IsItemLocked( rank::GetItemIndex( "feature_allocation_slot_" + i ) ) )
{
max_allocation--;
}
}
}
*/
self construct_loadout( max_allocation );
self.pers[ "bot_loadout" ] = true;
}
function construct_loadout( allocation_max )
{
/* if ( SessionModeIsPrivate() && self IsItemLocked( rank::GetItemIndex( "feature_cac" ) ) )
{
// cac still locked
return;
}
*/
pixbeginevent( "bot_construct_loadout" );
item_list = build_item_list();
// item_list["primary"] = [];
// item_list["primary"][0] = "WEAPON_RIOTSHIELD";
construct_class( 0, item_list, allocation_max );
construct_class( 1, item_list, allocation_max );
construct_class( 2, item_list, allocation_max );
construct_class( 3, item_list, allocation_max );
construct_class( 4, item_list, allocation_max );
killstreaks = item_list["killstreak1"];
if ( isdefined( item_list["killstreak2"] ) )
{
killstreaks = ArrayCombine( killstreaks, item_list["killstreak2"], true, false );
}
if ( isdefined( item_list["killstreak3"] ) )
{
killstreaks = ArrayCombine( killstreaks, item_list["killstreak3"], true, false );
}
if ( isdefined( killstreaks ) && killstreaks.size )
{
choose_weapon( 0, killstreaks );
choose_weapon( 0, killstreaks );
choose_weapon( 0, killstreaks );
}
self.claimed_items = undefined;
pixendevent();
}
function construct_class( constructclass, items, allocation_max )
{
allocation = 0;
claimed_count = build_claimed_list( items );
self.claimed_items = [];
// primary
weapon = choose_weapon( constructclass, items["primary"] );
claimed_count["primary"]++;
allocation++;
// secondary
weapon = choose_weapon( constructclass, items["secondary"] );
choose_weapon_option( constructclass, "camo", 1 );
}
function make_choice( chance, claimed, max_claim )
{
return ( claimed < max_claim && RandomInt( 100 ) < chance );
}
function chose_action( action1, chance1, action2, chance2, action3, chance3, action4, chance4 )
{
chance1 = Int( chance1 / 10 );
chance2 = Int( chance2 / 10 );
chance3 = Int( chance3 / 10 );
chance4 = Int( chance4 / 10 );
actions = [];
for( i = 0; i < chance1; i++ )
{
actions[ actions.size ] = action1;
}
for( i = 0; i < chance2; i++ )
{
actions[ actions.size ] = action2;
}
for( i = 0; i < chance3; i++ )
{
actions[ actions.size ] = action3;
}
for( i = 0; i < chance4; i++ )
{
actions[ actions.size ] = action4;
}
return array::random( actions );
}
function item_is_claimed( item )
{
foreach( claim in self.claimed_items )
{
if ( claim == item )
{
return true;
}
}
return false;
}
function choose_weapon( weaponclass, items )
{
if ( !isdefined( items ) || !items.size )
{
return undefined;
}
start = RandomInt( items.size );
for( i = 0; i < items.size; i++ )
{
weapon = items[ start ];
if ( !item_is_claimed( weapon ) )
{
break;
}
start = ( start + 1 ) % items.size;
}
self.claimed_items[ self.claimed_items.size ] = weapon;
self BotClassAddItem( weaponclass, weapon );
return weapon;
}
function build_weapon_options_list( optionType )
{
level.botWeaponOptionsId[optionType] = [];
level.botWeaponOptionsProb[optionType] = [];
csv_filename = "gamedata/weapons/common/attachmentTable.csv";
prob = 0;
for ( row = 0 ; row < 255 ; row++ )
{
if ( tableLookupColumnForRow( csv_filename, row, ATTACHMENT_TABLE_COL_TYPE ) == optionType )
{
index = level.botWeaponOptionsId[optionType].size;
level.botWeaponOptionsId[optionType][index] = Int( tableLookupColumnForRow( csv_filename, row, ATTACHMENT_TABLE_COL_NUMBERING ) );
prob += Int( tableLookupColumnForRow( csv_filename, row, ATTACHMENT_TABLE_COL_BOT_PROB ) );
level.botWeaponOptionsProb[optionType][index] = prob;
}
}
}
function choose_weapon_option( weaponclass, optionType, primary )
{
if ( !isdefined( level.botWeaponOptionsId ) )
{
level.botWeaponOptionsId = [];
level.botWeaponOptionsProb = [];
build_weapon_options_list( "camo" );
build_weapon_options_list( "reticle" );
}
// weapon options cannot be set in local matches
if ( !level.onlineGame && !level.systemLink )
return;
// Increase the range of the probability to reduce the chances of picking the option when the bot's level is less than BOT_RANK_ALL_OPTIONS_AVAILABLE
// (in system link all options are available)
numOptions = level.botWeaponOptionsProb[optionType].size;
maxProb = level.botWeaponOptionsProb[optionType][numOptions-1];
if ( !level.systemLink && self.pers[ "rank" ] < BOT_RANK_ALL_OPTIONS_AVAILABLE )
maxProb += BOT_RANK_OPTIONS_MULTIPLIER * maxProb * ( ( BOT_RANK_ALL_OPTIONS_AVAILABLE - self.pers[ "rank" ] ) / BOT_RANK_ALL_OPTIONS_AVAILABLE );
rnd = RandomInt( Int( maxProb ) );
for (i=0 ; i<numOptions ; i++)
{
if ( level.botWeaponOptionsProb[optionType][i] > rnd )
{
self BotClassSetWeaponOption( weaponclass, primary, optionType, level.botWeaponOptionsId[optionType][i] );
break;
}
}
}
function choose_primary_attachments( weaponclass, weapon, allocation, allocation_max )
{
attachments = weapon.supportedAttachments;
remaining = allocation_max - allocation;
if ( !attachments.size || !remaining )
{
return 0;
}
attachment_action = chose_action( "3_attachments", 25, "2_attachments", 65, "1_attachments", 10, "none", 5 );
if ( remaining >= 4 && attachment_action == "3_attachments" )
{
a1 = array::random( attachments );
self BotClassAddAttachment( weaponclass, weapon, a1, "primaryattachment1" );
count = 1;
attachments = GetWeaponAttachments( weapon, a1 );
if ( attachments.size )
{
a2 = array::random( attachments );
self BotClassAddAttachment( weaponclass, weapon, a2, "primaryattachment2" );
count++;
attachments = GetWeaponAttachments( weapon, a1, a2 );
if ( attachments.size )
{
a3 = array::random( attachments );
self BotClassAddItem( weaponclass, "BONUSCARD_PRIMARY_GUNFIGHTER" );
self BotClassAddAttachment( weaponclass, weapon, a3, "primaryattachment3" );
return 4;
}
}
return count;
}
else if ( remaining >= 2 && attachment_action == "2_attachments" )
{
a1 = array::random( attachments );
self BotClassAddAttachment( weaponclass, weapon, a1, "primaryattachment1" );
attachments = GetWeaponAttachments( weapon, a1 );
if ( attachments.size )
{
a2 = array::random( attachments );
self BotClassAddAttachment( weaponclass, weapon, a2, "primaryattachment2" );
return 2;
}
return 1;
}
else if ( remaining >= 1 && attachment_action == "1_attachments" )
{
a = array::random( attachments );
self BotClassAddAttachment( weaponclass, weapon, a, "primaryattachment1" );
return 1;
}
return 0;
}
function choose_secondary_attachments( weaponclass, weapon, allocation, allocation_max )
{
attachments = weapon.supportedAttachments ;
remaining = allocation_max - allocation;
if ( !attachments.size || !remaining )
{
return 0;
}
attachment_action = chose_action( "2_attachments", 10, "1_attachments", 40, "none", 50, "none", 0 );
if ( remaining >= 3 && attachment_action == "2_attachments" )
{
a1 = array::random( attachments );
self BotClassAddAttachment( weaponclass, weapon, a1, "secondaryattachment1" );
attachments = GetWeaponAttachments( weapon, a1 );
if ( attachments.size )
{
a2 = array::random( attachments );
self BotClassAddItem( weaponclass, "BONUSCARD_SECONDARY_GUNFIGHTER" );
self BotClassAddAttachment( weaponclass, weapon, a2, "secondaryattachment2" );
return 3;
}
return 1;
}
else if ( remaining >= 1 && attachment_action == "1_attachments" )
{
a = array::random( attachments );
self BotClassAddAttachment( weaponclass, weapon, a, "secondaryattachment1" );
return 1;
}
return 0;
}
function build_item_list()
{
items = [];
for( i = 0; i < STATS_TABLE_MAX_ITEMS; i++ )
{
row = tableLookupRowNum( level.statsTableID, STATS_TABLE_COL_NUMBERING, i );
if ( row > -1 )
{
slot = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_SLOT );
if ( slot == "" )
{
continue;
}
number = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NUMBERING ) );
/*
if ( SessionModeIsPrivate() && self IsItemLocked( number ) )
{
continue;
}
*/
allocation = Int( tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_ALLOCATION ) );
if ( allocation < 0 )
{
continue;
}
name = tableLookupColumnForRow( level.statsTableID, row, STATS_TABLE_COL_NAME );
/*
if ( item_is_banned( slot, name ) )
{
continue;
}
*/
if ( !isdefined( items[slot] ) )
{
items[slot] = [];
}
items[ slot ][ items[slot].size ] = name;
}
}
return items;
}
function build_claimed_list( items )
{
claimed = [];
keys = GetArrayKeys( items );
foreach( key in keys )
{
claimed[ key ] = 0;
}
return claimed;
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,209 @@
#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\system_shared;
#namespace serversettings;
function autoexec __init__sytem__() { system::register("serversettings",&__init__,undefined,undefined); }
function __init__()
{
callback::on_start_gametype( &init );
}
function init()
{
level.hostname = GetDvarString( "sv_hostname");
if(level.hostname == "")
level.hostname = "CoDHost";
SetDvar("sv_hostname", level.hostname);
SetDvar("ui_hostname", level.hostname);
//makeDvarServerInfo("ui_hostname", "CoDHost");
level.motd = GetDvarString( "scr_motd" );
if(level.motd == "")
level.motd = "";
SetDvar("scr_motd", level.motd);
SetDvar("ui_motd", level.motd);
//makeDvarServerInfo("ui_motd", "");
level.allowvote = GetDvarString( "g_allowvote" );
if(level.allowvote == "")
level.allowvote = "1";
SetDvar("g_allowvote", level.allowvote);
SetDvar("ui_allowvote", level.allowvote);
//makeDvarServerInfo("ui_allowvote", "1");
level.allow_teamchange = "1";
SetDvar("ui_allow_teamchange", level.allow_teamchange);
level.friendlyfire = GetGametypeSetting( "friendlyfiretype" );
SetDvar("ui_friendlyfire", level.friendlyfire);
//makeDvarServerInfo("ui_friendlyfire", "0");
if(GetDvarString( "scr_mapsize") == "")
SetDvar("scr_mapsize", "64");
else if(GetDvarfloat( "scr_mapsize") >= 64)
SetDvar("scr_mapsize", "64");
else if(GetDvarfloat( "scr_mapsize") >= 32)
SetDvar("scr_mapsize", "32");
else if(GetDvarfloat( "scr_mapsize") >= 16)
SetDvar("scr_mapsize", "16");
else
SetDvar("scr_mapsize", "8");
level.mapsize = GetDvarfloat( "scr_mapsize");
constrain_gametype(GetDvarString( "g_gametype"));
constrain_map_size(level.mapsize);
thread setup_callbacks();
for(;;)
{
update();
wait 5;
}
}
function update()
{
sv_hostname = GetDvarString( "sv_hostname");
if(level.hostname != sv_hostname)
{
level.hostname = sv_hostname;
SetDvar("ui_hostname", level.hostname);
}
scr_motd = GetDvarString( "scr_motd");
if(level.motd != scr_motd)
{
level.motd = scr_motd;
SetDvar("ui_motd", level.motd);
}
g_allowvote = GetDvarString( "g_allowvote" );
if(level.allowvote != g_allowvote)
{
level.allowvote = g_allowvote;
SetDvar("ui_allowvote", level.allowvote);
}
scr_friendlyfire = GetGametypeSetting( "friendlyfiretype" );
if(level.friendlyfire != scr_friendlyfire)
{
level.friendlyfire = scr_friendlyfire;
SetDvar("ui_friendlyfire", level.friendlyfire);
}
}
function constrain_gametype(gametype)
{
entities = getentarray();
for(i = 0; i < entities.size; i++)
{
entity = entities[i];
if(gametype == "dm")
{
if(isdefined(entity.script_gametype_dm) && entity.script_gametype_dm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "tdm")
{
if(isdefined(entity.script_gametype_tdm) && entity.script_gametype_tdm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "ctf")
{
if(isdefined(entity.script_gametype_ctf) && entity.script_gametype_ctf != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "hq")
{
if(isdefined(entity.script_gametype_hq) && entity.script_gametype_hq != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "sd")
{
if(isdefined(entity.script_gametype_sd) && entity.script_gametype_sd != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "koth")
{
if(isdefined(entity.script_gametype_koth) && entity.script_gametype_koth != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
}
}
function constrain_map_size(mapsize)
{
entities = getentarray();
for(i = 0; i < entities.size; i++)
{
entity = entities[i];
if(int(mapsize) == 8)
{
if(isdefined(entity.script_mapsize_08) && entity.script_mapsize_08 != "1")
{
//iprintln("DELETED(MapSize): ", entity.classname);
entity delete();
}
}
else if(int(mapsize) == 16)
{
if(isdefined(entity.script_mapsize_16) && entity.script_mapsize_16 != "1")
{
//iprintln("DELETED(MapSize): ", entity.classname);
entity delete();
}
}
else if(int(mapsize) == 32)
{
if(isdefined(entity.script_mapsize_32) && entity.script_mapsize_32 != "1")
{
//iprintln("DELETED(MapSize): ", entity.classname);
entity delete();
}
}
else if(int(mapsize) == 64)
{
if(isdefined(entity.script_mapsize_64) && entity.script_mapsize_64 != "1")
{
//iprintln("DELETED(MapSize): ", entity.classname);
entity delete();
}
}
}
}
function setup_callbacks()
{
level.onForfeit = &default_onForfeit;
}
function default_onForfeit()
{
level.gameForfeited = false;
}

Binary file not shown.

View File

@@ -0,0 +1,670 @@
#using scripts\codescripts\struct;
#using scripts\shared\callbacks_shared;
#using scripts\shared\persistence_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#insert scripts\shared\shared.gsh;
#using scripts\mp\gametypes\_globallogic_ui;
#using scripts\mp\gametypes\_spectating;
#using scripts\mp\_util;
#precache( "material", "mpflag_spectator" );
#precache( "string", "MP_AUTOBALANCE_NOW" );
#namespace teams;
REGISTER_SYSTEM( "teams", &__init__, undefined )
function __init__()
{
callback::on_start_gametype( &init );
level.getEnemyTeam = &getEnemyTeam;
level.use_team_based_logic_for_locking_on = true;
}
function init()
{
game["strings"]["autobalance"] = &"MP_AUTOBALANCE_NOW";
if(GetDvarString( "scr_teambalance") == "")
SetDvar("scr_teambalance", "0");
level.teambalance = GetDvarint( "scr_teambalance");
level.teambalancetimer = 0;
if(GetDvarString( "scr_timeplayedcap") == "")
SetDvar("scr_timeplayedcap", "1800");
level.timeplayedcap = int(GetDvarint( "scr_timeplayedcap"));
level.freeplayers = [];
if( level.teamBased )
{
level.alliesplayers = [];
level.axisplayers = [];
callback::on_connect( &on_player_connect );
callback::on_joined_team( &on_joined_team );
callback::on_joined_spectate( &on_joined_spectators );
level thread update_team_balance();
wait .15;
level thread update_player_times();
}
else
{
callback::on_connect( &on_free_player_connect );
wait .15;
level thread update_player_times();
}
}
function on_player_connect()
{
self thread track_played_time();
}
function on_free_player_connect()
{
self thread track_free_played_time();
}
function on_joined_team()
{
/#println( "joined team: " + self.pers["team"] );#/
self update_time();
}
function on_joined_spectators()
{
self.pers["teamTime"] = undefined;
}
function track_played_time()
{
self endon( "disconnect" );
if ( !isdefined( self.pers["totalTimePlayed"] ) )
{
self.pers["totalTimePlayed"] = 0;
}
foreach ( team in level.teams )
{
self.timePlayed[team] = 0;
}
self.timePlayed["free"] = 0;
self.timePlayed["other"] = 0;
self.timePlayed["alive"] = 0;
// dont reset time played in War when going into final fight, this is used for calculating match bonus
if ( !isdefined( self.timePlayed["total"] ) || !( (level.gameType == "twar") && (0 < game["roundsplayed"]) && (0 < self.timeplayed["total"]) ) )
self.timePlayed["total"] = 0;
while ( level.inPrematchPeriod )
WAIT_SERVER_FRAME;
for ( ;; )
{
if ( game["state"] == "playing" )
{
if ( isdefined( level.teams[self.sessionteam] ) )
{
self.timePlayed[self.sessionteam]++;
self.timePlayed["total"]++;
if ( level.mpCustomMatch )
{
self.pers["sbtimeplayed"] = self.timeplayed["total"];
self.sbtimeplayed = self.pers["sbtimeplayed"];
}
if ( IsAlive( self ) )
self.timePlayed["alive"]++;
}
else if ( self.sessionteam == "spectator" )
{
self.timePlayed["other"]++;
}
}
wait ( 1.0 );
}
}
function update_player_times()
{
const minWait = 10.0;
const step = 1.0;
varWait = minWait;
nextToUpdate = 0;
for ( ;; )
{
varWait = varWait - step;
nextToUpdate++;
if ( nextToUpdate >= level.players.size )
{
nextToUpdate = 0;
if ( varWait > 0 )
{
wait ( varWait );
}
varWait = minWait;
}
if ( isdefined( level.players[nextToUpdate] ) )
{
level.players[nextToUpdate] update_played_time();
level.players[nextToUpdate] persistence::check_contract_expirations();
}
wait ( step );
}
}
function update_played_time()
{
pixbeginevent("updatePlayedTime");
if ( level.rankedMatch || level.leagueMatch )
{
foreach( team in level.teams )
{
if ( self.timePlayed[team] )
{
if ( level.teambased )
{
self AddPlayerStat( "time_played_"+team, int( min( self.timePlayed[team], level.timeplayedcap ) ) );
}
self AddPlayerStatWithGameType( "time_played_total", int( min( self.timePlayed[team], level.timeplayedcap ) ) );
}
}
if ( self.timePlayed["other"] )
{
self AddPlayerStat( "time_played_other", int( min( self.timePlayed["other"], level.timeplayedcap ) ) );
self AddPlayerStatWithGameType( "time_played_total", int( min( self.timePlayed["other"], level.timeplayedcap ) ) );
}
if ( self.timePlayed["alive"] )
{
timeAlive = int( min( self.timePlayed["alive"], level.timeplayedcap ) );
self persistence::increment_contract_times( timeAlive );
self AddPlayerStat( "time_played_alive", timeAlive );
}
}
if ( level.onlineGame )
{
timeAlive = int( min( self.timePlayed["alive"], level.timeplayedcap ) );
self.pers["time_played_alive"] += timeAlive;
}
pixendevent();
if ( game["state"] == "postgame" )
return;
foreach( team in level.teams )
{
self.timePlayed[team] = 0;
}
self.timePlayed["other"] = 0;
self.timePlayed["alive"] = 0;
}
function update_time()
{
if ( game["state"] != "playing" )
return;
self.pers["teamTime"] = getTime();
}
function update_balance_dvar()
{
for(;;)
{
teambalance = GetDvarint( "scr_teambalance");
if(level.teambalance != teambalance)
level.teambalance = GetDvarint( "scr_teambalance");
timeplayedcap = GetDvarint( "scr_timeplayedcap");
if(level.timeplayedcap != timeplayedcap)
level.timeplayedcap = int(GetDvarint( "scr_timeplayedcap"));
wait 1;
}
}
function update_team_balance()
{
level thread update_balance_dvar();
wait .15;
if ( level.teamBalance && util::isRoundBased() && level.numlives )
{
if ( isDefined( game["BalanceTeamsNextRound"] ) )
iPrintLnbold( &"MP_AUTOBALANCE_NEXT_ROUND" );
level waittill( "game_ended" );
wait 1;
if ( isDefined( game["BalanceTeamsNextRound"] ) )
{
level balance_teams();
game["BalanceTeamsNextRound"] = undefined;
}
else if ( !get_team_balance() )
{
game["BalanceTeamsNextRound"] = true;
}
}
else
{
level endon ( "game_ended" );
for ( ;; )
{
if ( level.teamBalance )
{
if ( !get_team_balance() )
{
iPrintLnBold( &"MP_AUTOBALANCE_SECONDS", 15 );
wait 15.0;
if ( !get_team_balance() )
level balance_teams();
}
wait 59.0;
}
wait 1.0;
}
}
}
function get_team_balance()
{
level.team["allies"] = 0;
level.team["axis"] = 0;
players = level.players;
for ( i = 0; i < players.size; i++ )
{
if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "allies" ) )
level.team["allies"]++;
else if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "axis" ) )
level.team["axis"]++;
}
if ( ( level.team["allies"] > ( level.team["axis"] + level.teamBalance ) ) || ( level.team["axis"] > ( level.team["allies"] + level.teamBalance ) ) )
return false;
else
return true;
}
function balance_teams()
{
iPrintLnBold( game["strings"]["autobalance"] );
//Create/Clear the team arrays
AlliedPlayers = [];
AxisPlayers = [];
// Populate the team arrays
players = level.players;
for ( i = 0; i < players.size; i++ )
{
if ( !isdefined( players[i].pers["teamTime"] ) )
continue;
if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "allies" ) )
AlliedPlayers[AlliedPlayers.size] = players[i];
else if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "axis" ) )
AxisPlayers[AxisPlayers.size] = players[i];
}
MostRecent = undefined;
while ( ( AlliedPlayers.size > ( AxisPlayers.size + 1 ) ) || ( AxisPlayers.size > ( AlliedPlayers.size + 1 ) ) )
{
if ( AlliedPlayers.size > ( AxisPlayers.size + 1 ) )
{
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
// Ignore players capturing or carrying objects
for ( j = 0; j < AlliedPlayers.size; j++ )
{
if ( !isdefined( MostRecent ) )
MostRecent = AlliedPlayers[j];
else if ( AlliedPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] )
MostRecent = AlliedPlayers[j];
}
if ( isdefined( MostRecent ) )
MostRecent change( "axis" );
else
{
// Move the player that's been on the team the shortest ammount of time
for ( j = 0; j < AlliedPlayers.size; j++ )
{
if ( !isdefined( MostRecent ) )
MostRecent = AlliedPlayers[j];
else if ( AlliedPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] )
MostRecent = AlliedPlayers[j];
}
MostRecent change( "axis" );
}
}
else if ( AxisPlayers.size > ( AlliedPlayers.size + 1 ) )
{
// Move the player that's been on the team the shortest ammount of time (highest teamTime value)
// Ignore players capturing or carrying objects
for ( j = 0; j < AxisPlayers.size; j++ )
{
if ( !isdefined( MostRecent ) )
MostRecent = AxisPlayers[j];
else if ( AxisPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] )
MostRecent = AxisPlayers[j];
}
if ( isdefined( MostRecent ) )
MostRecent change( "allies" );
else
{
// Move the player that's been on the team the shortest ammount of time
for ( j = 0; j < AxisPlayers.size; j++ )
{
if ( !isdefined( MostRecent ) )
MostRecent = AxisPlayers[j];
else if ( AxisPlayers[j].pers["teamTime"] > MostRecent.pers["teamTime"] )
MostRecent = AxisPlayers[j];
}
MostRecent change( "allies" );
}
}
MostRecent = undefined;
AlliedPlayers = [];
AxisPlayers = [];
players = level.players;
for ( i = 0; i < players.size; i++ )
{
if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "allies" ) )
AlliedPlayers[AlliedPlayers.size] = players[i];
else if ( ( isdefined( players[i].pers["team"] ) ) && ( players[i].pers["team"] == "axis" ) )
AxisPlayers[AxisPlayers.size] = players[i];
}
}
}
function change( team )
{
if (self.sessionstate != "dead")
{
// Set a flag on the player to they aren't robbed points for dying - the callback will remove the flag
self.switching_teams = true;
self.switchedTeamsResetGadgets = true;
self.joining_team = team;
self.leaving_team = self.pers["team"];
// Suicide the player so they can't hit escape and fail the team balance
self suicide();
}
self.pers["team"] = team;
self.team = team;
self.pers["weapon"] = undefined;
self.pers["spawnweapon"] = undefined;
self.pers["savedmodel"] = undefined;
self.pers["teamTime"] = undefined;
self.sessionteam = self.pers["team"];
self globallogic_ui::updateObjectiveText();
// update spectator permissions immediately on change of team
self spectating::set_permissions();
self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
self openMenu(game[ "menu_start_menu" ]);
self notify("end_respawn");
}
function count_players()
{
players = level.players;
playerCounts = [];
foreach( team in level.teams )
{
playerCounts[team] = 0;
}
foreach( player in level.players )
{
if( player == self )
continue;
team = player.pers["team"];
if( isdefined(team) && isdefined( level.teams[team] ) )
playerCounts[team]++;
}
return playerCounts;
}
function track_free_played_time()
{
self endon( "disconnect" );
foreach( team in level.teams )
{
self.timePlayed[team] = 0;
}
self.timePlayed["other"] = 0;
self.timePlayed["total"] = 0;
self.timePlayed["alive"] = 0;
for ( ;; )
{
if ( game["state"] == "playing" )
{
team = self.pers["team"];
if ( isdefined( team ) && isdefined( level.teams[team] ) && self.sessionteam != "spectator" )
{
self.timePlayed[team]++;
self.timePlayed["total"]++;
if ( IsAlive( self ) )
self.timePlayed["alive"]++;
}
else
{
self.timePlayed["other"]++;
}
}
wait ( 1.0 );
}
}
function set_player_model( team, weapon )
{
self DetachAll();
self SetMoveSpeedScale( 1 );
self SetSprintDuration( 4 );
self SetSprintCooldown( 0 );
}
function get_flag_model( teamRef )
{
assert(isdefined(game["flagmodels"]));
assert(isdefined(game["flagmodels"][teamRef]));
return ( game["flagmodels"][teamRef] );
}
function get_flag_carry_model( teamRef )
{
assert(isdefined(game["carry_flagmodels"]));
assert(isdefined(game["carry_flagmodels"][teamRef]));
return ( game["carry_flagmodels"][teamRef] );
}
function getTeamIndex( team )
{
if( !isdefined( team ) )
{
return TEAM_FREE;
}
if( team == "free" )
{
return TEAM_FREE;
}
if( team == "allies" )
{
return TEAM_ALLIES;
}
if( team == "axis" )
{
return TEAM_AXIS;
}
return TEAM_FREE;
}
function getEnemyTeam( player_team )
{
foreach( team in level.teams )
{
if ( team == player_team )
continue;
if ( team == "spectator" )
continue;
return team;
}
return util::getOtherTeam( player_team );
}
function GetEnemyPlayers()
{
enemies = [];
foreach( player in level.players )
{
if( player.team == "spectator" )
{
continue;
}
if( ( level.teamBased && player.team != self.team ) || ( !level.teamBased && player != self ) )
{
ARRAY_ADD( enemies, player );
}
}
return enemies;
}
function GetFriendlyPlayers()
{
friendlies = [];
foreach( player in level.players )
{
if( ( player.team == self.team ) && ( player != self ) )
{
ARRAY_ADD( friendlies, player );
}
}
return friendlies;
}
function WaitUntilTeamChange( player, callback, arg, end_condition1, end_condition2, end_condition3 )
{
if( isdefined( end_condition1 ) )
self endon( end_condition1 );
if( isdefined( end_condition2 ) )
self endon( end_condition2 );
if( isdefined( end_condition3 ) )
self endon( end_condition3 );
event = player util::waittill_any( "joined_team", "disconnect", "joined_spectators" );
if( isdefined( callback ) )
{
self [[ callback ]]( arg, event );
}
}
function WaitUntilTeamChangeSingleTon( player, singletonString, callback, arg, end_condition1, end_condition2, end_condition3 )
{
self notify( singletonString );
self endon( singletonString );
if( isdefined( end_condition1 ) )
self endon( end_condition1 );
if( isdefined( end_condition2 ) )
self endon( end_condition2 );
if( isdefined( end_condition3 ) )
self endon( end_condition3 );
event = player util::waittill_any( "joined_team", "disconnect", "joined_spectators" );
if( isdefined( callback ) )
{
self thread [[ callback ]]( arg, event );
}
}
function HideToSameTeam()
{
if( level.teambased )
{
self SetVisibleToAllExceptTeam( self.team );
}
else
{
self SetVisibleToAll();
self SetInvisibleToPlayer( self.owner );
}
}

View File

@@ -0,0 +1,118 @@
if Engine.GetCurrentMap() ~= "core_frontend" then
return
end
require( "ui.uieditor.widgets.PC.ServerBrowser.ServerBrowserRowInternal" )
require( "ui.uieditor.widgets.Lobby.Common.FE_FocusBarContainer" )
CoD.ServerBrowserRow = InheritFrom( LUI.UIElement )
CoD.ServerBrowserRow.new = function ( menu, controller )
local self = LUI.UIElement.new()
if PreLoadFunc then
PreLoadFunc( self, controller )
end
self:setUseStencil( false )
self:setClass( CoD.ServerBrowserRow )
self.id = "ServerBrowserRow"
self.soundSet = "default"
self:setLeftRight( true, false, 0, 700 )
self:setTopBottom( true, false, 0, 22 )
self:makeFocusable()
self:setHandleMouse( true )
if CoD.isPC then
self:registerEventHandler( "leftmousedown", function ()
if self:isInFocus() then
ServerBrowserCancelRequest( self )
JoinServerBrowser( self, self, controller, menu )
end
end )
end
self.anyChildUsesUpdateState = true
local background = LUI.UIImage.new()
background:setLeftRight( true, true, 0, 0 )
background:setTopBottom( true, true, 0, 0 )
background:setRGB( 0.2, 0.2, 0.2 )
background:setAlpha( 0.8 )
self:addElement( background )
self.background = background
local rowItems = CoD.ServerBrowserRowInternal.new( menu, controller )
rowItems:setLeftRight( true, false, 0, 700 )
rowItems:setTopBottom( true, false, 0, 22 )
rowItems:linkToElementModel( self, nil, false, function ( model )
rowItems:setModel( model, controller )
end )
self:addElement( rowItems )
self.rowItems = rowItems
local FocusBarB = CoD.FE_FocusBarContainer.new( menu, controller )
FocusBarB:setLeftRight( true, true, -2, 2 )
FocusBarB:setTopBottom( false, true, -1, 3 )
FocusBarB:setAlpha( 0 )
FocusBarB:setZoom( 1 )
self:addElement( FocusBarB )
self.FocusBarB = FocusBarB
local FocusBarT = CoD.FE_FocusBarContainer.new( menu, controller )
FocusBarT:setLeftRight( true, true, -2, 2 )
FocusBarT:setTopBottom( true, false, -2, 2 )
FocusBarT:setAlpha( 0 )
FocusBarT:setZoom( 1 )
self:addElement( FocusBarT )
self.FocusBarT = FocusBarT
self.clipsPerState = {
DefaultState = {
DefaultClip = function ()
self:setupElementClipCounter( 3 )
background:completeAnimation()
self.background:setRGB( 0.2, 0.2, 0.2 )
self.clipFinished( background, {} )
FocusBarB:completeAnimation()
self.FocusBarB:setAlpha( 0 )
self.clipFinished( FocusBarB, {} )
FocusBarT:completeAnimation()
self.FocusBarT:setAlpha( 0 )
self.clipFinished( FocusBarT, {} )
end,
Focus = function ()
self:setupElementClipCounter( 3 )
background:completeAnimation()
self.background:setRGB( 0.2, 0.2, 0.2 )
self.clipFinished( background, {} )
FocusBarB:completeAnimation()
self.FocusBarB:setAlpha( 1 )
self.clipFinished( FocusBarB, {} )
FocusBarT:completeAnimation()
self.FocusBarT:setAlpha( 1 )
self.clipFinished( FocusBarT, {} )
end,
Over = function ()
self:setupElementClipCounter( 3 )
background:completeAnimation()
self.background:setRGB( 0.39, 0.39, 0.39 )
self.clipFinished( background, {} )
FocusBarB:completeAnimation()
self.FocusBarB:setAlpha( 0 )
self.clipFinished( FocusBarB, {} )
FocusBarT:completeAnimation()
self.FocusBarT:setAlpha( 0 )
self.clipFinished( FocusBarT, {} )
end
}
}
LUI.OverrideFunction_CallOriginalSecond( self, "close", function ( element )
element.rowItems:close()
element.FocusBarB:close()
element.FocusBarT:close()
element.m_leftMouseDown = nil
end )
if PostLoadFunc then
PostLoadFunc( self, controller, menu )
end
return self
end

View File

@@ -0,0 +1,156 @@
if Engine.GetCurrentMap() ~= "core_frontend" then
return
end
local enableLobbyMapVote = true -- toggle map vote in public lobby
local enableLargeServerBrowserButton = true -- toggle large server browser button
local utils = require("utils")
require("datasources_start_menu_tabs")
require("datasources_change_map_categories")
require("datasources_gamesettingsflyout_buttons")
CoD.LobbyButtons.MP_PUBLIC_MATCH = {
stringRef = "MENU_PLAY_CAPS",
action = NavigateToLobby_SelectionList,
param = "MPLobbyOnline",
customId = "btnPublicMatch",
}
CoD.LobbyButtons.MP_FIND_MATCH = {
stringRef = "MPUI_BASICTRAINING_CAPS",
action = OpenFindMatch,
customId = "btnFindMatch",
}
CoD.LobbyButtons.STATS = {
stringRef = "STATS",
action = function(self, element, controller, param, menu)
SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true)
OpenPopup(menu, "T7xStatsMenu", controller)
end,
customId = "btnMPStats"
}
CoD.LobbyButtons.MP_START_GAME = {
stringRef = "MENU_START_GAME_CAPS",
action = function(self, element, controller, param, menu)
Engine.SetDvar("party_minplayers", 1)
Engine.Exec(nil, "launchgame")
end,
customId = "btnStartGame"
}
CoD.LobbyButtons.SETTING_UP_BOTS = {
stringRef = "MENU_SETUP_BOTS_CAPS",
action = function(self, element, controller, param, menu)
SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true)
OpenPopup(menu, "GameSettings_Bots", controller)
end,
customId = "btnSettingUpBots"
}
CoD.LobbyButtons.GameSettingsFlyoutArenas = {
stringRef = "MPUI_SETUP_GAME_CAPS",
action = function(self, element, controller, param, menu)
SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true)
OpenPopup(menu, "GameSettingsFlyoutMP", controller)
end,
customId = "btnGameSettingsFlyoutMP"
}
CoD.LobbyButtons.GameSettingsFlyoutMP = {
stringRef = "MPUI_SETUP_GAME_CAPS",
action = function(self, element, controller, param, menu)
SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true)
OpenPopup(menu, "GameSettingsFlyoutMPCustom", controller)
end,
customId = "btnGameSettingsFlyoutMPCustom"
}
CoD.LobbyButtons.SERVER_BROWSER = {
stringRef = "MENU_SERVER_BROWSER_CAPS",
action = function(self, element, controller, param, menu)
SetPerControllerTableProperty(controller, "disableGameSettingsOptions", true)
OpenPopup(menu, "LobbyServerBrowserOnline", controller)
end,
customId = "btnDedicated"
}
local shouldShowMapVote = enableLobbyMapVote
local lobbyMapVote = function(lobbyMapVoteIsEnabled)
if lobbyMapVoteIsEnabled == true then
Engine.Exec(nil, "LobbyStopDemo")
end
end
local addCustomButtons = function(controller, menuId, buttonTable, isLeader)
if menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id then
utils.RemoveSpaces(buttonTable)
local theaterIndex = utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.THEATER_MP)
if theaterIndex ~= nil then
utils.AddSpacer(buttonTable, theaterIndex - 1)
end
end
if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then
utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.STATS)
end
if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id or menuId == LobbyData.UITargets.UI_MPLOBBYLANGAME.id then
Engine.Mods_Lists_UpdateUsermaps()
end
if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id then
shouldShowMapVote = enableLobbyMapVote
if enableLargeServerBrowserButton then
utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.SERVER_BROWSER, 1)
end
elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEPUBLICGAME.id then
utils.RemoveButton(buttonTable, CoD.LobbyButtons.MP_PUBLIC_LOBBY_LEADERBOARD)
utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1)
utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP, 2)
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutMP))
lobbyMapVote(shouldShowMapVote)
shouldShowMapVote = false
elseif menuId == LobbyData.UITargets.UI_MPLOBBYONLINEARENAGAME.id then
utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.MP_START_GAME, 1)
utils.AddSmallButton(controller, buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas, 2)
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.GameSettingsFlyoutArenas))
end
if menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then
utils.RemoveButton(buttonTable, CoD.LobbyButtons.THEATER_ZM)
utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM)
utils.RemoveSpaces(buttonTable)
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.SERVER_BROWSER))
local bgbIndex = utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS)
if bgbIndex ~= nil then
utils.AddSpacer(buttonTable, bgbIndex - 1)
end
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.STATS))
end
end
local oldAddButtonsForTarget = CoD.LobbyMenus.AddButtonsForTarget
CoD.LobbyMenus.AddButtonsForTarget = function(controller, id)
local model = nil
if Engine.IsLobbyActive(Enum.LobbyType.LOBBY_TYPE_GAME) then
model = Engine.GetModel(DataSources.LobbyRoot.getModel(controller), "gameClient.isHost")
else
model = Engine.GetModel(DataSources.LobbyRoot.getModel(controller), "privateClient.isHost")
end
local isLeader = nil
if model ~= nil then
isLeader = Engine.GetModelValue(model)
else
isLeader = 1
end
local result = oldAddButtonsForTarget(controller, id)
addCustomButtons(controller, id, result, isLeader)
return result
end

View File

@@ -0,0 +1,96 @@
local f0_local0 = function(f1_arg0, f1_arg1)
if not CoD.useMouse then
return
else
LUI.OverrideFunction_CallOriginalFirst(f1_arg0, "setState", function(element, controller)
if IsSelfInState(f1_arg0, "SelectingMap") then
f1_arg0.mapList:setMouseDisabled(false)
f1_arg0.mapCategoriesList:setMouseDisabled(true)
f1_arg0.m_categorySet = false
else
f1_arg0.mapList:setMouseDisabled(true)
f1_arg0.mapCategoriesList:setMouseDisabled(false)
end
end)
f1_arg0.mapList:setMouseDisabled(true)
f1_arg0.mapList:registerEventHandler("leftclick_outside", function(element, event)
if IsSelfInState(f1_arg0, "SelectingMap") and f1_arg0.m_categorySet then
CoD.PCUtil.SimulateButtonPress(f1_arg1, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE)
end
f1_arg0.m_categorySet = true
return true
end)
end
end
local PostLoadFunc = function(f4_arg0, f4_arg1)
f0_local0(f4_arg0, f4_arg1)
end
local f0_local2 = 10000
local f0_local3 = 10001
local f0_local4 = function(f5_arg0)
local f5_local0 = CoD.mapsTable[f5_arg0]
if CoD.CONTENT_DLC6_INDEX <= f5_local0.dlc_pack or f5_arg0 == "mp_redwood_ice" or f5_arg0 == "mp_veiled_heyday" then
return f0_local3
elseif f5_local0.dlc_pack > 0 then
return f0_local2
else
return f5_local0.dlc_pack
end
end
DataSources.ChangeMapCategories = DataSourceHelpers.ListSetup("ChangeMapCategories", function(f6_arg0)
local f6_local0 = {}
local f6_local1 = CoD.GetMapValue(Engine.DvarString(nil, "ui_mapname"), "dlc_pack", CoD.CONTENT_ORIGINAL_MAP_INDEX)
local f6_local2 = function(f7_arg0, f7_arg1)
return {
models = {
text = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS"),
buttonText = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_CAPS"),
image = "playlist_map",
description = Engine.Localize("MPUI_MAP_CATEGORY_" .. f7_arg0 .. "_DESC")
},
properties = {
category = f7_arg1,
selectIndex = f6_local1 == f7_arg1
}
}
end
CoD.mapsTable = Engine.GetGDTMapsTable()
local f6_local3 = function(f8_arg0)
for f8_local3, f8_local4 in pairs(CoD.mapsTable) do
if f8_local4.session_mode == CoD.gameModeEnum and f0_local4(f8_local3) == f8_arg0 and (ShowPurchasableMap(f6_arg0, f8_local3) or Engine.IsMapValid(f8_local3)) then
return true
end
end
return false
end
if CoD.isCampaign == true then
table.insert(f6_local0, f6_local2("missions", CoD.CONTENT_ORIGINAL_MAP_INDEX))
table.insert(f6_local0, f6_local2("dev", CoD.CONTENT_DEV_MAP_INDEX))
else
table.insert(f6_local0, f6_local2("standard", CoD.CONTENT_ORIGINAL_MAP_INDEX))
if not Dvar.ui_execdemo:get() and f6_local3(f0_local2) then
table.insert(f6_local0, f6_local2("dlc", f0_local2))
end
if not Dvar.ui_execdemo:get() and f6_local3(f0_local3) then
table.insert(f6_local0, f6_local2("dlc_bonus", f0_local3))
end
if Mods_Enabled() then --and Engine.Mods_Lists_GetInfoEntries( LuaEnums.USERMAP_BASE_PATH, 0, Engine.Mods_Lists_GetInfoEntriesCount( LuaEnums.USERMAP_BASE_PATH ) ) ~= nil then
local f9_local11 = Engine.Mods_Lists_GetInfoEntries(LuaEnums.USERMAP_BASE_PATH, 0,
Engine.Mods_Lists_GetInfoEntriesCount(LuaEnums.USERMAP_BASE_PATH))
if f9_local11 then
for f9_local12 = 0, #f9_local11, 1 do
local f9_local17 = f9_local11[f9_local12]
if LUI.startswith(f9_local17.internalName, "mp_") then
table.insert(f6_local0, f6_local2("mods", CoD.CONTENT_MODS_INDEX))
end
end
end
end
end
return f6_local0
end, true)

View File

@@ -0,0 +1,260 @@
local f0_local0 = function(f1_arg0, f1_arg1)
if not CoD.useMouse then
return
else
f1_arg0.Options:setHandleMouse(true)
f1_arg0.Options:registerEventHandler("leftclick_outside", function(element, event)
CoD.PCUtil.SimulateButtonPress(event.controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE)
return true
end)
end
end
local PostLoadFunc = function(f3_arg0, f3_arg1)
f0_local0(f3_arg0, f3_arg1)
f3_arg0.disableBlur = true
f3_arg0.disablePopupOpenCloseAnim = true
Engine.SetModelValue(Engine.CreateModel(Engine.GetGlobalModel(), "GameSettingsFlyoutOpen"), true)
LUI.OverrideFunction_CallOriginalSecond(f3_arg0, "close", function(element)
Engine.SetModelValue(Engine.CreateModel(Engine.GetGlobalModel(), "GameSettingsFlyoutOpen"), false)
end)
f3_arg0:registerEventHandler("occlusion_change", function(element, event)
local f5_local0 = element:getParent()
if f5_local0 then
local f5_local1 = f5_local0:getFirstChild()
while f5_local1 ~= nil do
if f5_local1.menuName == "Lobby" then
break
end
f5_local1 = f5_local1:getNextSibling()
end
if f5_local1 then
if event.occluded == true then
f5_local1:setAlpha(0)
end
f5_local1:setAlpha(1)
end
end
element:OcclusionChange(event)
end)
f3_arg0:subscribeToModel(Engine.CreateModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNav", true), function(model)
local f6_local0 = f3_arg0.occludedBy
while f6_local0 do
if f6_local0.occludedBy ~= nil then
f6_local0 = f6_local0.occludedBy
end
while f6_local0 and f6_local0.menuName ~= "Lobby" do
f6_local0 = GoBack(f6_local0, f3_arg1)
end
Engine.SendClientScriptNotify(f3_arg1, "menu_change" .. Engine.GetLocalClientNum(f3_arg1), "Main",
"closeToMenu")
return
end
GoBack(f3_arg0, f3_arg1)
end, false)
end
DataSources.GameSettingsFlyoutButtonsCustom = DataSourceHelpers.ListSetup("GameSettingsFlyoutButtonsCustom",
function(f7_arg0)
local f7_local0 = {
{
optionDisplay = "MPUI_CHANGE_MAP_CAPS",
customId = "btnChangeMap",
action = OpenChangeMap
},
-- {
-- optionDisplay = "MPUI_CHANGE_GAME_MODE_CAPS",
-- customId = "btnChangeGameMode",
-- action = OpenChangeGameMode
-- },
{
optionDisplay = "MENU_SETUP_BOTS_CAPS",
customId = "btnSetupBots",
action = OpenBotSettings
},
{
optionDisplay = "MPUI_EDIT_GAME_RULES_CAPS",
customId = "btnEditGameRules",
action = OpenEditGameRules
}
}
-- if CoD.isPC and IsServerBrowserEnabled() then
-- table.insert( f7_local0, {
-- optionDisplay = "PLATFORM_SERVER_SETTINGS_CAPS",
-- customID = "btnServerSettings",
-- action = OpenServerSettings
-- } )
-- end
local f7_local1 = {}
for f7_local5, f7_local6 in ipairs(f7_local0) do
table.insert(f7_local1, {
models = {
displayText = Engine.Localize(f7_local6.optionDisplay),
customId = f7_local6.customId,
disabled = f7_local6.disabled
},
properties = {
title = f7_local6.optionDisplay,
desc = f7_local6.desc,
action = f7_local6.action,
actionParam = f7_local6.actionParam
}
})
end
return f7_local1
end, nil, nil, nil)
LUI.createMenu.GameSettingsFlyoutMPCustom = function(controller)
local self = CoD.Menu.NewForUIEditor("GameSettingsFlyoutMPCustom")
if PreLoadFunc then
PreLoadFunc(self, controller)
end
self.soundSet = "default"
self:setOwner(controller)
self:setLeftRight(true, true, 0, 0)
self:setTopBottom(true, true, 0, 0)
self:playSound("menu_open", controller)
self.buttonModel = Engine.CreateModel(Engine.GetModelForController(controller), "GameSettingsFlyoutMP.buttonPrompts")
self.anyChildUsesUpdateState = true
local Options = LUI.UIList.new(self, controller, -2, 0, nil, false, false, 0, 0, false, false)
Options:makeFocusable()
Options:setLeftRight(true, false, 243.43, 523.43)
Options:setTopBottom(true, false, 177.56, 329.56)
Options:setYRot(25)
Options:setWidgetType(CoD.FE_List1ButtonLarge_PH)
Options:setVerticalCount(3)
Options:setSpacing(-2)
Options:setDataSource("GameSettingsFlyoutButtonsCustom")
Options:registerEventHandler("gain_focus", function(element, event)
local f9_local0 = nil
if element.gainFocus then
f9_local0 = element:gainFocus(event)
elseif element.super.gainFocus then
f9_local0 = element.super:gainFocus(event)
end
CoD.Menu.UpdateButtonShownState(element, self, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS)
return f9_local0
end)
Options:registerEventHandler("lose_focus", function(element, event)
local f10_local0 = nil
if element.loseFocus then
f10_local0 = element:loseFocus(event)
elseif element.super.loseFocus then
f10_local0 = element.super:loseFocus(event)
end
return f10_local0
end)
self:AddButtonCallbackFunction(Options, controller, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "ENTER",
function(element, menu, controller, model)
ProcessListAction(self, element, controller)
return true
end, function(element, menu, controller)
CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBA_PSCROSS, "MENU_SELECT")
return true
end, false)
self:addElement(Options)
self.Options = Options
self:mergeStateConditions({
{
stateName = "Local",
condition = function(menu, element, event)
return IsLobbyNetworkModeLAN()
end
}
})
self:subscribeToModel(Engine.GetModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNetworkMode"), function(model)
local f14_local0 = self
local f14_local1 = {
controller = controller,
name = "model_validation",
modelValue = Engine.GetModelValue(model),
modelName = "lobbyRoot.lobbyNetworkMode"
}
CoD.Menu.UpdateButtonShownState(f14_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE)
end)
self:subscribeToModel(Engine.GetModel(Engine.GetGlobalModel(), "lobbyRoot.lobbyNav"), function(model)
local f15_local0 = self
local f15_local1 = {
controller = controller,
name = "model_validation",
modelValue = Engine.GetModelValue(model),
modelName = "lobbyRoot.lobbyNav"
}
CoD.Menu.UpdateButtonShownState(f15_local0, self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE)
end)
self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil,
function(element, menu, controller, model)
GoBack(self, controller)
ClearMenuSavedState(menu)
return true
end, function(element, menu, controller)
CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, "")
return false
end, false)
self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_START, "M",
function(element, menu, controller, model)
GoBackAndOpenOverlayOnParent(self, "StartMenu_Main", controller)
return true
end, function(element, menu, controller)
CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_START, "MENU_MENU")
return true
end, false)
self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "S",
function(element, menu, controller, model)
if not IsLAN() and not IsPlayerAGuest(controller) and IsPlayerAllowedToPlayOnline(controller) then
GoBackAndOpenOverlayOnParent(self, "Social_Main", controller)
return true
else
end
end, function(element, menu, controller)
if not IsLAN() and not IsPlayerAGuest(controller) and IsPlayerAllowedToPlayOnline(controller) then
CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBY_PSTRIANGLE, "")
return false
else
return false
end
end, false)
self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_LB, nil,
function(element, menu, controller, model)
SendButtonPressToOccludedMenu(menu, controller, model, Enum.LUIButton.LUI_KEY_LB)
return true
end, function(element, menu, controller)
CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_LB, "")
return false
end, false)
self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_RB, nil,
function(element, menu, controller, model)
SendButtonPressToOccludedMenu(menu, controller, model, Enum.LUIButton.LUI_KEY_RB)
return true
end, function(element, menu, controller)
CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_RB, "")
return false
end, false)
Options.id = "Options"
self:processEvent({
name = "menu_loaded",
controller = controller
})
self:processEvent({
name = "update_state",
menu = self
})
if not self:restoreState() then
self.Options:processEvent({
name = "gain_focus",
controller = controller
})
end
LUI.OverrideFunction_CallOriginalSecond(self, "close", function(element)
element.Options:close()
Engine.UnsubscribeAndFreeModel(Engine.GetModel(Engine.GetModelForController(controller),
"GameSettingsFlyoutMP.buttonPrompts"))
end)
if PostLoadFunc then
PostLoadFunc(self, controller)
end
return self
end

View File

@@ -0,0 +1,217 @@
DataSources.StartMenuTabs = ListHelper_SetupDataSource("StartMenuTabs", function(f44_arg0)
local f44_local0 = {}
table.insert(f44_local0, {
models = {
tabIcon = CoD.buttonStrings.shoulderl
},
properties = {
m_mouseDisabled = true
}
})
if Engine.IsDemoPlaying() then
local f44_local1 = "CoD.StartMenu_GameOptions"
if Engine.IsZombiesGame() then
f44_local1 = "CoD.StartMenu_GameOptions_ZM"
end
table.insert(f44_local0, {
models = {
tabName = Engine.Localize("MENU_THEATER_CAPS"),
tabWidget = f44_local1,
tabIcon = ""
},
properties = {
tabId = "gameOptions"
}
})
elseif Engine.IsInGame() then
if IsGameTypeDOA() and not InSafehouse() then
table.insert(f44_local0, {
models = {
tabName = "DOA",
tabWidget = "CoD.StartMenu_GameOptions_DOA",
tabIcon = ""
},
properties = {
tabId = "gameOptions"
}
})
elseif CoD.isCampaign then
table.insert(f44_local0, {
models = {
tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()),
tabWidget = "CoD.StartMenu_GameOptions_CP",
tabIcon = ""
},
properties = {
tabId = "gameOptions"
}
})
if not Engine.IsCampaignModeZombies() then
if CoD.isSafehouse and CoD.isOnlineGame() and not IsInTrainingSim(f44_arg0) and Dvar.ui_safehousebarracks:get() and not IsPlayerAGuest(f44_arg0) then
table.insert(f44_local0, {
models = {
tabName = "CPUI_BARRACKS_CAPS",
tabWidget = "CoD.CombatRecordCP_Contents",
tabIcon = ""
},
properties = {
tabId = "combatRecord"
}
})
end
if HighestMapReachedGreaterThan(f44_arg0, 1) or LUI.DEV ~= nil then
table.insert(f44_local0, {
models = {
tabName = "CPUI_TACTICAL_MODE_CAPS",
tabWidget = "CoD.StartMenu_TacticalMode",
tabIcon = ""
},
properties = {
tabId = "tacticalMode"
}
})
end
if not CoD.isSafehouse and not IsPlayerAGuest(f44_arg0) then
table.insert(f44_local0, {
models = {
tabName = "CPUI_ACCOLADES",
tabWidget = "CoD.MissionRecordVault_Challenges",
tabIcon = ""
},
properties = {
tabId = "accolades"
}
})
end
end
elseif Engine.IsZombiesGame() then
table.insert(f44_local0, {
models = {
tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()),
tabWidget = "CoD.StartMenu_GameOptions_ZM",
tabIcon = ""
},
properties = {
tabId = "gameOptions"
}
})
else
table.insert(f44_local0, {
models = {
tabName = SessionModeToUnlocalizedSessionModeCaps(Engine.CurrentSessionMode()),
tabWidget = "CoD.StartMenu_GameOptions",
tabIcon = ""
},
properties = {
tabId = "gameOptions"
}
})
end
else
if not IsPlayerAGuest(f44_arg0) then
table.insert(f44_local0, {
models = {
tabName = "MENU_TAB_IDENTITY_CAPS",
tabWidget = "CoD.StartMenu_Identity",
tabIcon = ""
},
properties = {
tabId = "identity",
disabled = Dvar.ui_execdemo_gamescom:get()
}
})
end
if not IsLobbyNetworkModeLAN() and not Dvar.ui_execdemo:get() and not Engine.IsCampaignModeZombies() and not IsPlayerAGuest(f44_arg0) then
table.insert(f44_local0, {
models = {
tabName = "MENU_TAB_CHALLENGES_CAPS",
tabWidget = "CoD.StartMenu_Challenges",
tabIcon = ""
},
properties = {
tabId = "challenges"
}
})
local f44_local1 = CoD.isPC
if f44_local1 then
f44_local1 = false --Mods_IsUsingMods()
end
table.insert(f44_local0, {
models = {
tabName = "MENU_TAB_BARRACKS_CAPS",
tabWidget = "CoD.StartMenu_Barracks",
tabIcon = "",
disabled = f44_local1
},
properties = {
tabId = "barracks"
}
})
if CommunityOptionsEnabled() then
local f44_local2 = CoD.perController[f44_arg0].openMediaTabAfterClosingGroups
CoD.perController[f44_arg0].openMediaTabAfterClosingGroups = false
table.insert(f44_local0, {
models = {
tabName = "MENU_TAB_MEDIA_CAPS",
tabWidget = "CoD.StartMenu_Media",
tabIcon = ""
},
properties = {
tabId = "media",
selectIndex = f44_local2
}
})
end
end
end
if IsGameTypeDOA() and Engine.IsInGame() and not InSafehouse() then
local f44_local1 = table.insert
local f44_local2 = f44_local0
local f44_local3 = {
models = {
tabName = "MENU_TAB_OPTIONS_CAPS",
tabWidget = "CoD.StartMenu_Options_DOA",
tabIcon = ""
}
}
local f44_local4 = {
tabId = "options"
}
local f44_local5 = Dvar.ui_execdemo:get()
if f44_local5 then
f44_local5 = not Engine.IsInGame()
end
f44_local4.selectIndex = f44_local5
f44_local3.properties = f44_local4
f44_local1(f44_local2, f44_local3)
else
local f44_local1 = table.insert
local f44_local2 = f44_local0
local f44_local3 = {
models = {
tabName = "MENU_TAB_OPTIONS_CAPS",
tabWidget = "CoD.StartMenu_Options",
tabIcon = ""
}
}
local f44_local4 = {
tabId = "options"
}
local f44_local5 = Dvar.ui_execdemo_gamescom:get()
if f44_local5 then
f44_local5 = not Engine.IsInGame()
end
f44_local4.selectIndex = f44_local5
f44_local3.properties = f44_local4
f44_local1(f44_local2, f44_local3)
end
table.insert(f44_local0, {
models = {
tabIcon = CoD.buttonStrings.shoulderr
},
properties = {
m_mouseDisabled = true
}
})
return f44_local0
end, true)

View File

@@ -0,0 +1,160 @@
local IsGamescomDemo = function()
return Dvar.ui_execdemo_gamescom:get()
end
local IsBetaDemo = function()
return Dvar.ui_execdemo_beta:get()
end
local SetButtonState = function(button, state)
if state == nil then
return
elseif state == CoD.LobbyButtons.DISABLED then
button.disabled = true
elseif state == CoD.LobbyButtons.HIDDEN then
button.hidden = true
end
end
local RemoveButton = function(buttonTable, button)
if not button then
return
end
for id, v in pairs(buttonTable) do
if buttonTable[id].optionDisplay == button.stringRef then
table.remove(buttonTable, id)
end
end
end
local RemoveSpaces = function(buttonTable)
for id, v in pairs(buttonTable) do
buttonTable[id].isLastButtonInGroup = false
end
end
local GetButtonIndex = function(buttonTable, button)
if not button then
return nil
end
for id, v in pairs(buttonTable) do
if buttonTable[id].optionDisplay == button.stringRef then
return id
end
end
end
local AddButton = function(controller, options, button, isLargeButton, index)
if button == nil then
return
end
button.disabled = false
button.hidden = false
button.selected = false
button.warning = false
if button.defaultState ~= nil then
if button.defaultState == CoD.LobbyButtons.DISABLED then
button.disabled = true
elseif button.defaultState == CoD.LobbyButtons.HIDDEN then
button.hidden = true
end
end
if button.disabledFunc ~= nil then
button.disabled = button.disabledFunc(controller)
end
if button.visibleFunc ~= nil then
button.hidden = not button.visibleFunc(controller)
end
if IsBetaDemo() then
SetButtonState(button, button.demo_beta)
elseif IsGamescomDemo() then
SetButtonState(button, button.demo_gamescom)
end
if button.hidden then
return
end
local lobbyNav = LobbyData.GetLobbyNav()
if button.selectedFunc ~= nil then
button.selected = button.selectedFunc(button.selectedParam)
elseif CoD.LobbyMenus.History[lobbyNav] ~= nil then
button.selected = CoD.LobbyMenus.History[lobbyNav] == button.customId
end
if button.newBreadcrumbFunc then
local f8_local1 = button.newBreadcrumbFunc
if type(f8_local1) == "string" then
f8_local1 = LUI.getTableFromPath(f8_local1)
end
if f8_local1 then
button.isBreadcrumbNew = f8_local1(controller)
end
end
if button.warningFunc ~= nil then
button.warning = button.warningFunc(controller)
end
if button.starterPack == CoD.LobbyButtons.STARTERPACK_UPGRADE then
button.starterPackUpgrade = true
if IsStarterPack() then
button.disabled = false
end
end
if index ~= nil then
table.insert(options, index, {
optionDisplay = button.stringRef,
action = button.action,
param = button.param,
customId = button.customId,
isLargeButton = isLargeButton,
isLastButtonInGroup = false,
disabled = button.disabled,
selected = button.selected,
isBreadcrumbNew = button.isBreadcrumbNew,
warning = button.warning,
requiredChunk = button.selectedParam,
starterPackUpgrade = button.starterPackUpgrade,
unloadMod = button.unloadMod
})
else
table.insert(options, {
optionDisplay = button.stringRef,
action = button.action,
param = button.param,
customId = button.customId,
isLargeButton = isLargeButton,
isLastButtonInGroup = false,
disabled = button.disabled,
selected = button.selected,
isBreadcrumbNew = button.isBreadcrumbNew,
warning = button.warning,
requiredChunk = button.selectedParam,
starterPackUpgrade = button.starterPackUpgrade,
unloadMod = button.unloadMod
})
end
end
local AddLargeButton = function(controller, options, button, index)
AddButton(controller, options, button, true, index)
end
local AddSmallButton = function(controller, options, button, index)
AddButton(controller, options, button, false, index)
end
local AddSpacer = function(options, index)
if index ~= nil then
options[index].isLastButtonInGroup = true
elseif 0 < #options then
options[#options].isLastButtonInGroup = true
end
end
return {
AddButton = AddButton,
AddLargeButton = AddLargeButton,
AddSmallButton = AddSmallButton,
AddSpacer = AddSpacer,
RemoveButton = RemoveButton,
RemoveSpaces = RemoveSpaces,
GetButtonIndex = GetButtonIndex
}

View File

@@ -0,0 +1,148 @@
DataSources.OptionGraphicsVideo = DataSourceHelpers.ListSetup( "PC.OptionGraphicsVideo", function ( controller )
local videoSettings = {}
table.insert( videoSettings, {
models = {
label = "PLATFORM_DISPLAY_MODE",
description = "PLATFORM_DISPLAY_MODE_DESC",
profileVarName = "r_fullscreen",
datasource = "OptionPCGraphicsDisplayMode",
widgetType = "dropdown"
},
properties = CoD.PCUtil.DependantDropdownProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_MONITOR",
description = "PLATFORM_MONITOR_DESC",
profileVarName = "r_monitor",
datasource = "OptionPCGraphicsMonitor",
widgetType = "dropdown",
disabledFunction = function ()
return Engine.GetHardwareProfileValueAsString( "r_fullscreen" ) == "0"
end
},
properties = CoD.PCUtil.DependantDropdownProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_SCREEN_RESOLUTION",
description = "PLATFORM_SCREEN_RESOLUTION_DESC",
profileVarName = "r_mode",
datasource = "OptionPCGraphicsScreenResolution",
widgetType = "dropdown",
disabledFunction = function ()
return Engine.GetHardwareProfileValueAsString( "r_fullscreen" ) == "2"
end
},
properties = CoD.PCUtil.DependantDropdownProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_REFRESH_RATE",
description = "PLATFORM_REFRESH_RATE_DESC",
profileVarName = "r_refreshRate",
datasource = "OptionPCGraphicsRefreshRate",
widgetType = "dropdown",
disabledFunction = function ()
return Engine.GetHardwareProfileValueAsString( "r_fullscreen" ) ~= "1"
end
},
properties = CoD.PCUtil.OptionsGenericDropdownProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_SCENE_RESOLUTION_RATIO",
description = "PLATFORM_SCENE_RESOLUTION_RATIO_DESC",
profileVarName = "r_sceneResolutionMultiplier",
datasource = "OptionPCGraphicsSceneResolution",
widgetType = "dropdown"
},
properties = CoD.PCUtil.DependantDropdownProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_DISPLAY_GAMMA",
description = "PLATFORM_DISPLAY_GAMMA_DESC",
profileVarName = "r_videoMode",
datasource = "OptionPCGraphicsDisplayGamma",
widgetType = "dropdown"
},
properties = CoD.PCUtil.OptionsGenericDropdownProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_BRIGHTNESS",
description = "PLATFORM_BRIGHTNESS_DESC",
profileVarName = "r_sceneBrightness",
profileType = "user",
lowValue = -1,
highValue = 1,
widgetType = "slider"
},
properties = CoD.PCUtil.OptionsGenericSliderProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_FOV",
description = "PLATFORM_FOV_DESC",
profileVarName = "cg_fov_default",
lowValue = 65,
highValue = 120,
useIntegerDisplay = 1,
widgetType = "slider"
},
properties = CoD.PCUtil.OptionsGenericSliderProperties
} )
table.insert( videoSettings, {
models = {
widgetType = "spacer",
height = 32
}
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_MAX_FPS",
description = "PLATFORM_MAX_FPS_DESC",
profileVarName = "com_maxfps",
lowValue = 24,
highValue = 500,
useIntegerDisplay = 1,
widgetType = "slider"
},
properties = CoD.PCUtil.OptionsGenericSliderProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_SYNC_EVERY_FRAME",
description = "PLATFORM_VSYNC_DESC",
profileVarName = "r_vsync",
widgetType = "checkbox"
},
properties = CoD.PCUtil.OptionsGenericCheckboxProperties
} )
table.insert( videoSettings, {
models = {
label = "PLATFORM_DRAW_FPS",
description = "PLATFORM_DRAW_FPS_DESC",
profileVarName = "com_drawFPS_PC",
widgetType = "checkbox"
},
properties = CoD.PCUtil.OptionsGenericCheckboxProperties
} )
return videoSettings
end, true )
DataSources.OptionGraphicsVideo.getWidgetTypeForItem = function ( list, dataItemModel, row )
if dataItemModel then
local widgetType = Engine.GetModelValue( Engine.GetModel( dataItemModel, "widgetType" ) )
if widgetType == "dropdown" then
return CoD.OptionDropdown
elseif widgetType == "checkbox" then
return CoD.StartMenu_Options_CheckBoxOption
elseif widgetType == "slider" then
return CoD.StartMenu_Options_SliderBar
elseif widgetType == "spacer" then
return CoD.VerticalListSpacer
end
end
return nil
end

View File

@@ -0,0 +1,4 @@
-- Fix LUI_NULL_FUNCTION messages
function Engine.PIXBeginEvent() end
function Engine.PIXEndEvent() end

View File

@@ -0,0 +1,30 @@
local modeInfo = LobbyData:UITargetFromId(Engine.GetLobbyUIScreen())
local maxClients = modeInfo.maxClients
-- Disable setting party privacy in menu. Auto set to open + max.
Engine.SetDvar("partyprivacyenabled", 0)
Engine.SetDvar("tu4_partyprivacyuseglobal", 0)
Engine.SetDvar("tu4_partyprivacyluacheck", 0)
-- Fix for invisible bots in custom games
if maxClients >= 1 then
Engine.SetDvar("party_maxplayers", maxClients)
end
if not Engine.IsInGame() then
return
end
-- Removed check for public matches to allow team change in ranked matches
CoD.IsTeamChangeAllowed = function()
if Engine.GetGametypeSetting("allowInGameTeamChange") == 1 then
return true
else
return false
end
end
-- Set com_maxclients InGame so players can join via direct connect (default from lobbydata)
Engine.SetDvar("com_maxclients", maxClients)
require("datasources_start_menu_game_options")

View File

@@ -0,0 +1,75 @@
DataSources.StartMenuGameOptions = ListHelper_SetupDataSource("StartMenuGameOptions", function (controller)
local options = {}
if Engine.IsDemoPlaying() then
if not IsDemoRestrictedBasicMode() then
table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_UPLOAD_CLIP", Engine.GetDemoSegmentCount())), action = StartMenuUploadClip, disabledFunction = IsUploadClipButtonDisabled}, properties = {hideHelpItemLabel = true}})
end
if Engine.IsDemoHighlightReelMode() then
table.insert(options, {models = {displayText = Engine.ToUpper(Engine.Localize("MENU_DEMO_CUSTOMIZE_HIGHLIGHT_REEL")), action = StartMenuOpenCustomizeHighlightReel, disabledFunction = IsCustomizeHighlightReelButtonDisabled}})
end
table.insert(options, {models = {displayText = Engine.ToUpper(Engine.ToUpper(Engine.Localize("MENU_JUMP_TO_START"))), action = StartMenuJumpToStart, disabledFunction = IsJumpToStartButtonDisabled}, properties = {hideHelpItemLabel = true}})
local endDemoButtonText = nil
if Engine.IsDemoClipPlaying() then
endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_CLIP"))
else
endDemoButtonText = Engine.ToUpper(Engine.Localize("MENU_END_FILM"))
end
table.insert(options, {models = {displayText = Engine.ToUpper(endDemoButtonText), action = StartMenuEndDemo}})
elseif CoD.isCampaign then
table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}})
local inTrainingSim = CoD.SafeGetModelValue(Engine.GetModelForController(controller), "safehouse.inTrainingSim")
if not inTrainingSim then
inTrainingSim = 0
end
if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) then
if not CoD.isSafehouse and controller == Engine.GetPrimaryController() then
table.insert(options, {models = {displayText = "MENU_RESTART_MISSION_CAPS", action = RestartMission}})
if LUI.DEV ~= nil then
table.insert(options, {models = {displayText = "MENU_RESTART_CHECKPOINT_CAPS", action = RestartFromCheckpoint}})
end
end
if controller == Engine.GetPrimaryController() then
table.insert(options, {models = {displayText = "MENU_CHANGE_DIFFICULTY_CAPS", action = OpenDifficultySelect}})
end
if CoD.isSafehouse and inTrainingSim == 1 then
table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}})
elseif controller == Engine.GetPrimaryController() then
if Engine.DvarBool(0, "ui_blocksaves") then
table.insert(options, {models = {displayText = "MENU_EXIT_CAPS", action = SaveAndQuitGame}})
else
table.insert(options, {models = {displayText = "MENU_SAVE_AND_QUIT_CAPS", action = SaveAndQuitGame}})
end
end
elseif CoD.isSafehouse and inTrainingSim == 1 then
table.insert(options, {models = {displayText = "MENU_END_TRAINING_SIM", action = EndTrainingSim}})
else
table.insert(options, {models = {displayText = "MENU_LEAVE_PARTY_AND_EXIT_CAPS", action = QuitGame}})
end
elseif CoD.isMultiplayer then
if Engine.Team(controller, "name") ~= "TEAM_SPECTATOR" and Engine.GetGametypeSetting("disableClassSelection") ~= 1 then
table.insert(options, {models = {displayText = "MPUI_CHOOSE_CLASS_BUTTON_CAPS", action = ChooseClass}})
end
if not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_ROUND_END_KILLCAM) and not Engine.IsVisibilityBitSet(controller, Enum.UIVisibilityBit.BIT_FINAL_KILLCAM) and CoD.IsTeamChangeAllowed() then
table.insert(options, {models = {displayText = "MPUI_CHANGE_TEAM_BUTTON_CAPS", action = ChooseTeam}})
end
if controller == 0 then
local endGameText = "MENU_QUIT_GAME_CAPS"
if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and not CoD.isOnlineGame() then
endGameText = "MENU_END_GAME_CAPS"
end
table.insert(options, {models = {displayText = endGameText, action = QuitGame_MP}})
end
elseif CoD.isZombie then
table.insert(options, {models = {displayText = "MENU_RESUMEGAME_CAPS", action = StartMenuGoBack_ListElement}})
if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) and (not Engine.SessionModeIsMode(CoD.SESSIONMODE_SYSTEMLINK) or Engine.SessionModeIsMode(CoD.SESSIONMODE_OFFLINE)) then
table.insert(options, {models = {displayText = "MENU_RESTART_LEVEL_CAPS", action = RestartGame}})
end
if Engine.IsLobbyHost(Enum.LobbyType.LOBBY_TYPE_GAME) == true then
table.insert(options, {models = {displayText = "MENU_END_GAME_CAPS", action = QuitGame_MP}})
else
table.insert(options, {models = {displayText = "MENU_QUIT_GAME_CAPS", action = QuitGame_MP}})
end
end
table.insert(options, {models = {displayText = "QUIT TO DESKTOP", action = OpenPCQuit}})
return options
end, true)

View File

@@ -0,0 +1,34 @@
if Engine.GetCurrentMap() ~= "core_frontend" then
return
end
if CoD.LobbyMember then
local oldLobbyMember = CoD.LobbyMember.new
function CoD.LobbyMember.new(menu, controller)
local self = oldLobbyMember(menu, controller)
-- Hide the playlist count text
if self.SearchingForPlayer then
self.SearchingForPlayer:setAlpha(0)
end
if self.FEMemberBlurPanelContainer0 then
self.FEMemberBlurPanelContainer0:setAlpha(0)
end
return self
end
end
function IsLobbyStatusVisible()
return false
end
Engine.SetDvar("lobbyMigrate_Enabled", 0)
Engine.SetDvar("lobbyTimerStatusVotingInterval", 11000)
Engine.SetDvar("lobbyTimerStatusBeginInterval", 10)
Engine.SetDvar("lobbyTimerStatusStartInterval", 10)
Engine.SetDvar("lobbyTimerStatusPostGameInterval", 10)
Engine.SetDvar("lobbyTimerStatusVotingInterval_Arena", 11000)
require("widget_playlist_match_settings_info")
require("widget_playlist_category_match_settings_info")

View File

@@ -0,0 +1,15 @@
if not CoD.playlistCategoryMatchSettingsInfo then
return
end
local oldPlaylistCategoryMatchSettingsInfo = CoD.playlistCategoryMatchSettingsInfo.new
function CoD.playlistCategoryMatchSettingsInfo.new(menu, controller)
local self = oldPlaylistCategoryMatchSettingsInfo(menu, controller)
-- Hide the playlist count text
if self.playlistCount then
self.playlistCount:setAlpha(0)
end
return self
end

View File

@@ -0,0 +1,15 @@
if not CoD.playlistMatchSettingsInfo then
return
end
local oldPlaylistMatchSettingsInfo = CoD.playlistMatchSettingsInfo.new
function CoD.playlistMatchSettingsInfo.new(menu, controller)
local self = oldPlaylistMatchSettingsInfo(menu, controller)
-- Hide the playlist count text
if self.playlistCount then
self.playlistCount:setAlpha(0)
end
return self
end

View File

@@ -0,0 +1 @@
require("online_mods_loaded")

View File

@@ -0,0 +1,23 @@
if Engine.GetCurrentMap() ~= "core_frontend" then
return
end
function ShouldUnloadMod(arg0)
return false
end
-- Load usermaps mod if custom map selected
local mustLoadUsermaps = function(element, controller)
if CoD.perController[controller].mapCategory == CoD.CONTENT_MODS_INDEX then
if not Engine.IsUsingMods() then
LuaUtils.Mods_LoadMod("usermaps") -- LuaUtils.Mods_LoadMod(element.loadModName)
CoD.OverlayUtility.ShowToast("DefaultState", Engine.Localize("MENU_MODS_CAPS"), Engine.Localize("PLATFORM_MODS_LOADED") .. " " .. element.mapName)
end
end
end
function MapSelected(element, controller)
SetMap(controller, element.mapName, false)
mustLoadUsermaps(element, controller)
end

View File

@@ -0,0 +1,378 @@
if Engine.GetCurrentMap() ~= "core_frontend" then
return
end
function IsServerBrowserEnabled()
return true
end
DataSources.LobbyServer = {
prepare = function(controller, list, filter)
list.numElementsInList = list.vCount
list.controller = controller
list.serverBrowserRootModel = Engine.CreateModel(Engine.GetGlobalModel(), "serverBrowser")
local serverListCountModel = Engine.GetModel(list.serverBrowserRootModel, "serverListCount")
if serverListCountModel then
list.serverCount = Engine.GetModelValue(serverListCountModel)
else
list.serverCount = 0
end
list.servers = {}
local serversModel = Engine.CreateModel(list.serverBrowserRootModel, "servers")
for i = 1, list.numElementsInList, 1 do
list.servers[i] = {}
list.servers[i].root = Engine.CreateModel(serversModel, "server_" .. i)
list.servers[i].model = Engine.CreateModel(list.servers[i].root, "model")
end
list.updateModels = function(controller, list, offset)
local serverInfo = Engine.SteamServerBrowser_GetServerInfo(offset)
if serverInfo then
local SetModelValue = function(model, key, value)
local model = Engine.CreateModel(model, key)
if model then
Engine.SetModelValue(model, value)
end
end
local elementIndex = offset % list.numElementsInList + 1
local serverModel = list.servers[elementIndex].model
SetModelValue(serverModel, "serverIndex", serverInfo.serverIndex)
SetModelValue(serverModel, "connectAddr", serverInfo.connectAddr)
SetModelValue(serverModel, "ping", serverInfo.ping)
SetModelValue(serverModel, "modName", serverInfo.modName)
SetModelValue(serverModel, "mapName", serverInfo.map)
SetModelValue(serverModel, "desc", serverInfo.desc)
-- Change the client count to be the actual player count
local clientCount = serverInfo.playerCount - serverInfo.botCount
SetModelValue(serverModel, "clientCount", clientCount)
SetModelValue(serverModel, "maxClients", serverInfo.maxPlayers)
SetModelValue(serverModel, "passwordProtected", serverInfo.password)
SetModelValue(serverModel, "secure", serverInfo.secure)
SetModelValue(serverModel, "name", serverInfo.name)
SetModelValue(serverModel, "gameType", serverInfo.gametype)
SetModelValue(serverModel, "dedicated", serverInfo.dedicated)
SetModelValue(serverModel, "ranked", serverInfo.ranked)
SetModelValue(serverModel, "hardcore", serverInfo.hardcore)
SetModelValue(serverModel, "zombies", serverInfo.zombies)
-- Add the bot count
SetModelValue(serverModel, "botCount", serverInfo.botCount)
return serverModel
else
return nil
end
end
if list.serverListUpdateSubscription then
list:removeSubscription(list.serverListUpdateSubscription)
end
local serverListUpdateModel = Engine.CreateModel(list.serverBrowserRootModel, "serverListCount")
list.serverListUpdateSubscription = list:subscribeToModel(serverListUpdateModel, function(model)
list:updateDataSource(false, false)
end, false)
if list.serverListSortTypeSubscription then
list:removeSubscription(list.serverListSortTypeSubscription)
end
local serverListSortTypeModel = Engine.CreateModel(list.serverBrowserRootModel, "serverListSortType")
list.serverListSortTypeSubscription = list:subscribeToModel(serverListSortTypeModel, function(model)
list:updateDataSource(false, false)
end, false)
end,
getCount = function(list)
return list.serverCount
end,
getItem = function(controller, list, index)
local offset = index - 1
return list.updateModels(controller, list, offset)
end,
cleanup = function(list)
if list.serverBrowserRootModel then
Engine.UnsubscribeAndFreeModel(list.serverBrowserRootModel)
list.serverBrowserRootModel = nil
end
end
}
CoD.ServerBrowserRowInternal.new = function(menu, controller)
local self = LUI.UIHorizontalList.new({
left = 0,
top = 0,
right = 0,
bottom = 0,
leftAnchor = true,
topAnchor = true,
rightAnchor = true,
bottomAnchor = true,
spacing = 2
})
self:setAlignment(LUI.Alignment.Left)
if PreLoadFunc then
PreLoadFunc(self, controller)
end
self:setUseStencil(false)
self:setClass(CoD.ServerBrowserRowInternal)
self.id = "ServerBrowserRowInternal"
self.soundSet = "default"
self:setLeftRight(true, false, 0, 700)
self:setTopBottom(true, false, 0, 22)
self:makeFocusable()
self.onlyChildrenFocusable = true
self.anyChildUsesUpdateState = true
local passwordFlag = CoD.ServerBrowserFlag.new(menu, controller)
passwordFlag:setLeftRight(true, false, 0, 28)
passwordFlag:setTopBottom(true, true, 0, 0)
passwordFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_protected"))
passwordFlag:linkToElementModel(self, nil, false, function(model)
passwordFlag:setModel(model, controller)
end)
passwordFlag:mergeStateConditions({
{
stateName = "FlagOn",
condition = function(menu, element, event)
return IsSelfModelValueTrue(element, controller, "passwordProtected")
end
}
})
passwordFlag:linkToElementModel(passwordFlag, "passwordProtected", true, function(model)
menu:updateElementState(passwordFlag, {
name = "model_validation",
menu = menu,
modelValue = Engine.GetModelValue(model),
modelName = "passwordProtected"
})
end)
self:addElement(passwordFlag)
self.passwordFlag = passwordFlag
local dedicatedFlag = CoD.ServerBrowserFlag.new(menu, controller)
dedicatedFlag:setLeftRight(true, false, 30, 58)
dedicatedFlag:setTopBottom(true, true, 0, 0)
dedicatedFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_dedicated"))
dedicatedFlag:linkToElementModel(self, nil, false, function(model)
dedicatedFlag:setModel(model, controller)
end)
dedicatedFlag:mergeStateConditions({
{
stateName = "FlagOn",
condition = function(menu, element, event)
return IsSelfModelValueTrue(element, controller, "dedicated")
end
}
})
dedicatedFlag:linkToElementModel(dedicatedFlag, "dedicated", true, function(model)
menu:updateElementState(dedicatedFlag, {
name = "model_validation",
menu = menu,
modelValue = Engine.GetModelValue(model),
modelName = "dedicated"
})
end)
self:addElement(dedicatedFlag)
self.dedicatedFlag = dedicatedFlag
local rankedFlag = CoD.ServerBrowserFlag.new(menu, controller)
rankedFlag:setLeftRight(true, false, 60, 88)
rankedFlag:setTopBottom(true, true, 0, 0)
rankedFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_ranked"))
rankedFlag:linkToElementModel(self, nil, false, function(model)
rankedFlag:setModel(model, controller)
end)
rankedFlag:mergeStateConditions({
{
stateName = "FlagOn",
condition = function(menu, element, event)
return IsSelfModelValueTrue(element, controller, "ranked")
end
}
})
rankedFlag:linkToElementModel(rankedFlag, "ranked", true, function(model)
menu:updateElementState(rankedFlag, {
name = "model_validation",
menu = menu,
modelValue = Engine.GetModelValue(model),
modelName = "ranked"
})
end)
self:addElement(rankedFlag)
self.rankedFlag = rankedFlag
local name = CoD.horizontalScrollingTextBox_18pt.new(menu, controller)
name:setLeftRight(true, false, 90, 330)
name:setTopBottom(true, false, 2, 20)
name.textBox:setTTF("fonts/default.ttf")
name.textBox:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT)
name:linkToElementModel(self, "name", true, function(model)
local _name = Engine.GetModelValue(model)
if _name then
name.textBox:setText(Engine.Localize(_name))
end
end)
self:addElement(name)
self.name = name
local spacer = LUI.UIFrame.new(menu, controller, 0, 0, false)
spacer:setLeftRight(true, false, 332, 339)
spacer:setTopBottom(true, false, 0, 22)
spacer:setAlpha(0)
self:addElement(spacer)
self.spacer = spacer
local map = CoD.horizontalScrollingTextBox_18pt.new(menu, controller)
map:setLeftRight(true, false, 341, 446)
map:setTopBottom(true, false, 2, 20)
map.textBox:setTTF("fonts/default.ttf")
map.textBox:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT)
map:linkToElementModel(self, "mapName", true, function(model)
local mapName = Engine.GetModelValue(model)
if mapName then
map.textBox:setText(MapNameToLocalizedMapName(mapName))
end
end)
self:addElement(map)
self.map = map
local hardcoreFlag = CoD.ServerBrowserFlag.new(menu, controller)
hardcoreFlag:setLeftRight(true, false, 448, 470)
hardcoreFlag:setTopBottom(true, true, 0, 0)
hardcoreFlag.icon:setImage(RegisterImage("uie_t7_icon_serverbrowser_skull"))
hardcoreFlag:linkToElementModel(self, nil, false, function(model)
hardcoreFlag:setModel(model, controller)
end)
hardcoreFlag:mergeStateConditions({
{
stateName = "FlagOn",
condition = function(menu, element, event)
return IsSelfModelValueTrue(element, controller, "hardcore")
end
}
})
hardcoreFlag:linkToElementModel(hardcoreFlag, "hardcore", true, function(model)
menu:updateElementState(hardcoreFlag, {
name = "model_validation",
menu = menu,
modelValue = Engine.GetModelValue(model),
modelName = "hardcore"
})
end)
self:addElement(hardcoreFlag)
self.hardcoreFlag = hardcoreFlag
local gametype = LUI.UIText.new()
gametype:setLeftRight(true, false, 472, 576)
gametype:setTopBottom(true, false, 2, 20)
gametype:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf")
gametype:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT)
gametype:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP)
gametype:linkToElementModel(self, "gameType", true, function(model)
local gameType = Engine.GetModelValue(model)
if gameType then
gametype:setText(Engine.Localize(GetGameTypeDisplayString(gameType)))
end
end)
self:addElement(gametype)
self.gametype = gametype
local playerCount = LUI.UIText.new()
playerCount:setLeftRight(true, false, 593, 613)
playerCount:setTopBottom(true, false, 2, 20)
playerCount:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf")
playerCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_RIGHT)
playerCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP)
playerCount:linkToElementModel(self, "clientCount", true, function(model)
local clientCount = Engine.GetModelValue(model)
if clientCount then
playerCount:setText(Engine.Localize(clientCount))
end
end)
self:addElement(playerCount)
self.playerCount = playerCount
local slash = LUI.UIText.new()
slash:setLeftRight(true, false, 615, 624)
slash:setTopBottom(true, false, 2, 20)
slash:setText(Engine.Localize("/"))
slash:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf")
slash:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT)
slash:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP)
self:addElement(slash)
self.slash = slash
local maxPlayers = LUI.UIText.new()
maxPlayers:setLeftRight(true, false, 626, 645)
maxPlayers:setTopBottom(true, false, 2, 20)
maxPlayers:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf")
maxPlayers:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT)
maxPlayers:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP)
maxPlayers:linkToElementModel(self, "maxClients", true, function(model)
local maxClients = Engine.GetModelValue(model)
if maxClients then
maxPlayers:setText(Engine.Localize(maxClients))
end
end)
self:addElement(maxPlayers)
self.maxPlayers = maxPlayers
local botCount = LUI.UIText.new()
botCount:setLeftRight(true, false, 637, 659)
botCount:setTopBottom(true, false, 2, 20)
botCount:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf")
botCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_LEFT)
botCount:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP)
botCount:linkToElementModel(self, "botCount", true, function(model)
local _botCount = Engine.GetModelValue(model)
if _botCount then
botCount:setText("[" .. Engine.Localize(_botCount) .. "]")
end
end)
botCount:linkToElementModel(self, "zombies", true, function(model)
local zombies = Engine.GetModelValue(model)
if zombies ~= nil then
botCount:setAlpha(zombies and 0 or 1)
end
end)
self:addElement(botCount)
self.botCount = botCount
local ping = LUI.UIText.new()
ping:setLeftRight(true, false, 661, 699.37)
ping:setTopBottom(true, false, 2, 20)
ping:setTTF("fonts/RefrigeratorDeluxe-Regular.ttf")
ping:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_CENTER)
ping:setAlignment(Enum.LUIAlignment.LUI_ALIGNMENT_TOP)
ping:linkToElementModel(self, "ping", true, function(model)
local _ping = Engine.GetModelValue(model)
if _ping then
ping:setText(Engine.Localize(_ping))
end
end)
self:addElement(ping)
self.ping = ping
spacer.id = "spacer"
self:registerEventHandler("gain_focus", function(self, event)
if self.m_focusable and self.spacer:processEvent(event) then
return true
else
return LUI.UIElement.gainFocus(self, event)
end
end)
LUI.OverrideFunction_CallOriginalSecond(self, "close", function(element)
element.passwordFlag:close()
element.dedicatedFlag:close()
element.rankedFlag:close()
element.name:close()
element.map:close()
element.hardcoreFlag:close()
element.gametype:close()
element.playerCount:close()
element.maxPlayers:close()
element.botCount:close()
element.ping:close()
end)
if PostLoadFunc then
PostLoadFunc(self, controller, menu)
end
return self
end

View File

@@ -0,0 +1,421 @@
if Engine.GetCurrentMap() ~= "core_frontend" then
return
end
DataSources.MPStatsSettings = DataSourceHelpers.ListSetup("MPStatsSettings", function(controller)
local optionsTable = {}
local updateDvar = function(f1_arg0, f1_arg1, f1_arg2, dvarName, f1_arg4)
local oldValue = Engine.DvarInt(nil, dvarName)
local newValue = f1_arg1.value
UpdateInfoModels(f1_arg1)
if oldValue == newValue then
return
end
Engine.SetDvar(dvarName, f1_arg1.value)
if dvarName == "cg_unlockall_loot" then
Engine.SetDvar("ui_enableAllHeroes", f1_arg1.value)
end
if dvarName == "all_ee_completed" then
Engine.ExecNow(f1_arg0, "statsetbyname darkops_zod_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_zod_super_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_factory_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_factory_super_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_castle_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_castle_super_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_island_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_island_super_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_stalingrad_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_stalingrad_super_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname darkops_genesis_ee " .. f1_arg1.value)
Engine.ExecNow(f1_arg0, "statsetbyname DARKOPS_GENESIS_SUPER_EE " .. f1_arg1.value)
end
end
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Loot",
"Unlocks all Black Market loot.", "MPStatsSettings_unlock_loot",
"cg_unlockall_loot", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Purchases",
"All items that need to be purchased with unlock tokens are unlocked.", "MPStatsSettings_purchase_all",
"cg_unlockall_purchases", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Class Slots",
"Unlocks all create-a-class slots and sets.", "MPStatsSettings_unlockall_cac_slots",
"cg_unlockall_cac_slots", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
end
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock All Attachments",
"All attachments on weapons are unlocked.",
"MPStatsSettings_unlockall_attachments", "cg_unlockall_attachments", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock all Camos and Reticles",
"All camos and reticles on weapons are unlocked.", "MPStatsSettings_unlockall_camos_and_reticles",
"cg_unlockall_camos_and_reticles", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock all Calling Cards", "All calling cards are unlocked.",
"MPStatsSettings_unlockall_calling_cards", "cg_unlockall_calling_cards", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock all Specialists Outfits",
"All specialists outfits are unlocked.", "MPStatsSettings_unlockall_specialists_outfits",
"cg_unlockall_specialists_outfits", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
end
if Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then
table.insert(optionsTable,
CoD.OptionsUtility.CreateDvarSettings(controller, "Unlock Easter Eggs",
"Complete all Easter Egg Achievements.", "MPStatsSettings_complete_ee",
"all_ee_completed", {
{
option = "MENU_DISABLED",
value = 0,
default = true
},
{
option = "MENU_ENABLED",
value = 1
},
}, nil, updateDvar))
end
local rankLevels = {}
local rankObjs = {}
local hasDefault = true
local currentPrestige = CoD.PrestigeUtility.GetCurrentPLevel(controller, Engine.CurrentSessionMode())
local currentRank = CoD.BlackMarketUtility.GetCurrentRank(controller) + 1
local isMasterPrestige = currentPrestige == 11
if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then
if not isMasterPrestige then
rankLevels = { 1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55 }
else
rankLevels = { 56, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }
end
elseif Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then
if not isMasterPrestige then
rankLevels = { 1, 5, 10, 15, 20, 25, 30, 35 }
else
rankLevels = { 36, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }
end
end
local maxlevel = math.max(table.unpack(rankLevels))
local minlevel = math.min(table.unpack(rankLevels))
for index, value in ipairs(rankLevels) do
table.insert(rankObjs, {
name = value <= minlevel and "Min" or value >= maxlevel and "Max" or value,
value = value - 1,
default = value == currentRank,
title = "Rank Level",
desc = value ~= currentRank and "" or "Current Rank"
})
end
if hasDefault and currentRank ~= minlevel and currentRank < maxlevel and not isMasterPrestige then
table.insert(rankObjs, {
name = "Current: " ..
tostring(currentRank <= minlevel and "Min" or currentRank >= maxlevel and "Max" or currentRank),
value = currentRank - 1,
default = true,
title = "Rank Level",
desc = "Do not adjust rank"
})
end
local prestigeTable = {}
for i = 0, 11 do
table.insert(prestigeTable, {
name = i == 0 and "None" or i == 11 and "Master" or i,
value = i,
default = i == currentPrestige,
title = "Prestige",
desc = ""
})
end
local createSettingsDatasource = function(controller, datasourceName, optionsTable, currentValue, loopEdges, action)
if currentValue == nil then
currentValue = 0
end
DataSources[datasourceName] = DataSourceHelpers.ListSetup(datasourceName, function(f47_arg0)
local f47_local0 = {}
for f47_local4, f47_local5 in ipairs(optionsTable) do
table.insert(f47_local0, {
models = {
text = optionsTable[f47_local4].name
},
properties = {
title = optionsTable[f47_local4].title,
desc = optionsTable[f47_local4].desc,
image = optionsTable[f47_local4].image,
value = optionsTable[f47_local4].value,
default = optionsTable[f47_local4].default,
action = action,
selectIndex = optionsTable[f47_local4].value == currentValue,
loopEdges = loopEdges,
showChangeIndicator = function(f48_arg0, f48_arg1, f48_arg2)
return f48_arg0.default ~= true
end
}
})
end
f47_local0[1].properties.first = true
f47_local0[#optionsTable].properties.last = true
return f47_local0
end, nil, nil, nil)
return datasourceName
end
table.insert(optionsTable, {
models = {
name = "Prestige",
desc = "",
image = nil,
optionsDatasource = createSettingsDatasource(controller, "MPStatsSettings_rank_prestige", prestigeTable,
CoD.PrestigeUtility.GetCurrentPLevel(controller, Engine.CurrentSessionMode()), false,
function(f1_arg0, f1_arg1, f1_arg2, dvarName, f1_arg4)
UpdateInfoModels(f1_arg1)
local newPrestige = f1_arg1.value
if newPrestige == 11 then
Engine.Exec(f1_arg0, "PrestigeStatsMaster " .. tostring(Engine.CurrentSessionMode()))
end
Engine.ExecNow(f1_arg0, "statsetbyname plevel " .. newPrestige)
Engine.ExecNow(f1_arg0, "statsetbyname hasprestiged " .. (newPrestige > 0 and 1 or 0))
Engine.Exec(f1_arg0, "uploadstats " .. tostring(Engine.CurrentSessionMode()))
end)
},
properties = {
revert = function(f50_arg0)
end
}
})
table.insert(optionsTable, {
models = {
name = "Rank Level",
desc = "",
image = nil,
optionsDatasource = createSettingsDatasource(controller, "MPStatsSettings_rank_level", rankObjs,
CoD.BlackMarketUtility.GetCurrentRank(controller), false,
function(f1_arg0, f1_arg1, f1_arg2, dvarName, f1_arg4)
UpdateInfoModels(f1_arg1)
local rankTable = nil
local rank = f1_arg1.value + 1
if currentPrestige <= 10 then
if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then
rankTable = "gamedata/tables/mp/mp_ranktable.csv"
elseif Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then
rankTable = "gamedata/tables/zm/zm_ranktable.csv"
end
local skipLines = Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER and 3 or 2
local maxXp = tonumber(Engine.TableLookupGetColumnValueForRow(rankTable, rank - 2 + skipLines, 7))
if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then
if maxXp ~= nil and rank == maxlevel then
maxXp = maxXp + 55600
end
end
if Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then
if maxXp ~= nil and rank == maxlevel then
maxXp = maxXp + 54244
end
end
if maxXp == nil then
maxXp = 0
end
Engine.ExecNow(f1_arg0, "statsetbyname rank " .. rank - 1)
Engine.ExecNow(f1_arg0, "statsetbyname rankxp " .. maxXp)
Engine.ExecNow(f1_arg0, "statsetbyname paragon_rankxp " .. 0)
else
if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then
rankTable = "gamedata/tables/mp/mp_paragonranktable.csv"
elseif Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then
rankTable = "gamedata/tables/zm/zm_paragonranktable.csv"
end
local skipLines = 2
local maxXp = 0
if Engine.CurrentSessionMode() == Enum.eModes.MODE_MULTIPLAYER then
maxXp = tonumber(Engine.TableLookupGetColumnValueForRow(rankTable, rank - 57 + skipLines, 7))
if maxXp ~= nil and rank == maxlevel then
maxXp = maxXp + 55600
end
rank = rank - 55
end
if Engine.CurrentSessionMode() == Enum.eModes.MODE_ZOMBIES then
maxXp = tonumber(Engine.TableLookupGetColumnValueForRow(rankTable, rank - 37 + skipLines, 7))
if maxXp ~= nil and rank == maxlevel then
maxXp = maxXp + 54244
end
rank = rank - 35
end
if maxXp == nil then
maxXp = 0
end
Engine.ExecNow(f1_arg0, "statsetbyname paragon_rank " .. rank - 1)
Engine.ExecNow(f1_arg0, "statsetbyname paragon_rankxp " .. maxXp)
end
Engine.Exec(f1_arg0, "uploadstats " .. tostring(Engine.CurrentSessionMode()))
currentRank = rank
end)
},
properties = {
revert = function(f50_arg0)
end
}
})
return optionsTable
end)
if Dvar.cg_unlockall_loot:get() == true then
Engine.SetDvar("ui_enableAllHeroes", 1)
end
LUI.createMenu.T7xStatsMenu = function(controller)
local self = CoD.Menu.NewForUIEditor("T7xStatsMenu")
if PreLoadFunc then
PreLoadFunc(self, controller)
end
self.soundSet = "ChooseDecal"
self:setOwner(controller)
self:setLeftRight(true, true, 0, 0)
self:setTopBottom(true, true, 0, 0)
self:playSound("menu_open", controller)
self.buttonModel = Engine.CreateModel(Engine.GetModelForController(controller), "T7xStatsMenu.buttonPrompts")
self.anyChildUsesUpdateState = true
local GameSettingsBackground = CoD.GameSettings_Background.new(self, controller)
GameSettingsBackground:setLeftRight(true, true, 0, 0)
GameSettingsBackground:setTopBottom(true, true, 0, 0)
GameSettingsBackground.MenuFrame.titleLabel:setText(Engine.Localize("STATS SETTINGS"))
GameSettingsBackground.MenuFrame.cac3dTitleIntermediary0.FE3dTitleContainer0.MenuTitle.TextBox1.Label0:setText(
Engine.Localize("STATS SETTINGS"))
GameSettingsBackground.GameSettingsSelectedItemInfo.GameModeInfo:setAlpha(0)
GameSettingsBackground.GameSettingsSelectedItemInfo.GameModeName:setAlpha(0)
self:addElement(GameSettingsBackground)
self.GameSettingsBackground = GameSettingsBackground
local Options = CoD.Competitive_SettingsList.new(self, controller)
Options:setLeftRight(true, false, 26, 741)
Options:setTopBottom(true, false, 135, 720)
Options.Title.DescTitle:setText(Engine.Localize("Stats"))
Options.ButtonList:setVerticalCount(15)
Options.ButtonList:setDataSource("MPStatsSettings")
self:addElement(Options)
self.Options = Options
self:AddButtonCallbackFunction(self, controller, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, nil,
function(element, menu, controller, model)
GoBack(self, controller)
SetPerControllerTableProperty(controller, "disableGameSettingsOptions", nil)
return true
end, function(element, menu, controller)
CoD.Menu.SetButtonLabel(menu, Enum.LUIButton.LUI_KEY_XBB_PSCIRCLE, "MENU_BACK")
return true
end, false)
GameSettingsBackground.MenuFrame:setModel(self.buttonModel, controller)
Options.id = "Options"
self:processEvent({
name = "menu_loaded",
controller = controller
})
self:processEvent({
name = "update_state",
menu = self
})
if not self:restoreState() then
self.Options:processEvent({
name = "gain_focus",
controller = controller
})
end
LUI.OverrideFunction_CallOriginalSecond(self, "close", function(element)
element.GameSettingsBackground:close()
element.Options:close()
Engine.UnsubscribeAndFreeModel(Engine.GetModel(Engine.GetModelForController(controller),
"T7xStatsMenu.buttonPrompts"))
end)
if PostLoadFunc then
PostLoadFunc(self, controller)
end
return self
end