diff options
22 files changed, 743 insertions, 209 deletions
diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt Binary files differindex c277964b..c74bbef3 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_english.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_english.txt diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_german.txt b/Northstar.Client/mod/resource/northstar_client_localisation_german.txt Binary files differindex 3d7a7551..e35378cb 100644 --- a/Northstar.Client/mod/resource/northstar_client_localisation_german.txt +++ b/Northstar.Client/mod/resource/northstar_client_localisation_german.txt diff --git a/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt b/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt Binary files differnew file mode 100644 index 00000000..d7f144f0 --- /dev/null +++ b/Northstar.Client/mod/resource/northstar_client_localisation_italian.txt diff --git a/Northstar.Client/mod/resource/ui/menus/connect_password.menu b/Northstar.Client/mod/resource/ui/menus/connect_password.menu index b5e12ad2..d2421477 100644 --- a/Northstar.Client/mod/resource/ui/menus/connect_password.menu +++ b/Northstar.Client/mod/resource/ui/menus/connect_password.menu @@ -34,7 +34,7 @@ resource/ui/menus/mods_browse.menu ControlName ImagePanel InheritProperties MenuTopBar } - + ButtonRowAnchor { ControlName Label @@ -43,7 +43,7 @@ resource/ui/menus/mods_browse.menu xpos 120 ypos 160 } - + MatchmakingStatus { ControlName CNestedPanel @@ -62,6 +62,34 @@ resource/ui/menus/mods_browse.menu ControlName TextEntry wide 700 tall 53 + zpos 1 + visible 1 + enabled 1 + textHidden 0 + editable 1 + maxchars 32 + NumericInputOnly 0 + textAlignment "east" + font DefaultBold_53 + keyboardTitle "#CONNECT_WITH_PASSWORD" + keyboardDescription "#ENTER_PASSWORD" + allowRightClickMenu 1 + allowSpecialCharacters 0 + unicode 0 + paintborder 0 + alpha 0 + + pin_to_sibling ButtonRowAnchor + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + EnterPasswordBoxDummy + { + ControlName TextEntry + wide 700 + tall 53 + zpos 0 visible 1 enabled 1 textHidden 1 @@ -76,12 +104,12 @@ resource/ui/menus/mods_browse.menu allowSpecialCharacters 0 unicode 0 paintborder 0 - + pin_to_sibling ButtonRowAnchor pin_corner_to_sibling TOP_LEFT pin_to_sibling_corner BOTTOM_LEFT } - + ConnectButton { ControlName RuiButton diff --git a/Northstar.Client/mod/resource/ui/menus/server_browser.menu b/Northstar.Client/mod/resource/ui/menus/server_browser.menu index 959c1b09..94b57451 100644 --- a/Northstar.Client/mod/resource/ui/menus/server_browser.menu +++ b/Northstar.Client/mod/resource/ui/menus/server_browser.menu @@ -2142,6 +2142,7 @@ resource/ui/menus/mods_browse.menu wide 1200 tall 153 xpos -8 + classname FilterPanelChild rui "ui/control_options_description.rpak" @@ -2159,6 +2160,8 @@ resource/ui/menus/mods_browse.menu InheritProperties RuiSmallButton labelText "#SEARCHBAR_LABEL" textAlignment west + classname FilterPanelChild + wide 500 xpos -23 ypos -16 @@ -2178,6 +2181,7 @@ resource/ui/menus/mods_browse.menu BtnServerSearch { ControlName TextEntry + classname FilterPanelChild zpos 100 // This works around input weirdness when the control is constructed by code instead of VGUI blackbox. xpos -400 ypos -5 @@ -2204,6 +2208,7 @@ resource/ui/menus/mods_browse.menu InheritProperties SwitchButton labelText "#MAP_FILTER" ConVar "filter_map" + classname FilterPanelChild wide 500 pin_to_sibling BtnSearchLabel @@ -2220,6 +2225,7 @@ resource/ui/menus/mods_browse.menu InheritProperties SwitchButton labelText "#GAMEMODE_FILTER" ConVar "filter_gamemode" + classname FilterPanelChild wide 500 pin_to_sibling SwtBtnSelectMap @@ -2236,6 +2242,7 @@ resource/ui/menus/mods_browse.menu InheritProperties SwitchButton labelText "#HIDE_FULL_FILTER" ConVar "filter_hide_full" + classname FilterPanelChild wide 500 @@ -2259,6 +2266,7 @@ resource/ui/menus/mods_browse.menu InheritProperties SwitchButton labelText "#HIDE_EMPTY_FILTER" ConVar "filter_hide_empty" + classname FilterPanelChild wide 500 @@ -2282,6 +2290,7 @@ resource/ui/menus/mods_browse.menu InheritProperties SwitchButton labelText "#HIDE_PROT_FILTER" ConVar "filter_hide_protected" + classname FilterPanelChild wide 500 list @@ -2303,6 +2312,7 @@ resource/ui/menus/mods_browse.menu ControlName RuiButton InheritProperties RuiSmallButton labelText "#CLEAR_FILTERS" + classname FilterPanelChild wide 100 xpos -17 ypos -57 @@ -2322,6 +2332,7 @@ resource/ui/menus/mods_browse.menu BtnDummyAfterFilterClear { ControlName RuiButton + classname FilterPanelChild width 0 height 0 visible 1 diff --git a/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut b/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut index cd663a06..b1b97bc9 100644 --- a/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut +++ b/Northstar.Client/mod/scripts/vscripts/sh_menu_models.gnut @@ -2,9 +2,9 @@ // Model tracking and save/Clear functions are temp. We already update the client knowledge of loadouts. Derive from that. // Move the struct off the player? -#if CLIENT && MP +//#if CLIENT && MP untyped -#endif //client && MP +//#endif //client && MP #if CLIENT const float CARD_TAG_SCALE = 0.0 // update to match same const in hud_defs.rui @@ -207,12 +207,18 @@ #endif // CLIENT && MP #if UI + struct + { + table MouseMovementCaptureFunctionsTable = {} + } file + const MOUSE_ROTATE_MULTIPLIER = 25.0 global function UpdateUIMapSupportsMenuModels global function RunMenuClientFunction global function UI_SetPresentationType + global function AddMouseMovementCaptureHandler global function UICodeCallback_MouseMovementCapture #endif // UI @@ -2892,6 +2898,18 @@ } } + void function AddMouseMovementCaptureHandler( var menu, void functionref( int, int ) func ) + { + file.MouseMovementCaptureFunctionsTable.rawset( menu, func ) + } + + void function UpdateMouseMovementCaptureFunctions( int deltaX, int deltaY ) + { + var activeMenu = GetActiveMenu() + if ( file.MouseMovementCaptureFunctionsTable.rawin( activeMenu ) ) + file.MouseMovementCaptureFunctionsTable.rawget( activeMenu )(deltaX, deltaY) + } + void function UICodeCallback_MouseMovementCapture( var capturePanel, int deltaX, int deltaY ) { float screenScaleXModifier = 1920.0 / GetScreenSize()[0] // 1920 is base screen width @@ -2901,7 +2919,7 @@ float screenScaleYModifier = 1080.0 / GetScreenSize()[1] // 1920 is base screen width float mouseYRotationDelta = deltaY * screenScaleYModifier * MOUSE_ROTATE_MULTIPLIER - UpdateMouseDeltaBuffer( deltaX, deltaY ) + UpdateMouseMovementCaptureFunctions( deltaX, deltaY ) RunMenuClientFunction( "UpdateMouseRotateDelta", mouseXRotateDelta, mouseYRotationDelta ) } diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut index e1ed8991..56db0ccc 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_connect_password.nut @@ -1,5 +1,13 @@ global function AddNorthstarConnectWithPasswordMenu +struct +{ + var menu + var enterPasswordBox + var enterPasswordDummy + var connectButton +} file + void function AddNorthstarConnectWithPasswordMenu() { AddMenu( "ConnectWithPasswordMenu", $"resource/ui/menus/connect_password.menu", InitConnectWithPasswordMenu, "#MENU_CONNECT" ) @@ -7,24 +15,42 @@ void function AddNorthstarConnectWithPasswordMenu() void function InitConnectWithPasswordMenu() { - AddMenuEventHandler( GetMenu( "ConnectWithPasswordMenu" ), eUIEvent.MENU_OPEN, OnConnectWithPasswordMenuOpened ) - AddMenuFooterOption( GetMenu( "ConnectWithPasswordMenu" ), BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + file.menu = GetMenu( "ConnectWithPasswordMenu" ) + + file.enterPasswordBox = Hud_GetChild( file.menu, "EnterPasswordBox") + file.enterPasswordDummy = Hud_GetChild( file.menu, "EnterPasswordBoxDummy") + file.connectButton = Hud_GetChild( file.menu, "ConnectButton") + + AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnConnectWithPasswordMenuOpened ) + AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + + AddButtonEventHandler( file.connectButton, UIE_CLICK, ConnectWithPassword ) + + AddButtonEventHandler( file.enterPasswordBox, UIE_CHANGE, UpdatePasswordLabel ) - AddButtonEventHandler( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "ConnectButton" ), UIE_CLICK, ConnectWithPassword ) RegisterButtonPressedCallback( KEY_ENTER, ConnectWithPassword ) } +void function UpdatePasswordLabel( var n ) +{ + string hiddenPSWD + for ( int i = 0; i < Hud_GetUTF8Text( file.enterPasswordBox ).len(); i++) + hiddenPSWD += "*" + Hud_SetText( file.enterPasswordDummy, hiddenPSWD ) +} + void function OnConnectWithPasswordMenuOpened() { UI_SetPresentationType( ePresentationType.KNOWLEDGEBASE_SUB ) - Hud_SetText( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "Title" ), "#MENU_TITLE_CONNECT_PASSWORD" ) - Hud_SetText( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "ConnectButton" ), "#MENU_CONNECT_MENU_CONNECT" ) - Hud_SetText( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "EnterPasswordBox" ), "" ) + Hud_SetText( Hud_GetChild( file.menu, "Title" ), "#MENU_TITLE_CONNECT_PASSWORD" ) + Hud_SetText( file.connectButton, "#MENU_CONNECT_MENU_CONNECT" ) + Hud_SetText( file.enterPasswordBox, "" ) + Hud_SetText( file.enterPasswordDummy, "" ) } void function ConnectWithPassword( var button ) { - if ( GetTopNonDialogMenu() == GetMenu( "ConnectWithPasswordMenu" ) ) - thread ThreadedAuthAndConnectToServer( Hud_GetUTF8Text( Hud_GetChild( GetMenu( "ConnectWithPasswordMenu" ), "EnterPasswordBox" ) ) ) + if ( GetTopNonDialogMenu() == file.menu ) + thread ThreadedAuthAndConnectToServer( Hud_GetUTF8Text( Hud_GetChild( file.menu, "EnterPasswordBox" ) ) ) }
\ No newline at end of file diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut index 286cd192..cb1535d3 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_modmenu.nut @@ -13,7 +13,7 @@ void function AddNorthstarModMenu() void function AddNorthstarModMenu_MainMenuFooter() { - AddMenuFooterOption( GetMenu( "MainMenu" ), BUTTON_Y, "#Y_MENU_TITLE_MODS", "#MENU_TITLE_MODS", AdvanceToModListMenu ) + AddMenuFooterOption( GetMenu( "MainMenu" ), BUTTON_Y, "#Y_BUTTON_MENU_TITLE_MODS", "#MENU_TITLE_MODS", AdvanceToModListMenu ) } void function AdvanceToModListMenu( var button ) @@ -28,7 +28,7 @@ void function InitModMenu() AddMenuEventHandler( menu, eUIEvent.MENU_OPEN, OnModMenuOpened ) AddMenuEventHandler( menu, eUIEvent.MENU_CLOSE, OnModMenuClosed ) AddMenuFooterOption( menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) - AddMenuFooterOption( menu, BUTTON_Y, "#Y_RELOAD_MODS", "#RELOAD_MODS", OnReloadModsButtonPressed ) + AddMenuFooterOption( menu, BUTTON_Y, "#Y_BUTTON_RELOAD_MODS", "#RELOAD_MODS", OnReloadModsButtonPressed ) AddMenuFooterOption( menu, BUTTON_BACK, "#BACK_AUTHENTICATION_AGREEMENT", "#AUTHENTICATION_AGREEMENT", OnAuthenticationAgreementButtonPressed ) foreach ( var button in GetElementsByClassname( GetMenu( "ModListMenu" ), "ModButton" ) ) diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut index 7254f199..437a8cf2 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_serverbrowser.nut @@ -4,12 +4,11 @@ untyped global function AddNorthstarServerBrowserMenu global function ThreadedAuthAndConnectToServer -global function UpdateMouseDeltaBuffer // Stop peeking const int BUTTONS_PER_PAGE = 15 -const float DOUBLE_CLICK_TIME_MS = 0.2 // unsure what the ideal value is +const float DOUBLE_CLICK_TIME_MS = 0.3 // unsure what the ideal value is struct { @@ -29,6 +28,17 @@ struct { string filterGamemode } filterArguments + +enum sortingBy +{ + NONE, + NAME, + PLAYERS, + MAP, + GAMEMODE, + LATENCY +} + struct { // true = alphabeticaly false = reverse bool serverName = true @@ -100,22 +110,22 @@ void function UpdatePrivateMatchModesAndMaps() { if ( filterArguments.filterMaps.find( map ) != -1 ) continue - + filterArguments.filterMaps.append( map ) - + string localized = GetMapDisplayName( map ) Hud_DialogList_AddListItem( Hud_GetChild( file.menu, "SwtBtnSelectMap" ) , localized, string( enum_ + 1 ) ) - } - + } + array<string> realModes = [ "private_match" ] realModes.extend( GetPrivateMatchModes() ) - + foreach( int enum_, string mode in realModes ) { string localized = GetGameModeDisplayName( mode ) if ( filterArguments.filterGamemodes.find( localized ) != -1 ) continue - + filterArguments.filterGamemodes.append( localized ) Hud_DialogList_AddListItem( Hud_GetChild( file.menu, "SwtBtnSelectGamemode" ) , localized, string( enum_ + 1 ) ) } @@ -125,6 +135,8 @@ void function InitServerBrowserMenu() { file.menu = GetMenu( "ServerBrowserMenu" ) + AddMouseMovementCaptureHandler( file.menu, UpdateMouseDeltaBuffer ) + // Get menu stuff file.serverButtons = GetElementsByClassname( file.menu, "ServerButton" ) file.serversName = GetElementsByClassname( file.menu, "ServerName" ) @@ -136,7 +148,7 @@ void function InitServerBrowserMenu() filterArguments.filterMaps = [ "SWITCH_ANY" ] Hud_DialogList_AddListItem( Hud_GetChild( file.menu, "SwtBtnSelectMap" ), "SWITCH_ANY", "0" ) - + filterArguments.filterGamemodes = [ "SWITCH_ANY" ] Hud_DialogList_AddListItem( Hud_GetChild( file.menu, "SwtBtnSelectGamemode" ), "SWITCH_ANY", "0" ) @@ -144,7 +156,7 @@ void function InitServerBrowserMenu() AddMenuEventHandler( file.menu, eUIEvent.MENU_CLOSE, OnCloseServerBrowserMenu ) AddMenuEventHandler( file.menu, eUIEvent.MENU_OPEN, OnServerBrowserMenuOpened ) AddMenuFooterOption( file.menu, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) - AddMenuFooterOption( file.menu, BUTTON_Y, "#Y_REFRESH_SERVERS", "#REFRESH_SERVERS", RefreshServers ) + AddMenuFooterOption( file.menu, BUTTON_Y, "#Y_BUTTON_REFRESH_SERVERS", "#REFRESH_SERVERS", RefreshServers ) // Setup server buttons var width = 1120.0 * (GetScreenSize()[1] / 1080.0) @@ -171,11 +183,11 @@ void function InitServerBrowserMenu() AddButtonEventHandler( Hud_GetChild( file.menu, "BtnFiltersClear"), UIE_CLICK, OnBtnFiltersClear_Activate ) - AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerNameTab"), UIE_CLICK, SortServerListByName ) - AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerPlayersTab"), UIE_CLICK, SortServerListByPlayers ) - AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerMapTab"), UIE_CLICK, SortServerListByMap ) - AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerGamemodeTab"), UIE_CLICK, SortServerListByGamemode ) - AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerLatencyTab"), UIE_CLICK, SortServerListByLatency ) + AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerNameTab"), UIE_CLICK, SortServerListByName_Activate ) + AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerPlayersTab"), UIE_CLICK, SortServerListByPlayers_Activate ) + AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerMapTab"), UIE_CLICK, SortServerListByMap_Activate ) + AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerGamemodeTab"), UIE_CLICK, SortServerListByGamemode_Activate ) + AddButtonEventHandler( Hud_GetChild( file.menu, "BtnServerLatencyTab"), UIE_CLICK, SortServerListByLatency_Activate ) AddButtonEventHandler( Hud_GetChild( file.menu, "SwtBtnSelectMap"), UIE_CHANGE, FilterAndUpdateList ) @@ -278,10 +290,12 @@ void function UpdateListSliderHeight( float servers ) var movementCapture = Hud_GetChild( file.menu , "MouseMovementCapture" ) float maxHeight = 562.0 * (GetScreenSize()[1] / 1080.0) + float minHeight = 80.0 * (GetScreenSize()[1] / 1080.0) float height = maxHeight * (15.0 / servers ) if ( height > maxHeight ) height = maxHeight + if ( height < minHeight ) height = minHeight Hud_SetHeight( sliderButton , height ) Hud_SetHeight( sliderPanel , height ) @@ -419,36 +433,29 @@ bool function IsFilterPanelElementFocused() { var focusedElement = GetFocus(); var name = Hud_GetHudName(focusedElement); - print(name) - - // kinda sucks but just check if any of the filter elements - // has focus. would be nice to have tags or sth here - bool match = (name == "FilterPanel") || - (name == "BtnSearchLabel") || - (name == "BtnServerSearch") || - (name == "SwtBtnSelectMap") || - (name == "SwtBtnSelectGamemode") || - (name == "SwtBtnHideFull") || - (name == "SwtBtnHideEmpty") || - (name == "SwtBtnHideProtected") || - (name == "BtnFiltersClear") || - (name == "BtnDummyAfterFilterClear"); + foreach (element in GetElementsByClassname( file.menu, "FilterPanelChild")) { + if ( element == focusedElement ) return true + } - return match; + return false; } void function OnKeyTabPressed(var button) { - // toggle focus between server list and filter panel - if (IsFilterPanelElementFocused()) { - // print("Switching focus from filter panel to server list") - Hud_SetFocused(Hud_GetChild(file.menu, "BtnServer1")) - } - else { - // print("Switching focus from server list to filter panel") - Hud_SetFocused(Hud_GetChild(file.menu, "BtnServerSearch")) - HideServerInfo() + try + { + // toggle focus between server list and filter panel + if (IsFilterPanelElementFocused()) { + // print("Switching focus from filter panel to server list") + Hud_SetFocused(Hud_GetChild(file.menu, "BtnServer1")) + } + else { + // print("Switching focus from server list to filter panel") + Hud_SetFocused(Hud_GetChild(file.menu, "BtnServerSearch")) + HideServerInfo() + } } + catch ( ex ) {} } void function OnHitDummyTop(var button) { @@ -570,30 +577,31 @@ void function FilterAndUpdateList( var n ) FilterServerList() + switch ( filterDirection.sortingBy ) { - case 0: + case sortingBy.NONE: UpdateShownPage() break - case 1: + case sortingBy.NAME: filterDirection.serverName = !filterDirection.serverName - SortServerListByName(0) + SortServerListByName_Activate(0) break - case 2: + case sortingBy.PLAYERS: filterDirection.serverPlayers = !filterDirection.serverPlayers - SortServerListByPlayers(0) + SortServerListByPlayers_Activate(0) break - case 3: + case sortingBy.MAP: filterDirection.serverMap = !filterDirection.serverMap - SortServerListByMap(0) + SortServerListByMap_Activate(0) break - case 5: // 4 skipped cause it doesn't work respawn pls fix + case sortingBy.GAMEMODE: filterDirection.serverGamemode = !filterDirection.serverGamemode - SortServerListByGamemode(0) + SortServerListByGamemode_Activate(0) break - case 6: + case sortingBy.LATENCY: filterDirection.serverLatency = !filterDirection.serverLatency - SortServerListByLatency(0) + SortServerListByLatency_Activate(0) break default: printt( "How the f did you get here" ) @@ -684,7 +692,8 @@ void function FilterServerList() { if ( filterArguments.useSearch ) { - string sName = tempServer.serverName.tolower() + string sName = tempServer.serverName.tolower() + " " + Localize(GetMapDisplayName(tempServer.serverMap)).tolower() + " " + tempServer.serverMap.tolower() + " " + tempServer.serverGamemode.tolower() + " " + Localize(tempServer.serverGamemode).tolower() + string sTerm = filterArguments.searchTerm.tolower() if ( sName.find(sTerm) != null) @@ -1020,130 +1029,105 @@ void function ThreadedAuthAndConnectToServer( string password = "" ) ////////////////////////////////////// // Shadow realm ////////////////////////////////////// -void function SortServerListByName( var button ) +int function ServerSortLogic ( serverStruct a, serverStruct b) { - filterDirection.sortingBy = 1 + var aTemp + var bTemp + + bool direction + + // We can hard code this cause adding entire columns isn't as easy + switch ( filterDirection.sortingBy ) { + case sortingBy.NAME: + aTemp = a.serverName.tolower() + bTemp = b.serverName.tolower() + direction = filterDirection.serverName + break; + case sortingBy.PLAYERS: + aTemp = a.serverPlayers + bTemp = b.serverPlayers + direction = filterDirection.serverPlayers + break; + case sortingBy.MAP: + aTemp = Localize(a.serverMap).tolower() + bTemp = Localize(b.serverMap).tolower() + direction = filterDirection.serverMap + break; + case sortingBy.GAMEMODE: + aTemp = Localize(a.serverGamemode).tolower() + bTemp = Localize(b.serverGamemode).tolower() + direction = filterDirection.serverGamemode + break; + case sortingBy.LATENCY: + aTemp = a.serverLatency + bTemp = b.serverLatency + direction = filterDirection.serverLatency + break; + default: + return 0 + } - int n = file.serversArrayFiltered.len() - 1 + int invert = direction == true ? 1 : -1 - serverStruct tempServer + if ( aTemp > bTemp ) + return 1 * invert - for ( int i = 0; i < n; i++) - { - for ( int j = 0; j < n - 1; j++) - { - if ( file.serversArrayFiltered[ j ].serverName < file.serversArrayFiltered[ j + 1 ].serverName && filterDirection.serverName || file.serversArrayFiltered[ j ].serverName > file.serversArrayFiltered[ j + 1 ].serverName && !filterDirection.serverName) - { - tempServer = file.serversArrayFiltered[ j ] - file.serversArrayFiltered[ j ] = file.serversArrayFiltered[ j + 1 ] - file.serversArrayFiltered[ j + 1 ] = tempServer - } - } - } + if ( aTemp < bTemp ) + return -1 * invert + + return 0 +} + +void function SortServerListByName_Activate ( var button ) +{ + filterDirection.sortingBy = sortingBy.NAME + + file.serversArrayFiltered.sort( ServerSortLogic ) filterDirection.serverName = !filterDirection.serverName UpdateShownPage() } -void function SortServerListByPlayers( var button ) -{ - filterDirection.sortingBy = 2 - int n = file.serversArrayFiltered.len() - 1 - - serverStruct tempServer +void function SortServerListByPlayers_Activate( var button ) +{ + filterDirection.sortingBy = sortingBy.PLAYERS - for ( int i = 0; i < n; i++) - { - for ( int j = 0; j < n - 1; j++) - { - if ( file.serversArrayFiltered[ j ].serverPlayers < file.serversArrayFiltered[ j + 1 ].serverPlayers && filterDirection.serverPlayers || file.serversArrayFiltered[ j ].serverPlayers > file.serversArrayFiltered[ j + 1 ].serverPlayers && !filterDirection.serverPlayers) - { - tempServer = file.serversArrayFiltered[ j ] - file.serversArrayFiltered[ j ] = file.serversArrayFiltered[ j + 1 ] - file.serversArrayFiltered[ j + 1 ] = tempServer - } - } - } + file.serversArrayFiltered.sort( ServerSortLogic ) filterDirection.serverPlayers = !filterDirection.serverPlayers UpdateShownPage() } -void function SortServerListByMap( var button ) +void function SortServerListByMap_Activate( var button ) { - filterDirection.sortingBy = 3 - - int n = file.serversArrayFiltered.len() - 1 + filterDirection.sortingBy = sortingBy.MAP - serverStruct tempServer - - for ( int i = 0; i < n; i++) - { - for ( int j = 0; j < n - 1; j++) - { - if ( Localize(file.serversArrayFiltered[ j ].serverMap) < Localize(file.serversArrayFiltered[ j + 1 ].serverMap) && filterDirection.serverMap || Localize(file.serversArrayFiltered[ j ].serverMap) > Localize(file.serversArrayFiltered[ j + 1 ].serverMap) && !filterDirection.serverMap) - { - tempServer = file.serversArrayFiltered[ j ] - file.serversArrayFiltered[ j ] = file.serversArrayFiltered[ j + 1 ] - file.serversArrayFiltered[ j + 1 ] = tempServer - } - } - } + file.serversArrayFiltered.sort( ServerSortLogic ) filterDirection.serverMap = !filterDirection.serverMap UpdateShownPage() } -void function SortServerListByGamemode( var button ) +void function SortServerListByGamemode_Activate( var button ) { - filterDirection.sortingBy = 5 - - int n = file.serversArrayFiltered.len() - 1 - - serverStruct tempServer + filterDirection.sortingBy = sortingBy.GAMEMODE - for ( int i = 0; i < n; i++) - { - for ( int j = 0; j < n - 1; j++) - { - if ( Localize(file.serversArrayFiltered[ j ].serverGamemode) < Localize(file.serversArrayFiltered[ j + 1 ].serverGamemode) && filterDirection.serverGamemode || Localize(file.serversArrayFiltered[ j ].serverGamemode) > Localize(file.serversArrayFiltered[ j + 1 ].serverGamemode) && !filterDirection.serverGamemode) - { - tempServer = file.serversArrayFiltered[ j ] - file.serversArrayFiltered[ j ] = file.serversArrayFiltered[ j + 1 ] - file.serversArrayFiltered[ j + 1 ] = tempServer - } - } - } + file.serversArrayFiltered.sort( ServerSortLogic ) filterDirection.serverGamemode = !filterDirection.serverGamemode UpdateShownPage() } -void function SortServerListByLatency( var button ) +void function SortServerListByLatency_Activate( var button ) { - filterDirection.sortingBy = 5 + filterDirection.sortingBy = sortingBy.LATENCY - int n = file.serversArrayFiltered.len() - 1 - - serverStruct tempServer - - for ( int i = 0; i < n; i++) - { - for ( int j = 0; j < n - 1; j++) - { - if ( file.serversArrayFiltered[ j ].serverLatency < file.serversArrayFiltered[ j + 1 ].serverLatency && filterDirection.serverLatency || file.serversArrayFiltered[ j ].serverLatency > file.serversArrayFiltered[ j + 1 ].serverLatency && !filterDirection.serverLatency) - { - tempServer = file.serversArrayFiltered[ j ] - file.serversArrayFiltered[ j ] = file.serversArrayFiltered[ j + 1 ] - file.serversArrayFiltered[ j + 1 ] = tempServer - } - } - } + file.serversArrayFiltered.sort( ServerSortLogic ) filterDirection.serverLatency = !filterDirection.serverLatency diff --git a/Northstar.Custom/keyvalues/playlists_v2.txt b/Northstar.Custom/keyvalues/playlists_v2.txt index 37734025..3bf111b5 100644 --- a/Northstar.Custom/keyvalues/playlists_v2.txt +++ b/Northstar.Custom/keyvalues/playlists_v2.txt @@ -241,6 +241,23 @@ playlists gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM } } + tffa + { + inherit defaults + vars + { + name #PL_tffa + lobbytitle #PL_tffa_lobby + description #PL_tffa_desc + abbreviation #PL_sbox_abbr + + scorelimit 20 + max_players 10 + max_teams 10 + classic_mp 1 + gamemode_score_hint #GAMEMODE_SCORE_HINT_TDM + } + } } Playlists { @@ -652,35 +669,38 @@ playlists { hs { - mp_complex3 1 - mp_drydock 1 - mp_glitch 1 - mp_homestead 2 - mp_eden 1 - mp_forwardbase_kodai 1 - mp_black_water_canal 1 - mp_glitch 1 - mp_angel_city 1 - mp_colony02 1 - mp_relic02 1 - mp_grave 1 - mp_homestead 1 - mp_drydock 1 - mp_glitch 1 - mp_thaw 1 - mp_eden 2 - mp_black_water_canal 1 - mp_glitch 1 - mp_relic02 1 - mp_wargames 1 - mp_rise 1 - mp_crashsite3 1 - mp_lf_stacks 1 - mp_lf_deck 1 - mp_lf_meadow 1 - mp_lf_traffic 1 - mp_lf_township 1 - mp_lf_uma 1 + maps + { + mp_complex3 1 + mp_drydock 1 + mp_glitch 1 + mp_homestead 2 + mp_eden 1 + mp_forwardbase_kodai 1 + mp_black_water_canal 1 + mp_glitch 1 + mp_angel_city 1 + mp_colony02 1 + mp_relic02 1 + mp_grave 1 + mp_homestead 1 + mp_drydock 1 + mp_glitch 1 + mp_thaw 1 + mp_eden 2 + mp_black_water_canal 1 + mp_glitch 1 + mp_relic02 1 + mp_wargames 1 + mp_rise 1 + mp_crashsite3 1 + mp_lf_stacks 1 + mp_lf_deck 1 + mp_lf_meadow 1 + mp_lf_traffic 1 + mp_lf_township 1 + mp_lf_uma 1 + } } } } @@ -780,5 +800,43 @@ playlists } } } + tffa + { + inherit defaults + vars + { + name #PL_tffa + lobbytitle #PL_tffa_lobby + description #PL_tffa_desc + hint #PL_tffa_hint + image lts + abbreviation #PL_tffa_abbr + visible 0 + } + gamemodes + { + tffa + { + maps + { + mp_forwardbase_kodai 1 + mp_grave 1 + mp_homestead 1 + mp_thaw 1 + mp_black_water_canal 1 + mp_eden 1 + mp_drydock 1 + mp_crashsite3 1 + mp_complex3 1 + mp_angel_city 1 + mp_colony02 1 + mp_glitch 1 + mp_relic02 1 + mp_wargames 1 + mp_rise 1 + } + } + } + } } } diff --git a/Northstar.Custom/mod.json b/Northstar.Custom/mod.json index d6c54033..2aaa7eb7 100644 --- a/Northstar.Custom/mod.json +++ b/Northstar.Custom/mod.json @@ -278,6 +278,28 @@ "Before": "ShGamemodeCTFComp_Init" } }, + + { + "Path": "gamemodes/sh_gamemode_tffa.gnut", + "RunOn": "( CLIENT || SERVER ) && MP", + "ClientCallback": { + "Before": "Sh_GamemodeTFFA_Init" + }, + + "ServerCallback": { + "Before": "Sh_GamemodeTFFA_Init" + } + }, + + { + "Path": "gamemodes/_gamemode_tffa.gnut", + "RunOn": "SERVER && MP" + }, + + { + "Path": "gamemodes/cl_gamemode_tffa.gnut", + "RunOn": "CLIENT && MP" + }, { "Path": "sh_3psequence_to_1p_hacks.gnut", diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut index fa07a7ff..a5348498 100644 --- a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_fastball.gnut @@ -97,6 +97,22 @@ void function GamemodeFastball_Init() < 8, 825, 1096 >, < 0, -90.00, 0 > , < 740 , -600, 960 >, < 0, 0, 0 > ]) + + FastballAddBuddySpawnForLevel( "mp_crashsite3", TEAM_MILITIA, < -6364.65, -1291.28, 822.02>, <0, -19.17, 0> ) + FastballAddBuddySpawnForLevel( "mp_crashsite3", TEAM_IMC, < -2455.29, 821.52, 539.21>, <0, -179.21, 0> ) + FastballAddPanelSpawnsForLevel( "mp_crashsite3", [ + < -672.27, -2786, 931.17 >, < 0, -45, 0 >, + < -3770, -990, 985 >, < 10, 80.00, 20 >, + < -6190.25, 1658.51, 1400.03 >, < 0, 144, 0 > + ]) + + FastballAddBuddySpawnForLevel( "mp_rise", TEAM_MILITIA, < -3885.97, 35.11, 704.03>, <0, 11.86, 0> ) + FastballAddBuddySpawnForLevel( "mp_rise", TEAM_IMC, < 2206.76, 1869.08, 453.9>, <0, -165.77, 0> ) + FastballAddPanelSpawnsForLevel( "mp_rise", [ + < 141, 2484.71, 296.03 >, < 0, 0, 0 >, + < -448.54, 1091.42, 545.03 >, < 0, 0, 0 >, + < -2097, 1050, 320.03 >, < 0, 180, 0 > + ]) //Current BT fast ball points are good FastballAddPanelSpawnsForLevel( "mp_colony02", [ diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_tffa.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_tffa.gnut new file mode 100644 index 00000000..edea5a76 --- /dev/null +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/_gamemode_tffa.gnut @@ -0,0 +1,79 @@ +// literally just ttdm paste + +global function GamemodeTFFA_Init + +const float TFFAIntroLength = 15.0 + +void function GamemodeTFFA_Init() +{ + Riff_ForceSetSpawnAsTitan( eSpawnAsTitan.Always ) + Riff_ForceTitanExitEnabled( eTitanExitEnabled.Never ) + TrackTitanDamageInPlayerGameStat( PGS_ASSAULT_SCORE ) + ScoreEvent_SetupEarnMeterValuesForMixedModes() + SetLoadoutGracePeriodEnabled( false ) + + ClassicMP_SetCustomIntro( TFFAIntroSetup, TFFAIntroLength ) + + AddCallback_OnPlayerKilled( AddTeamScoreForPlayerKilled ) // dont have to track autotitan kills since you cant leave your titan in this mode + + // probably needs scoreevent earnmeter values +} + +void function TFFAIntroSetup() +{ + // this should show intermission cam for 15 sec in prematch, before spawning players as titans + AddCallback_GameStateEnter( eGameState.Prematch, TFFAIntroStart ) + AddCallback_OnClientConnected( TFFAIntroShowIntermissionCam ) +} + +void function TFFAIntroStart() +{ + thread TFFAIntroStartThreaded() +} + +void function TFFAIntroStartThreaded() +{ + ClassicMP_OnIntroStarted() + + foreach ( entity player in GetPlayerArray() ) + TFFAIntroShowIntermissionCam( player ) + + wait TFFAIntroLength + + ClassicMP_OnIntroFinished() +} + +void function TFFAIntroShowIntermissionCam( entity player ) +{ + if ( GetGameState() != eGameState.Prematch ) + return + + thread PlayerWatchesTFFAIntroIntermissionCam( player ) +} + +void function PlayerWatchesTFFAIntroIntermissionCam( entity player ) +{ + ScreenFadeFromBlack( player ) + + entity intermissionCam = GetEntArrayByClass_Expensive( "info_intermission" )[ 0 ] + + // the angle set here seems sorta inconsistent as to whether it actually works or just stays at 0 for some reason + player.SetObserverModeStaticPosition( intermissionCam.GetOrigin() ) + player.SetObserverModeStaticAngles( intermissionCam.GetAngles() ) + player.StartObserverMode( OBS_MODE_STATIC_LOCKED ) + + wait TFFAIntroLength + + RespawnAsTitan( player, false ) + TryGameModeAnnouncement( player ) +} + +void function AddTeamScoreForPlayerKilled( entity victim, entity attacker, var damageInfo ) +{ + if ( victim != attacker && victim.IsPlayer() && attacker.IsPlayer() && GetGameState() == eGameState.Playing ) + { + AddTeamScore( attacker.GetTeam(), 1 ) + // why isn't this PGS_SCORE? odd game + attacker.AddToPlayerGameStat( PGS_ASSAULT_SCORE, 1 ) + } +}
\ No newline at end of file diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_tffa.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_tffa.gnut new file mode 100644 index 00000000..5a5a3b9c --- /dev/null +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/cl_gamemode_tffa.gnut @@ -0,0 +1,28 @@ +global function ClGamemodeTFFA_Init + +void function ClGamemodeTFFA_Init() +{ + // register gamestate asset, this is default so not necessary but doing it anyway + ClGameState_RegisterGameStateAsset( $"ui/gamestate_info_ffa.rpak" ) + + // add music for mode, this is copied directly from the attrition/tdm music registered in cl_music.gnut + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "music_mp_pilothunt_intro_flyin", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_INTRO, "music_mp_pilothunt_intro_flyin", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_WIN, "music_mp_pilothunt_epilogue_win", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_WIN, "music_mp_pilothunt_epilogue_win", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_DRAW, "music_mp_pilothunt_epilogue_win", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_DRAW, "music_mp_pilothunt_epilogue_win", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LOSS, "music_mp_pilothunt_epilogue_lose", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LOSS, "music_mp_pilothunt_epilogue_lose", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.GAMEMODE_1, "music_mp_pilothunt_almostdone", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.GAMEMODE_1, "music_mp_pilothunt_almostdone", TEAM_MILITIA ) + + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LAST_MINUTE, "music_mp_pilothunt_lastminute", TEAM_IMC ) + RegisterLevelMusicForTeam( eMusicPieceID.LEVEL_LAST_MINUTE, "music_mp_pilothunt_lastminute", TEAM_MILITIA ) + + AddCallback_GameStateEnter( eGameState.Postmatch, DisplayPostMatchTop3 ) +}
\ No newline at end of file diff --git a/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_tffa.gnut b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_tffa.gnut new file mode 100644 index 00000000..a45e59a4 --- /dev/null +++ b/Northstar.Custom/mod/scripts/vscripts/gamemodes/sh_gamemode_tffa.gnut @@ -0,0 +1,39 @@ +global function Sh_GamemodeTFFA_Init + +global const string GAMEMODE_TFFA = "tffa" + +void function Sh_GamemodeTFFA_Init() +{ + AddCallback_OnCustomGamemodesInit( CreateGamemodeTFFA ) +} + +void function CreateGamemodeTFFA() +{ + GameMode_Create( GAMEMODE_TFFA ) + GameMode_SetName( GAMEMODE_TFFA, "#GAMEMODE_TFFA" ) + GameMode_SetDesc( GAMEMODE_TFFA, "#PL_tffa_desc" ) + GameMode_SetGameModeAnnouncement( GAMEMODE_TFFA, "ffa_modeDesc" ) + GameMode_SetDefaultTimeLimits( GAMEMODE_TFFA, 10, 0.0 ) + GameMode_AddScoreboardColumnData( GAMEMODE_TFFA, "#SCOREBOARD_TITAN_KILLS", PGS_TITAN_KILLS, 2 ) + GameMode_AddScoreboardColumnData( GAMEMODE_TFFA, "#SCOREBOARD_TITAN_DAMAGE", PGS_ASSAULT_SCORE, 6 ) + GameMode_SetColor( GAMEMODE_TFFA, [147, 204, 57, 255] ) + + AddPrivateMatchMode( GAMEMODE_TFFA ) + + GameMode_SetDefaultScoreLimits( GAMEMODE_TFFA, 20, 0) + + #if SERVER + GameMode_AddServerInit( GAMEMODE_TFFA, GamemodeTFFA_Init ) + GameMode_AddServerInit( GAMEMODE_TFFA, GamemodeFFAShared_Init ) + GameMode_SetPilotSpawnpointsRatingFunc( GAMEMODE_TFFA, RateSpawnpoints_Generic ) + GameMode_SetTitanSpawnpointsRatingFunc( GAMEMODE_TFFA, RateSpawnpoints_Generic ) + #elseif CLIENT + GameMode_AddClientInit( GAMEMODE_TFFA, ClGamemodeTFFA_Init ) + GameMode_AddClientInit( GAMEMODE_TFFA, GamemodeFFAShared_Init ) + GameMode_AddClientInit( GAMEMODE_TFFA, ClGamemodeTFFA_Init ) + #endif + #if !UI + GameMode_SetScoreCompareFunc( GAMEMODE_TFFA, CompareAssaultScore ) + GameMode_AddSharedInit( GAMEMODE_TFFA, GamemodeFFA_Dialogue_Init ) + #endif +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut index 73277371..d1f4bd80 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/burnmeter/_burnmeter.gnut @@ -293,6 +293,9 @@ void function PlayerUsesAmpedWeaponsBurncardThreaded( entity player ) //weapons.extend( player.GetOffhandWeapons() ) // idk? unsure of vanilla behaviour here
foreach ( entity weapon in weapons )
{
+ if( weapon.GetWeaponPrimaryClipCountMax() > 0 )
+ weapon.SetWeaponPrimaryClipCount( weapon.GetWeaponPrimaryClipCountMax() ) // kind of a fix to get ammo to full, cba to give new weapon
+
weapon.RemoveMod( "silencer" ) // both this and the burnmod will override firing fx, if a second one overrides this we crash
foreach ( string mod in GetWeaponBurnMods( weapon.GetWeaponClassName() ) )
{
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut index b75ed51b..573ea72f 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_at.nut @@ -1,6 +1,5 @@ global function GamemodeAt_Init global function RateSpawnpoints_AT -global function RateSpawnpoints_SpawnZones void function GamemodeAt_Init() { @@ -10,9 +9,4 @@ void function GamemodeAt_Init() void function RateSpawnpoints_AT( int checkclass, array<entity> spawnpoints, int team, entity player ) { RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) // temp -} - -void function RateSpawnpoints_SpawnZones( int checkclass, array<entity> spawnpoints, int team, entity player ) -{ - RateSpawnpoints_Generic( checkclass, spawnpoints, team, player ) // temp }
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut index 7eec7c89..4f05d87a 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_ps.nut @@ -1,4 +1,16 @@ +untyped
global function GamemodePs_Init
+global function RateSpawnpoints_SpawnZones
+
+struct {
+ array<entity> spawnzones
+
+ entity militiaActiveSpawnZone
+ entity imcActiveSpawnZone
+
+ array<entity> militiaPreviousSpawnZones
+ array<entity> imcPreviousSpawnZones
+} file
void function GamemodePs_Init()
{
@@ -8,6 +20,12 @@ void function GamemodePs_Init() ScoreEvent_SetupEarnMeterValuesForMixedModes()
SetTimeoutWinnerDecisionFunc( CheckScoreForDraw )
+ // spawnzone stuff
+ AddCallback_OnPlayerKilled( CheckSpawnzoneSuspiciousDeaths )
+ AddSpawnCallbackEditorClass( "trigger_multiple", "trigger_mp_spawn_zone", SpawnzoneTriggerInit )
+
+ file.militiaPreviousSpawnZones = [ null, null, null ]
+ file.imcPreviousSpawnZones = [ null, null, null ]
}
void function GiveScoreForPlayerKill( entity victim, entity attacker, var damageInfo )
@@ -18,10 +36,186 @@ void function GiveScoreForPlayerKill( entity victim, entity attacker, var damage int function CheckScoreForDraw()
{
- if (GameRules_GetTeamScore(TEAM_IMC) > GameRules_GetTeamScore(TEAM_MILITIA))
+ if ( GameRules_GetTeamScore( TEAM_IMC ) > GameRules_GetTeamScore( TEAM_MILITIA ) )
return TEAM_IMC
- else if (GameRules_GetTeamScore(TEAM_MILITIA) > GameRules_GetTeamScore(TEAM_IMC))
+ else if ( GameRules_GetTeamScore( TEAM_MILITIA ) > GameRules_GetTeamScore( TEAM_IMC ) )
return TEAM_MILITIA
return TEAM_UNASSIGNED
+}
+
+// spawnzone logic
+void function SpawnzoneTriggerInit( entity spawnzone )
+{
+ // initialise spawnzone script vars
+ spawnzone.s.lastDeathRateCheck <- 0.0
+ spawnzone.s.numRecentSuspiciousDeaths <- 0
+ spawnzone.s.minimapObj <- null
+
+ file.spawnzones.append( spawnzone )
+}
+
+void function SetNewSpawnzoneForTeam( int team, entity spawnzone )
+{
+ entity minimapObj = CreatePropScript( $"models/dev/empty_model.mdl", spawnzone.GetOrigin() )
+ SetTeam( minimapObj, team )
+ minimapObj.Minimap_SetObjectScale( 100.0 / Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) )
+ minimapObj.Minimap_SetAlignUpright( true )
+ minimapObj.Minimap_AlwaysShow( TEAM_IMC, null )
+ minimapObj.Minimap_AlwaysShow( TEAM_MILITIA, null )
+ minimapObj.Minimap_SetHeightTracking( true )
+ minimapObj.Minimap_SetZOrder( MINIMAP_Z_OBJECT )
+
+ if ( team == TEAM_IMC )
+ {
+ if ( IsValid( file.imcActiveSpawnZone ) )
+ file.imcActiveSpawnZone.s.minimapObj.Destroy()
+
+ // update last 3 zones
+ file.imcPreviousSpawnZones[ 2 ] = file.imcPreviousSpawnZones[ 1 ]
+ file.imcPreviousSpawnZones[ 1 ] = file.imcPreviousSpawnZones[ 0 ]
+ file.imcPreviousSpawnZones[ 0 ] = file.imcActiveSpawnZone
+
+ file.imcActiveSpawnZone = spawnzone
+ minimapObj.Minimap_SetCustomState( eMinimapObject_prop_script.SPAWNZONE_IMC )
+ }
+ else
+ {
+ if ( IsValid( file.militiaActiveSpawnZone ) )
+ file.militiaActiveSpawnZone.s.minimapObj.Destroy()
+
+ // update last 3 zones
+ file.militiaPreviousSpawnZones[ 2 ] = file.militiaPreviousSpawnZones[ 1 ]
+ file.militiaPreviousSpawnZones[ 1 ] = file.militiaPreviousSpawnZones[ 0 ]
+ file.militiaPreviousSpawnZones[ 0 ] = file.militiaActiveSpawnZone
+
+ file.militiaActiveSpawnZone = spawnzone
+ minimapObj.Minimap_SetCustomState( eMinimapObject_prop_script.SPAWNZONE_MIL )
+ }
+
+ minimapObj.DisableHibernation()
+
+ spawnzone.s.minimapObj = minimapObj
+ spawnzone.s.lastDeathRateCheck = 0.0
+ spawnzone.s.numRecentSuspiciousDeaths = Time()
+}
+
+void function CheckSpawnzoneSuspiciousDeaths( entity victim, entity attacker, var damageInfo )
+{
+ if ( victim.s.respawnTime + 10.0 < Time() )
+ return
+
+ entity spawnzone
+ if ( victim.GetTeam() == TEAM_IMC )
+ spawnzone = file.imcActiveSpawnZone
+ else
+ spawnzone = file.militiaActiveSpawnZone
+
+ if ( Distance2D( victim.GetOrigin(), spawnzone.GetOrigin() ) <= Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) * 1.2 )
+ spawnzone.s.numRecentSuspiciousDeaths++
+}
+
+entity function FindNewSpawnZone( int team )
+{
+ array<entity> startSpawns = SpawnPoints_GetPilotStart( team )
+ array<entity> enemyStartSpawns = SpawnPoints_GetPilotStart( GetOtherTeam( team ) )
+
+ // get average friendly startspawn position
+ vector averageFriendlySpawns
+ foreach ( entity spawn in startSpawns )
+ averageFriendlySpawns += spawn.GetOrigin()
+ averageFriendlySpawns /= startSpawns.len()
+
+ // get average enemy startspawn position
+ vector averageEnemySpawns
+ foreach ( entity spawn in enemyStartSpawns )
+ averageEnemySpawns += spawn.GetOrigin()
+ averageEnemySpawns /= enemyStartSpawns.len()
+
+ array<entity> validZones
+ array<entity> enemyPlayers = GetPlayerArrayOfTeam( GetOtherTeam( team ) )
+ float averageFriendlySpawnDist
+
+ foreach ( entity spawnzone in file.spawnzones )
+ {
+ if ( team == TEAM_IMC && file.imcPreviousSpawnZones.contains( spawnzone ) )
+ continue
+ else if ( file.militiaPreviousSpawnZones.contains( spawnzone ) )
+ continue
+
+ // check if it's too far from startspawns
+ float friendlySpawnDist = Distance2D( spawnzone.GetOrigin(), averageFriendlySpawns )
+ if ( friendlySpawnDist > Distance2D( averageFriendlySpawns, averageEnemySpawns ) * 1.2 )
+ continue
+
+ // check if it's safe atm
+ bool safe = true
+ foreach ( entity enemy in enemyPlayers )
+ {
+ if ( Distance2D( enemy.GetOrigin(), spawnzone.GetOrigin() ) < Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) * 1.2 )
+ {
+ safe = false
+ break
+ }
+ }
+
+ if ( !safe )
+ continue
+
+ averageFriendlySpawnDist += friendlySpawnDist
+ validZones.append( spawnzone )
+ }
+
+ averageFriendlySpawnDist /= validZones.len()
+
+ array<entity> realValidZones = clone validZones
+ foreach ( entity validzone in validZones )
+ {
+ if ( Distance2D( averageFriendlySpawns, validzone.GetOrigin() ) < averageFriendlySpawnDist * 1.4 )
+ realValidZones.append( validzone )
+ }
+
+ entity spawnzone = realValidZones.getrandom()
+ SetNewSpawnzoneForTeam( team, spawnzone )
+
+ return spawnzone
+}
+
+void function RateSpawnpoints_SpawnZones( int checkClass, array<entity> spawnpoints, int team, entity player )
+{
+ entity spawnzone
+ if ( player.GetTeam() == TEAM_IMC )
+ spawnzone = file.imcActiveSpawnZone
+ else
+ spawnzone = file.militiaActiveSpawnZone
+
+ // spawnzones don't exist yet, create them now
+ if ( !IsValid( spawnzone ) )
+ spawnzone = FindNewSpawnZone( player.GetTeam() )
+
+ // check if we should shift spawnzones
+ // if it's been more than 15 seconds since last check, reset
+ if ( spawnzone.s.lastDeathRateCheck + 15.0 < Time() )
+ {
+ spawnzone.s.numRecentSuspiciousDeaths = 0
+ spawnzone.s.lastDeathRateCheck = Time()
+ }
+
+ // check if we've gone over the threshold for recent deaths too close to our current spawnzone
+ if ( spawnzone.s.numRecentSuspiciousDeaths >= GetPlayerArrayOfTeam( player.GetTeam() ).len() * 0.4 )
+ // over the threshold, find a new spawn zone
+ spawnzone = FindNewSpawnZone( player.GetTeam() )
+
+ // rate spawnpoints
+ foreach ( entity spawn in spawnpoints )
+ {
+ float rating = 0.0
+ float distance = Distance2D( spawn.GetOrigin(), spawnzone.GetOrigin() )
+ if ( distance < Distance2D( < 0, 0, 0 >, spawnzone.GetBoundingMaxs() ) )
+ rating = 100.0
+ else // max 35 rating if not in zone, rate by closest
+ rating = 35.0 * ( 1 - ( distance / 5000.0 ) )
+
+ spawn.CalculateRating( checkClass, player.GetTeam(), rating, rating )
+ }
}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut index 974481c1..207af721 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/gamemodes/_gamemode_speedball.nut @@ -23,6 +23,7 @@ void function GamemodeSpeedball_Init() AddCallback_GameStateEnter( eGameState.Prematch, CreateFlagIfNoFlagSpawnpoint ) AddCallback_GameStateEnter( eGameState.Playing, ResetFlag ) + AddCallback_GameStateEnter( eGameState.WinnerDetermined,GamemodeSpeedball_OnWinnerDetermined) AddCallback_OnTouchHealthKit( "item_flag", OnFlagCollected ) AddCallback_OnPlayerKilled( OnPlayerKilled ) SetTimeoutWinnerDecisionFunc( TimeoutCheckFlagHolder ) @@ -147,3 +148,9 @@ int function TimeoutCheckFlagHolder() return file.flagCarrier.GetTeam() } + +void function GamemodeSpeedball_OnWinnerDetermined() +{ + if(IsValid(file.flagCarrier)) + file.flagCarrier.AddToPlayerGameStat( PGS_ASSAULT_SCORE, 1 ) +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut index b8cd67ad..4b2e539c 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut @@ -222,6 +222,7 @@ void function CodeCallback_OnPlayerRespawned( entity player ) player.SetPredictionEnabled( true ) Loadouts_TryGivePilotLoadout( player ) SetHumanRagdollImpactTable( player ) + ClearLastAttacker( player ) // so dying to anything doesn't credit the same attacker after respawning foreach ( entity weapon in player.GetMainWeapons() ) weapon.SetProScreenOwner( player ) @@ -261,7 +262,7 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga player.SetNoTargetSmartAmmo( false ) player.ClearExtraWeaponMods() - player.AddToPlayerGameStat( PGS_DEATHS, 1 ) + if ( player.IsTitan() ) SoulDies( player.GetTitanSoul(), damageInfo ) // cleanup some titan stuff, no idea where else to put this @@ -303,7 +304,10 @@ void function PostDeathThread_MP( entity player, var damageInfo ) // based on ga player.SetObserverTarget( null ) if ( !file.playerDeathsHidden ) + { + player.AddToPlayerGameStat( PGS_DEATHS, 1 ) Remote_CallFunction_NonReplay( player, "ServerCallback_YouDied", attacker.GetEncodedEHandle(), GetHealthFrac( attacker ), methodOfDeath ) + } float deathcamLength = GetDeathCamLength( player ) wait deathcamLength @@ -630,4 +634,4 @@ float function GetTitanBuildTime(entity player) void function TitanPlayerHotDropsIntoLevel( entity player ) { -}
\ No newline at end of file +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut index 598b4522..2d39cf2d 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut @@ -15,6 +15,7 @@ global function SetRoundWinningKillReplayAttacker global function SetWinner global function SetTimeoutWinnerDecisionFunc global function AddTeamScore +global function GetWinningTeamWithFFASupport global function GameState_GetTimeLimitOverride global function IsRoundBasedGameOver @@ -231,10 +232,7 @@ void function GameStateEnter_Playing_Threaded() if ( file.timeoutWinnerDecisionFunc != null ) winningTeam = file.timeoutWinnerDecisionFunc() else - winningTeam = GetWinningTeam() - - if ( winningTeam == -1 ) - winningTeam = TEAM_UNASSIGNED + winningTeam = GetWinningTeamWithFFASupport() if ( file.switchSidesBased && !file.hasSwitchedSides && !IsRoundBased() ) // in roundbased modes, we handle this in setwinner SetGameState( eGameState.SwitchingSides ) @@ -264,9 +262,7 @@ void function GameStateEnter_WinnerDetermined() void function GameStateEnter_WinnerDetermined_Threaded() { // do win announcement - int winningTeam = GetWinningTeam() - if ( winningTeam == -1 ) - winningTeam = TEAM_UNASSIGNED + int winningTeam = GetWinningTeamWithFFASupport() foreach ( entity player in GetPlayerArray() ) { @@ -334,9 +330,7 @@ void function GameStateEnter_WinnerDetermined_Threaded() int roundsPlayed = expect int ( GetServerVar( "roundsPlayed" ) ) SetServerVar( "roundsPlayed", roundsPlayed + 1 ) - int winningTeam = GetWinningTeam() - if ( winningTeam == -1 ) - winningTeam = TEAM_UNASSIGNED + int winningTeam = GetWinningTeamWithFFASupport() int highestScore = GameRules_GetTeamScore( winningTeam ) int roundScoreLimit = GameMode_GetRoundScoreLimit( GAMETYPE ) @@ -801,6 +795,35 @@ void function SetTimeoutWinnerDecisionFunc( int functionref() callback ) file.timeoutWinnerDecisionFunc = callback } +int function GetWinningTeamWithFFASupport() +{ + if ( !IsFFAGame() ) + return GameScore_GetWinningTeam() + else + { + // custom logic for calculating ffa winner as GameScore_GetWinningTeam doesn't handle this + int winningTeam = TEAM_UNASSIGNED + int winningScore = 0 + + foreach ( entity player in GetPlayerArray() ) + { + int currentScore = GameRules_GetTeamScore( player.GetTeam() ) + + if ( currentScore == winningScore ) + winningTeam = TEAM_UNASSIGNED // if 2 teams are equal, return TEAM_UNASSIGNED + else if ( currentScore > winningScore ) + { + winningTeam = player.GetTeam() + winningScore = currentScore + } + } + + return winningTeam + } + + unreachable +} + // idk float function GameState_GetTimeLimitOverride() diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut index 002b1331..7b86a1d8 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut @@ -95,7 +95,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag // have to do this early before we reset victim's player killstreaks // nemesis when you kill a player that is dominating you - if ( attacker.IsPlayer() && attacker in victim.p.playerKillStreaks && victim.p.playerKillStreaks[ attacker ] == NEMESIS_KILL_REQUIREMENT ) + if ( attacker.IsPlayer() && attacker in victim.p.playerKillStreaks && victim.p.playerKillStreaks[ attacker ] >= NEMESIS_KILL_REQUIREMENT ) AddPlayerScore( attacker, "Nemesis" ) // reset killstreaks on specific players @@ -108,7 +108,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag if ( !attacker.IsPlayer() ) return - + attacker.p.numberOfDeathsSinceLastKill = 0 // since they got a kill, remove the comeback trigger // pilot kill AddPlayerScore( attacker, "KillPilot", victim ) @@ -145,7 +145,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag attacker.p.playerKillStreaks[ victim ]++ // dominating - if ( attacker.p.playerKillStreaks[ victim ] == DOMINATING_KILL_REQUIREMENT ) + if ( attacker.p.playerKillStreaks[ victim ] >= DOMINATING_KILL_REQUIREMENT ) AddPlayerScore( attacker, "Dominating" ) if ( Time() - attacker.s.lastKillTime > CASCADINGKILL_REQUIREMENT_TIME ) @@ -163,7 +163,7 @@ void function ScoreEvent_PlayerKilled( entity victim, entity attacker, var damag AddPlayerScore( attacker, "DoubleKill" ) else if ( attacker.s.currentTimedKillstreak == TRIPLEKILL_REQUIREMENT_KILLS ) AddPlayerScore( attacker, "TripleKill" ) - else if ( attacker.s.currentTimedKillstreak == MEGAKILL_REQUIREMENT_KILLS ) + else if ( attacker.s.currentTimedKillstreak >= MEGAKILL_REQUIREMENT_KILLS ) AddPlayerScore( attacker, "MegaKill" ) } |