Merge pull request #41 from GenZmeY/MegaLinter

add Mega linter
This commit is contained in:
GenZmeY 2023-05-14 06:45:50 +03:00 committed by GitHub
commit 64a4edf178
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
193 changed files with 1198 additions and 2016 deletions

33
.editorconfig Normal file
View File

@ -0,0 +1,33 @@
root = true
# Global
[*]
indent_style = unset
indent_size = 4
tab_width = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = unset
# Unreal Engine 3 / Source
[*.uc]
indent_style = tab
[*.{uci,upkg}]
# Unreal Engine 3 / i18n
[*.{chn,cht,cze,dan,deu,dut,esl,esn,fra,frc,hun,int,ita,jpn,kor,pol,por,ptb,rus,tur,ukr}]
charset = utf-16le
# Other
[*.md]
indent_style = space
trim_trailing_whitespace = false
[*.yml]
indent_style = space
indent_size = 2
[*.{txt,cfg,conf}]
indent_style = tab

View File

@ -1,8 +0,0 @@
### Details
Tell us exactly what happens, every single detail that you can think of
### Screenshots
Provide a screenshot of the issue so we can debug it's not a user issue
### Steps to reproduce
Tell us how to reproduce the problem, step by step

74
.github/workflows/mega-linter.yml vendored Normal file
View File

@ -0,0 +1,74 @@
---
name: MegaLinter
permissions: read-all
on:
push:
pull_request:
branches: [master]
env:
APPLY_FIXES: none
APPLY_FIXES_EVENT: pull_request
APPLY_FIXES_MODE: commit
DISABLE: SPELL
DISABLE_ERRORS_LINTERS: MARKDOWN_MARKDOWN_LINK_CHECK
EDITORCONFIG_EDITORCONFIG_CHECKER_FILTER_REGEX_EXCLUDE: 'xVoteAnnouncer.upk'
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
jobs:
build:
name: MegaLinter
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
with:
token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
- name: MegaLinter
id: ml
uses: oxsecurity/megalinter@v6
env:
VALIDATE_ALL_CODEBASE: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Archive production artifacts
if: ${{ success() }} || ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: MegaLinter reports
path: |
megalinter-reports
mega-linter.log
- name: Create Pull Request with applied fixes
id: cpr
if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
commit-message: "[MegaLinter] Apply linters automatic fixes"
title: "[MegaLinter] Apply linters automatic fixes"
labels: bot
- name: Create PR output
if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
- name: Prepare commit
if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
run: sudo chown -Rc $UID .git/
- name: Commit and push applied linter fixes
if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'commit' && github.ref != 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository)
uses: stefanzweifel/git-auto-commit-action@v4
with:
branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }}
commit_message: "[MegaLinter] Apply linters fixes"
commit_user_name: megalinter-bot
commit_user_email: nicolas.vuillamy@ox.security

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,9 +1,11 @@
[![](PublicationContent/mutbanner.png)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712) # Server Extension
[![Banner](PublicationContent/mutbanner.png)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712)
[![Steam Workshop](https://img.shields.io/static/v1?message=workshop&logo=steam&labelColor=gray&color=blue&logoColor=white&label=steam%20)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712) [![Steam Workshop](https://img.shields.io/static/v1?message=workshop&logo=steam&labelColor=gray&color=blue&logoColor=white&label=steam%20)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712)
[![Steam Subscriptions](https://img.shields.io/steam/subscriptions/2085786712)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712) [![Steam Subscriptions](https://img.shields.io/steam/subscriptions/2085786712)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712)
[![Steam Favorites](https://img.shields.io/steam/favorites/2085786712)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712) [![Steam Favorites](https://img.shields.io/steam/favorites/2085786712)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712)
[![Steam Update Date](https://img.shields.io/steam/update-date/2085786712)](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712) [![MegaLinter](https://github.com/GenZmeY/KF2-Server-Extension/actions/workflows/mega-linter.yml/badge.svg?branch=master)](https://github.com/GenZmeY/KF2-Server-Extension/actions/workflows/mega-linter.yml)
[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/GenZmeY/KF2-Server-Extension)](https://github.com/GenZmeY/KF2-Server-Extension/tags) [![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/GenZmeY/KF2-Server-Extension)](https://github.com/GenZmeY/KF2-Server-Extension/tags)
[![GitHub top language](https://img.shields.io/github/languages/top/GenZmeY/KF2-Server-Extension)](https://docs.unrealengine.com/udk/Three/WebHome.html) [![GitHub top language](https://img.shields.io/github/languages/top/GenZmeY/KF2-Server-Extension)](https://docs.unrealengine.com/udk/Three/WebHome.html)
[![GitHub](https://img.shields.io/github/license/GenZmeY/KF2-Server-Extension)](LICENSE) [![GitHub](https://img.shields.io/github/license/GenZmeY/KF2-Server-Extension)](LICENSE)
@ -16,7 +18,7 @@
*This is a further development of the ServerExt mutator from [Marco](https://forums.tripwireinteractive.com/index.php?threads/mutator-server-extension-mod.109463) and [Forrest Mark X](https://github.com/ForrestMarkX/KF2-Server-Extension).* *This is a further development of the ServerExt mutator from [Marco](https://forums.tripwireinteractive.com/index.php?threads/mutator-server-extension-mod.109463) and [Forrest Mark X](https://github.com/ForrestMarkX/KF2-Server-Extension).*
# Features ## Features
- RPG elements (traits and stats); - RPG elements (traits and stats);
- New menu system; - New menu system;
- Scoreboard that supports unlimited playercount on server; - Scoreboard that supports unlimited playercount on server;
@ -33,7 +35,7 @@ The full changelog is available on [steam workshop](https://steamcommunity.com/s
**Note:** If you want to build/test/brew/publish a mutator without git-bash and/or scripts, follow [these instructions](https://tripwireinteractive.atlassian.net/wiki/spaces/KF2SW/pages/26247172/KF2+Code+Modding+How-to) instead of what is described here. **Note:** If you want to build/test/brew/publish a mutator without git-bash and/or scripts, follow [these instructions](https://tripwireinteractive.atlassian.net/wiki/spaces/KF2SW/pages/26247172/KF2+Code+Modding+How-to) instead of what is described here.
# Build ## Build
1. Install [Killing Floor 2](https://store.steampowered.com/app/232090/Killing_Floor_2/), Killing Floor 2 - SDK and [git for windows](https://git-scm.com/download/win); 1. Install [Killing Floor 2](https://store.steampowered.com/app/232090/Killing_Floor_2/), Killing Floor 2 - SDK and [git for windows](https://git-scm.com/download/win);
2. open git-bash and go to any folder where you want to store ServerExt sources: 2. open git-bash and go to any folder where you want to store ServerExt sources:
`cd <ANY_FOLDER_YOU_WANT>` `cd <ANY_FOLDER_YOU_WANT>`
@ -46,29 +48,13 @@ The full changelog is available on [steam workshop](https://steamcommunity.com/s
5. The compiled files will be here: 5. The compiled files will be here:
`C:\Users\<USERNAME>\Documents\My Games\KillingFloor2\KFGame\Unpublished\BrewedPC\Script\` `C:\Users\<USERNAME>\Documents\My Games\KillingFloor2\KFGame\Unpublished\BrewedPC\Script\`
# Testing ## Using and configuring ServerExt
Open git-bash in the ServerExt source folder and run command:
`./tools/builder -t`
(or `./tools/builder -ct` if you haven't compiled the mutator yet)
A local single-user test will be launched with parameters from `builder.cfg` (edit this file if you want to test mutator with different parameters).
# Using and configuring ServerExt
A detailed manual is available on the [mod page](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712) in the steam workshop. A detailed manual is available on the [mod page](https://steamcommunity.com/sharedfiles/filedetails/?id=2085786712) in the steam workshop.
# Publication in steam workshop ## Contributing
1. Modify the publish files if necessary, they are in the `PublicationContent`:
> description.txt
> preview.png
> tags.txt
> title.txt
2. Run this command in the source folder: `./tools/builder -cbu`
# Contributing
**Participation is welcome!** **Participation is welcome!**
## Bug reports ### Bug reports
If you find a bug, go to the [issue page](https://github.com/GenZmeY/KF2-Server-Extension/issues) and check if there is a description of your bug. If not, create a new issue. If you find a bug, go to the [issue page](https://github.com/GenZmeY/KF2-Server-Extension/issues) and check if there is a description of your bug. If not, create a new issue.
Describe what the bug looks like and how we can reproduce it. Describe what the bug looks like and how we can reproduce it.
Attach screenshots if you think it might help. Attach screenshots if you think it might help.
@ -77,12 +63,12 @@ If it's a crash issue, be sure to include the `Launch.log` and `Launch_2.log` fi
`C:\Users\<USERNAME>\Documents\My Games\KillingFloor2\KFGame\Logs\` `C:\Users\<USERNAME>\Documents\My Games\KillingFloor2\KFGame\Logs\`
Please note that these files are overwritten every time you start the game/server. Therefore, you must take these files immediately after the game crashes in order not to lose information. Please note that these files are overwritten every time you start the game/server. Therefore, you must take these files immediately after the game crashes in order not to lose information.
## Localization ### Localization
The mutator supports localization and you can help translate it into other languages. The mutator supports localization and you can help translate it into other languages.
It does not require any special knowledge or programming skills, so you just need to know the language into which you will translate. It does not require any special knowledge or programming skills, so you just need to know the language into which you will translate.
Here's a quick guide on how to do it: [localization guide](https://steamcommunity.com/workshop/filedetails/discussion/2085786712/2942494909176752884) Here's a quick guide on how to do it: [localization guide](https://steamcommunity.com/workshop/filedetails/discussion/2085786712/2942494909176752884)
## Contribute code ### Contribute code
You can help improve ServerExt by fixing bugs and adding new features. You can help improve ServerExt by fixing bugs and adding new features.
Before making a pull request, make sure that: Before making a pull request, make sure that:
1. Your code is working correctly. 1. Your code is working correctly.
@ -91,8 +77,8 @@ Before making a pull request, make sure that:
In the description of the pull request, describe the changes you made. In the description of the pull request, describe the changes you made.
# License ## License
[GNU GPLv3](LICENSE) [![license](https://www.gnu.org/graphics/gplv3-with-text-136x68.png)](LICENSE)
*** ***

View File

@ -46,4 +46,5 @@ final function SaveData(FMyCustomChar R)
defaultproperties defaultproperties
{ {
} }

View File

@ -7,4 +7,5 @@ protected function SpecialCringeEffectsfor (Actor Victim, float VictimDist)
defaultproperties defaultproperties
{ {
} }

View File

@ -31,4 +31,5 @@ function UpdateGrenades()
defaultproperties defaultproperties
{ {
} }

View File

@ -44,4 +44,5 @@ function UpdatePlayerInfo(optional bool bForceUpdate)
defaultproperties defaultproperties
{ {
} }

View File

@ -88,4 +88,5 @@ simulated function SetWeaponGroupList(out array<KFWeapon> WeaponList, byte Group
defaultproperties defaultproperties
{ {
} }

View File

@ -62,4 +62,5 @@ function Callback_Equip(int ItemDefinition)
defaultproperties defaultproperties
{ {
} }

View File

@ -98,7 +98,6 @@ function AttachWeaponByItemDefinition(int ItemDefinition)
//setweapon skin //setweapon skin
WeaponAttachment.SetWeaponSkin(ItemDefinition); WeaponAttachment.SetWeaponSkin(ItemDefinition);
} }
defaultproperties defaultproperties

View File

@ -7,4 +7,5 @@ static simulated event bool IsABoss()
defaultproperties defaultproperties
{ {
} }

View File

@ -47,4 +47,5 @@ function PlayAnimation()
defaultproperties defaultproperties
{ {
} }

View File

@ -52,4 +52,5 @@ function SetPerkList()
defaultproperties defaultproperties
{ {
} }

View File

@ -1347,5 +1347,4 @@ defaultproperties
Skins.Add((Id=5303, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Pickup_MIC")) Skins.Add((Id=5303, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Pickup_MIC"))
Skins.Add((Id=5302, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_1P_FieldTested_MIC"), MIC_3P="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_FieldTested_MIC", MIC_Pickup="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Pickup_MIC")) Skins.Add((Id=5302, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_1P_FieldTested_MIC"), MIC_3P="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_FieldTested_MIC", MIC_Pickup="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Pickup_MIC"))
Skins.Add((Id=5301, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_1P_BattleScarred_MIC"), MIC_3P="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_BattleScarred_MIC", MIC_Pickup="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Pickup_MIC")) Skins.Add((Id=5301, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_1P_BattleScarred_MIC"), MIC_3P="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_BattleScarred_MIC", MIC_Pickup="WEP_SkinSet17_MAT.sports_aa12.Vault_Sports_AA12_3P_Pickup_MIC"))
} }

View File

@ -7,6 +7,7 @@ function SpecialMoveStarted(bool bForced, Name PrevMove)
function SpecialMoveEnded(Name PrevMove, Name NextMove) function SpecialMoveEnded(Name PrevMove, Name NextMove)
{ {
} }
defaultproperties defaultproperties

View File

@ -2,4 +2,5 @@ class Ext_TGroupMonster extends Ext_TGroupBase;
defaultproperties defaultproperties
{ {
} }

View File

@ -33,4 +33,5 @@ static final function byte GetMaxLimit(Ext_PerkBase Perk)
defaultproperties defaultproperties
{ {
} }

View File

@ -2,4 +2,5 @@ class Ext_TGroupZEDTime extends Ext_TGroupBase;
defaultproperties defaultproperties
{ {
} }

View File

@ -24,4 +24,5 @@ function Timer()
defaultproperties defaultproperties
{ {
} }

View File

@ -8,4 +8,5 @@ var class<Ext_TraitBase> TraitClass;
defaultproperties defaultproperties
{ {
} }

View File

@ -59,4 +59,5 @@ function PreClientTravel(string PendingURL, ETravelType TravelType, bool bIsSeam
defaultproperties defaultproperties
{ {
} }

View File

@ -53,4 +53,5 @@ function DrawMenu()
defaultproperties defaultproperties
{ {
} }

View File

@ -90,4 +90,5 @@ function HandleMouseClick(bool bRight);
defaultproperties defaultproperties
{ {
} }

View File

@ -56,4 +56,5 @@ function PreDraw()
defaultproperties defaultproperties
{ {
} }

View File

@ -1,928 +0,0 @@
//====================================================================
// HTML Text box, written by Marco
// Simply call SetContents to change window contents.
// Only callback available is for LaunchKFURL.
// ====================================================================
class KFGUI_HTMLTextBox extends KFGUI_MultiComponent;
struct FTextLine
{
var string Text,URL;
var color Color,ALColor;
var Font Font;
var float FontScale;
var byte Align,FontSize;
var int X,Y,XS,YS,Tab,TOffset;
var byte LineSkips;
var array<int> ImgList;
var bool bHasURL,bSplit;
};
var array<FTextLine> Lines;
struct FImageEntry
{
var Surface Img;
var int X,Y,XS,YS,YOffset,XOffset;
var byte Align,Style;
};
var array<FImageEntry> Images;
var FImageEntry BgImage;
var float OldXSize,OldYSize;
var int YSize,HoverOverLinkLine,OldHoverLine;
var() Color BGColor,WhiteColor,BlueColor,RedColor;
var KFGUI_ScrollBarV MyScrollBar;
var string TitleString;
var int CurTab;
var byte DefaultFontSize;
var bool bNeedsInit,bHasSplitLines,bNeedScrollbar;
function InitMenu()
{
Super.InitMenu();
MyScrollBar = KFGUI_ScrollBarV(FindComponentID('Scrollbar'));
}
final function int AddText( string Input, color TextColor, byte TextAlign, byte FontSize, out byte NumSkips )
{
local int i;
i = Lines.Length;
Lines.Length = i+1;
Lines[i].Text = Input;
Lines[i].Color = TextColor;
Lines[i].Align = TextAlign;
Lines[i].FontSize = FontSize;
Lines[i].LineSkips = NumSkips;
Lines[i].Tab = CurTab;
NumSkips = 0;
return i;
}
final function string ParseLinkType( string URL )
{
if( InStr(URL,"//")>0 )
return URL;
if( Left(URL,4)~="ftp." )
return "ftp://"$URL;
return "http://"$URL;
}
final function AddImage( string Input )
{
local string Temp;
local byte Align,Sty;
local Material M;
local int X,Y,XS,YS,i,j,z;
Align = 3;
Temp = GetOption(Input, "ALIGN=");
if (Temp != "")
{
switch( Caps(Temp) )
{
case "LEFT":
case "0":
Align = 0;
break;
case "CENTER":
case "1":
Align = 1;
break;
case "RIGHT":
case "2":
Align = 2;
break;
}
}
Temp = GetOption(Input, "STYLE=");
if (Temp != "")
{
switch( Caps(Temp) )
{
case "NORMAL":
case "0":
Sty = 0;
break;
case "STRETCH":
case "1":
Sty = 1;
break;
case "TILEDX":
case "2":
Sty = 2;
break;
case "TILEDY":
case "3":
Sty = 3;
break;
case "TILED":
case "4":
Sty = 4;
break;
}
}
Temp = GetOption(Input, "SRC=");
if (Temp != "")
M = Surface(DynamicLoadObject(Temp,Class'Surface'));
if( M==None )
M = class'Canvas'.Default.DefaultTexture;
X = int(GetOption(Input, "VSPACE="));
Y = int(GetOption(Input, "HSPACE="));
XS = int(GetOption(Input, "WIDTH="));
YS = int(GetOption(Input, "HEIGHT="));
if( XS==0 )
XS = M.GetSurfaceWidth();
if( YS==0 )
YS = M.GetSurfaceHeight();
i = Images.Length;
Images.Length = i+1;
Images[i].Img = M;
Images[i].XOffset = X;
Images[i].YOffset = Y;
Images[i].XS = XS;
Images[i].YS = YS;
Images[i].Style = Sty;
Images[i].Align = Align;
j = Lines.Length-1;
z = Lines[j].ImgList.Length;
Lines[j].ImgList.Length = z+1;
Lines[j].ImgList[z] = i;
}
final function SetContents( string Input )
{
local string LeftText,HTML,RightText,Output,Temp,Link;
local int Index;
local color TextColor,LinkColor,ALinkColor,OrgTextColor;
local byte Alignment,FontScaler,NextLineSkips;
CurTab = 0;
BGColor.A = 0;
BgImage.Img = None;
Lines.Length = 0;
Images.Length = 0;
TitleString = "";
bHasSplitLines = false;
bNeedsInit = true;
// First remove new liners
Input = Repl(Input, Chr(13)$Chr(10), "");
Input = Repl(Input, Chr(13), "");
Input = Repl(Input, Chr(10), "");
Input = Repl(Input, Chr(9), " ");
Input = Repl(Input, "\\n", "<BR>");
TextColor = WhiteColor;
OrgTextColor = WhiteColor;
LinkColor = BlueColor;
ALinkColor = RedColor;
FontScaler = 3;
DefaultFontSize = 3;
Index = -1;
while (Input != "")
{
ParseHTML(Input, LeftText, HTML, RightText);
switch (GetTag(HTML))
{
// multiline HTML tags
case "P":
Output $= LeftText;
if( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
NextLineSkips = 2;
Output = "";
}
else ++NextLineSkips;
break;
case "BR":
Output $= LeftText;
if( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
NextLineSkips = 1;
Output = "";
}
else ++NextLineSkips;
break;
case "BODY":
Temp = GetOption(HTML, "BGCOLOR=");
if (Temp != "")
BGColor = ParseColor(Temp);
Temp = GetOption(HTML, "LINK=");
if (Temp != "")
LinkColor = ParseColor(Temp);
Temp = GetOption(HTML, "ALINK=");
if (Temp != "")
ALinkColor = ParseColor(Temp);
Temp = GetOption(HTML, "TEXT=");
if (Temp != "")
{
TextColor = ParseColor(Temp);
OrgTextColor = TextColor;
}
Temp = GetOption(HTML, "SIZE=");
if (Temp != "")
{
FontScaler = int(Temp);
DefaultFontSize = FontScaler;
}
Temp = GetOption(Input, "IMG=");
if (Temp != "")
{
if( BGColor.A==0 )
BGColor = Class'Hud'.Default.WhiteColor;
BgImage.Img = Surface(DynamicLoadObject(Temp,Class'Surface'));
if( BgImage.Img==None )
BgImage.Img = Class'Canvas'.Default.DefaultTexture;
BgImage.X = BgImage.Img.GetSurfaceWidth();
BgImage.Y = BgImage.Img.GetSurfaceHeight();
switch( Caps(GetOption(Input, "IMGSTYLE=")) )
{
case "TILED":
BgImage.XS = BgImage.X;
BgImage.YS = BgImage.Y;
BgImage.Style = 1;
Temp = GetOption(Input, "TILEX=");
if (Temp != "")
BgImage.XS = int(Temp);
Temp = GetOption(Input, "TILEY=");
if (Temp != "")
BgImage.YS = int(Temp);
break;
case "FITX":
BgImage.Style = 2;
break;
case "FITY":
BgImage.Style = 3;
break;
default: // FIT
BgImage.Style = 0;
}
BgImage.Align = 0;
if( GetOption(Input, "IMGLOCK=")=="0" )
BgImage.Align = 1;
}
Output $= LeftText;
break;
case "CENTER":
Output $= LeftText;
if ( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
NextLineSkips = Max(NextLineSkips,1);
Alignment = 1;
break;
case "RIGHT":
Output $= LeftText;
if ( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
NextLineSkips = Max(NextLineSkips,1);
Alignment = 2;
break;
case "/CENTER":
case "/RIGHT":
Index = AddText(Output $ LeftText,TextColor,Alignment,FontScaler,NextLineSkips);
++NextLineSkips;
Alignment = 0;
Output = "";
break;
// Inline HTML tags
case "H1":
Output $= LeftText;
if ( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
NextLineSkips = Max(NextLineSkips,1);
FontScaler = 5;
Alignment = 1;
break;
case "/H1":
Index = AddText(Output $ LeftText,TextColor,Alignment,FontScaler,NextLineSkips);
++NextLineSkips;
Output = "";
FontScaler = DefaultFontSize;
Alignment = 0;
break;
case "FONT":
Output $= LeftText;
if( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
Temp = GetOption(HTML, "COLOR=");
if (Temp != "")
TextColor = ParseColor(Temp);
Temp = GetOption(HTML, "SIZE=");
if (Temp != "")
FontScaler = int(Temp);
break;
case "/FONT":
Output $= LeftText;
if( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
TextColor = OrgTextColor;
FontScaler = DefaultFontSize;
break;
case "TAB":
Output $= LeftText;
if( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
CurTab = int(GetOption(HTML, "X="));
break;
case "/TAB":
Output $= LeftText;
if( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
CurTab = 0;
break;
case "TITLE":
Output $= LeftText;
break;
case "/TITLE":
TitleString = LeftText;
break;
case "A":
Output $= LeftText;
if( Output!="" )
{
Index = AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
}
Link = GetOption(HTML, "HREF=");
break;
case "/A":
Output $= LeftText;
Index = AddText(Output,LinkColor,Alignment,FontScaler,NextLineSkips);
Lines[Index].ALColor = ALinkColor;
Lines[Index].bHasURL = true;
if( Link=="" )
Lines[Index].URL = ParseLinkType(Output);
else Lines[Index].URL = ParseLinkType(Link);
Output = "";
FontScaler = DefaultFontSize;
Alignment = 0;
break;
case "IMG":
Output $= LeftText;
if( Output!="" || NextLineSkips>0 )
AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
Output = "";
AddImage(HTML);
break;
default:
Output = Output $ LeftText;
break;
}
Input = RightText;
}
AddText(Output,TextColor,Alignment,FontScaler,NextLineSkips);
}
// Get the next HTML tag, the text before it and everthing after it.
final function ParseHTML(string Input, out string LeftText, out string HTML, out string RightText)
{
local int i;
i = InStr(Input, "<");
if (i == -1)
{
LeftText = Input;
HTML = "";
RightText = "";
return;
}
LeftText = Left(Input, i);
HTML = Mid(Input, i);
i = InStr(HTML, ">");
if (i == -1)
{
RightText = "";
return;
}
RightText = Mid(HTML, i+1);
HTML = Left(HTML, i+1);
}
final function string GetTag(string HTML)
{
local int i;
if (HTML == "")
return "";
HTML = Mid(HTML, 1); // lose <
i = FirstMatching(InStr(HTML, ">"), InStr(HTML, " "));
if (i == -1)
return Caps(HTML);
else
return Caps(Left(HTML, i));
}
final function string GetOption(string HTML, string Option)
{
local int i, j;
local string s;
i = InStr(Caps(HTML), Caps(Option));
if (i == 1 || Mid(HTML, i-1, 1) == " ")
{
s = Mid(HTML, i+Len(Option));
j = FirstMatching(InStr(s, ">"), InStr(s, " "));
s = Left(s, j);
if (Left(s, 1) == "\"")
s = Mid(s, 1);
if (Right(s, 1) == "\"")
s = Left(s, Len(s) - 1);
return s;
}
return "";
}
final function int FirstMatching(int i, int j)
{
if (i == -1)
return j;
if (j == -1)
return i;
return Min(i, j);
}
final function Color ParseColor(string S)
{
local Color C;
local int i;
S = Caps(S);
if (Left(S, 1) == "#")
{
C.R = (GetHexDigit(Mid(S, 1, 1)) << 4) + GetHexDigit(Mid(S, 2, 1));
C.G = (GetHexDigit(Mid(S, 3, 1)) << 4) + GetHexDigit(Mid(S, 4, 1));
C.B = (GetHexDigit(Mid(S, 5, 1)) << 4) + GetHexDigit(Mid(S, 6, 1));
}
else if (Left(S, 4) == "RGB(")
{
S = Mid(S, 4);
i = InStr(S,",");
C.R = int(Left(S,i));
S = Mid(S,i+1);
i = InStr(S,",");
C.G = int(Left(S,i));
C.B = int(Mid(S,i+1));
}
else
{
switch( S )
{
case "RED":
C.R = 255;
C.G = 0;
C.B = 0;
break;
case "BLUE":
C.R = 0;
C.G = 0;
C.B = 255;
break;
case "GREEN":
C.R = 0;
C.G = 255;
C.B = 0;
break;
case "YELLOW":
C.R = 255;
C.G = 255;
C.B = 0;
break;
case "BLACK":
C.R = 0;
C.G = 0;
C.B = 0;
break;
default: // WHITE
C.R = 255;
C.G = 255;
C.B = 255;
}
}
C.A = 255;
return C;
}
final function byte GetHexDigit(string D)
{
local byte i;
i = Asc(D);
if( i>=48 && i<=57 ) // i>='0' && i<='9'
return (i-48); // i-'0'
return Min(i-55,15); // i-('A'-10)
}
final function SplitLine( int iLine, int iOffset )
{
local int i;
local string S;
++iLine;
Lines.Insert(iLine,1);
S = Lines[iLine-1].Text;
for( i=iOffset; i<Len(S); ++i )
if( Mid(S,i,1)!=" " )
break;
Lines[iLine].Text = Mid(S,i);
Lines[iLine-1].Text = Left(S,iOffset);
Lines[iLine].URL = Lines[iLine-1].URL;
Lines[iLine].Color = Lines[iLine-1].Color;
Lines[iLine].ALColor = Lines[iLine-1].ALColor;
Lines[iLine].Align = Lines[iLine-1].Align;
Lines[iLine].FontSize = Lines[iLine-1].FontSize;
Lines[iLine].Tab = Lines[iLine-1].Tab;
Lines[iLine].LineSkips = 1;
Lines[iLine].bHasURL = Lines[iLine-1].bHasURL;
Lines[iLine].bSplit = true;
bHasSplitLines = true;
}
final protected function InitHTMLArea()
{
local float XS,YS;
local int i,j,X,Y,iStart,BestHeight,FontSize,PrevY,Remain,iLastWord,iLen,z,ImgHeight;
// Used to detect resolution changes when text needs realignment.
OldXSize = CompPos[2];
OldYSize = CompPos[3];
// Merge splitted lines again
if( bHasSplitLines )
{
bHasSplitLines = false;
for( i=1; i<Lines.Length; ++i )
{
if( Lines[i].bSplit )
{
Lines[i-1].Text @= Lines[i].Text;
Lines.Remove(i--,1);
}
}
}
// Setup background image scaling
if( BgImage.Img!=None )
{
switch( BgImage.Style )
{
case 1: // Tiled
if( BgImage.X==BgImage.XS )
BgImage.XOffset = Canvas.ClipX;
else
{
XS = Canvas.ClipX / float(BgImage.XS) * float(BgImage.X);
BgImage.XOffset = XS;
}
if( BgImage.Y==BgImage.YS )
BgImage.YOffset = Canvas.ClipY;
else
{
XS = Canvas.ClipY / float(BgImage.YS) * float(BgImage.Y);
BgImage.YOffset = XS;
}
break;
case 2: // Fit X
XS = Canvas.ClipY * (Canvas.ClipX / float(BgImage.X));
BgImage.YS = XS;
break;
case 3: // Fit Y
XS = Canvas.ClipX * (Canvas.ClipY / float(BgImage.Y));
BgImage.XS = XS;
break;
}
}
FontSize = Owner.CurrentStyle.DefaultFontSize;
Canvas.SetPos(0,0);
if( Lines.Length>0 )
{
while( true )
{
if( i>=Lines.Length || (i>0 && Lines[i].LineSkips>0) )
{
for( j=iStart; j<i; ++j )
{
switch( Lines[j].Align )
{
case 0: // Left
Lines[j].X = Lines[j].TOffset;
break;
case 1: // Center
Lines[j].X = (Canvas.ClipX-X+Lines[j].TOffset)/2;
break;
case 2: // Right
Lines[j].X = Canvas.ClipX-X+Lines[j].TOffset;
break;
}
}
if( i>=Lines.Length )
break;
X = 0;
iStart = i;
PrevY = BestHeight;
BestHeight = 0;
}
if( Lines[i].FontSize>=247 )
Lines[i].Font = Owner.CurrentStyle.PickFont(Max(Lines[i].FontSize-247,0),Lines[i].FontScale);
else Lines[i].Font = Owner.CurrentStyle.PickFont(Max(FontSize+Lines[i].FontSize,0),Lines[i].FontScale);
Canvas.Font = Lines[i].Font;
if( Lines[i].Text=="" )
{
Canvas.TextSize("ABC",XS,YS,Lines[i].FontScale,Lines[i].FontScale);
XS = 0;
}
else Canvas.TextSize(Lines[i].Text,XS,YS,Lines[i].FontScale,Lines[i].FontScale);
if( Lines[i].LineSkips>0 )
{
if( PrevY==0 )
PrevY = YS;
Y+=(PrevY*Lines[i].LineSkips);
}
X = Max(X,Lines[i].Tab);
Lines[i].TOffset = X;
Lines[i].Y = Y;
Lines[i].YS = YS;
BestHeight = Max(BestHeight,YS);
if( (X+XS)>Canvas.ClipX )
{
// Split to next row.
Remain = Canvas.ClipX-X;
iLastWord = 0;
iLen = Len(Lines[i].Text);
for( j=1; j<iLen; ++j )
{
Canvas.TextSize(Left(Lines[i].Text,j),XS,YS,Lines[i].FontScale,Lines[i].FontScale);
if( Remain<XS )
{
if( iLastWord==0 ) // Must cut off a word now.
SplitLine(i,Max(j-1,0));
else SplitLine(i,iLastWord);
break;
}
if( Mid(Lines[i].Text,j,1)==" " )
iLastWord = j+1;
}
Canvas.TextSize(Lines[i].Text,XS,YS,Lines[i].FontScale,Lines[i].FontScale);
}
Lines[i].XS = XS;
X+=XS;
for( j=0; j<Lines[i].ImgList.Length; ++j )
{
z = Lines[i].ImgList[j];
if( Images[z].Align==3 )
Images[z].X = X+Images[z].XOffset;
else Images[z].X = Images[z].XOffset;
Images[z].Y = Y+Images[z].YOffset;
ImgHeight = Max(ImgHeight,Images[z].Y+Images[z].YS);
}
++i;
}
YSize = Max(Y+BestHeight,ImgHeight);
}
else YSize = 0;
bNeedScrollbar = (YSize>Canvas.ClipY);
if( bNeedScrollbar )
{
MyScrollBar.SetDisabled(false);
MyScrollBar.UpdateScrollSize(0,YSize,Canvas.ClipY,512);
}
else MyScrollBar.SetDisabled(true);
}
simulated final function DrawTileStretchedClipped( Surface M, float XS, float YS )
{
Canvas.CurX += Canvas.OrgX;
Canvas.CurY += Canvas.OrgY;
if( Canvas.CurX<Canvas.OrgX )
{
XS-=(Canvas.OrgX-Canvas.CurX);
Canvas.CurX = Canvas.OrgX;
}
if( Canvas.CurY<Canvas.OrgY )
{
YS-=(Canvas.OrgY-Canvas.CurY);
Canvas.CurY = Canvas.OrgY;
}
if( (Canvas.CurX+XS)>Canvas.ClipX )
XS = (Canvas.ClipX-Canvas.CurX);
if( (Canvas.CurY+YS)>Canvas.ClipY )
YS = (Canvas.ClipY-Canvas.CurY);
if( Texture(M)!=None )
Canvas.DrawTileStretched(Texture(M),XS,YS);
}
function DrawMenu()
{
local float YS;
local int i,YOffset,MX,MY;
local bool bMouseOnClient;
if( bNeedsInit || OldXSize!=CompPos[2] || OldYSize!=CompPos[3] )
{
bNeedsInit = false;
InitHTMLArea();
}
if( bNeedScrollbar )
YOffset = MyScrollBar.CurrentScroll;
if( BGColor.A>0 )
{
C.SetPos(0,0);
C.DrawColor = BGColor;
if( BgImage.Img!=None )
{
if( BgImage.Align==1 ) // not locked on screen.
MX = YOffset;
switch( BgImage.Style )
{
case 0: // Stretched to fit
C.DrawTileClipped(BgImage.Img,C.ClipX,C.ClipY,0,MX,BgImage.X,BgImage.Y);
break;
case 1: // Tiled
C.DrawTileClipped(BgImage.Img,C.ClipX,C.ClipY,0,MX,BgImage.XOffset,BgImage.YOffset);
break;
case 2: // Fit X
C.DrawTileClipped(BgImage.Img,C.ClipX,C.ClipY,0,MX,BgImage.X,BgImage.YS);
break;
case 3: // Fit Y
C.DrawTileClipped(BgImage.Img,C.ClipX,C.ClipY,0,MX,BgImage.XS,BgImage.Y);
break;
}
}
else C.DrawTile(Texture'WhiteTexture',C.ClipX,C.ClipY,0,0,1,1);
}
MX = Controller.MouseX-C.OrgX;
MY = Controller.MouseY-C.OrgY;
bMouseOnClient = (MX>=0 && MX<=C.ClipX && MY>=0 && MY<=C.ClipY);
HoverOverLinkLine = -1;
MY+=YOffset;
C.DrawColor = Class'HUD'.Default.WhiteColor;
for( i=0; i<Images.Length; ++i )
{
C.CurY = Images[i].Y-YOffset;
if( (C.CurY+Images[i].YS)<0 || C.CurY>C.ClipY )
continue;
switch( Images[i].Align )
{
case 0: // Left
case 3: // Unaligned, postition after text.
C.CurX = 0;
break;
case 1: // Center
C.CurX = (C.ClipX-Images[i].XS)/2;
break;
case 1: // Right
C.CurX = C.ClipX-Images[i].XS;
break;
}
C.CurX += Images[i].X;
switch( Images[i].Style )
{
case 1: // Stretched
DrawTileStretchedClipped(C,Images[i].Img,Images[i].XS,Images[i].YS);
break;
case 2: // Tiled on X axis
C.DrawTileClipped(Images[i].Img,Images[i].XS,Images[i].YS,0,0,Images[i].XS,Images[i].Img.MaterialVSize());
break;
case 3: // Tiled on Y axis
C.DrawTileClipped(Images[i].Img,Images[i].XS,Images[i].YS,0,0,Images[i].Img.MaterialUSize(),Images[i].YS);
break;
case 4: // Fully tiled
C.DrawTileClipped(Images[i].Img,Images[i].XS,Images[i].YS,0,0,Images[i].XS,Images[i].YS);
break;
default: // Normal
C.DrawTileClipped(Images[i].Img,Images[i].XS,Images[i].YS,0,0,Images[i].Img.MaterialUSize(),Images[i].Img.MaterialVSize());
}
}
for( i=0; i<Lines.Length; ++i )
{
C.SetPos(Lines[i].X,Lines[i].Y-YOffset);
if( (C.CurY+Lines[i].YS)<0 || Lines[i].Text=="" )
continue;
if( C.CurY>C.ClipY )
break;
// Check if mouse hovers over URL
if( bMouseOnClient && Lines[i].bHasURL && MX>=Lines[i].X && MX<=(Lines[i].X+Lines[i].XS)
&& MY>=Lines[i].Y && MY<=(Lines[i].Y+Lines[i].YS) )
{
HoverOverLinkLine = i;
bMouseOnClient = false; // No need to check on rest anymore.
C.DrawColor = Lines[i].ALColor;
}
else C.DrawColor = Lines[i].Color;
C.Font = Lines[i].Font;
C.DrawTextClipped(Lines[i].Text);
if( Lines[i].bHasURL )
{
YS = Max(Lines[i].YS/15,1);
C.SetPos(Lines[i].X,Lines[i].Y+Lines[i].YS-(YS*2)-YOffset);
if( C.CurY<C.ClipY )
C.DrawTileClipped(Texture'WhiteTexture',Lines[i].XS,YS,0,0,1,1);
}
}
if( OldHoverLine!=HoverOverLinkLine )
{
OldHoverLine = HoverOverLinkLine;
if( HoverOverLinkLine>=0 )
{
Controller.PlayInterfaceSound(CS_Hover);
SetToolTipText(Lines[HoverOverLinkLine].URL);
}
else SetToolTipText("");
}
}
function bool LaunchURL(GUIComponent Sender)
{
if( HoverOverLinkLine>=0 )
{
if( Left(Lines[HoverOverLinkLine].URL,8)~="kfurl://" )
LaunchKFURL(Mid(Lines[HoverOverLinkLine].URL,8));
else if( Left(Lines[HoverOverLinkLine].URL,5)~="kf://" )
ChangeGameURL(Mid(Lines[HoverOverLinkLine].URL,5));
else LaunchURLPage(Lines[HoverOverLinkLine].URL);
}
}
delegate LaunchKFURL( string URL );
delegate ChangeGameURL( string URL )
{
Class'SRLevelCleanup'.Static.AddSafeCleanup(PlayerOwner(),URL);
}
delegate LaunchURLPage( string URL )
{
PlayerOwner().Player.Console.DelayedConsoleCommand("START "$URL);
}
defaultproperties
{
bNeedsInit=true
PropagateVisibility=true
OnDraw=RenderHTMLText
OnClick=LaunchURL
Begin Object Class=GUIVertScrollBar Name=TheScrollbar
bBoundToParent=true
bScaleToParent=true
WinWidth=0.03
WinLeft=0.97
WinTop=0.0
WinHeight=1.0
bVisible=true
PropagateVisibility=true
OnPreDraw=TheScrollbar.GripPreDraw
End Object
MyScrollBar=TheScrollbar
StyleName="NoBackground"
bAcceptsInput=True
Begin Object Class=GUIToolTip Name=GUIListBoxBaseToolTip
ExpirationSeconds=0
End Object
ToolTip=GUIListBoxBaseToolTip
WhiteColor=(R=255,G=255,B=255,A=255)
BlueColor=(R=0,G=0,B=255,A=255)
RedColor=(R=255,G=0,B=0,A=255)
}

View File

@ -64,4 +64,5 @@ function DrawMenu()
defaultproperties defaultproperties
{ {
} }

View File

@ -2,4 +2,5 @@ Class KFGUI_ScrollBarH extends KFGUI_ScrollBarBase;
defaultproperties defaultproperties
{ {
} }

View File

@ -49,4 +49,5 @@ function DrawMenu()
defaultproperties defaultproperties
{ {
} }

View File

@ -64,4 +64,5 @@ function PreDraw()
defaultproperties defaultproperties
{ {
} }

View File

@ -68,4 +68,5 @@ final function RenderProgress()
defaultproperties defaultproperties
{ {
} }

View File

@ -2,4 +2,5 @@ Class SRPerkManager extends ExtPerkManager;
defaultproperties defaultproperties
{ {
} }

View File

@ -257,4 +257,5 @@ function SetSaveVersion(int Num)
defaultproperties defaultproperties
{ {
} }

View File

@ -34,4 +34,5 @@ event AllowBroadcastLocalizedTeam(int TeamIndex, actor Sender, class<LocalMessag
defaultproperties defaultproperties
{ {
} }