mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
Upload
This commit is contained in:
378
gamemodes/terrortown/gamemode/cl_lang.lua
Normal file
378
gamemodes/terrortown/gamemode/cl_lang.lua
Normal file
@@ -0,0 +1,378 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
---- Clientside language stuff
|
||||
|
||||
-- Need to build custom tables of strings. Can't use language.Add as there is no
|
||||
-- way to access the translated string in Lua. Identifiers only get translated
|
||||
-- when Source/gmod print them. By using our own table and our own lookup, we
|
||||
-- have far more control. Maybe it's slower, but maybe not, we aren't scanning
|
||||
-- strings for "#identifiers" after all.
|
||||
|
||||
LANG.Strings = {}
|
||||
|
||||
local ttt_language = CreateConVar("ttt_language", "auto", FCVAR_ARCHIVE)
|
||||
|
||||
LANG.DefaultLanguage = "english"
|
||||
LANG.ActiveLanguage = LANG.DefaultLanguage
|
||||
|
||||
LANG.ServerLanguage = "english"
|
||||
|
||||
local cached_default, cached_active
|
||||
|
||||
function LANG.CreateLanguage(raw_lang_name)
|
||||
if not raw_lang_name then return end
|
||||
lang_name = string.lower(raw_lang_name)
|
||||
|
||||
if not LANG.IsLanguage(lang_name) then
|
||||
LANG.Strings[lang_name] = {
|
||||
-- Empty string is very convenient to have, so init with that.
|
||||
[""] = "",
|
||||
-- Presentational, not-lowercased language name
|
||||
language_name = raw_lang_name
|
||||
}
|
||||
end
|
||||
|
||||
if lang_name == LANG.DefaultLanguage then
|
||||
cached_default = LANG.Strings[lang_name]
|
||||
|
||||
-- when a string is not found in the active or the default language, an
|
||||
-- error message is shown
|
||||
setmetatable(LANG.Strings[lang_name],
|
||||
{
|
||||
__index = function(tbl, name)
|
||||
return Format("[ERROR: Translation of %s not found]", name), false
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
return LANG.Strings[lang_name]
|
||||
end
|
||||
|
||||
-- Add a string to a language. Should not be used in a language file, only for
|
||||
-- adding strings elsewhere, such as a SWEP script.
|
||||
function LANG.AddToLanguage(lang_name, string_name, string_text)
|
||||
lang_name = lang_name and string.lower(lang_name)
|
||||
|
||||
if not LANG.IsLanguage(lang_name) then
|
||||
ErrorNoHalt(Format("Failed to add '%s' to language '%s': language does not exist.\n", tostring(string_name), tostring(lang_name)))
|
||||
return false
|
||||
end
|
||||
|
||||
LANG.Strings[lang_name][string_name] = string_text
|
||||
|
||||
return string_name
|
||||
end
|
||||
|
||||
-- Simple and fastest name->string lookup
|
||||
function LANG.GetTranslation(name)
|
||||
return cached_active[name]
|
||||
end
|
||||
|
||||
-- Lookup with no error upon failback, just nil. Slightly slower, but best way
|
||||
-- to handle lookup of strings that may legitimately fail to exist
|
||||
-- (eg. SWEP-defined).
|
||||
function LANG.GetRawTranslation(name)
|
||||
return rawget(cached_active, name) or rawget(cached_default, name)
|
||||
end
|
||||
|
||||
-- A common idiom
|
||||
local GetRaw = LANG.GetRawTranslation
|
||||
function LANG.TryTranslation(name)
|
||||
return GetRaw(name) or name
|
||||
end
|
||||
|
||||
local interp = string.Interp
|
||||
|
||||
-- Parameterised version, performs string interpolation. Slower than
|
||||
-- GetTranslation.
|
||||
function LANG.GetParamTranslation(name, params)
|
||||
return interp(cached_active[name], params)
|
||||
end
|
||||
LANG.GetPTranslation = LANG.GetParamTranslation
|
||||
|
||||
function LANG.GetTranslationFromLanguage(name, lang_name)
|
||||
return rawget(LANG.Strings[lang_name], name)
|
||||
end
|
||||
|
||||
-- Ability to perform lookups in the current language table directly is of
|
||||
-- interest to consumers in draw/think hooks. Grabbing a translation directly
|
||||
-- from the table is very fast, and much simpler than a local caching solution.
|
||||
-- Modifying it would typically be a bad idea.
|
||||
function LANG.GetUnsafeLanguageTable() return cached_active end
|
||||
|
||||
function LANG.GetUnsafeNamed(name) return LANG.Strings[name] end
|
||||
|
||||
-- Safe and slow access, not sure if it's ever useful.
|
||||
function LANG.GetLanguageTable(lang_name)
|
||||
lang_name = lang_name or LANG.ActiveLanguage
|
||||
|
||||
local cpy = table.Copy(LANG.Strings[lang_name])
|
||||
SetFallback(cpy)
|
||||
|
||||
return cpy
|
||||
end
|
||||
|
||||
|
||||
local function SetFallback(tbl)
|
||||
-- languages may deal with this themselves, or may already have the fallback
|
||||
local m = getmetatable(tbl)
|
||||
if m and m.__index then return end
|
||||
|
||||
-- Set the __index of the metatable to use the default lang, which makes any
|
||||
-- keys not found in the table to be looked up in the default. This is faster
|
||||
-- than using branching ("return lang[x] or default[x] or errormsg") and
|
||||
-- allows fallback to occur even when consumer code directly accesses the
|
||||
-- lang table for speed (eg. in a rendering hook).
|
||||
setmetatable(tbl,
|
||||
{
|
||||
__index = cached_default
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
function LANG.SetActiveLanguage(lang_name)
|
||||
lang_name = lang_name and string.lower(lang_name)
|
||||
|
||||
if LANG.IsLanguage(lang_name) then
|
||||
local old_name = LANG.ActiveLanguage
|
||||
LANG.ActiveLanguage = lang_name
|
||||
|
||||
-- cache ref to table to avoid hopping through LANG and Strings every time
|
||||
cached_active = LANG.Strings[lang_name]
|
||||
|
||||
-- set the default lang as fallback, if it hasn't yet
|
||||
SetFallback(cached_active)
|
||||
|
||||
-- some interface elements will want to know so they can update themselves
|
||||
if old_name != lang_name then
|
||||
hook.Call("TTTLanguageChanged", GAMEMODE, old_name, lang_name)
|
||||
end
|
||||
else
|
||||
MsgN(Format("The language '%s' does not exist on this server. Falling back to English...", lang_name))
|
||||
|
||||
-- fall back to default if possible
|
||||
if lang_name != LANG.DefaultLanguage then
|
||||
LANG.SetActiveLanguage(LANG.DefaultLanguage)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function LANG.Init()
|
||||
local lang_name = ttt_language:GetString()
|
||||
|
||||
-- if we want to use the server language, we'll be switching to it as soon as
|
||||
-- we hear from the server which one it is, for now use default
|
||||
if LANG.IsServerDefault(lang_name) then
|
||||
lang_name = LANG.ServerLanguage
|
||||
end
|
||||
|
||||
LANG.SetActiveLanguage(lang_name)
|
||||
end
|
||||
|
||||
function LANG.IsServerDefault(lang_name)
|
||||
lang_name = string.lower(lang_name)
|
||||
return lang_name == "server default" or lang_name == "auto"
|
||||
end
|
||||
|
||||
function LANG.IsLanguage(lang_name)
|
||||
lang_name = lang_name and string.lower(lang_name)
|
||||
return LANG.Strings[lang_name]
|
||||
end
|
||||
|
||||
local function LanguageChanged(cv, old, new)
|
||||
if new and new != LANG.ActiveLanguage then
|
||||
|
||||
if LANG.IsServerDefault(new) then
|
||||
new = LANG.ServerLanguage
|
||||
end
|
||||
|
||||
LANG.SetActiveLanguage(new)
|
||||
end
|
||||
end
|
||||
cvars.AddChangeCallback("ttt_language", LanguageChanged)
|
||||
|
||||
local function ForceReload()
|
||||
LANG.SetActiveLanguage("english")
|
||||
end
|
||||
concommand.Add("ttt_reloadlang", ForceReload)
|
||||
|
||||
-- Get a copy of all available languages (keys in the Strings tbl)
|
||||
function LANG.GetLanguages()
|
||||
local langs = {}
|
||||
for lang, strings in pairs(LANG.Strings) do
|
||||
table.insert(langs, lang)
|
||||
end
|
||||
return langs
|
||||
end
|
||||
|
||||
function LANG.GetLanguageNames()
|
||||
-- Typically preferable to GetLanguages but separate to avoid API breakage.
|
||||
local lang_names = {}
|
||||
for lang, strings in pairs(LANG.Strings) do
|
||||
lang_names[lang] = strings["language_name"] or string.Capitalize(lang)
|
||||
end
|
||||
return lang_names
|
||||
end
|
||||
|
||||
---- Styling
|
||||
|
||||
local bgcolor = {
|
||||
[ROLE_TRAITOR] = Color(150, 0, 0, 200),
|
||||
[ROLE_DETECTIVE] = Color(0, 0, 150, 200),
|
||||
[ROLE_INNOCENT] = Color(0, 50, 0, 200)
|
||||
};
|
||||
|
||||
-- Table of styles that can take a string and display it in some position,
|
||||
-- colour, etc.
|
||||
LANG.Styles = {
|
||||
default = function(text)
|
||||
MSTACK:AddMessage(text)
|
||||
print("TTT: " .. text)
|
||||
end,
|
||||
|
||||
rolecolour = function(text)
|
||||
MSTACK:AddColoredBgMessage(text,
|
||||
bgcolor[ LocalPlayer():GetRole() ])
|
||||
print("TTT: " .. text)
|
||||
end,
|
||||
|
||||
chat_warn = function(text)
|
||||
chat.AddText(COLOR_RED, text)
|
||||
end,
|
||||
|
||||
|
||||
chat_plain = chat.AddText
|
||||
};
|
||||
|
||||
-- Table mapping message name => message style name. If no message style is
|
||||
-- defined, the default style is used. This is the case for the vast majority of
|
||||
-- messages at the time of writing.
|
||||
LANG.MsgStyle = {}
|
||||
|
||||
-- Access of message styles
|
||||
function LANG.GetStyle(name)
|
||||
return LANG.MsgStyle[name] or LANG.Styles.default
|
||||
end
|
||||
|
||||
-- Set a style by name or directly as style-function
|
||||
function LANG.SetStyle(name, style)
|
||||
if isstring(style) then
|
||||
style = LANG.Styles[style]
|
||||
end
|
||||
|
||||
LANG.MsgStyle[name] = style
|
||||
end
|
||||
|
||||
function LANG.ShowStyledMsg(text, style)
|
||||
style(text)
|
||||
end
|
||||
|
||||
function LANG.ProcessMsg(name, params)
|
||||
local raw = LANG.GetTranslation(name)
|
||||
|
||||
local text = raw
|
||||
|
||||
if params then
|
||||
-- some of our params may be string names themselves
|
||||
for k, v in pairs(params) do
|
||||
if isstring(v) then
|
||||
local name = LANG.GetNameParam(v)
|
||||
if not name then continue end
|
||||
|
||||
params[k] = LANG.GetTranslation(name)
|
||||
end
|
||||
end
|
||||
|
||||
text = interp(raw, params)
|
||||
end
|
||||
|
||||
LANG.ShowStyledMsg(text, LANG.GetStyle(name))
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Message style declarations
|
||||
|
||||
-- Rather than having a big list of LANG.SetStyle calls, we specify it the other
|
||||
-- way around here and churn through it in code. This is convenient because
|
||||
-- we're doing it en-masse for some random interface things spread out over the
|
||||
-- place.
|
||||
--
|
||||
-- Styles of custom SWEP messages and such should use LANG.SetStyle in their
|
||||
-- script. The SWEP stuff here might be moved out to the SWEPS too.
|
||||
|
||||
local styledmessages = {
|
||||
rolecolour = {
|
||||
"round_traitors_one",
|
||||
"round_traitors_more",
|
||||
|
||||
"buy_no_stock",
|
||||
"buy_pending",
|
||||
"buy_received",
|
||||
|
||||
"xfer_no_recip",
|
||||
"xfer_no_credits",
|
||||
"xfer_success",
|
||||
"xfer_received",
|
||||
|
||||
"c4_no_disarm",
|
||||
|
||||
"tele_failed",
|
||||
"tele_no_mark",
|
||||
"tele_marked",
|
||||
|
||||
"dna_identify",
|
||||
"dna_notfound",
|
||||
"dna_limit",
|
||||
"dna_decayed",
|
||||
"dna_killer",
|
||||
"dna_no_killer",
|
||||
"dna_armed",
|
||||
"dna_object",
|
||||
"dna_gone",
|
||||
|
||||
"credit_det_all",
|
||||
"credit_tr_all",
|
||||
"credit_kill"
|
||||
},
|
||||
|
||||
chat_plain = {
|
||||
"body_call",
|
||||
"disg_turned_on",
|
||||
"disg_turned_off",
|
||||
"mute_all",
|
||||
"mute_off",
|
||||
"mute_specs",
|
||||
"mute_living"
|
||||
},
|
||||
|
||||
chat_warn = {
|
||||
"spec_mode_warning",
|
||||
"radar_not_owned",
|
||||
"radar_charging",
|
||||
"drop_no_room",
|
||||
"body_burning",
|
||||
|
||||
"tele_no_ground",
|
||||
"tele_no_crouch",
|
||||
"tele_no_mark_ground",
|
||||
"tele_no_mark_crouch",
|
||||
|
||||
"drop_no_ammo"
|
||||
}
|
||||
};
|
||||
|
||||
local set_style = LANG.SetStyle
|
||||
for style, msgs in pairs(styledmessages) do
|
||||
for _, name in ipairs(msgs) do
|
||||
set_style(name, style)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user