mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-19 17:14:18 +00:00
Compare commits
13 commits
3b83f51a94
...
36ae5f8324
Author | SHA1 | Date | |
---|---|---|---|
36ae5f8324 | |||
78d702d3b7 | |||
cbc21fab4a | |||
ChillerDragon | 3781f95190 | ||
ChillerDragon | 32e8bb1f05 | ||
a2e0ab2dbe | |||
255694c061 | |||
b475c67039 | |||
a266cd2f70 | |||
2c77e79061 | |||
ChillerDragon | 46c5344d71 | ||
fe2f73b518 | |||
41ad7263eb |
|
@ -996,6 +996,7 @@ endif()
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
set(EXPECTED_DATA
|
set(EXPECTED_DATA
|
||||||
|
announcement.txt
|
||||||
arrow.png
|
arrow.png
|
||||||
assets/entities/comfort/ddnet.png
|
assets/entities/comfort/ddnet.png
|
||||||
assets/entities/license.txt
|
assets/entities/license.txt
|
||||||
|
@ -1845,6 +1846,7 @@ set(EXPECTED_DATA
|
||||||
themes/winter.png
|
themes/winter.png
|
||||||
themes/winter_day.map
|
themes/winter_day.map
|
||||||
themes/winter_night.map
|
themes/winter_night.map
|
||||||
|
touch_controls.json
|
||||||
wordlist.txt
|
wordlist.txt
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2401,6 +2403,8 @@ if(CLIENT)
|
||||||
components/statboard.h
|
components/statboard.h
|
||||||
components/tooltips.cpp
|
components/tooltips.cpp
|
||||||
components/tooltips.h
|
components/tooltips.h
|
||||||
|
components/touch_controls.cpp
|
||||||
|
components/touch_controls.h
|
||||||
components/voting.cpp
|
components/voting.cpp
|
||||||
components/voting.h
|
components/voting.h
|
||||||
gameclient.cpp
|
gameclient.cpp
|
||||||
|
|
0
data/announcement.txt
Normal file
0
data/announcement.txt
Normal file
|
@ -80,10 +80,10 @@ sv_rescue_delay 5
|
||||||
# Message on chat displayed when joining
|
# Message on chat displayed when joining
|
||||||
sv_welcome "Welcome to my server!"
|
sv_welcome "Welcome to my server!"
|
||||||
|
|
||||||
# File which will have the announcements (each one in new line)
|
# File which contains the announcements (One on each line)
|
||||||
sv_announcement_filename "announcement.txt"
|
sv_announcement_filename "announcement.txt"
|
||||||
|
|
||||||
# Number of minutes before next announcement will be displayed (from the announcement file)
|
# Number of minutes before the next announcement will be displayed (from the announcement file)
|
||||||
sv_announcement_interval 120
|
sv_announcement_interval 120
|
||||||
|
|
||||||
# Whether announcements will be displayed in their order or chosen randomly
|
# Whether announcements will be displayed in their order or chosen randomly
|
||||||
|
|
306
data/touch_controls.json
Normal file
306
data/touch_controls.json
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
{
|
||||||
|
"direct-touch-ingame": true,
|
||||||
|
"direct-touch-spectate": true,
|
||||||
|
"touch-buttons": [
|
||||||
|
{
|
||||||
|
"x": 0,
|
||||||
|
"y": 833333,
|
||||||
|
"w": 200000,
|
||||||
|
"h": 166667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"ingame"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Move left",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "+left"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 200000,
|
||||||
|
"y": 833333,
|
||||||
|
"w": 200000,
|
||||||
|
"h": 166667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"ingame"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Move right",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "+right"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 100000,
|
||||||
|
"y": 666667,
|
||||||
|
"w": 200000,
|
||||||
|
"h": 166667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"ingame"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Jump",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "+jump"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 116667,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 83333,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"ingame"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Prev. weapon",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "+prevweapon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 200000,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 83333,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"ingame"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Next weapon",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "+nextweapon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 16667,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 83333,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "predefined",
|
||||||
|
"id": "extra-menu",
|
||||||
|
"number": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 300000,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 83333,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu",
|
||||||
|
"zoom-allowed"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Zoom out",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "zoom-"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 383333,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 83333,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu",
|
||||||
|
"zoom-allowed"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Default zoom",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "zoom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 466666,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 83333,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu",
|
||||||
|
"zoom-allowed"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Zoom in",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "zoom+"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 16667,
|
||||||
|
"y": 133333,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 66667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Scoreboard",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "+scoreboard"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 116667,
|
||||||
|
"y": 133333,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 66667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"ingame",
|
||||||
|
"extra-menu"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "predefined",
|
||||||
|
"id": "emoticon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 116667,
|
||||||
|
"y": 133333,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 66667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"-ingame",
|
||||||
|
"extra-menu"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "predefined",
|
||||||
|
"id": "spectate"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 216667,
|
||||||
|
"y": 133333,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 66667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Chat",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "chat all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 316667,
|
||||||
|
"y": 133333,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 66667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Team chat",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "chat team"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 16667,
|
||||||
|
"y": 333333,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 66667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu",
|
||||||
|
"vote-active"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Vote yes",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "vote yes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 116667,
|
||||||
|
"y": 333333,
|
||||||
|
"w": 83333,
|
||||||
|
"h": 66667,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"extra-menu",
|
||||||
|
"vote-active"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Vote no",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "vote no"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 766667,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 100000,
|
||||||
|
"h": 100000,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"dummy-connected"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "bind",
|
||||||
|
"label": "Toggle dummy",
|
||||||
|
"label-type": "localized",
|
||||||
|
"command": "toggle cl_dummy 0 1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 883333,
|
||||||
|
"y": 16667,
|
||||||
|
"w": 100000,
|
||||||
|
"h": 100000,
|
||||||
|
"shape": "rect",
|
||||||
|
"visibilities": [
|
||||||
|
"ingame"
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "predefined",
|
||||||
|
"id": "swap-action"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 755000,
|
||||||
|
"y": 580000,
|
||||||
|
"w": 225000,
|
||||||
|
"h": 400000,
|
||||||
|
"shape": "circle",
|
||||||
|
"visibilities": [
|
||||||
|
],
|
||||||
|
"behavior": {
|
||||||
|
"type": "predefined",
|
||||||
|
"id": "joystick-action"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -80,6 +80,7 @@ void CInput::Init()
|
||||||
|
|
||||||
m_pGraphics = Kernel()->RequestInterface<IEngineGraphics>();
|
m_pGraphics = Kernel()->RequestInterface<IEngineGraphics>();
|
||||||
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
m_pConsole = Kernel()->RequestInterface<IConsole>();
|
||||||
|
m_pConfigManager = Kernel()->RequestInterface<IConfigManager>();
|
||||||
|
|
||||||
MouseModeRelative();
|
MouseModeRelative();
|
||||||
|
|
||||||
|
@ -300,6 +301,14 @@ const std::vector<IInput::CTouchFingerState> &CInput::TouchFingerStates() const
|
||||||
return m_vTouchFingerStates;
|
return m_vTouchFingerStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CInput::ClearTouchDeltas()
|
||||||
|
{
|
||||||
|
for(CTouchFingerState &TouchFingerState : m_vTouchFingerStates)
|
||||||
|
{
|
||||||
|
TouchFingerState.m_Delta = vec2(0.0f, 0.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string CInput::GetClipboardText()
|
std::string CInput::GetClipboardText()
|
||||||
{
|
{
|
||||||
char *pClipboardText = SDL_GetClipboardText();
|
char *pClipboardText = SDL_GetClipboardText();
|
||||||
|
@ -347,10 +356,7 @@ void CInput::Clear()
|
||||||
mem_zero(m_aInputState, sizeof(m_aInputState));
|
mem_zero(m_aInputState, sizeof(m_aInputState));
|
||||||
mem_zero(m_aInputCount, sizeof(m_aInputCount));
|
mem_zero(m_aInputCount, sizeof(m_aInputCount));
|
||||||
m_vInputEvents.clear();
|
m_vInputEvents.clear();
|
||||||
for(CTouchFingerState &TouchFingerState : m_vTouchFingerStates)
|
ClearTouchDeltas();
|
||||||
{
|
|
||||||
TouchFingerState.m_Delta = vec2(0.0f, 0.0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float CInput::GetUpdateTime() const
|
float CInput::GetUpdateTime() const
|
||||||
|
@ -824,6 +830,9 @@ int CInput::Update()
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_MINIMIZED:
|
case SDL_WINDOWEVENT_MINIMIZED:
|
||||||
|
#if defined(CONF_PLATFORM_ANDROID) // Save the config when minimized on Android.
|
||||||
|
m_pConfigManager->Save();
|
||||||
|
#endif
|
||||||
Graphics()->WindowDestroyNtf(Event.window.windowID);
|
Graphics()->WindowDestroyNtf(Event.window.windowID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class IEngineGraphics;
|
class IEngineGraphics;
|
||||||
|
class IConfigManager;
|
||||||
|
|
||||||
class CInput : public IEngineInput
|
class CInput : public IEngineInput
|
||||||
{
|
{
|
||||||
|
@ -59,6 +60,7 @@ public:
|
||||||
private:
|
private:
|
||||||
IEngineGraphics *m_pGraphics;
|
IEngineGraphics *m_pGraphics;
|
||||||
IConsole *m_pConsole;
|
IConsole *m_pConsole;
|
||||||
|
IConfigManager *m_pConfigManager;
|
||||||
|
|
||||||
IEngineGraphics *Graphics() const { return m_pGraphics; }
|
IEngineGraphics *Graphics() const { return m_pGraphics; }
|
||||||
IConsole *Console() const { return m_pConsole; }
|
IConsole *Console() const { return m_pConsole; }
|
||||||
|
@ -144,6 +146,7 @@ public:
|
||||||
bool NativeMousePressed(int Index) const override;
|
bool NativeMousePressed(int Index) const override;
|
||||||
|
|
||||||
const std::vector<CTouchFingerState> &TouchFingerStates() const override;
|
const std::vector<CTouchFingerState> &TouchFingerStates() const override;
|
||||||
|
void ClearTouchDeltas() override;
|
||||||
|
|
||||||
std::string GetClipboardText() override;
|
std::string GetClipboardText() override;
|
||||||
void SetClipboardText(const char *pText) override;
|
void SetClipboardText(const char *pText) override;
|
||||||
|
|
|
@ -137,6 +137,12 @@ public:
|
||||||
* @return vector of all touch finger states
|
* @return vector of all touch finger states
|
||||||
*/
|
*/
|
||||||
virtual const std::vector<CTouchFingerState> &TouchFingerStates() const = 0;
|
virtual const std::vector<CTouchFingerState> &TouchFingerStates() const = 0;
|
||||||
|
/**
|
||||||
|
* Must be called after the touch finger states have been used during the client update to ensure that
|
||||||
|
* touch deltas are only accumulated until the next update. If the touch states are only used during
|
||||||
|
* rendering, i.e. for user interfaces, then this is called automatically by calling @link Clear @endlink.
|
||||||
|
*/
|
||||||
|
virtual void ClearTouchDeltas() = 0;
|
||||||
|
|
||||||
// clipboard
|
// clipboard
|
||||||
virtual std::string GetClipboardText() = 0;
|
virtual std::string GetClipboardText() = 0;
|
||||||
|
|
|
@ -273,7 +273,8 @@ public:
|
||||||
virtual bool DnsblWhite(int ClientId) = 0;
|
virtual bool DnsblWhite(int ClientId) = 0;
|
||||||
virtual bool DnsblPending(int ClientId) = 0;
|
virtual bool DnsblPending(int ClientId) = 0;
|
||||||
virtual bool DnsblBlack(int ClientId) = 0;
|
virtual bool DnsblBlack(int ClientId) = 0;
|
||||||
virtual const char *GetAnnouncementLine(const char *pFileName) = 0;
|
virtual const char *GetAnnouncementLine() = 0;
|
||||||
|
virtual void ReadAnnouncementsFile(const char *pFileName) = 0;
|
||||||
virtual bool ClientPrevIngame(int ClientId) = 0;
|
virtual bool ClientPrevIngame(int ClientId) = 0;
|
||||||
virtual const char *GetNetErrorString(int ClientId) = 0;
|
virtual const char *GetNetErrorString(int ClientId) = 0;
|
||||||
virtual void ResetNetErrorString(int ClientId) = 0;
|
virtual void ResetNetErrorString(int ClientId) = 0;
|
||||||
|
|
|
@ -537,8 +537,7 @@ int CServer::Init()
|
||||||
|
|
||||||
m_CurrentGameTick = MIN_TICK;
|
m_CurrentGameTick = MIN_TICK;
|
||||||
|
|
||||||
m_AnnouncementLastLine = 0;
|
m_AnnouncementLastLine = -1;
|
||||||
m_aAnnouncementFile[0] = '\0';
|
|
||||||
mem_zero(m_aPrevStates, sizeof(m_aPrevStates));
|
mem_zero(m_aPrevStates, sizeof(m_aPrevStates));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2783,6 +2782,8 @@ int CServer::Run()
|
||||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReadAnnouncementsFile(g_Config.m_SvAnnouncementFileName);
|
||||||
|
|
||||||
// process pending commands
|
// process pending commands
|
||||||
m_pConsole->StoreCommands(false);
|
m_pConsole->StoreCommands(false);
|
||||||
m_pRegister->OnConfigChange();
|
m_pRegister->OnConfigChange();
|
||||||
|
@ -3809,6 +3810,17 @@ void CServer::ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CServer::ConchainAnnouncementFileName(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||||
|
{
|
||||||
|
CServer *pSelf = (CServer *)pUserData;
|
||||||
|
bool Changed = pResult->NumArguments() && str_comp(pResult->GetString(0), g_Config.m_SvAnnouncementFileName);
|
||||||
|
pfnCallback(pResult, pCallbackUserData);
|
||||||
|
if(Changed)
|
||||||
|
{
|
||||||
|
pSelf->ReadAnnouncementsFile(g_Config.m_SvAnnouncementFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(CONF_FAMILY_UNIX)
|
#if defined(CONF_FAMILY_UNIX)
|
||||||
void CServer::ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
void CServer::ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||||
{
|
{
|
||||||
|
@ -3887,6 +3899,8 @@ void CServer::RegisterCommands()
|
||||||
Console()->Chain("loglevel", ConchainLoglevel, this);
|
Console()->Chain("loglevel", ConchainLoglevel, this);
|
||||||
Console()->Chain("stdout_output_level", ConchainStdoutOutputLevel, this);
|
Console()->Chain("stdout_output_level", ConchainStdoutOutputLevel, this);
|
||||||
|
|
||||||
|
Console()->Chain("sv_announcement_filename", ConchainAnnouncementFileName, this);
|
||||||
|
|
||||||
#if defined(CONF_FAMILY_UNIX)
|
#if defined(CONF_FAMILY_UNIX)
|
||||||
Console()->Chain("sv_conn_logging_server", ConchainConnLoggingServerChange, this);
|
Console()->Chain("sv_conn_logging_server", ConchainConnLoggingServerChange, this);
|
||||||
#endif
|
#endif
|
||||||
|
@ -3930,27 +3944,30 @@ void CServer::GetClientAddr(int ClientId, NETADDR *pAddr) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CServer::GetAnnouncementLine(const char *pFileName)
|
void CServer::ReadAnnouncementsFile(const char *pFileName)
|
||||||
{
|
{
|
||||||
if(str_comp(pFileName, m_aAnnouncementFile) != 0)
|
m_vAnnouncements.clear();
|
||||||
{
|
|
||||||
str_copy(m_aAnnouncementFile, pFileName);
|
|
||||||
m_vAnnouncements.clear();
|
|
||||||
|
|
||||||
CLineReader LineReader;
|
if(pFileName[0] == '\0')
|
||||||
if(!LineReader.OpenFile(m_pStorage->OpenFile(pFileName, IOFLAG_READ, IStorage::TYPE_ALL)))
|
return;
|
||||||
|
|
||||||
|
CLineReader LineReader;
|
||||||
|
if(!LineReader.OpenFile(m_pStorage->OpenFile(pFileName, IOFLAG_READ, IStorage::TYPE_ALL)))
|
||||||
|
{
|
||||||
|
dbg_msg("announcements", "failed to open '%s'", pFileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(const char *pLine = LineReader.Get())
|
||||||
|
{
|
||||||
|
if(str_length(pLine) && pLine[0] != '#')
|
||||||
{
|
{
|
||||||
return 0;
|
m_vAnnouncements.emplace_back(pLine);
|
||||||
}
|
|
||||||
while(const char *pLine = LineReader.Get())
|
|
||||||
{
|
|
||||||
if(str_length(pLine) && pLine[0] != '#')
|
|
||||||
{
|
|
||||||
m_vAnnouncements.emplace_back(pLine);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *CServer::GetAnnouncementLine()
|
||||||
|
{
|
||||||
if(m_vAnnouncements.empty())
|
if(m_vAnnouncements.empty())
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3959,7 +3976,7 @@ const char *CServer::GetAnnouncementLine(const char *pFileName)
|
||||||
{
|
{
|
||||||
m_AnnouncementLastLine = 0;
|
m_AnnouncementLastLine = 0;
|
||||||
}
|
}
|
||||||
else if(!Config()->m_SvAnnouncementRandom)
|
else if(!g_Config.m_SvAnnouncementRandom)
|
||||||
{
|
{
|
||||||
if(++m_AnnouncementLastLine >= m_vAnnouncements.size())
|
if(++m_AnnouncementLastLine >= m_vAnnouncements.size())
|
||||||
m_AnnouncementLastLine %= m_vAnnouncements.size();
|
m_AnnouncementLastLine %= m_vAnnouncements.size();
|
||||||
|
|
|
@ -259,7 +259,6 @@ public:
|
||||||
|
|
||||||
size_t m_AnnouncementLastLine;
|
size_t m_AnnouncementLastLine;
|
||||||
std::vector<std::string> m_vAnnouncements;
|
std::vector<std::string> m_vAnnouncements;
|
||||||
char m_aAnnouncementFile[IO_MAX_PATH_LENGTH];
|
|
||||||
|
|
||||||
std::shared_ptr<ILogger> m_pFileLogger = nullptr;
|
std::shared_ptr<ILogger> m_pFileLogger = nullptr;
|
||||||
std::shared_ptr<ILogger> m_pStdoutLogger = nullptr;
|
std::shared_ptr<ILogger> m_pStdoutLogger = nullptr;
|
||||||
|
@ -427,6 +426,7 @@ public:
|
||||||
static void ConchainSixupUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
static void ConchainSixupUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||||
static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||||
static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||||
|
static void ConchainAnnouncementFileName(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||||
|
|
||||||
#if defined(CONF_FAMILY_UNIX)
|
#if defined(CONF_FAMILY_UNIX)
|
||||||
static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||||
|
@ -443,7 +443,8 @@ public:
|
||||||
|
|
||||||
void GetClientAddr(int ClientId, NETADDR *pAddr) const override;
|
void GetClientAddr(int ClientId, NETADDR *pAddr) const override;
|
||||||
int m_aPrevStates[MAX_CLIENTS];
|
int m_aPrevStates[MAX_CLIENTS];
|
||||||
const char *GetAnnouncementLine(const char *pFileName) override;
|
const char *GetAnnouncementLine() override;
|
||||||
|
void ReadAnnouncementsFile(const char *pFileName) override;
|
||||||
|
|
||||||
int *GetIdMap(int ClientId) override;
|
int *GetIdMap(int ClientId) override;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,11 @@ MACRO_CONFIG_INT(ClAntiPingSmooth, cl_antiping_smooth, 0, 0, 1, CFGFLAG_CLIENT |
|
||||||
MACRO_CONFIG_INT(ClAntiPingGunfire, cl_antiping_gunfire, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict gunfire and show predicted weapon physics (with cl_antiping_grenade 1 and cl_antiping_weapons 1)")
|
MACRO_CONFIG_INT(ClAntiPingGunfire, cl_antiping_gunfire, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict gunfire and show predicted weapon physics (with cl_antiping_grenade 1 and cl_antiping_weapons 1)")
|
||||||
MACRO_CONFIG_INT(ClPredictionMargin, cl_prediction_margin, 10, 1, 300, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Prediction margin in ms (adds latency, can reduce lag from ping jumps)")
|
MACRO_CONFIG_INT(ClPredictionMargin, cl_prediction_margin, 10, 1, 300, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Prediction margin in ms (adds latency, can reduce lag from ping jumps)")
|
||||||
MACRO_CONFIG_INT(ClSubTickAiming, cl_sub_tick_aiming, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Send aiming data at sub-tick accuracy")
|
MACRO_CONFIG_INT(ClSubTickAiming, cl_sub_tick_aiming, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Send aiming data at sub-tick accuracy")
|
||||||
|
#if defined(CONF_PLATFORM_ANDROID)
|
||||||
|
MACRO_CONFIG_INT(ClTouchControls, cl_touch_controls, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable ingame touch controls")
|
||||||
|
#else
|
||||||
|
MACRO_CONFIG_INT(ClTouchControls, cl_touch_controls, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable ingame touch controls")
|
||||||
|
#endif
|
||||||
|
|
||||||
MACRO_CONFIG_INT(ClNameplates, cl_nameplates, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show name plates")
|
MACRO_CONFIG_INT(ClNameplates, cl_nameplates, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show name plates")
|
||||||
MACRO_CONFIG_INT(ClAfkEmote, cl_afk_emote, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show zzz emote next to afk players")
|
MACRO_CONFIG_INT(ClAfkEmote, cl_afk_emote, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show zzz emote next to afk players")
|
||||||
|
@ -548,8 +553,8 @@ MACRO_CONFIG_INT(SvMinTeamSize, sv_min_team_size, 2, 1, MAX_CLIENTS, CFGFLAG_SER
|
||||||
MACRO_CONFIG_INT(SvMaxTeamSize, sv_max_team_size, MAX_CLIENTS, 1, MAX_CLIENTS, CFGFLAG_SERVER | CFGFLAG_GAME, "Maximum team size")
|
MACRO_CONFIG_INT(SvMaxTeamSize, sv_max_team_size, MAX_CLIENTS, 1, MAX_CLIENTS, CFGFLAG_SERVER | CFGFLAG_GAME, "Maximum team size")
|
||||||
MACRO_CONFIG_INT(SvMapVote, sv_map_vote, 1, 0, 1, CFGFLAG_SERVER, "Whether to allow /map")
|
MACRO_CONFIG_INT(SvMapVote, sv_map_vote, 1, 0, 1, CFGFLAG_SERVER, "Whether to allow /map")
|
||||||
|
|
||||||
MACRO_CONFIG_STR(SvAnnouncementFileName, sv_announcement_filename, 24, "announcement.txt", CFGFLAG_SERVER, "file which will have the announcement, each one at a line")
|
MACRO_CONFIG_STR(SvAnnouncementFileName, sv_announcement_filename, IO_MAX_PATH_LENGTH, "announcement.txt", CFGFLAG_SERVER, "File which contains the announcements, one on each line")
|
||||||
MACRO_CONFIG_INT(SvAnnouncementInterval, sv_announcement_interval, 300, 1, 9999, CFGFLAG_SERVER, "time(minutes) in which the announcement will be displayed from the announcement file")
|
MACRO_CONFIG_INT(SvAnnouncementInterval, sv_announcement_interval, 120, 1, 9999, CFGFLAG_SERVER, "The time (minutes) for how often an announcement will be displayed from the announcement file")
|
||||||
MACRO_CONFIG_INT(SvAnnouncementRandom, sv_announcement_random, 1, 0, 1, CFGFLAG_SERVER, "Whether announcements are sequential or random")
|
MACRO_CONFIG_INT(SvAnnouncementRandom, sv_announcement_random, 1, 0, 1, CFGFLAG_SERVER, "Whether announcements are sequential or random")
|
||||||
|
|
||||||
MACRO_CONFIG_INT(SvOldLaser, sv_old_laser, 0, 0, 1, CFGFLAG_SERVER | CFGFLAG_GAME, "Whether lasers can hit you if you shot them and that they pull you towards the bounce origin (0 for all new maps) or lasers can't hit you if you shot them, and they pull others towards the shooter")
|
MACRO_CONFIG_INT(SvOldLaser, sv_old_laser, 0, 0, 1, CFGFLAG_SERVER | CFGFLAG_GAME, "Whether lasers can hit you if you shot them and that they pull you towards the bounce origin (0 for all new maps) or lasers can't hit you if you shot them, and they pull others towards the shooter")
|
||||||
|
|
|
@ -212,6 +212,14 @@ public:
|
||||||
* @param Event The input event.
|
* @param Event The input event.
|
||||||
*/
|
*/
|
||||||
virtual bool OnInput(const IInput::CEvent &Event) { return false; }
|
virtual bool OnInput(const IInput::CEvent &Event) { return false; }
|
||||||
|
/**
|
||||||
|
* Called with all current touch finger states.
|
||||||
|
*
|
||||||
|
* @param vTouchFingerStates The touch finger states to be handled.
|
||||||
|
*
|
||||||
|
* @return `true` if the component used the touch events, `false` otherwise
|
||||||
|
*/
|
||||||
|
virtual bool OnTouchState(const std::vector<IInput::CTouchFingerState> &vTouchFingerStates) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
class CControls : public CComponent
|
class CControls : public CComponent
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
float GetMinMouseDistance() const;
|
float GetMinMouseDistance() const;
|
||||||
float GetMaxMouseDistance() const;
|
float GetMaxMouseDistance() const;
|
||||||
|
|
||||||
public:
|
|
||||||
vec2 m_aMousePos[NUM_DUMMIES];
|
vec2 m_aMousePos[NUM_DUMMIES];
|
||||||
vec2 m_aMousePosOnAction[NUM_DUMMIES];
|
vec2 m_aMousePosOnAction[NUM_DUMMIES];
|
||||||
vec2 m_aTargetPos[NUM_DUMMIES];
|
vec2 m_aTargetPos[NUM_DUMMIES];
|
||||||
|
|
|
@ -476,8 +476,12 @@ protected:
|
||||||
// found in menus_ingame.cpp
|
// found in menus_ingame.cpp
|
||||||
STextContainerIndex m_MotdTextContainerIndex;
|
STextContainerIndex m_MotdTextContainerIndex;
|
||||||
void RenderGame(CUIRect MainView);
|
void RenderGame(CUIRect MainView);
|
||||||
|
void RenderTouchControlsEditor(CUIRect MainView);
|
||||||
void PopupConfirmDisconnect();
|
void PopupConfirmDisconnect();
|
||||||
void PopupConfirmDisconnectDummy();
|
void PopupConfirmDisconnectDummy();
|
||||||
|
void PopupConfirmDiscardTouchControlsChanged();
|
||||||
|
void PopupConfirmResetTouchControls();
|
||||||
|
void PopupConfirmImportTouchControlsClipboard();
|
||||||
void RenderPlayers(CUIRect MainView);
|
void RenderPlayers(CUIRect MainView);
|
||||||
void RenderServerInfo(CUIRect MainView);
|
void RenderServerInfo(CUIRect MainView);
|
||||||
void RenderServerInfoMotd(CUIRect Motd);
|
void RenderServerInfoMotd(CUIRect Motd);
|
||||||
|
@ -638,7 +642,6 @@ protected:
|
||||||
static CUi::EPopupMenuFunctionResult PopupMapPicker(void *pContext, CUIRect View, bool Active);
|
static CUi::EPopupMenuFunctionResult PopupMapPicker(void *pContext, CUIRect View, bool Active);
|
||||||
|
|
||||||
void SetNeedSendInfo();
|
void SetNeedSendInfo();
|
||||||
void SetActive(bool Active);
|
|
||||||
void UpdateColors();
|
void UpdateColors();
|
||||||
|
|
||||||
IGraphics::CTextureHandle m_TextureBlob;
|
IGraphics::CTextureHandle m_TextureBlob;
|
||||||
|
@ -658,6 +661,8 @@ public:
|
||||||
bool IsInit() { return m_IsInit; }
|
bool IsInit() { return m_IsInit; }
|
||||||
|
|
||||||
bool IsActive() const { return m_MenuActive; }
|
bool IsActive() const { return m_MenuActive; }
|
||||||
|
void SetActive(bool Active);
|
||||||
|
|
||||||
void KillServer();
|
void KillServer();
|
||||||
|
|
||||||
virtual void OnInit() override;
|
virtual void OnInit() override;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <game/client/animstate.h>
|
#include <game/client/animstate.h>
|
||||||
#include <game/client/components/countryflags.h>
|
#include <game/client/components/countryflags.h>
|
||||||
|
#include <game/client/components/touch_controls.h>
|
||||||
#include <game/client/gameclient.h>
|
#include <game/client/gameclient.h>
|
||||||
#include <game/client/render.h>
|
#include <game/client/render.h>
|
||||||
#include <game/client/ui.h>
|
#include <game/client/ui.h>
|
||||||
|
@ -40,21 +41,19 @@ using namespace std::chrono_literals;
|
||||||
|
|
||||||
void CMenus::RenderGame(CUIRect MainView)
|
void CMenus::RenderGame(CUIRect MainView)
|
||||||
{
|
{
|
||||||
CUIRect Button, ButtonBar, ButtonBar2;
|
CUIRect Button, ButtonBars, ButtonBar, ButtonBar2;
|
||||||
bool ShowDDRaceButtons = MainView.w > 855.0f;
|
bool ShowDDRaceButtons = MainView.w > 855.0f;
|
||||||
MainView.HSplitTop(45.0f, &ButtonBar, &MainView);
|
MainView.HSplitTop(45.0f + (g_Config.m_ClTouchControls ? 35.0f : 0.0f), &ButtonBars, &MainView);
|
||||||
ButtonBar.Draw(ms_ColorTabbarActive, IGraphics::CORNER_B, 10.0f);
|
ButtonBars.Draw(ms_ColorTabbarActive, IGraphics::CORNER_B, 10.0f);
|
||||||
|
ButtonBars.Margin(10.0f, &ButtonBars);
|
||||||
// button bar
|
ButtonBars.HSplitTop(25.0f, &ButtonBar, &ButtonBars);
|
||||||
ButtonBar.HSplitTop(10.0f, 0, &ButtonBar);
|
if(g_Config.m_ClTouchControls)
|
||||||
ButtonBar.HSplitTop(25.0f, &ButtonBar, 0);
|
{
|
||||||
ButtonBar.VMargin(10.0f, &ButtonBar);
|
ButtonBars.HSplitTop(10.0f, nullptr, &ButtonBars);
|
||||||
|
ButtonBars.HSplitTop(25.0f, &ButtonBar2, &ButtonBars);
|
||||||
ButtonBar.HSplitTop(30.0f, 0, &ButtonBar2);
|
}
|
||||||
ButtonBar2.HSplitTop(25.0f, &ButtonBar2, 0);
|
|
||||||
|
|
||||||
ButtonBar.VSplitRight(120.0f, &ButtonBar, &Button);
|
ButtonBar.VSplitRight(120.0f, &ButtonBar, &Button);
|
||||||
|
|
||||||
static CButtonContainer s_DisconnectButton;
|
static CButtonContainer s_DisconnectButton;
|
||||||
if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button))
|
if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button))
|
||||||
{
|
{
|
||||||
|
@ -214,6 +213,147 @@ void CMenus::RenderGame(CUIRect MainView)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(g_Config.m_ClTouchControls)
|
||||||
|
{
|
||||||
|
ButtonBar2.VSplitLeft(200.0f, &Button, &ButtonBar2);
|
||||||
|
static char s_TouchControlsEditCheckbox;
|
||||||
|
if(DoButton_CheckBox(&s_TouchControlsEditCheckbox, Localize("Edit touch controls"), GameClient()->m_TouchControls.IsEditingActive(), &Button))
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SetEditingActive(!GameClient()->m_TouchControls.IsEditingActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonBar2.VSplitRight(80.0f, &ButtonBar2, &Button);
|
||||||
|
static CButtonContainer s_CloseButton;
|
||||||
|
if(DoButton_Menu(&s_CloseButton, Localize("Close"), 0, &Button))
|
||||||
|
{
|
||||||
|
SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonBar2.VSplitRight(5.0f, &ButtonBar2, nullptr);
|
||||||
|
ButtonBar2.VSplitRight(160.0f, &ButtonBar2, &Button);
|
||||||
|
static CButtonContainer s_RemoveConsoleButton;
|
||||||
|
if(DoButton_Menu(&s_RemoveConsoleButton, Localize("Remote console"), 0, &Button))
|
||||||
|
{
|
||||||
|
Console()->ExecuteLine("toggle_remote_console");
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonBar2.VSplitRight(5.0f, &ButtonBar2, nullptr);
|
||||||
|
ButtonBar2.VSplitRight(120.0f, &ButtonBar2, &Button);
|
||||||
|
static CButtonContainer s_LocalConsoleButton;
|
||||||
|
if(DoButton_Menu(&s_LocalConsoleButton, Localize("Console"), 0, &Button))
|
||||||
|
{
|
||||||
|
Console()->ExecuteLine("toggle_local_console");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GameClient()->m_TouchControls.IsEditingActive())
|
||||||
|
{
|
||||||
|
CUIRect TouchControlsEditor;
|
||||||
|
MainView.VMargin((MainView.w - 505.0f) / 2.0f, &TouchControlsEditor);
|
||||||
|
TouchControlsEditor.HMargin((TouchControlsEditor.h - 195.0f) / 2.0f, &TouchControlsEditor);
|
||||||
|
RenderTouchControlsEditor(TouchControlsEditor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenus::RenderTouchControlsEditor(CUIRect MainView)
|
||||||
|
{
|
||||||
|
CUIRect Button, Row;
|
||||||
|
MainView.Draw(ms_ColorTabbarActive, IGraphics::CORNER_ALL, 10.0f);
|
||||||
|
MainView.Margin(10.0f, &MainView);
|
||||||
|
|
||||||
|
MainView.HSplitTop(25.0f, &Button, &MainView);
|
||||||
|
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||||
|
Ui()->DoLabel(&Button, Localize("Edit touch controls"), 20.0f, TEXTALIGN_MC);
|
||||||
|
|
||||||
|
MainView.HSplitTop(25.0f, &Row, &MainView);
|
||||||
|
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||||
|
|
||||||
|
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||||
|
static CButtonContainer s_SaveConfigurationButton;
|
||||||
|
if(DoButton_Menu(&s_SaveConfigurationButton, Localize("Save changes"), GameClient()->m_TouchControls.HasEditingChanges() ? 0 : 1, &Button))
|
||||||
|
{
|
||||||
|
if(GameClient()->m_TouchControls.SaveConfigurationToFile())
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SetEditingChanges(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SWarning Warning(Localize("Error saving touch controls"), Localize("Could not save touch controls to file. See local console for details."));
|
||||||
|
Warning.m_AutoHide = false;
|
||||||
|
Client()->AddWarning(Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row.VSplitLeft(5.0f, nullptr, &Row);
|
||||||
|
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||||
|
if(GameClient()->m_TouchControls.HasEditingChanges())
|
||||||
|
{
|
||||||
|
TextRender()->TextColor(ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
Ui()->DoLabel(&Button, Localize("Unsaved changes"), 14.0f, TEXTALIGN_MC);
|
||||||
|
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
MainView.HSplitTop(25.0f, &Row, &MainView);
|
||||||
|
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||||
|
|
||||||
|
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||||
|
static CButtonContainer s_DiscardChangesButton;
|
||||||
|
if(DoButton_Menu(&s_DiscardChangesButton, Localize("Discard changes"), GameClient()->m_TouchControls.HasEditingChanges() ? 0 : 1, &Button))
|
||||||
|
{
|
||||||
|
PopupConfirm(Localize("Discard changes"),
|
||||||
|
Localize("Are you sure that you want to discard the current changes to the touch controls?"),
|
||||||
|
Localize("Yes"), Localize("No"),
|
||||||
|
&CMenus::PopupConfirmDiscardTouchControlsChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
Row.VSplitLeft(5.0f, nullptr, &Row);
|
||||||
|
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||||
|
static CButtonContainer s_ResetButton;
|
||||||
|
if(DoButton_Menu(&s_ResetButton, Localize("Reset to default"), 0, &Button))
|
||||||
|
{
|
||||||
|
PopupConfirm(Localize("Reset to default"),
|
||||||
|
Localize("Are you sure that you want to reset the touch controls to default?"),
|
||||||
|
Localize("Yes"), Localize("No"),
|
||||||
|
&CMenus::PopupConfirmResetTouchControls);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainView.HSplitTop(25.0f, &Row, &MainView);
|
||||||
|
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||||
|
|
||||||
|
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||||
|
static CButtonContainer s_ClipboardImportButton;
|
||||||
|
if(DoButton_Menu(&s_ClipboardImportButton, Localize("Import from clipboard"), 0, &Button))
|
||||||
|
{
|
||||||
|
PopupConfirm(Localize("Import from clipboard"),
|
||||||
|
Localize("Are you sure that you want to import the touch controls from the clipboard? The will overwrite your current touch controls."),
|
||||||
|
Localize("Yes"), Localize("No"),
|
||||||
|
&CMenus::PopupConfirmImportTouchControlsClipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
Row.VSplitLeft(5.0f, nullptr, &Row);
|
||||||
|
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||||
|
static CButtonContainer s_ClipboardExportButton;
|
||||||
|
if(DoButton_Menu(&s_ClipboardExportButton, Localize("Export to clipboard"), 0, &Button))
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SaveConfigurationToClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainView.HSplitTop(25.0f, &Button, &MainView);
|
||||||
|
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||||
|
static char s_DirectTouchIngameButton;
|
||||||
|
if(DoButton_CheckBox(&s_DirectTouchIngameButton, Localize("Direct touch input while ingame"), GameClient()->m_TouchControls.IsDirectTouchIngame(), &Button))
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SetDirectTouchIngame(!GameClient()->m_TouchControls.IsDirectTouchIngame());
|
||||||
|
}
|
||||||
|
|
||||||
|
MainView.HSplitTop(25.0f, &Button, &MainView);
|
||||||
|
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||||
|
static char s_DirectTouchSpectateButton;
|
||||||
|
if(DoButton_CheckBox(&s_DirectTouchSpectateButton, Localize("Direct touch input while spectate"), GameClient()->m_TouchControls.IsDirectTouchSpectate(), &Button))
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SetDirectTouchSpectate(!GameClient()->m_TouchControls.IsDirectTouchSpectate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMenus::PopupConfirmDisconnect()
|
void CMenus::PopupConfirmDisconnect()
|
||||||
|
@ -227,6 +367,57 @@ void CMenus::PopupConfirmDisconnectDummy()
|
||||||
SetActive(false);
|
SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMenus::PopupConfirmDiscardTouchControlsChanged()
|
||||||
|
{
|
||||||
|
if(GameClient()->m_TouchControls.LoadConfigurationFromFile(IStorage::TYPE_ALL))
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SetEditingChanges(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SWarning Warning(Localize("Error loading touch controls"), Localize("Could not load touch controls from file. See local console for details."));
|
||||||
|
Warning.m_AutoHide = false;
|
||||||
|
Client()->AddWarning(Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenus::PopupConfirmResetTouchControls()
|
||||||
|
{
|
||||||
|
bool Success = false;
|
||||||
|
for(int StorageType = 1; StorageType < Storage()->NumPaths(); ++StorageType)
|
||||||
|
{
|
||||||
|
if(GameClient()->m_TouchControls.LoadConfigurationFromFile(StorageType))
|
||||||
|
{
|
||||||
|
Success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Success)
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SetEditingChanges(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SWarning Warning(Localize("Error loading touch controls"), Localize("Could not load default touch controls from file. See local console for details."));
|
||||||
|
Warning.m_AutoHide = false;
|
||||||
|
Client()->AddWarning(Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMenus::PopupConfirmImportTouchControlsClipboard()
|
||||||
|
{
|
||||||
|
if(GameClient()->m_TouchControls.LoadConfigurationFromClipboard())
|
||||||
|
{
|
||||||
|
GameClient()->m_TouchControls.SetEditingChanges(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SWarning Warning(Localize("Error loading touch controls"), Localize("Could not load touch controls from clipboard. See local console for details."));
|
||||||
|
Warning.m_AutoHide = false;
|
||||||
|
Client()->AddWarning(Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CMenus::RenderPlayers(CUIRect MainView)
|
void CMenus::RenderPlayers(CUIRect MainView)
|
||||||
{
|
{
|
||||||
CUIRect Button, Button2, ButtonBar, PlayerList, Player;
|
CUIRect Button, Button2, ButtonBar, PlayerList, Player;
|
||||||
|
@ -1281,6 +1472,9 @@ void CMenus::RenderGhost(CUIRect MainView)
|
||||||
|
|
||||||
void CMenus::RenderIngameHint()
|
void CMenus::RenderIngameHint()
|
||||||
{
|
{
|
||||||
|
if(g_Config.m_ClTouchControls)
|
||||||
|
return;
|
||||||
|
|
||||||
float Width = 300 * Graphics()->ScreenAspect();
|
float Width = 300 * Graphics()->ScreenAspect();
|
||||||
Graphics()->MapScreen(0, 0, Width, 300);
|
Graphics()->MapScreen(0, 0, Width, 300);
|
||||||
TextRender()->TextColor(1, 1, 1, 1);
|
TextRender()->TextColor(1, 1, 1, 1);
|
||||||
|
|
1302
src/game/client/components/touch_controls.cpp
Normal file
1302
src/game/client/components/touch_controls.cpp
Normal file
File diff suppressed because it is too large
Load diff
424
src/game/client/components/touch_controls.h
Normal file
424
src/game/client/components/touch_controls.h
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
#ifndef GAME_CLIENT_COMPONENTS_TOUCH_CONTROLS_H
|
||||||
|
#define GAME_CLIENT_COMPONENTS_TOUCH_CONTROLS_H
|
||||||
|
|
||||||
|
#include <base/vmath.h>
|
||||||
|
|
||||||
|
#include <engine/input.h>
|
||||||
|
|
||||||
|
#include <game/client/component.h>
|
||||||
|
#include <game/client/ui_rect.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class CJsonWriter;
|
||||||
|
typedef struct _json_value json_value;
|
||||||
|
|
||||||
|
class CTouchControls : public CComponent
|
||||||
|
{
|
||||||
|
enum class EButtonShape
|
||||||
|
{
|
||||||
|
RECT,
|
||||||
|
CIRCLE,
|
||||||
|
NUM_SHAPES
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr const char *SHAPE_NAMES[(int)EButtonShape::NUM_SHAPES] = {"rect", "circle"};
|
||||||
|
|
||||||
|
enum class EButtonVisibility
|
||||||
|
{
|
||||||
|
INGAME,
|
||||||
|
ZOOM_ALLOWED,
|
||||||
|
VOTE_ACTIVE,
|
||||||
|
DUMMY_ALLOWED,
|
||||||
|
DUMMY_CONNECTED,
|
||||||
|
RCON_AUTHED,
|
||||||
|
EXTRA_MENU_1,
|
||||||
|
EXTRA_MENU_2,
|
||||||
|
EXTRA_MENU_3,
|
||||||
|
EXTRA_MENU_4,
|
||||||
|
EXTRA_MENU_5,
|
||||||
|
NUM_VISIBILITIES
|
||||||
|
};
|
||||||
|
|
||||||
|
class CButtonVisibility
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EButtonVisibility m_Type;
|
||||||
|
bool m_Parity;
|
||||||
|
|
||||||
|
CButtonVisibility(EButtonVisibility Type, bool Parity) :
|
||||||
|
m_Type(Type), m_Parity(Parity) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CButtonVisibilityData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char *m_pId;
|
||||||
|
std::function<bool()> m_Function;
|
||||||
|
};
|
||||||
|
|
||||||
|
CButtonVisibilityData m_aVisibilityFunctions[(int)EButtonVisibility::NUM_VISIBILITIES];
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ACTION_FIRE,
|
||||||
|
ACTION_HOOK,
|
||||||
|
NUM_ACTIONS
|
||||||
|
};
|
||||||
|
|
||||||
|
class CButtonLabel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class EType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Label is used as is.
|
||||||
|
*/
|
||||||
|
PLAIN,
|
||||||
|
/**
|
||||||
|
* Label is localized. Only usable for default button labels for which there must be
|
||||||
|
* corresponding `Localizable`-calls in code and string in the translation files.
|
||||||
|
*/
|
||||||
|
LOCALIZED,
|
||||||
|
/**
|
||||||
|
* Icon font is used for the label.
|
||||||
|
*/
|
||||||
|
ICON,
|
||||||
|
/**
|
||||||
|
* Number of label types.
|
||||||
|
*/
|
||||||
|
NUM_TYPES
|
||||||
|
};
|
||||||
|
|
||||||
|
EType m_Type;
|
||||||
|
const char *m_pLabel;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr const char *LABEL_TYPE_NAMES[(int)CButtonLabel::EType::NUM_TYPES] = {"plain", "localized", "icon"};
|
||||||
|
|
||||||
|
class CUnitRect
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int m_X;
|
||||||
|
int m_Y;
|
||||||
|
int m_W;
|
||||||
|
int m_H;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CTouchButtonBehavior;
|
||||||
|
|
||||||
|
class CTouchButton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTouchButton(CTouchControls *pTouchControls);
|
||||||
|
CTouchButton(CTouchButton &&Other) noexcept;
|
||||||
|
CTouchButton(const CTouchButton &Other) = delete;
|
||||||
|
|
||||||
|
CTouchButton &operator=(const CTouchButton &Other) = delete;
|
||||||
|
CTouchButton &operator=(CTouchButton &&Other) noexcept;
|
||||||
|
|
||||||
|
CTouchControls *m_pTouchControls;
|
||||||
|
|
||||||
|
CUnitRect m_UnitRect;
|
||||||
|
CUIRect m_ScreenRect;
|
||||||
|
|
||||||
|
EButtonShape m_Shape;
|
||||||
|
int m_BackgroundCorners; // only used with EButtonShape::RECT
|
||||||
|
|
||||||
|
std::vector<CButtonVisibility> m_vVisibilities;
|
||||||
|
std::unique_ptr<CTouchButtonBehavior> m_pBehavior;
|
||||||
|
|
||||||
|
void UpdatePointers();
|
||||||
|
void UpdateScreenFromUnitRect();
|
||||||
|
void UpdateUnitFromScreenRect();
|
||||||
|
void UpdateBackgroundCorners();
|
||||||
|
|
||||||
|
vec2 ClampTouchPosition(vec2 TouchPosition) const;
|
||||||
|
bool IsInside(vec2 TouchPosition) const;
|
||||||
|
bool IsVisible() const;
|
||||||
|
void Render() const;
|
||||||
|
void WriteToConfiguration(CJsonWriter *pWriter);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CTouchButtonBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTouchButton *m_pTouchButton;
|
||||||
|
CTouchControls *m_pTouchControls;
|
||||||
|
|
||||||
|
bool m_Active; // variables below must only be used when active
|
||||||
|
IInput::CTouchFinger m_Finger;
|
||||||
|
vec2 m_ActivePosition;
|
||||||
|
vec2 m_AccumulatedDelta;
|
||||||
|
std::chrono::nanoseconds m_ActivationStartTime;
|
||||||
|
|
||||||
|
virtual ~CTouchButtonBehavior() = default;
|
||||||
|
virtual void Init(CTouchButton *pTouchButton);
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
void SetActive(const IInput::CTouchFingerState &FingerState);
|
||||||
|
void SetInactive();
|
||||||
|
bool IsActive() const;
|
||||||
|
bool IsActive(const IInput::CTouchFinger &Finger) const;
|
||||||
|
|
||||||
|
virtual CButtonLabel GetLabel() const = 0;
|
||||||
|
virtual void OnActivate() {}
|
||||||
|
virtual void OnDeactivate() {}
|
||||||
|
virtual void OnUpdate() {}
|
||||||
|
virtual void WriteToConfiguration(CJsonWriter *pWriter) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class for predefined behaviors.
|
||||||
|
*
|
||||||
|
* Subclasses must implemented the concrete behavior and provide the label.
|
||||||
|
*/
|
||||||
|
class CPredefinedTouchButtonBehavior : public CTouchButtonBehavior
|
||||||
|
{
|
||||||
|
const char *m_pId;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_TYPE = "predefined";
|
||||||
|
|
||||||
|
CPredefinedTouchButtonBehavior(const char *pId) :
|
||||||
|
m_pId(pId) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the serialization for predefined behaviors. Subclasses
|
||||||
|
* may override this, but they should call the parent function first.
|
||||||
|
*/
|
||||||
|
void WriteToConfiguration(CJsonWriter *pWriter) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CIngameMenuTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "ingame-menu";
|
||||||
|
|
||||||
|
CIngameMenuTouchButtonBehavior() :
|
||||||
|
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CExtraMenuTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||||
|
{
|
||||||
|
int m_Number;
|
||||||
|
char m_aLabel[16];
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "extra-menu";
|
||||||
|
|
||||||
|
CExtraMenuTouchButtonBehavior(int Number);
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
void WriteToConfiguration(CJsonWriter *pWriter) override;
|
||||||
|
static std::unique_ptr<CExtraMenuTouchButtonBehavior> Parse(const json_value *pBehaviorObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CEmoticonTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "emoticon";
|
||||||
|
|
||||||
|
CEmoticonTouchButtonBehavior() :
|
||||||
|
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CSpectateTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "spectate";
|
||||||
|
|
||||||
|
CSpectateTouchButtonBehavior() :
|
||||||
|
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CSwapActionTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||||
|
{
|
||||||
|
int m_ActiveAction = NUM_ACTIONS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "swap-action";
|
||||||
|
|
||||||
|
CSwapActionTouchButtonBehavior() :
|
||||||
|
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnActivate() override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CUseActionTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||||
|
{
|
||||||
|
int m_ActiveAction = NUM_ACTIONS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "use-action";
|
||||||
|
|
||||||
|
CUseActionTouchButtonBehavior() :
|
||||||
|
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnActivate() override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CJoystickTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||||
|
{
|
||||||
|
int m_ActiveAction = NUM_ACTIONS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CJoystickTouchButtonBehavior(const char *pId) :
|
||||||
|
CPredefinedTouchButtonBehavior(pId) {}
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnActivate() override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
void OnUpdate() override;
|
||||||
|
int ActiveAction() const { return m_ActiveAction; }
|
||||||
|
virtual int SelectedAction() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CJoystickActionTouchButtonBehavior : public CJoystickTouchButtonBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "joystick-action";
|
||||||
|
|
||||||
|
CJoystickActionTouchButtonBehavior() :
|
||||||
|
CJoystickTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
~CJoystickActionTouchButtonBehavior();
|
||||||
|
|
||||||
|
void Init(CTouchButton *pTouchButton) override;
|
||||||
|
int SelectedAction() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CJoystickFireTouchButtonBehavior : public CJoystickTouchButtonBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "joystick-fire";
|
||||||
|
|
||||||
|
CJoystickFireTouchButtonBehavior() :
|
||||||
|
CJoystickTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
|
||||||
|
int SelectedAction() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CJoystickHookTouchButtonBehavior : public CJoystickTouchButtonBehavior
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_ID = "joystick-hook";
|
||||||
|
|
||||||
|
CJoystickHookTouchButtonBehavior() :
|
||||||
|
CJoystickTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||||
|
|
||||||
|
int SelectedAction() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic behavior implementation that executes a console command like a bind.
|
||||||
|
*/
|
||||||
|
class CBindTouchButtonBehavior : public CTouchButtonBehavior
|
||||||
|
{
|
||||||
|
std::string m_Label;
|
||||||
|
CButtonLabel::EType m_LabelType;
|
||||||
|
std::string m_Command;
|
||||||
|
|
||||||
|
bool m_Repeating = false;
|
||||||
|
std::chrono::nanoseconds m_LastUpdateTime;
|
||||||
|
std::chrono::nanoseconds m_AccumulatedRepeatingTime;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const char *BEHAVIOR_TYPE = "bind";
|
||||||
|
|
||||||
|
CBindTouchButtonBehavior(const char *pLabel, CButtonLabel::EType LabelType, const char *pCommand) :
|
||||||
|
m_Label(pLabel),
|
||||||
|
m_LabelType(LabelType),
|
||||||
|
m_Command(pCommand) {}
|
||||||
|
|
||||||
|
CButtonLabel GetLabel() const override;
|
||||||
|
void OnActivate() override;
|
||||||
|
void OnDeactivate() override;
|
||||||
|
void OnUpdate() override;
|
||||||
|
void WriteToConfiguration(CJsonWriter *pWriter) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool m_DirectTouchIngame = true;
|
||||||
|
bool m_DirectTouchSpectate = true;
|
||||||
|
|
||||||
|
std::vector<CTouchButton> m_vTouchButtons;
|
||||||
|
|
||||||
|
bool m_aExtraMenuActive[(int)EButtonVisibility::EXTRA_MENU_5 - (int)EButtonVisibility::EXTRA_MENU_1 + 1] = {false};
|
||||||
|
|
||||||
|
class CActionState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool m_Active = false;
|
||||||
|
IInput::CTouchFinger m_Finger;
|
||||||
|
};
|
||||||
|
|
||||||
|
int m_ActionSelected = ACTION_FIRE;
|
||||||
|
int m_ActionLastActivated = ACTION_FIRE;
|
||||||
|
CActionState m_aActionStates[NUM_ACTIONS];
|
||||||
|
CJoystickActionTouchButtonBehavior *m_pPrimaryJoystickTouchButtonBehavior;
|
||||||
|
|
||||||
|
bool m_EditingActive = false;
|
||||||
|
bool m_EditingChanges = false;
|
||||||
|
|
||||||
|
void InitVisibilityFunctions();
|
||||||
|
void UpdateButtons(const std::vector<IInput::CTouchFingerState> &vTouchFingerStates);
|
||||||
|
void RenderButtons();
|
||||||
|
vec2 CalculateScreenSize() const;
|
||||||
|
|
||||||
|
std::unique_ptr<CPredefinedTouchButtonBehavior> ParsePredefinedBehavior(const json_value *pBehaviorObject);
|
||||||
|
std::unique_ptr<CBindTouchButtonBehavior> ParseBindBehavior(const json_value *pBehaviorObject);
|
||||||
|
std::unique_ptr<CTouchButtonBehavior> ParseBehavior(const json_value *pBehaviorObject);
|
||||||
|
std::optional<CTouchButton> ParseButton(const json_value *pButtonObject);
|
||||||
|
bool ParseConfiguration(const void *pFileData, unsigned FileLength);
|
||||||
|
void WriteConfiguration(CJsonWriter *pWriter);
|
||||||
|
|
||||||
|
public:
|
||||||
|
int Sizeof() const override { return sizeof(*this); }
|
||||||
|
void OnInit() override;
|
||||||
|
void OnReset() override;
|
||||||
|
void OnWindowResize() override;
|
||||||
|
bool OnTouchState(const std::vector<IInput::CTouchFingerState> &vTouchFingerStates) override;
|
||||||
|
void OnRender() override;
|
||||||
|
|
||||||
|
bool LoadConfigurationFromFile(int StorageType);
|
||||||
|
bool LoadConfigurationFromClipboard();
|
||||||
|
bool SaveConfigurationToFile();
|
||||||
|
void SaveConfigurationToClipboard();
|
||||||
|
|
||||||
|
bool IsDirectTouchIngame() const { return m_DirectTouchIngame; }
|
||||||
|
void SetDirectTouchIngame(bool DirectTouchIngame)
|
||||||
|
{
|
||||||
|
m_DirectTouchIngame = DirectTouchIngame;
|
||||||
|
m_EditingChanges = true;
|
||||||
|
}
|
||||||
|
bool IsDirectTouchSpectate() const { return m_DirectTouchSpectate; }
|
||||||
|
void SetDirectTouchSpectate(bool DirectTouchSpectate)
|
||||||
|
{
|
||||||
|
m_DirectTouchSpectate = DirectTouchSpectate;
|
||||||
|
m_EditingChanges = true;
|
||||||
|
}
|
||||||
|
bool IsEditingActive() const { return m_EditingActive; }
|
||||||
|
void SetEditingActive(bool EditingActive) { m_EditingActive = EditingActive; }
|
||||||
|
bool HasEditingChanges() const { return m_EditingChanges; }
|
||||||
|
void SetEditingChanges(bool EditingChanges) { m_EditingChanges = EditingChanges; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -145,6 +145,7 @@ void CGameClient::OnConsoleInit()
|
||||||
&m_Chat,
|
&m_Chat,
|
||||||
&m_Broadcast,
|
&m_Broadcast,
|
||||||
&m_DebugHud,
|
&m_DebugHud,
|
||||||
|
&m_TouchControls,
|
||||||
&m_Scoreboard,
|
&m_Scoreboard,
|
||||||
&m_Statboard,
|
&m_Statboard,
|
||||||
&m_Motd,
|
&m_Motd,
|
||||||
|
@ -164,6 +165,7 @@ void CGameClient::OnConsoleInit()
|
||||||
&m_Emoticon,
|
&m_Emoticon,
|
||||||
&m_Menus,
|
&m_Menus,
|
||||||
&m_Controls,
|
&m_Controls,
|
||||||
|
&m_TouchControls,
|
||||||
&m_Binds});
|
&m_Binds});
|
||||||
|
|
||||||
// add basic console commands
|
// add basic console commands
|
||||||
|
@ -443,6 +445,23 @@ void CGameClient::OnUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle touch events
|
||||||
|
const std::vector<IInput::CTouchFingerState> &vTouchFingerStates = Input()->TouchFingerStates();
|
||||||
|
bool TouchHandled = false;
|
||||||
|
for(auto &pComponent : m_vpInput)
|
||||||
|
{
|
||||||
|
if(TouchHandled)
|
||||||
|
{
|
||||||
|
// Also update inactive components so they can handle touch fingers being released.
|
||||||
|
pComponent->OnTouchState({});
|
||||||
|
}
|
||||||
|
else if(pComponent->OnTouchState(vTouchFingerStates))
|
||||||
|
{
|
||||||
|
Input()->ClearTouchDeltas();
|
||||||
|
TouchHandled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// handle key presses
|
// handle key presses
|
||||||
Input()->ConsumeEvents([&](const IInput::CEvent &Event) {
|
Input()->ConsumeEvents([&](const IInput::CEvent &Event) {
|
||||||
for(auto &pComponent : m_vpInput)
|
for(auto &pComponent : m_vpInput)
|
||||||
|
@ -1565,7 +1584,7 @@ void CGameClient::OnNewSnapshot()
|
||||||
pClient->m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1);
|
pClient->m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pClient->UpdateRenderInfo(IsTeamPlay(), g_Config.m_ClDummy);
|
pClient->UpdateRenderInfo(IsTeamPlay());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Item.m_Type == NETOBJTYPE_PLAYERINFO)
|
else if(Item.m_Type == NETOBJTYPE_PLAYERINFO)
|
||||||
|
@ -2388,7 +2407,7 @@ void CGameClient::CClientStats::Reset()
|
||||||
m_FlagCaptures = 0;
|
m_FlagCaptures = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay, int Conn)
|
void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay)
|
||||||
{
|
{
|
||||||
m_RenderInfo = m_SkinInfo;
|
m_RenderInfo = m_SkinInfo;
|
||||||
|
|
||||||
|
@ -2403,6 +2422,7 @@ void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay, int Conn)
|
||||||
m_RenderInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(aTeamColors[m_Team]));
|
m_RenderInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(aTeamColors[m_Team]));
|
||||||
|
|
||||||
// 0.7
|
// 0.7
|
||||||
|
for(auto &Sixup : m_RenderInfo.m_aSixup)
|
||||||
{
|
{
|
||||||
const ColorRGBA aTeamColorsSixup[2] = {
|
const ColorRGBA aTeamColorsSixup[2] = {
|
||||||
ColorRGBA(0.753f, 0.318f, 0.318f, 1.0f),
|
ColorRGBA(0.753f, 0.318f, 0.318f, 1.0f),
|
||||||
|
@ -2410,19 +2430,20 @@ void CGameClient::CClientData::UpdateRenderInfo(bool IsTeamPlay, int Conn)
|
||||||
const ColorRGBA aMarkingColorsSixup[2] = {
|
const ColorRGBA aMarkingColorsSixup[2] = {
|
||||||
ColorRGBA(0.824f, 0.345f, 0.345f, 1.0f),
|
ColorRGBA(0.824f, 0.345f, 0.345f, 1.0f),
|
||||||
ColorRGBA(0.345f, 0.514f, 0.824f, 1.0f)};
|
ColorRGBA(0.345f, 0.514f, 0.824f, 1.0f)};
|
||||||
float MarkingAlpha = m_RenderInfo.m_aSixup[Conn].m_aColors[protocol7::SKINPART_MARKING].a;
|
float MarkingAlpha = Sixup.m_aColors[protocol7::SKINPART_MARKING].a;
|
||||||
for(auto &Color : m_RenderInfo.m_aSixup[Conn].m_aColors)
|
for(auto &Color : Sixup.m_aColors)
|
||||||
Color = aTeamColorsSixup[m_Team];
|
Color = aTeamColorsSixup[m_Team];
|
||||||
if(MarkingAlpha > 0.1f)
|
if(MarkingAlpha > 0.1f)
|
||||||
m_RenderInfo.m_aSixup[Conn].m_aColors[protocol7::SKINPART_MARKING] = aMarkingColorsSixup[m_Team];
|
Sixup.m_aColors[protocol7::SKINPART_MARKING] = aMarkingColorsSixup[m_Team];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_RenderInfo.m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
m_RenderInfo.m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
||||||
m_RenderInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
m_RenderInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
||||||
for(auto &Color : m_RenderInfo.m_aSixup[Conn].m_aColors)
|
for(auto &Sixup : m_RenderInfo.m_aSixup)
|
||||||
Color = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
for(auto &Color : Sixup.m_aColors)
|
||||||
|
Color = color_cast<ColorRGBA>(ColorHSLA(12829350));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3757,8 +3778,7 @@ void CGameClient::RefreshSkins()
|
||||||
Client.m_SkinInfo.m_OriginalRenderSkin.Reset();
|
Client.m_SkinInfo.m_OriginalRenderSkin.Reset();
|
||||||
Client.m_SkinInfo.m_ColorableRenderSkin.Reset();
|
Client.m_SkinInfo.m_ColorableRenderSkin.Reset();
|
||||||
}
|
}
|
||||||
for(int Dummy = 0; Dummy < NUM_DUMMIES; Dummy++)
|
Client.UpdateRenderInfo(IsTeamPlay());
|
||||||
Client.UpdateRenderInfo(IsTeamPlay(), Dummy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &pComponent : m_vpAll)
|
for(auto &pComponent : m_vpAll)
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "components/spectator.h"
|
#include "components/spectator.h"
|
||||||
#include "components/statboard.h"
|
#include "components/statboard.h"
|
||||||
#include "components/tooltips.h"
|
#include "components/tooltips.h"
|
||||||
|
#include "components/touch_controls.h"
|
||||||
#include "components/voting.h"
|
#include "components/voting.h"
|
||||||
|
|
||||||
class CGameInfo
|
class CGameInfo
|
||||||
|
@ -146,6 +147,7 @@ public:
|
||||||
CSounds m_Sounds;
|
CSounds m_Sounds;
|
||||||
CEmoticon m_Emoticon;
|
CEmoticon m_Emoticon;
|
||||||
CDamageInd m_DamageInd;
|
CDamageInd m_DamageInd;
|
||||||
|
CTouchControls m_TouchControls;
|
||||||
CVoting m_Voting;
|
CVoting m_Voting;
|
||||||
CSpectator m_Spectator;
|
CSpectator m_Spectator;
|
||||||
|
|
||||||
|
@ -438,7 +440,7 @@ public:
|
||||||
bool m_SpecCharPresent;
|
bool m_SpecCharPresent;
|
||||||
vec2 m_SpecChar;
|
vec2 m_SpecChar;
|
||||||
|
|
||||||
void UpdateRenderInfo(bool IsTeamPlay, int Conn);
|
void UpdateRenderInfo(bool IsTeamPlay);
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
class CSixup
|
class CSixup
|
||||||
|
|
|
@ -196,7 +196,7 @@ void *CGameClient::TranslateGameMsg(int *pMsgId, CUnpacker *pUnpacker, int Conn)
|
||||||
{
|
{
|
||||||
m_aClients[pMsg7->m_ClientId].m_Team = pMsg7->m_Team;
|
m_aClients[pMsg7->m_ClientId].m_Team = pMsg7->m_Team;
|
||||||
m_pClient->m_TranslationContext.m_aClients[pMsg7->m_ClientId].m_Team = pMsg7->m_Team;
|
m_pClient->m_TranslationContext.m_aClients[pMsg7->m_ClientId].m_Team = pMsg7->m_Team;
|
||||||
m_aClients[pMsg7->m_ClientId].UpdateRenderInfo(IsTeamPlay(), Conn);
|
m_aClients[pMsg7->m_ClientId].UpdateRenderInfo(IsTeamPlay());
|
||||||
|
|
||||||
// if(pMsg7->m_ClientId == m_LocalClientId)
|
// if(pMsg7->m_ClientId == m_LocalClientId)
|
||||||
// {
|
// {
|
||||||
|
|
|
@ -328,8 +328,10 @@ public:
|
||||||
bool CanFillGameTiles() const;
|
bool CanFillGameTiles() const;
|
||||||
void AddGroup();
|
void AddGroup();
|
||||||
void AddTileLayer();
|
void AddTileLayer();
|
||||||
|
void AddFrontLayer();
|
||||||
void LayerSelectImage();
|
void LayerSelectImage();
|
||||||
bool IsNonGameTileLayerSelected() const;
|
bool IsNonGameTileLayerSelected() const;
|
||||||
|
void MapDetails();
|
||||||
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) CQuickAction m_QuickAction##name;
|
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) CQuickAction m_QuickAction##name;
|
||||||
#include <game/editor/quick_actions.h>
|
#include <game/editor/quick_actions.h>
|
||||||
#undef REGISTER_QUICK_ACTION
|
#undef REGISTER_QUICK_ACTION
|
||||||
|
|
|
@ -32,7 +32,6 @@ CUi::EPopupMenuFunctionResult CEditor::PopupMenuFile(void *pContext, CUIRect Vie
|
||||||
static int s_OpenButton = 0;
|
static int s_OpenButton = 0;
|
||||||
static int s_OpenCurrentMapButton = 0;
|
static int s_OpenCurrentMapButton = 0;
|
||||||
static int s_AppendButton = 0;
|
static int s_AppendButton = 0;
|
||||||
static int s_MapInfoButton = 0;
|
|
||||||
static int s_ExitButton = 0;
|
static int s_ExitButton = 0;
|
||||||
|
|
||||||
CUIRect Slot;
|
CUIRect Slot;
|
||||||
|
@ -115,15 +114,9 @@ CUi::EPopupMenuFunctionResult CEditor::PopupMenuFile(void *pContext, CUIRect Vie
|
||||||
|
|
||||||
View.HSplitTop(10.0f, nullptr, &View);
|
View.HSplitTop(10.0f, nullptr, &View);
|
||||||
View.HSplitTop(12.0f, &Slot, &View);
|
View.HSplitTop(12.0f, &Slot, &View);
|
||||||
if(pEditor->DoButton_MenuItem(&s_MapInfoButton, "Map details", 0, &Slot, 0, "Adjust the map details of the current map"))
|
if(pEditor->DoButton_MenuItem(&pEditor->m_QuickActionMapDetails, pEditor->m_QuickActionMapDetails.Label(), 0, &Slot, 0, pEditor->m_QuickActionMapDetails.Description()))
|
||||||
{
|
{
|
||||||
const CUIRect *pScreen = pEditor->Ui()->Screen();
|
pEditor->m_QuickActionMapDetails.Call();
|
||||||
pEditor->m_Map.m_MapInfoTmp.Copy(pEditor->m_Map.m_MapInfo);
|
|
||||||
static SPopupMenuId s_PopupMapInfoId;
|
|
||||||
constexpr float PopupWidth = 400.0f;
|
|
||||||
constexpr float PopupHeight = 170.0f;
|
|
||||||
pEditor->Ui()->DoPopupMenu(&s_PopupMapInfoId, pScreen->w / 2.0f - PopupWidth / 2.0f, pScreen->h / 2.0f - PopupHeight / 2.0f, PopupWidth, PopupHeight, pEditor, PopupMapInfo);
|
|
||||||
pEditor->Ui()->SetActiveItem(nullptr);
|
|
||||||
return CUi::POPUP_CLOSE_CURRENT;
|
return CUi::POPUP_CLOSE_CURRENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,16 +536,9 @@ CUi::EPopupMenuFunctionResult CEditor::PopupGroup(void *pContext, CUIRect View,
|
||||||
// new front layer
|
// new front layer
|
||||||
View.HSplitBottom(5.0f, &View, nullptr);
|
View.HSplitBottom(5.0f, &View, nullptr);
|
||||||
View.HSplitBottom(12.0f, &View, &Button);
|
View.HSplitBottom(12.0f, &View, &Button);
|
||||||
static int s_NewFrontLayerButton = 0;
|
if(pEditor->DoButton_Editor(&pEditor->m_QuickActionAddFrontLayer, pEditor->m_QuickActionAddFrontLayer.Label(), 0, &Button, 0, pEditor->m_QuickActionAddFrontLayer.Description()))
|
||||||
if(pEditor->DoButton_Editor(&s_NewFrontLayerButton, "Add front layer", 0, &Button, 0, "Creates a new item layer"))
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<CLayer> pFrontLayer = std::make_shared<CLayerFront>(pEditor, pEditor->m_Map.m_pGameLayer->m_Width, pEditor->m_Map.m_pGameLayer->m_Height);
|
pEditor->m_QuickActionAddFrontLayer.Call();
|
||||||
pEditor->m_Map.MakeFrontLayer(pFrontLayer);
|
|
||||||
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->AddLayer(pFrontLayer);
|
|
||||||
int LayerIndex = pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_vpLayers.size() - 1;
|
|
||||||
pEditor->SelectLayer(LayerIndex);
|
|
||||||
pEditor->m_pBrush->Clear();
|
|
||||||
pEditor->m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(pEditor, pEditor->m_SelectedGroup, LayerIndex));
|
|
||||||
return CUi::POPUP_CLOSE_CURRENT;
|
return CUi::POPUP_CLOSE_CURRENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,17 @@ void CEditor::AddTileLayer()
|
||||||
m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(this, m_SelectedGroup, LayerIndex));
|
m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(this, m_SelectedGroup, LayerIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEditor::AddFrontLayer()
|
||||||
|
{
|
||||||
|
std::shared_ptr<CLayer> pFrontLayer = std::make_shared<CLayerFront>(this, m_Map.m_pGameLayer->m_Width, m_Map.m_pGameLayer->m_Height);
|
||||||
|
m_Map.MakeFrontLayer(pFrontLayer);
|
||||||
|
m_Map.m_vpGroups[m_SelectedGroup]->AddLayer(pFrontLayer);
|
||||||
|
int LayerIndex = m_Map.m_vpGroups[m_SelectedGroup]->m_vpLayers.size() - 1;
|
||||||
|
SelectLayer(LayerIndex);
|
||||||
|
m_pBrush->Clear();
|
||||||
|
m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(this, m_SelectedGroup, LayerIndex));
|
||||||
|
}
|
||||||
|
|
||||||
bool CEditor::IsNonGameTileLayerSelected() const
|
bool CEditor::IsNonGameTileLayerSelected() const
|
||||||
{
|
{
|
||||||
std::shared_ptr<CLayer> pLayer = GetSelectedLayer(0);
|
std::shared_ptr<CLayer> pLayer = GetSelectedLayer(0);
|
||||||
|
@ -69,3 +80,21 @@ void CEditor::LayerSelectImage()
|
||||||
Ui()->DoPopupMenu(&s_LayerPopupContext, Ui()->MouseX(), Ui()->MouseY(), 120, 270, &s_LayerPopupContext, PopupLayer);
|
Ui()->DoPopupMenu(&s_LayerPopupContext, Ui()->MouseX(), Ui()->MouseY(), 120, 270, &s_LayerPopupContext, PopupLayer);
|
||||||
PopupSelectImageInvoke(pTiles->m_Image, Ui()->MouseX(), Ui()->MouseY());
|
PopupSelectImageInvoke(pTiles->m_Image, Ui()->MouseX(), Ui()->MouseY());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEditor::MapDetails()
|
||||||
|
{
|
||||||
|
const CUIRect *pScreen = Ui()->Screen();
|
||||||
|
m_Map.m_MapInfoTmp.Copy(m_Map.m_MapInfo);
|
||||||
|
static SPopupMenuId s_PopupMapInfoId;
|
||||||
|
constexpr float PopupWidth = 400.0f;
|
||||||
|
constexpr float PopupHeight = 170.0f;
|
||||||
|
Ui()->DoPopupMenu(
|
||||||
|
&s_PopupMapInfoId,
|
||||||
|
pScreen->w / 2.0f - PopupWidth / 2.0f,
|
||||||
|
pScreen->h / 2.0f - PopupHeight / 2.0f,
|
||||||
|
PopupWidth,
|
||||||
|
PopupHeight,
|
||||||
|
this,
|
||||||
|
PopupMapInfo);
|
||||||
|
Ui()->SetActiveItem(nullptr);
|
||||||
|
}
|
||||||
|
|
|
@ -169,6 +169,14 @@ REGISTER_QUICK_ACTION(
|
||||||
"Toggles proof borders. These borders represent the area that a player can see with default zoom.")
|
"Toggles proof borders. These borders represent the area that a player can see with default zoom.")
|
||||||
REGISTER_QUICK_ACTION(
|
REGISTER_QUICK_ACTION(
|
||||||
AddTileLayer, "Add tile layer", [&]() { AddTileLayer(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Creates a new tile layer.")
|
AddTileLayer, "Add tile layer", [&]() { AddTileLayer(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Creates a new tile layer.")
|
||||||
|
REGISTER_QUICK_ACTION(
|
||||||
|
AddFrontLayer,
|
||||||
|
"Add front layer",
|
||||||
|
[&]() { AddFrontLayer(); },
|
||||||
|
[&]() -> bool { return !GetSelectedGroup()->m_GameGroup || m_Map.m_pFrontLayer; },
|
||||||
|
ALWAYS_FALSE,
|
||||||
|
DEFAULT_BTN,
|
||||||
|
"Creates a new item layer.")
|
||||||
REGISTER_QUICK_ACTION(
|
REGISTER_QUICK_ACTION(
|
||||||
SaveAs,
|
SaveAs,
|
||||||
"Save As",
|
"Save As",
|
||||||
|
@ -276,6 +284,14 @@ REGISTER_QUICK_ACTION(
|
||||||
[&]() -> bool { return m_ColorPipetteActive; },
|
[&]() -> bool { return m_ColorPipetteActive; },
|
||||||
DEFAULT_BTN,
|
DEFAULT_BTN,
|
||||||
"[Ctrl+Shift+C] Color pipette. Pick a color from the screen by clicking on it.")
|
"[Ctrl+Shift+C] Color pipette. Pick a color from the screen by clicking on it.")
|
||||||
|
REGISTER_QUICK_ACTION(
|
||||||
|
MapDetails,
|
||||||
|
"Map details",
|
||||||
|
[&]() { MapDetails(); },
|
||||||
|
ALWAYS_FALSE,
|
||||||
|
ALWAYS_FALSE,
|
||||||
|
DEFAULT_BTN,
|
||||||
|
"Adjust the map details of the current map.")
|
||||||
|
|
||||||
#undef ALWAYS_FALSE
|
#undef ALWAYS_FALSE
|
||||||
#undef DEFAULT_BTN
|
#undef DEFAULT_BTN
|
||||||
|
|
|
@ -893,6 +893,12 @@ void CGameContext::ConReloadCensorlist(IConsole::IResult *pResult, void *pUserDa
|
||||||
pSelf->ReadCensorList();
|
pSelf->ReadCensorList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameContext::ConReloadAnnouncement(IConsole::IResult *pResult, void *pUserData)
|
||||||
|
{
|
||||||
|
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||||
|
pSelf->Server()->ReadAnnouncementsFile(g_Config.m_SvAnnouncementFileName);
|
||||||
|
}
|
||||||
|
|
||||||
void CGameContext::ConDumpAntibot(IConsole::IResult *pResult, void *pUserData)
|
void CGameContext::ConDumpAntibot(IConsole::IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||||
|
|
|
@ -1253,7 +1253,7 @@ void CGameContext::OnTick()
|
||||||
|
|
||||||
if(Server()->Tick() % (g_Config.m_SvAnnouncementInterval * Server()->TickSpeed() * 60) == 0)
|
if(Server()->Tick() % (g_Config.m_SvAnnouncementInterval * Server()->TickSpeed() * 60) == 0)
|
||||||
{
|
{
|
||||||
const char *pLine = Server()->GetAnnouncementLine(g_Config.m_SvAnnouncementFileName);
|
const char *pLine = Server()->GetAnnouncementLine();
|
||||||
if(pLine)
|
if(pLine)
|
||||||
SendChat(-1, TEAM_ALL, pLine);
|
SendChat(-1, TEAM_ALL, pLine);
|
||||||
}
|
}
|
||||||
|
@ -3643,6 +3643,7 @@ void CGameContext::OnConsoleInit()
|
||||||
Console()->Register("set_team_all", "i[team-id]", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team");
|
Console()->Register("set_team_all", "i[team-id]", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team");
|
||||||
Console()->Register("hot_reload", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConHotReload, this, "Reload the map while preserving the state of tees and teams");
|
Console()->Register("hot_reload", "", CFGFLAG_SERVER | CMDFLAG_TEST, ConHotReload, this, "Reload the map while preserving the state of tees and teams");
|
||||||
Console()->Register("reload_censorlist", "", CFGFLAG_SERVER, ConReloadCensorlist, this, "Reload the censorlist");
|
Console()->Register("reload_censorlist", "", CFGFLAG_SERVER, ConReloadCensorlist, this, "Reload the censorlist");
|
||||||
|
Console()->Register("reload_announcement", "", CFGFLAG_SERVER, ConReloadAnnouncement, this, "Reload the announcements");
|
||||||
|
|
||||||
Console()->Register("add_vote", "s[name] r[command]", CFGFLAG_SERVER, ConAddVote, this, "Add a voting option");
|
Console()->Register("add_vote", "s[name] r[command]", CFGFLAG_SERVER, ConAddVote, this, "Add a voting option");
|
||||||
Console()->Register("remove_vote", "r[name]", CFGFLAG_SERVER, ConRemoveVote, this, "remove a voting option");
|
Console()->Register("remove_vote", "r[name]", CFGFLAG_SERVER, ConRemoveVote, this, "remove a voting option");
|
||||||
|
|
|
@ -516,6 +516,7 @@ private:
|
||||||
static void ConUnFreezeHammer(IConsole::IResult *pResult, void *pUserData);
|
static void ConUnFreezeHammer(IConsole::IResult *pResult, void *pUserData);
|
||||||
|
|
||||||
static void ConReloadCensorlist(IConsole::IResult *pResult, void *pUserData);
|
static void ConReloadCensorlist(IConsole::IResult *pResult, void *pUserData);
|
||||||
|
static void ConReloadAnnouncement(IConsole::IResult *pResult, void *pUserData);
|
||||||
|
|
||||||
CCharacter *GetPracticeCharacter(IConsole::IResult *pResult);
|
CCharacter *GetPracticeCharacter(IConsole::IResult *pResult);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue