You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
9.5 KiB
241 lines
9.5 KiB
/** |
|
* API that provides functions for outputting text in |
|
* Killing Floor's console. It takes care of coloring output and breaking up |
|
* long lines (since allowing game to handle line breaking completely |
|
* messes up console output). |
|
* |
|
* Actual output is taken care of by `ConsoleWriter` objects that this |
|
* API generates. |
|
* Copyright 2020 Anton Tarasenko |
|
*------------------------------------------------------------------------------ |
|
* This file is part of Acedia. |
|
* |
|
* Acedia is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* Acedia is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. |
|
*/ |
|
class ConsoleAPI extends AcediaObject |
|
config(AcediaSystem); |
|
|
|
/** |
|
* Main issue with console output in Killing Floor is |
|
* automatic line breaking of long enough messages: |
|
* it breaks formatting and can lead to an ugly text overlapping. |
|
* To fix this we will try to break up user's output into lines ourselves, |
|
* before game does it for us. |
|
* |
|
* We are not 100% sure how Killing Floor decides when to break the line, |
|
* but it seems to calculate how much text can actually fit in a certain |
|
* area on screen. |
|
* There are two issues: |
|
* 1. We do not know for sure what this limit value is. |
|
* Even if we knew how to compute it, we cannot do that in server mode, |
|
* since it depends on a screen resolution and font, which |
|
* can vary for different players. |
|
* 2. Even invisible characters, such as color change sequences, |
|
* that do not take any space on the screen, contribute towards |
|
* that limit. So for a heavily colored text we will have to |
|
* break line much sooner than for the plain text. |
|
* Both issues are solved by introducing two limits that users themselves |
|
* are allowed to change: visible character limit and total character limit. |
|
* ~ Total character limit will be a hard limit on a character amount in |
|
* a line (including hidden ones used for color change sequences) that |
|
* will be used to prevent Killing Floor's native line breaks. |
|
* ~ Visible character limit will be a lower limit on amount of actually |
|
* visible character. It introduction basically reserves some space that can be |
|
* used only for color change sequences. Without this limit lines with |
|
* colored lines will appear to be shorter that mono-colored ones. |
|
* Visible limit will help to alleviate this problem. |
|
* |
|
* For example, if we set total limit to `120` and visible limit to `80`: |
|
* 1. Line not formatted with color will all break at |
|
* around length of `80`. |
|
* 2. Since color change sequence consists of 4 characters: |
|
* we can fit up to `(120 - 80) / 4 = 10` color swaps into each line, |
|
* while still breaking them at a around the same length of `80`. |
|
* ~ To differentiate our line breaks from line breaks intended by |
|
* the user, we will also add 2 symbols worth of padding in front of all our |
|
* output: |
|
* 1. Before intended new line they will be just two spaces. |
|
* 2. After our line break we will replace first space with "|" to indicate |
|
* that we had to break a long line. |
|
* |
|
* Described measures are not perfect: |
|
* 1. Since Killing Floor's console does not use monospaced font, |
|
* the same amount of characters on the line does not mean lines of |
|
* visually the same length; |
|
* 2. Heavily enough colored lines are still going to be shorter; |
|
* 3. Depending on a resolution, default limits may appear to either use |
|
* too little space (for high resolutions) or, on the contrary, |
|
* not prevent native line breaks (low resolutions). |
|
* In these cases user might be required to manually set limits; |
|
* 4. There are probably more. |
|
* But if seems to provide good enough results for the average use case. |
|
*/ |
|
|
|
/** |
|
* Configures how text will be rendered in target console(s). |
|
*/ |
|
struct ConsoleDisplaySettings |
|
{ |
|
// What color to use for text by default |
|
var Color defaultColor; |
|
// How many visible characters in be displayed in a line? |
|
var int maxVisibleLineWidth; |
|
// How many total characters can be output at once? |
|
var int maxTotalLineWidth; |
|
}; |
|
// We will store data for `ConsoleDisplaySettings` separately for the ease of |
|
// configuration. |
|
var private config Color defaultColor; |
|
var private config int maxVisibleLineWidth; |
|
var private config int maxTotalLineWidth; |
|
|
|
/** |
|
* Return current global visible limit that describes how many (at most) |
|
* visible characters can be output in the console line. |
|
* |
|
* Instances of `ConsoleWriter` are initialized with this value, |
|
* but can later change this value independently. |
|
* Changes to global values do not affect already created `ConsoleWriters`. |
|
* |
|
* @return Current global visible limit. |
|
*/ |
|
public final function int GetVisibleLineLength() |
|
{ |
|
return maxVisibleLineWidth; |
|
} |
|
|
|
/** |
|
* Sets current global visible limit that describes how many (at most) visible |
|
* characters can be output in the console line. |
|
* |
|
* Instances of `ConsoleWriter` are initialized with this value, |
|
* but can later change this value independently. |
|
* Changes to global values do not affect already created `ConsoleWriters`. |
|
* |
|
* @param newMaxVisibleLineWidth New global visible character limit. |
|
*/ |
|
public final function SetVisibleLineLength(int newMaxVisibleLineWidth) |
|
{ |
|
maxVisibleLineWidth = newMaxVisibleLineWidth; |
|
} |
|
|
|
/** |
|
* Return current global total limit that describes how many (at most) |
|
* characters can be output in the console line. |
|
* |
|
* Instances of `ConsoleWriter` are initialized with this value, |
|
* but can later change this value independently. |
|
* Changes to global values do not affect already created `ConsoleWriters`. |
|
* |
|
* @return Current global total limit. |
|
*/ |
|
public final function int GetTotalLineLength() |
|
{ |
|
return maxTotalLineWidth; |
|
} |
|
|
|
/** |
|
* Sets current global total limit that describes how many (at most) |
|
* characters can be output in the console line, counting both visible symbols |
|
* and color change sequences. |
|
* |
|
* Instances of `ConsoleWriter` are initialized with this value, |
|
* but can later change this value independently. |
|
* Changes to global values do not affect already created `ConsoleWriters`. |
|
* |
|
* @param newMaxTotalLineWidth New global total character limit. |
|
*/ |
|
public final function SetTotalLineLength(int newMaxTotalLineWidth) |
|
{ |
|
maxTotalLineWidth = newMaxTotalLineWidth; |
|
} |
|
|
|
/** |
|
* Return current global total limit that describes how many (at most) |
|
* characters can be output in the console line. |
|
* |
|
* Instances of `ConsoleWriter` are initialized with this value, |
|
* but can later change this value independently. |
|
* Changes to global values do not affect already created `ConsoleWriters`. |
|
* |
|
* @return Current default output color. |
|
*/ |
|
public final function Color GetDefaultColor(int newMaxTotalLineWidth) |
|
{ |
|
return defaultColor; |
|
} |
|
|
|
/** |
|
* Sets current global default color for console output., |
|
* |
|
* Instances of `ConsoleWriter` are initialized with this value, |
|
* but can later change this value independently. |
|
* Changes to global values do not affect already created `ConsoleWriters`. |
|
* |
|
* @param newMaxTotalLineWidth New global default output color. |
|
*/ |
|
public final function SetDefaultColor(Color newDefaultColor) |
|
{ |
|
defaultColor = newDefaultColor; |
|
} |
|
|
|
/** |
|
* Returns new `ConsoleWriter` instance that will write into |
|
* consoles of all players. |
|
* Should be freed after use. |
|
* |
|
* @return ConsoleWriter New `ConsoleWriter` instance, configured to |
|
* write into consoles of all players. |
|
* Guaranteed to not be `none`. |
|
*/ |
|
public final function ConsoleWriter ForAll() |
|
{ |
|
local ConsoleDisplaySettings globalSettings; |
|
globalSettings.defaultColor = defaultColor; |
|
globalSettings.maxTotalLineWidth = maxTotalLineWidth; |
|
globalSettings.maxVisibleLineWidth = maxVisibleLineWidth; |
|
return ConsoleWriter(_.memory.Allocate(class'ConsoleWriter')) |
|
.Initialize(globalSettings).ForAll(); |
|
} |
|
|
|
/** |
|
* Returns new `ConsoleWriter` instance that will write into |
|
* console of the given player. |
|
* Should be freed after use. |
|
* |
|
* @param targetPlayer Player, to whom console we want to write. |
|
* If `none` - returned `ConsoleWriter` would be configured to |
|
* throw messages away. |
|
* @return New `ConsoleWriter` instance, configured to |
|
* write into consoles of all players. |
|
* Guaranteed to not be `none`. |
|
*/ |
|
public final function ConsoleWriter For(APlayer targetPlayer) |
|
{ |
|
local ConsoleDisplaySettings globalSettings; |
|
globalSettings.defaultColor = defaultColor; |
|
globalSettings.maxTotalLineWidth = maxTotalLineWidth; |
|
globalSettings.maxVisibleLineWidth = maxVisibleLineWidth; |
|
return ConsoleWriter(_.memory.Allocate(class'ConsoleWriter')) |
|
.Initialize(globalSettings).ForPlayer(targetPlayer); |
|
} |
|
|
|
defaultproperties |
|
{ |
|
defaultColor = (R=255,G=255,B=255,A=255) |
|
// These should guarantee decent text output even at |
|
// 640x480 shit resolution |
|
maxVisibleLineWidth = 80 |
|
maxTotalLineWidth = 108 |
|
} |