init
This commit is contained in:
29
LICENSE
Normal file
29
LICENSE
Normal 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
7
README.md
Normal 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
|
||||
26
data/gamesettings/mp/gamesettings_escort.cfg
Normal file
26
data/gamesettings/mp/gamesettings_escort.cfg
Normal 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
BIN
data/launcher/bigboiii.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
146
data/launcher/main.html
Normal file
146
data/launcher/main.html
Normal 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
BIN
data/launcher/noise.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
7026
data/lookup_tables/dvar_list.txt
Normal file
7026
data/lookup_tables/dvar_list.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
data/scripts/mp/bots/_bot.gsc
Normal file
BIN
data/scripts/mp/bots/_bot.gsc
Normal file
Binary file not shown.
1125
data/scripts/mp/bots/_bot.gsc_raw
Normal file
1125
data/scripts/mp/bots/_bot.gsc_raw
Normal file
File diff suppressed because it is too large
Load Diff
BIN
data/scripts/mp/bots/_bot_loadout.gsc
Normal file
BIN
data/scripts/mp/bots/_bot_loadout.gsc
Normal file
Binary file not shown.
854
data/scripts/mp/bots/_bot_loadout.gsc_raw
Normal file
854
data/scripts/mp/bots/_bot_loadout.gsc_raw
Normal 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;
|
||||
}
|
||||
BIN
data/scripts/mp/gametypes/_globallogic_player.gsc
Normal file
BIN
data/scripts/mp/gametypes/_globallogic_player.gsc
Normal file
Binary file not shown.
4524
data/scripts/mp/gametypes/_globallogic_player.gsc_raw
Normal file
4524
data/scripts/mp/gametypes/_globallogic_player.gsc_raw
Normal file
File diff suppressed because it is too large
Load Diff
BIN
data/scripts/mp/gametypes/_serversettings.gsc
Normal file
BIN
data/scripts/mp/gametypes/_serversettings.gsc
Normal file
Binary file not shown.
209
data/scripts/mp/gametypes/_serversettings.gsc_raw
Normal file
209
data/scripts/mp/gametypes/_serversettings.gsc_raw
Normal 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;
|
||||
}
|
||||
BIN
data/scripts/mp/teams/_teams.gsc
Normal file
BIN
data/scripts/mp/teams/_teams.gsc
Normal file
Binary file not shown.
670
data/scripts/mp/teams/_teams.gsc_raw
Normal file
670
data/scripts/mp/teams/_teams.gsc_raw
Normal 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 );
|
||||
}
|
||||
}
|
||||
|
||||
118
data/ui_scripts/doubleclick_join_server/__init__.lua
Normal file
118
data/ui_scripts/doubleclick_join_server/__init__.lua
Normal 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
|
||||
156
data/ui_scripts/frontend_menus/__init__.lua
Normal file
156
data/ui_scripts/frontend_menus/__init__.lua
Normal 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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
217
data/ui_scripts/frontend_menus/datasources_start_menu_tabs.lua
Normal file
217
data/ui_scripts/frontend_menus/datasources_start_menu_tabs.lua
Normal 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)
|
||||
160
data/ui_scripts/frontend_menus/utils.lua
Normal file
160
data/ui_scripts/frontend_menus/utils.lua
Normal 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
|
||||
}
|
||||
148
data/ui_scripts/graphics_settings/__init__.lua
Normal file
148
data/ui_scripts/graphics_settings/__init__.lua
Normal 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
|
||||
4
data/ui_scripts/lua_fixes/__init__.lua
Normal file
4
data/ui_scripts/lua_fixes/__init__.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
-- Fix LUI_NULL_FUNCTION messages
|
||||
function Engine.PIXBeginEvent() end
|
||||
function Engine.PIXEndEvent() end
|
||||
30
data/ui_scripts/party/__init__.lua
Normal file
30
data/ui_scripts/party/__init__.lua
Normal 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")
|
||||
@@ -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)
|
||||
34
data/ui_scripts/playlist/__init__.lua
Normal file
34
data/ui_scripts/playlist/__init__.lua
Normal 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")
|
||||
@@ -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
|
||||
@@ -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
|
||||
1
data/ui_scripts/ranked/__init__.lua
Normal file
1
data/ui_scripts/ranked/__init__.lua
Normal file
@@ -0,0 +1 @@
|
||||
require("online_mods_loaded")
|
||||
23
data/ui_scripts/ranked/online_mods_loaded.lua
Normal file
23
data/ui_scripts/ranked/online_mods_loaded.lua
Normal 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
|
||||
378
data/ui_scripts/server_browser/__init__.lua
Normal file
378
data/ui_scripts/server_browser/__init__.lua
Normal 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
|
||||
421
data/ui_scripts/stats/__init__.lua
Normal file
421
data/ui_scripts/stats/__init__.lua
Normal 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
|
||||
Reference in New Issue
Block a user