Get rid of Visual Studio warnings.

Relicensed under the MIT license.
Added safety checks here and there.
This commit is contained in:
jeefo 2019-09-21 23:20:33 +03:00
commit 61fad287e7
48 changed files with 517 additions and 554 deletions

View file

@ -1,23 +1,21 @@
Copyright (c) 2003-2019, YaPB Development Team
The MIT License (MIT)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the YaPB Dev Team nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
Copyright (c) 2004-2019 Yet Another POD-Bot Contributors <yapb@entix.io>
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL YAPB DEVELOPMENT TEAM BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -33,11 +32,7 @@ public:
// calloc on linux with debug enabled doesn't always zero out memory
#if defined (CR_DEBUG) && !defined (CR_WINDOWS)
auto *zeroing = reinterpret_cast <uint8 *> (ptr);
for (size_t i = 0; i < length; ++i) {
zeroing[i] = 0;
}
plat.bzero (ptr);
#endif
return ptr;
}

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -13,14 +12,6 @@
#define CR_NAMESPACE_BEGIN namespace cr {
#define CR_NAMESPACE_END }
// disable microsoft deprecation warning
#if defined (_MSC_VER)
# if !defined (_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
# define _WINSOCK_DEPRECATED_NO_WARNINGS
# endif
#endif
#include <stdio.h>
#include <stdlib.h>

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -32,14 +31,10 @@ public:
~File () {
close ();
}
public:
bool open (const String &file, const String &mode) {
if (*this) {
close ();
}
if ((m_handle = fopen (file.chars (), mode.chars ())) == nullptr) {
if (!openFile (file, mode)) {
return false;
}
fseek (m_handle, 0L, SEEK_END);
@ -157,6 +152,20 @@ public:
}
plat.createDirectory (path);
}
private:
bool openFile (const String &filename, const String &mode) {
if (*this) {
close ();
}
#if defined (CR_WINDOWS)
fopen_s (&m_handle, filename.chars (), mode.chars ());
#else
m_handle = fopen (filename.chars (), mode.chars ());
#endif
return m_handle != nullptr;
}
};
// wrapper for memory file for loading data into the memory

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -28,6 +27,7 @@
# include <fcntl.h>
#elif defined (CR_WINDOWS)
# include <winsock2.h>
# include <ws2tcpip.h>
#endif
// status codes for http client
@ -71,12 +71,17 @@ public:
public:
bool connect (const String &hostname) {
auto host = gethostbyname (hostname.chars ());
addrinfo hints, *result = nullptr;
plat.bzero (&hints, sizeof (hints));
if (!host) {
hints.ai_flags = AI_NUMERICSERV;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo (hostname.chars (), "80", &hints, &result) != 0) {
return false;
}
m_socket = static_cast <int> (socket (AF_INET, SOCK_STREAM, 0));
m_socket = static_cast <int> (socket (result->ai_family, result->ai_socktype, 0));
if (m_socket < 0) {
return false;
@ -93,24 +98,21 @@ public:
auto timeouts = getTimeouts ();
if (setsockopt (m_socket, SOL_SOCKET, SO_RCVTIMEO, timeouts.first, timeouts.second) == -1) {
logger.error ("Unable to set SO_RCVTIMEO.");
logger.message ("Unable to set SO_RCVTIMEO.");
}
if (setsockopt (m_socket, SOL_SOCKET, SO_SNDTIMEO, timeouts.first, timeouts.second) == -1) {
logger.error ("Unable to set SO_SNDTIMEO.");
logger.message ("Unable to set SO_SNDTIMEO.");
}
sockaddr_in dest;
memset (&dest, 0, sizeof (dest));
dest.sin_family = AF_INET;
dest.sin_port = htons (80);
dest.sin_addr.s_addr = inet_addr (inet_ntoa (*(reinterpret_cast <in_addr *> (host->h_addr))));
if (::connect (m_socket, reinterpret_cast <sockaddr *> (&dest), static_cast <int> (sizeof (dest))) == -1) {
if (::connect (m_socket, result->ai_addr, static_cast <decltype (result->ai_addrlen)> (result->ai_addrlen)) == -1) {
disconnect ();
freeaddrinfo (result);
return false;
}
freeaddrinfo (result);
return true;
}

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -69,7 +68,7 @@ public:
m_handle = reinterpret_cast <void *> (mbi.AllocationBase);
#else
Dl_info dli;
memset (&dli, 0, sizeof (dli));
plat.bzero (&dli, sizeof (dli));
if (dladdr (address, &dli)) {
return load (dli.dli_fname);

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -37,10 +36,19 @@ private:
return;
}
time_t ticks = time (&ticks);
auto tm = localtime (&ticks);
tm *timeinfo = nullptr;
#if defined (CR_WINDOWS)
tm get;
localtime_s (&get, &ticks);
timeinfo = &get;
#else
timeinfo = localtime (&ticks);
#endif
auto timebuf = strings.chars ();
strftime (timebuf, StringBuffer::StaticBufferSize, "%Y-%m-%d %H:%M:%S", tm);
strftime (timebuf, StringBuffer::StaticBufferSize, "%Y-%m-%d %H:%M:%S", timeinfo);
m_handle.puts ("%s (%s): %s\n", timebuf, level, msg);
}

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -89,6 +88,7 @@ CR_NAMESPACE_END
#include <stdio.h>
#include <assert.h>
#include <locale.h>
#include <string.h>
#include <stdarg.h>
#if defined (CR_ANDROID)
@ -97,6 +97,8 @@ CR_NAMESPACE_END
CR_NAMESPACE_BEGIN
class String;
// helper struct for platform detection
struct Platform : public Singleton <Platform> {
bool win32 = false;
@ -178,14 +180,6 @@ struct Platform : public Singleton <Platform> {
#endif
}
bool caseStrMatch (const char *str1, const char *str2) {
#if defined(CR_WINDOWS)
return _stricmp (str1, str2) == 0;
#else
return ::strcasecmp (str1, str2) == 0;
#endif
}
float seconds () {
#if defined(CR_WINDOWS)
LARGE_INTEGER count, freq;
@ -213,13 +207,42 @@ struct Platform : public Singleton <Platform> {
#endif
#if defined(CR_WINDOWS)
if (msg) {
DestroyWindow (GetForegroundWindow ());
MessageBoxA (GetActiveWindow (), msg, "crlib.fatal", MB_ICONSTOP);
}
#endif
::abort ();
}
// anologue of memset
template <typename U> void bzero (U *ptr, size_t len) noexcept {
#if defined (CR_WINDOWS)
memset (ptr, 0, len);
#else
auto zeroing = reinterpret_cast <uint8 *> (ptr);
for (size_t i = 0; i < len; ++i) {
zeroing[i] = 0;
}
#endif
}
const char *env (const char *var) {
static char result[256];
bzero (result, sizeof (result));
#if defined(CR_WINDOWS)
char *buffer = nullptr;
size_t size = 0;
if (_dupenv_s (&buffer, &size, var) == 0 && buffer != nullptr) {
strncpy_s (result, buffer, sizeof (result));
free (buffer);
}
#else
strncpy (result, getenv (var), cr::bufsize (result));
#endif
return result;
}
};
// expose platform singleton

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -88,7 +87,7 @@ private:
};
public:
explicit String () {
String () {
reset ();
assign ("", 0);
}
@ -849,34 +848,60 @@ public:
~StringBuffer () = default;
public:
char *chars () {
char *chars () noexcept {
if (++m_rotate >= RotationCount) {
m_rotate = 0;
}
return m_data[cr::clamp <size_t> (m_rotate, 0, RotationCount)];
}
template <typename U, typename ...Args> U *format (const U *fmt, Args ...args) {
template <typename U, typename ...Args> U *format (const U *fmt, Args ...args) noexcept {
auto buffer = Singleton <StringBuffer>::get ().chars ();
snprintf (buffer, StaticBufferSize, fmt, args...);
return buffer;
}
template <typename U> U *format (const U *fmt) {
template <typename U> U *format (const U *fmt) noexcept {
auto buffer = Singleton <StringBuffer>::get ().chars ();
strncpy (buffer, fmt, StaticBufferSize);
copy (buffer, fmt, StaticBufferSize);
return buffer;
}
// checks if string is not empty
bool isEmpty (const char *input) const {
bool isEmpty (const char *input) const noexcept {
if (input == nullptr) {
return true;
}
return *input == '\0';
}
bool matches (const char *str1, const char *str2) noexcept {
#if defined(CR_WINDOWS)
return _stricmp (str1, str2) == 0;
#else
return ::strcasecmp (str1, str2) == 0;
#endif
}
template <typename U> U *copy (U *dst, const U *src, size_t len) noexcept {
#if defined(CR_WINDOWS)
strncpy_s (dst, len, src, len - 1);
return dst;
#else
return strncpy (dst, src, len);
#endif
}
template <typename U> U *concat (U *dst, const U *src, size_t len) noexcept {
#if defined(CR_WINDOWS)
strncat_s (dst, len, src, len - 1);
return dst;
#else
return strncat (dst, src, len);
#endif
}
};
// expose global string pool

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -350,7 +349,7 @@ public:
// send server command
template <typename ...Args> void serverCommand (const char *fmt, Args ...args) {
engfuncs.pfnServerCommand (strncat (strings.format (fmt, cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
engfuncs.pfnServerCommand (strings.concat (strings.format (fmt, cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
}
// send a bot command
@ -360,7 +359,7 @@ public:
// prints data to servers console
template <typename ...Args> void print (const char *fmt, Args ...args) {
engfuncs.pfnServerPrint (strncat (strings.format (conf.translate (fmt), cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
engfuncs.pfnServerPrint (strings.concat (strings.format (conf.translate (fmt), cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
}
// prints center message to specified player
@ -369,7 +368,7 @@ public:
print (fmt, cr::forward <Args> (args)...);
return;
}
sendClientMessage (true, ent, strncat (strings.format (conf.translate (fmt), cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
sendClientMessage (true, ent, strings.concat (strings.format (conf.translate (fmt), cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
}
// prints message to client console
@ -378,7 +377,7 @@ public:
print (fmt, cr::forward <Args> (args)...);
return;
}
sendClientMessage (false, ent, strncat (strings.format (conf.translate (fmt), cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
sendClientMessage (false, ent, strings.concat (strings.format (conf.translate (fmt), cr::forward <Args> (args)...), "\n", StringBuffer::StaticBufferSize));
}
};
@ -535,6 +534,10 @@ public:
m_worldModel = model;
}
model_t *getWorldModel () const {
return m_worldModel;
}
void enableAnimation (bool enable) {
m_doAnimation = enable;
}
@ -607,11 +610,11 @@ public:
class DynamicEntityLink : public Singleton <DynamicEntityLink> {
private:
#if defined (CR_WINDOWS)
# define CastType HMODULE
# define LookupSymbol GetProcAddress
# define MODULE_HANDLE HMODULE
# define MODULE_SYMBOL GetProcAddress
#else
# define CastType void *
# define LookupSymbol dlsym
# define MODULE_HANDLE void *
# define MODULE_SYMBOL dlsym
#endif
private:
@ -650,7 +653,7 @@ public:
if (plat.arm) {
return;
}
m_dlsym.patch (reinterpret_cast <void *> (&LookupSymbol), reinterpret_cast <void *> (&DynamicEntityLink::replacement));
m_dlsym.patch (reinterpret_cast <void *> (&MODULE_SYMBOL), reinterpret_cast <void *> (&DynamicEntityLink::replacement));
m_self.locate (&engfuncs);
}

View file

@ -12,6 +12,7 @@
* use or distribution of this code by or to any unlicensed person is illegal.
*
****/
#ifndef CONST_H
#define CONST_H
//

View file

@ -38,7 +38,7 @@ public:
~string_t () = default;
public:
const char *chars () const;
const char *chars (size_t shift = 0) const;
public:
operator int () const {
@ -104,8 +104,8 @@ static inline int MAKE_STRING (const char *val) {
#define MAKE_STRING(str) ((uint64)(str) - (uint64)(STRING(0)))
#endif
inline const char *string_t::chars () const {
return STRING (offset);
inline const char *string_t::chars (size_t shift) const {
return STRING (offset) + shift;
}
#endif // EXTDLL_H

View file

@ -1,6 +1,32 @@
/*
* Copyright (c) 2001-2006 Will Day <willday@hpgx.net>
* See the file "dllapi.h" in this folder for full information
*
* This file is part of Metamod.
*
* Metamod 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; either version 2 of the License, or (at
* your option) any later version.
*
* Metamod 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 Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
// Simplified version by Wei Mingzhi

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -113,6 +112,7 @@ public:
void forEach (ForEachBot handler);
void erase (Bot *bot);
void handleDeath (edict_t *killer, edict_t *victim);
void setLastWinner (int winner);
bool isTeamStacked (int team);
bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned);
@ -142,10 +142,6 @@ public:
return m_lastWinner;
}
void setLastWinner (int winner) {
m_lastWinner = winner;
}
// get the list of filters
SmallArray <BotTask> &getFilters () {
return m_filters;

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -13,16 +12,16 @@
#define PRODUCT_NAME "Yet Another POD-Bot"
#define PRODUCT_SHORT_NAME "YaPB"
#define PRODUCT_VERSION "2.92"
#define PRODUCT_AUTHOR "YaPB Dev Team"
#define PRODUCT_AUTHOR "YaPB Contributors"
#define PRODUCT_URL "https://yapb.ru/"
#define PRODUCT_EMAIL "d@entix.io"
#define PRODUCT_EMAIL "yapb@entix.io"
#define PRODUCT_LOGTAG "YAPB"
#define PRODUCT_END_YEAR "2019"
#define PRODUCT_DESCRIPTION PRODUCT_NAME " v" PRODUCT_VERSION " - The Counter-Strike Bot (" PRODUCT_COMMENTS ")"
#define PRODUCT_COPYRIGHT "Copyright © 1999-" PRODUCT_END_YEAR ", by " PRODUCT_AUTHOR
#define PRODUCT_COPYRIGHT "Copyright © 2004-" PRODUCT_END_YEAR ", by " PRODUCT_AUTHOR
#define PRODUCT_LEGAL "Half-Life, Counter-Strike, Counter-Strike: Condition Zero, Steam, Valve is a trademark of Valve Corporation"
#define PRODUCT_ORIGINAL_NAME "yapb.dll"
#define PRODUCT_INTERNAL_NAME "skybot"
#define PRODUCT_INTERNAL_NAME "podbot"
#define PRODUCT_GIT_HASH "unspecified_hash"
#define PRODUCT_GIT_COMMIT_AUTHOR "unspecified_author"
#define PRODUCT_GIT_COMMIT_ID 0000

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#pragma once
@ -19,6 +18,11 @@ using namespace cr;
#include <resource.h>
// forwards
class Bot;
class BotGraph;
class BotManager;
// defines bots tasks
CR_DECLARE_SCOPED_ENUM (Task,
Normal = 0,
@ -455,6 +459,10 @@ public:
// tasks definition
struct BotTask {
using Function = void (Bot::*) ();
public:
Function func; // corresponding exec function in bot class
Task id; // major task/action carried out
float desire; // desire (filled in) for this task
int data; // additional data (node index)
@ -462,7 +470,7 @@ struct BotTask {
bool resume; // if task can be continued if interrupted
public:
BotTask (Task id, float desire, int data, float time, bool resume) : id (id), desire (desire), data (data), time (time), resume (resume) { }
BotTask (Function func, Task id, float desire, int data, float time, bool resume) : func (func), id (id), desire (desire), data (data), time (time), resume (resume) { }
};
// weapon properties structure
@ -827,7 +835,7 @@ private:
void hide_ ();
void moveToPos_ ();
void plantBomb_ ();
void bombDefuse_ ();
void defuseBomb_ ();
void followUser_ ();
void throwExplosive_ ();
void throwFlashbang_ ();
@ -992,7 +1000,6 @@ public:
void pushChatMessage (int type, bool isTeamSay = false);
void pushRadioMessage (int message);
void pushChatterMessage (int message);
void handleChatter (const char *tempMessage);
void tryHeadTowardRadioMessage ();
void kill ();
void kick ();

View file

@ -1,25 +1,25 @@
#
# Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
# Copyright (c) YaPB Development Team.
# Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
#
# This software is licensed under the BSD-style license.
# Additional exceptions apply. For full license details, see LICENSE.txt or visit:
# https://yapb.ru/license
# This software is licensed under the MIT license.
# Additional exceptions apply. For full license details, see LICENSE.txt
#
PROJECT = yapb
SOURCES = ../source
OBJECTS = $(wildcard $(SOURCES)/*.cpp)
COMPILER_FLAGS = -std=c++11 -m32 -Wall -Wextra -Werror -fno-exceptions -fno-rtti -pedantic
COMPILER_FLAGS = -std=c++11 -m32 -Wall -Wextra -Werror -fno-exceptions -fno-rtti
LINKER_FLAGS = -m32 -ldl
ifeq "$(DEBUG)" "true"
COMPILER_FLAGS += -g3 -DCR_DEBUG
BINARY_DIR = debug
else
COMPILER_FLAGS += -pipe -O2 -march=core2 -msse2 -mfpmath=sse -ffast-math -fno-builtin -fno-threadsafe-statics -funroll-loops -fomit-frame-pointer -fno-stack-protector -fvisibility=hidden -fvisibility-inlines-hidden
COMPILER_FLAGS += -pipe -O3 -march=core2 -msse2 -mfpmath=sse -fno-builtin -fno-threadsafe-statics -funroll-loops -fomit-frame-pointer -fno-stack-protector -fvisibility=hidden -fvisibility-inlines-hidden
BINARY_DIR = release
LINKER_FLAGS += -static-libgcc
endif
INCLUDE = -I../include
@ -42,16 +42,18 @@ BINARY_OUTPUT = $(PROJECT).$(LIBRARY_EXT)
ifeq ($(findstring clang,$(COMPILER)),clang)
ifeq "$(OSX)" "false"
LINKER_FLAGS += -lgcc_eh
else
ifeq "$(DEBUG)" "true"
LINKER_FLAGS += -lstdc++
else
LINKER_FLAGS += -static-libgcc -nostdlib++ -Wunused-command-line-argument -fuse-ld=lld -Wl,-z,notext --no-undefined
LINKER_FLAGS += -nostdlib++ -Wunused-command-line-argument -fuse-ld=lld -Wl,-z,notext --no-undefined
endif
endif
else ifeq ($(findstring gcc,$(COMPILER)),gcc)
ifneq "$(OSX)" "false"
ifneq "$(DEBUG)" "true"
LINKER_FLAGS += -static-libgcc -Wl,--no-undefined -flto=thin
LINKER_FLAGS += -Wl,--no-undefined -flto=thin
COMPILER_FLAGS += -funroll-all-loops -flto=thin
endif
endif
@ -60,7 +62,7 @@ else ifeq ($(findstring icc,$(COMPILER)),icc)
ifneq "$(DEBUG)" "true"
COMPILER_FLAGS += -funroll-all-loops -ipo -wd11076 -wd11074
LINKER_FLAGS += -static-libgcc -cxxlib-nostd -Wl,--no-undefined,-z,notext,--gc-sections -ipo
LINKER_FLAGS += -cxxlib-nostd -Wl,--no-undefined,-z,notext,--gc-sections -ipo
endif
endif

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -93,20 +92,20 @@ bool Bot::isInViewCone (const Vector &origin) {
}
bool Bot::seesItem (const Vector &destination, const char *itemName) {
TraceResult tr;
TraceResult tr {};
// trace a line from bot's eyes to destination..
game.testLine (getEyesPos (), destination, TraceIgnore::Monsters, ent (), &tr);
// check if line of sight to object is not blocked (i.e. visible)
if (tr.flFraction != 1.0f) {
if (tr.flFraction != 1.0f && tr.pHit) {
return strcmp (tr.pHit->v.classname.chars (), itemName) == 0;
}
return true;
}
bool Bot::seesEntity (const Vector &dest, bool fromBody) {
TraceResult tr;
TraceResult tr {};
// trace a line from bot's eyes to destination...
game.testLine (fromBody ? pev->origin : getEyesPos (), dest, TraceIgnore::Everything, ent (), &tr);
@ -330,7 +329,7 @@ void Bot::avoidGrenades () {
if (!seesEntity (pent->v.origin) && isInFOV (pent->v.origin - getEyesPos ()) > pev->fov * 0.5f) {
continue;
}
auto model = pent->v.model.chars () + 9;
auto model = pent->v.model.chars (9);
if (m_preventFlashing < game.time () && m_personality == Personality::Rusher && m_difficulty == 4 && strcmp (model, "flashbang.mdl") == 0) {
// don't look at flash bang
@ -428,7 +427,7 @@ void Bot::checkBreakablesAround () {
edict_t *Bot::lookupBreakable () {
// this function checks if bot is blocked by a shoot able breakable in his moving direction
TraceResult tr;
TraceResult tr {};
game.testLine (pev->origin, pev->origin + (m_destOrigin - pev->origin).normalize () * 72.0f, TraceIgnore::None, ent (), &tr);
if (tr.flFraction != 1.0f) {
@ -539,7 +538,7 @@ void Bot::updatePickups () {
}
auto classname = ent->v.classname.chars ();
auto model = ent->v.model.chars () + 9;
auto model = ent->v.model.chars (9);
// check if line of sight to object is not blocked (i.e. visible)
if (seesItem (origin, classname)) {
@ -830,7 +829,7 @@ void Bot::getCampDirection (Vector *dest) {
// this function check if view on last enemy position is blocked - replace with better vector then
// mostly used for getting a good camping direction vector if not camping on a camp waypoint
TraceResult tr;
TraceResult tr {};
const Vector &src = getEyesPos ();
game.testLine (src, *dest, TraceIgnore::Monsters, ent (), &tr);
@ -1484,7 +1483,7 @@ void Bot::buyStuff () {
break;
case BuyState::SecondaryWeapon: // if bot has still some money, buy a better secondary weapon
if (isPistolMode || (isFirstRound && hasDefaultPistols) || (hasDefaultPistols && bots.getLastWinner () == m_team && m_moneyAmount > rg.int_ (3500, 4500)) || (hasPrimaryWeapon () && hasDefaultPistols && m_moneyAmount > rg.int_ (7500, 9000))) {
if (isPistolMode || (isFirstRound && hasDefaultPistols) || (hasDefaultPistols && bots.getLastWinner () == m_team && m_moneyAmount > rg.int_ (2000, 3000)) || (hasPrimaryWeapon () && hasDefaultPistols && m_moneyAmount > rg.int_ (7500, 9000))) {
do {
pref--;
@ -2031,6 +2030,8 @@ void Bot::clearTasks () {
}
void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
static const auto &filter = bots.getFilters ();
for (auto &task : m_tasks) {
if (task.id == id) {
if (!cr::fequal (task.desire, desire)) {
@ -2039,7 +2040,7 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
return;
}
}
m_tasks.emplace (id, desire, data, time, resume);
m_tasks.emplace (filter[id].func, id, desire, data, time, resume);
clearSearchNodes ();
ignoreCollision ();
@ -2056,6 +2057,7 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
}
// this is best place to handle some voice commands report team some info
if (yb_radio_mode.int_ () > 1) {
if (rg.chance (90)) {
if (tid == Task::Blind) {
pushChatterMessage (Chatter::Blind);
@ -2074,21 +2076,22 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
}
}
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inVIPZone) {
pushChatterMessage (Chatter::GoingToGuardVIPSafety);
}
}
if (yb_debug_goal.int_ () != kInvalidNodeIndex) {
m_chosenGoalIndex = yb_debug_goal.int_ ();
}
else {
m_chosenGoalIndex = getTask ()->data;
}
if (rg.chance (75) && tid == Task::Camp && m_team == Team::Terrorist && m_inVIPZone) {
pushChatterMessage (Chatter::GoingToGuardVIPSafety);
}
}
BotTask *Bot::getTask () {
if (m_tasks.empty ()) {
m_tasks.emplace (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
startTask (Task::Normal, TaskPri::Normal, kInvalidNodeIndex, 0.0f, true);
}
return &m_tasks.last ();
}
@ -3200,7 +3203,7 @@ void Bot::spraypaint_ () {
const auto &forward = pev->v_angle.forward ();
Vector sprayOrigin = getEyesPos () + forward * 128.0f;
TraceResult tr;
TraceResult tr {};
game.testLine (getEyesPos (), sprayOrigin, TraceIgnore::Monsters, ent (), &tr);
// no wall in front?
@ -3732,7 +3735,7 @@ void Bot::plantBomb_ () {
}
}
void Bot::bombDefuse_ () {
void Bot::defuseBomb_ () {
float fullDefuseTime = m_hasDefuser ? 7.0f : 12.0f;
float timeToBlowUp = getBombTimeleft ();
float defuseRemainingTime = fullDefuseTime;
@ -3908,7 +3911,7 @@ void Bot::followUser_ () {
}
if (m_targetEntity->v.button & IN_ATTACK) {
TraceResult tr;
TraceResult tr {};
game.testLine (m_targetEntity->v.origin + m_targetEntity->v.view_ofs, m_targetEntity->v.v_angle.forward () * 500.0f, TraceIgnore::Everything, ent (), &tr);
if (!game.isNullEntity (tr.pHit) && util.isPlayer (tr.pHit) && game.getTeam (tr.pHit) != m_team) {
@ -4201,7 +4204,7 @@ void Bot::doublejump_ () {
const auto &src = pev->origin + Vector (0.0f, 0.0f, 45.0f);
const auto &dest = src + Vector (0.0f, pev->angles.y, 0.0f).upward () * 256.0f;
TraceResult tr;
TraceResult tr {};
game.testLine (src, dest, TraceIgnore::None, ent (), &tr);
if (tr.flFraction < 1.0f && tr.pHit == m_doubleJumpEntity && inJump) {
@ -4373,7 +4376,7 @@ void Bot::pickupItem_ () {
auto &info = conf.getWeapons ();
for (index = 0; index < 7; ++index) {
if (strcmp (info[index].model, m_pickupItem->v.model.chars () + 9) == 0) {
if (strcmp (info[index].model, m_pickupItem->v.model.chars (9)) == 0) {
break;
}
}
@ -4536,108 +4539,15 @@ void Bot::pickupItem_ () {
void Bot::executeTasks () {
// this is core function that handle task execution
switch (getCurrentTaskId ()) {
// normal task
default:
case Task::Normal:
normal_ ();
break;
auto func = getTask ()->func;
// bot sprays messy logos all over the place...
case Task::Spraypaint:
spraypaint_ ();
break;
// hunt down enemy
case Task::Hunt:
huntEnemy_ ();
break;
// bot seeks cover from enemy
case Task::SeekCover:
seekCover_ ();
break;
// plain attacking
case Task::Attack:
attackEnemy_ ();
break;
// Bot is pausing
case Task::Pause:
pause_ ();
break;
// blinded (flashbanged) behaviour
case Task::Blind:
blind_ ();
break;
// camping behaviour
case Task::Camp:
camp_ ();
break;
// hiding behaviour
case Task::Hide:
hide_ ();
break;
// moves to a position specified in position has a higher priority than task_normal
case Task::MoveToPosition:
moveToPos_ ();
break;
// planting the bomb right now
case Task::PlantBomb:
plantBomb_ ();
break;
// bomb defusing behaviour
case Task::DefuseBomb:
bombDefuse_ ();
break;
// follow user behaviour
case Task::FollowUser:
followUser_ ();
break;
// HE grenade throw behaviour
case Task::ThrowExplosive:
throwExplosive_ ();
break;
// flashbang throw behavior (basically the same code like for HE's)
case Task::ThrowFlashbang:
throwFlashbang_ ();
break;
// smoke grenade throw behavior
// a bit different to the others because it mostly tries to throw the sg on the ground
case Task::ThrowSmoke:
throwSmoke_ ();
break;
// bot helps human player (or other bot) to get somewhere
case Task::DoubleJump:
doublejump_ ();
break;
// escape from bomb behaviour
case Task::EscapeFromBomb:
escapeFromBomb_ ();
break;
// shooting breakables in the way action
case Task::ShootBreakable:
shootBreakable_ ();
break;
// picking up items and stuff behaviour
case Task::PickupItem:
pickupItem_ ();
break;
// run the current task
if (func != nullptr) {
(this->*func) ();
}
else {
logger.error ("Missing callback function of Task %d.", getCurrentTaskId ());
kick (); // drop the player, as it's fatal for bot
}
}
@ -4737,6 +4647,9 @@ void Bot::logic () {
if (canRunHeavyWeight ()) {
setConditions ();
}
else if (!game.isNullEntity (m_enemy)) {
trackEnemies ();
}
// some stuff required by by chatter engine
if (yb_radio_mode.int_ () == 2) {
@ -5086,7 +4999,6 @@ void Bot::takeDamage (edict_t *inflictor, int damage, int armor, int bits) {
m_enemyOrigin = m_enemy->v.origin;
pushChatMessage (Chat::TeamAttack);
handleChatter ("#Bot_TeamAttack");
pushChatterMessage (Chatter::FriendlyFire);
}
else {
@ -5235,29 +5147,6 @@ void Bot::updatePracticeDamage (edict_t *attacker, int damage) {
graph.setDangerDamage (m_team, victimIndex, attackerIndex, damageValue);
}
void Bot::handleChatter (const char *tempMessage) {
// this function is added to prevent engine crashes with: 'Message XX started, before message XX ended', or something.
if ((m_team == Team::CT && strcmp (tempMessage, "#CTs_Win") == 0) || (m_team == Team::Terrorist && strcmp (tempMessage, "#Terrorists_Win") == 0)) {
if (bots.getRoundMidTime () > game.time ()) {
pushChatterMessage (Chatter::QuickWonRound);
}
else {
pushChatterMessage (Chatter::WonTheRound);
}
}
else if (strcmp (tempMessage, "#Bot_TeamAttack") == 0) {
pushChatterMessage (Chatter::FriendlyFire);
}
else if (strcmp (tempMessage, "#Bot_NiceShotCommander") == 0) {
pushChatterMessage (Chatter::NiceShotCommander);
}
else if (strcmp (tempMessage, "#Bot_NiceShotPall") == 0) {
pushChatterMessage (Chatter::NiceShotPall);
}
}
void Bot::pushChatMessage (int type, bool isTeamSay) {
if (!conf.hasChatBank (type) || !yb_chat.bool_ ()) {
return;
@ -5352,7 +5241,7 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) {
// this function returns the velocity at which an object should looped from start to land near end.
// returns null vector if toss is not feasible.
TraceResult tr;
TraceResult tr {};
float gravity = sv_gravity.float_ () * 0.55f;
Vector end = stop - pev->velocity;
@ -5364,7 +5253,7 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) {
Vector midPoint = start + (end - start) * 0.5f;
game.testHull (midPoint, midPoint + Vector (0.0f, 0.0f, 500.0f), TraceIgnore::Monsters, head_hull, ent (), &tr);
if (tr.flFraction < 1.0f) {
if (tr.flFraction < 1.0f && tr.pHit) {
midPoint = tr.vecEndPos;
midPoint.z = tr.pHit->v.absmin.z - 1.0f;
}
@ -5406,7 +5295,7 @@ Vector Bot::calcThrow (const Vector &start, const Vector &stop) {
// returns null vector if throw is not feasible.
Vector velocity = stop - start;
TraceResult tr;
TraceResult tr {};
float gravity = sv_gravity.float_ () * 0.55f;
float time = velocity.length () / 195.0f;
@ -5444,7 +5333,7 @@ edict_t *Bot::correctGrenadeVelocity (const char *model) {
edict_t *result = nullptr;
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
if (ent->v.owner == this->ent () && strcmp (ent->v.model.chars () + 9, model) == 0) {
if (ent->v.owner == this->ent () && strcmp (ent->v.model.chars (9), model) == 0) {
result = ent;
// set the correct velocity for the grenade

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -97,7 +96,7 @@ bool Bot::checkBodyParts (edict_t *target) {
return false;
}
TraceResult result;
TraceResult result {};
auto eyes = getEyesPos ();
auto spot = target->v.origin;
@ -539,7 +538,7 @@ bool Bot::isFriendInLineOfFire (float distance) {
return false;
}
TraceResult tr;
TraceResult tr {};
game.testLine (getEyesPos (), getEyesPos () + distance * pev->v_angle.normalize (), TraceIgnore::None, ent (), &tr);
// check if we hit something
@ -582,7 +581,7 @@ bool Bot::isPenetrableObstacle (const Vector &dest) {
if (penetratePower == 0) {
return false;
}
TraceResult tr;
TraceResult tr {};
float obstacleDistance = 0.0f;
game.testLine (getEyesPos (), dest, TraceIgnore::Monsters, ent (), &tr);
@ -632,7 +631,7 @@ bool Bot::isPenetrableObstacle2 (const Vector &dest) {
int numHits = 0;
Vector point;
TraceResult tr;
TraceResult tr {};
game.testLine (source, dest, TraceIgnore::Everything, ent (), &tr);
@ -1197,7 +1196,7 @@ bool Bot::hasSecondaryWeapon () {
bool Bot::hasShield () {
// this function returns true, if bot has a tactical shield
return strncmp (pev->viewmodel.chars (), "models/shield/v_shield_", 23) == 0;
return strncmp (pev->viewmodel.chars (14), "v_shield_", 9) == 0;
}
bool Bot::isShieldDrawn () {
@ -1217,7 +1216,7 @@ bool Bot::isEnemyBehindShield (edict_t *enemy) {
}
// check if enemy has shield and this shield is drawn
if ((enemy->v.weaponanim == 6 || enemy->v.weaponanim == 7) && strncmp (enemy->v.viewmodel.chars (), "models/shield/v_shield_", 23) == 0) {
if ((enemy->v.weaponanim == 6 || enemy->v.weaponanim == 7) && strncmp (enemy->v.viewmodel.chars (14), "v_shield_", 9) == 0) {
if (util.isInViewCone (pev->origin, enemy)) {
return true;
}
@ -1356,7 +1355,7 @@ bool Bot::rateGroundWeapon (edict_t *ent) {
auto tab = conf.getRawWeapons ();
for (int i = 0; i < kNumWeapons; ++i) {
if (strcmp (tab[*pref].model, ent->v.model.chars () + 9) == 0) {
if (strcmp (tab[*pref].model, ent->v.model.chars (9)) == 0) {
groundIndex = i;
break;
}

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -22,8 +21,8 @@ Game::Game () {
m_precached = false;
m_isBotCommand = false;
memset (m_drawModels, 0, sizeof (m_drawModels));
memset (m_spawnCount, 0, sizeof (m_spawnCount));
plat.bzero (m_drawModels, sizeof (m_drawModels));
plat.bzero (m_spawnCount, sizeof (m_spawnCount));
m_gameFlags = 0;
m_mapFlags = 0;
@ -88,7 +87,7 @@ void Game::levelInitialize (edict_t *entities, int max) {
util.installSendTo ();
}
else if (strcmp (classname, "player_weaponstrip") == 0) {
if (is (GameFlags::Legacy) && ent->v.target.chars ()[0] == '\0') {
if (is (GameFlags::Legacy) && strings.isEmpty (ent->v.target.chars ())) {
ent->v.target = ent->v.targetname = engfuncs.pfnAllocString ("fake");
}
else {
@ -256,7 +255,7 @@ float Game::getWaveLen (const char *fileName) {
unsigned long dataChunkLength;
} waveHdr;
memset (&waveHdr, 0, sizeof (waveHdr));
plat.bzero (&waveHdr, sizeof (waveHdr));
if (fp.read (&waveHdr, sizeof (WavHeader)) == 0) {
logger.error ("Wave File %s - has wrong or unsupported format", filePath);
@ -465,6 +464,20 @@ bool Game::isSoftwareRenderer () {
if (isDedicated ()) {
return true;
}
auto model = illum.getWorldModel ();
if (model->nodes[0].parent != nullptr) {
return false;
}
const auto child = model->nodes[0].children[0];
if (child < model->nodes || child > model->nodes + model->numnodes) {
return false;
}
if (child->parent != &model->nodes[0]) {
return false;
}
// and on only windows version you can use software-render game. Linux, OSX always defaults to OpenGL
if (plat.win32) {
@ -476,7 +489,7 @@ bool Game::isSoftwareRenderer () {
void Game::addNewCvar (const char *name, const char *value, const char *info, bool bounded, float min, float max, Var varType, bool missingAction, const char *regval, ConVar *self) {
// this function adds globally defined variable to registration stack
VarPair pair;
VarPair pair {};
pair.reg.name = const_cast <char *> (name);
pair.reg.string = const_cast <char *> (value);
@ -747,7 +760,7 @@ bool Game::postload () {
if (is (GameFlags::Metamod)) {
return true; // we should stop the attempt for loading the real gamedll, since metamod handle this for us
}
auto gamedll = strings.format ("%s/%s", getenv ("XASH3D_GAMELIBDIR"), plat.hfp ? "libserver_hardfp.so" : "libserver.so");
auto gamedll = strings.format ("%s/%s", plat.env ("XASH3D_GAMELIBDIR"), plat.hfp ? "libserver_hardfp.so" : "libserver.so");
if (!m_gameLib.load (gamedll)) {
logger.fatal ("Unable to load gamedll \"%s\". Exiting... (gamedir: %s)", gamedll, getModName ());
@ -938,7 +951,7 @@ void LightMeasure::updateLight (int style, char *value) {
return;
}
const auto copyLimit = sizeof (m_lightstyle[style].map) - sizeof ('\0');
strncpy (m_lightstyle[style].map, value, copyLimit);
strings.copy (m_lightstyle[style].map, value, copyLimit);
m_lightstyle[style].map[copyLimit] = '\0';
m_lightstyle[style].length = strlen (m_lightstyle[style].map);
@ -1072,7 +1085,7 @@ DynamicEntityLink::Handle DynamicEntityLink::search (Handle module, Name functio
Handle ret = nullptr;
if (m_dlsym.disable ()) {
ret = LookupSymbol (reinterpret_cast <CastType> (handle), function);
ret = MODULE_SYMBOL (reinterpret_cast <MODULE_HANDLE> (handle), function);
m_dlsym.enable ();
}
return ret;

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -637,7 +636,7 @@ void BotGraph::add (int type, const Vector &pos) {
if (m_paths.length () >= kMaxNodes) {
return;
}
m_paths.push (Path ());
m_paths.push (Path {});
index = m_paths.length () - 1;
path = &m_paths[index];
@ -737,7 +736,7 @@ void BotGraph::add (int type, const Vector &pos) {
float minDistance = kInfiniteDistance;
int destIndex = kInvalidNodeIndex;
TraceResult tr;
TraceResult tr {};
// calculate all the paths to this new node
for (const auto &calc : m_paths) {
@ -929,7 +928,7 @@ int BotGraph::getFacingIndex () {
}
// check if visible, (we're not using visiblity tables here, as they not valid at time of waypoint editing)
TraceResult tr;
TraceResult tr {};
game.testLine (editorEyes, path.origin, TraceIgnore::Everything, m_editor, &tr);
if (!cr::fequal (tr.flFraction, 1.0f)) {
@ -1076,7 +1075,7 @@ void BotGraph::calculatePathRadius (int index) {
return;
}
}
TraceResult tr;
TraceResult tr {};
bool wayBlocked = false;
for (float scanDistance = 32.0f; scanDistance < 128.0f; scanDistance += 16.0f) {
@ -1098,7 +1097,7 @@ void BotGraph::calculatePathRadius (int index) {
if (tr.flFraction < 1.0f) {
game.testLine (radiusStart, radiusEnd, TraceIgnore::Monsters, nullptr, &tr);
if (strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
if (tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
path.radius = 0.0f;
wayBlocked = true;
@ -1336,7 +1335,7 @@ bool BotGraph::convertOldFormat () {
MemFile fp (getOldFormatGraphName (true));
PODGraphHeader header;
memset (&header, 0, sizeof (header));
plat.bzero (&header, sizeof (header));
// save for faster access
const char *map = game.getMapName ();
@ -1350,7 +1349,7 @@ bool BotGraph::convertOldFormat () {
if (header.fileVersion != StorageVersion::Podbot) {
return false;
}
else if (!plat.caseStrMatch (header.mapName, map)) {
else if (!strings.matches (header.mapName, map)) {
return false;
}
else {
@ -1693,9 +1692,9 @@ bool BotGraph::saveGraphData () {
void BotGraph::saveOldFormat () {
PODGraphHeader header {};
strcpy (header.header, kPodbotMagic);
strncpy (header.author, m_editor->v.netname.chars (), cr::bufsize (header.author));
strncpy (header.mapName, game.getMapName (), cr::bufsize (header.mapName));
strings.copy (header.header, kPodbotMagic, sizeof (kPodbotMagic));
strings.copy (header.author, m_editor->v.netname.chars (), cr::bufsize (header.author));
strings.copy (header.mapName, game.getMapName (), cr::bufsize (header.mapName));
header.mapName[31] = 0;
header.fileVersion = StorageVersion::Podbot;
@ -1739,7 +1738,7 @@ float BotGraph::calculateTravelTime (float maxSpeed, const Vector &src, const Ve
}
bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
TraceResult tr;
TraceResult tr {};
float distance = (destination - src).length ();
@ -1751,7 +1750,7 @@ bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
// check if we go through a func_illusionary, in which case return false
game.testHull (src, destination, TraceIgnore::Monsters, head_hull, m_editor, &tr);
if (!game.isNullEntity (tr.pHit) && strcmp ("func_illusionary", tr.pHit->v.classname.chars ()) == 0) {
if (tr.pHit && strcmp ("func_illusionary", tr.pHit->v.classname.chars ()) == 0) {
return false; // don't add pathnodes through func_illusionaries
}
@ -1759,7 +1758,7 @@ bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) {
game.testLine (src, destination, TraceIgnore::Monsters, m_editor, &tr);
// if node is visible from current position (even behind head)...
if (tr.flFraction >= 1.0f || strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
if (tr.flFraction >= 1.0f || (tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0)) {
// if it's a door check if nothing blocks behind
if (strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) {
game.testLine (tr.vecEndPos, destination, TraceIgnore::Monsters, tr.pHit, &tr);
@ -1827,7 +1826,7 @@ void BotGraph::rebuildVisibility () {
return;
}
TraceResult tr;
TraceResult tr {};
uint8 res, shift;
for (const auto &vis : m_paths) {
@ -2525,7 +2524,7 @@ void BotGraph::addBasic () {
Vector ladderRight = ent->v.absmax;
ladderLeft.z = ladderRight.z;
TraceResult tr;
TraceResult tr {};
Vector up, down, front, back;
const Vector &diff = ((ladderLeft - ladderRight) ^ Vector (0.0f, 0.0f, 0.0f)).normalize () * 15.0f;
@ -2650,7 +2649,7 @@ void BotGraph::setBombOrigin (bool reset, const Vector &pos) {
}
game.searchEntities ("classname", "grenade", [&] (edict_t *ent) {
if (strcmp (ent->v.model.chars () + 9, "c4.mdl") == 0) {
if (strcmp (ent->v.model.chars (9), "c4.mdl") == 0) {
m_bombOrigin = game.getEntityWorldOrigin (ent);
return EntitySearchResult::Break;
}
@ -2674,7 +2673,7 @@ void BotGraph::setSearchIndex (int index) {
}
BotGraph::BotGraph () {
memset (m_highestDamage, 0, sizeof (m_highestDamage));
plat.bzero (m_highestDamage, sizeof (m_highestDamage));
m_endJumpPoint = false;
m_needsVisRebuild = false;

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -87,7 +86,7 @@ CR_EXPORT int GetEntityAPI2 (gamefuncs_t *table, int *) {
// engine, and then calls the MOD DLL's version of GetEntityAPI to get the REAL gamedll
// functions this time (to use in the bot code).
memset (table, 0, sizeof (gamefuncs_t));
plat.bzero (table, sizeof (gamefuncs_t));
if (!(game.is (GameFlags::Metamod))) {
auto api_GetEntityAPI = game.lib ().resolve <int (*) (gamefuncs_t *, int)> ("GetEntityAPI");
@ -457,7 +456,7 @@ CR_LINKAGE_C int GetEntityAPI2_Post (gamefuncs_t *table, int *) {
// engine, and then calls the MOD DLL's version of GetEntityAPI to get the REAL gamedll
// functions this time (to use in the bot code). Post version, called only by metamod.
memset (table, 0, sizeof (gamefuncs_t));
plat.bzero (table, sizeof (gamefuncs_t));
table->pfnSpawn = [] (edict_t *ent) {
// this function asks the game DLL to spawn (i.e, give a physical existence in the virtual
@ -505,7 +504,7 @@ CR_LINKAGE_C int GetEntityAPI2_Post (gamefuncs_t *table, int *) {
CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) {
if (game.is (GameFlags::Metamod)) {
memset (table, 0, sizeof (enginefuncs_t));
plat.bzero (table, sizeof (enginefuncs_t));
}
table->pfnChangeLevel = [] (char *s1, char *s2) {
@ -811,7 +810,7 @@ CR_EXPORT int GetNewDLLFunctions (newgamefuncs_t *table, int *interfaceVersion)
}
CR_LINKAGE_C int GetEngineFunctions_Post (enginefuncs_t *table, int *) {
memset (table, 0, sizeof (enginefuncs_t));
plat.bzero (table, sizeof (enginefuncs_t));
table->pfnMessageEnd = [] () {
msgs.stop (); // this allows us to send messages right in handler code

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -273,7 +272,7 @@ void BotManager::frame () {
void BotManager::addbot (const String &name, int difficulty, int personality, int team, int member, bool manual) {
// this function putting bot creation process to queue to prevent engine crashes
CreateQueue create;
CreateQueue create {};
// fill the holder
create.name = name;
@ -290,7 +289,7 @@ void BotManager::addbot (const String &name, int difficulty, int personality, in
void BotManager::addbot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member, bool manual) {
// this function is same as the function above, but accept as parameters string instead of integers
CreateQueue create;
CreateQueue create {};
const String &any = "*";
create.name = (name.empty () || name == any) ? String ("\0") : name;
@ -358,10 +357,10 @@ void BotManager::maintainQuota () {
int desiredBotCount = yb_quota.int_ ();
int botsInGame = getBotCount ();
if (plat.caseStrMatch (yb_quota_mode.str (), "fill")) {
if (strings.matches (yb_quota_mode.str (), "fill")) {
botsInGame += humanPlayersInGame;
}
else if (plat.caseStrMatch (yb_quota_mode.str (), "match")) {
else if (strings.matches (yb_quota_mode.str (), "match")) {
int detectQuotaMatch = yb_quota_match.int_ () == 0 ? yb_quota.int_ () : yb_quota_match.int_ ();
desiredBotCount = cr::max <int> (0, detectQuotaMatch * humanPlayersInGame);
@ -427,26 +426,26 @@ void BotManager::reset () {
void BotManager::initFilters () {
// table with all available actions for the bots (filtered in & out in bot::setconditions) some of them have subactions included
m_filters.emplace (Task::Normal, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (Task::Pause, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::MoveToPosition, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (Task::FollowUser, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (Task::PickupItem, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (Task::Camp, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (Task::PlantBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::DefuseBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::Attack, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::Hunt, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::SeekCover, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::ThrowExplosive, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::ThrowFlashbang, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::ThrowSmoke, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::DoubleJump, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::EscapeFromBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::ShootBreakable, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::Hide, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::Blind, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (Task::Spraypaint, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::normal_, Task::Normal, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (&Bot::pause_, Task::Pause, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::moveToPos_, Task::MoveToPosition, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (&Bot::followUser_, Task::FollowUser, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (&Bot::pickupItem_, Task::PickupItem, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (&Bot::camp_, Task::Camp, 0.0f, kInvalidNodeIndex, 0.0f, true);
m_filters.emplace (&Bot::plantBomb_, Task::PlantBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::defuseBomb_, Task::DefuseBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::attackEnemy_, Task::Attack, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::huntEnemy_, Task::Hunt, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::seekCover_, Task::SeekCover, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::throwExplosive_, Task::ThrowExplosive, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::throwFlashbang_, Task::ThrowFlashbang, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::throwSmoke_, Task::ThrowSmoke, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::doublejump_, Task::DoubleJump, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::escapeFromBomb_, Task::EscapeFromBomb, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::shootBreakable_, Task::ShootBreakable, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::hide_, Task::Hide, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::blind_, Task::Blind, 0.0f, kInvalidNodeIndex, 0.0f, false);
m_filters.emplace (&Bot::spraypaint_, Task::Spraypaint, 0.0f, kInvalidNodeIndex, 0.0f, false);
}
void BotManager::resetFilters () {
@ -619,6 +618,26 @@ bool BotManager::kickRandom (bool decQuota, Team fromTeam) {
return false;
}
void BotManager::setLastWinner (int winner) {
m_lastWinner = winner;
if (yb_radio_mode.int_ () != 2) {
return;
}
auto notify = findAliveBot ();
if (notify) {
if (notify->m_team == winner) {
if (getRoundMidTime () > game.time ()) {
notify->pushChatterMessage (Chatter::QuickWonRound);
}
else {
notify->pushChatterMessage (Chatter::WonTheRound);
}
}
}
}
void BotManager::setWeaponMode (int selection) {
// this function sets bots weapon mode
@ -785,12 +804,13 @@ void BotManager::destroy () {
}
Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member) {
// this function does core operation of creating bot, it's called by CreateBot (),
// this function does core operation of creating bot, it's called by addbot (),
// when bot setup completed, (this is a bot class constructor)
int clientIndex = game.indexOfEntity (bot);
// we're not initializing all the variables in bot class, so do an ugly thing... memset this
plat.bzero (this, sizeof (*this));
memset (reinterpret_cast <void *> (this), 0, sizeof (*this));
int clientIndex = game.indexOfEntity (bot);
pev = &bot->v;
if (bot->pvPrivateData != nullptr) {
@ -881,8 +901,8 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int member) {
break;
}
memset (&m_ammoInClip, 0, sizeof (m_ammoInClip));
memset (&m_ammo, 0, sizeof (m_ammo));
plat.bzero (&m_ammoInClip, sizeof (m_ammoInClip));
plat.bzero (&m_ammo, sizeof (m_ammo));
m_currentWeapon = 0; // current weapon is not assigned at start
m_voicePitch = rg.int_ (80, 115); // assign voice pitch
@ -975,10 +995,10 @@ void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
for (const auto &notify : bots) {
if (notify->m_notKilled && killerTeam == notify->m_team && killerTeam != victimTeam && killer != notify->ent () && notify->seesEntity (victim->v.origin)) {
if (!(killer->v.flags & FL_FAKECLIENT)) {
notify->handleChatter ("#Bot_NiceShotCommander");
notify->pushChatterMessage (Chatter::NiceShotCommander);
}
else {
notify->handleChatter ("#Bot_NiceShotPall");
notify->pushChatterMessage (Chatter::NiceShotPall);
}
break;
}
@ -1179,8 +1199,8 @@ void Bot::newRound () {
// if bot died, clear all weapon stuff and force buying again
if (!m_notKilled) {
memset (&m_ammoInClip, 0, sizeof (m_ammoInClip));
memset (&m_ammo, 0, sizeof (m_ammo));
plat.bzero (&m_ammoInClip, sizeof (m_ammoInClip));
plat.bzero (&m_ammo, sizeof (m_ammo));
m_currentWeapon = 0;
}
@ -1339,7 +1359,7 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en
return;
}
if (plat.caseStrMatch (cmd, "say") || plat.caseStrMatch (cmd, "say_team")) {
if (strings.matches (cmd, "say") || strings.matches (cmd, "say_team")) {
bool alive = util.isAlive (ent);
int team = -1;
@ -1414,7 +1434,7 @@ void BotManager::updateActiveGrenade () {
// search the map for any type of grenade
game.searchEntities ("classname", "grenade", [&] (edict_t *e) {
// do not count c4 as a grenade
if (strcmp (e->v.model.chars () + 9, "c4.mdl") == 0) {
if (strcmp (e->v.model.chars (9), "c4.mdl") == 0) {
return EntitySearchResult::Continue;
}
m_activeGrenades.push (e);
@ -1668,10 +1688,10 @@ void BotConfig::loadMainConfig () {
if (cvar != nullptr) {
auto value = const_cast <char *> (keyval[1].trim ().trim ("\"").trim ().chars ());
if (needsToIgnoreVar (ignore, key) && !plat.caseStrMatch (value, cvar->string)) {
if (needsToIgnoreVar (ignore, key) && !strings.matches (value, cvar->string)) {
// preserve quota number if it's zero
if (plat.caseStrMatch (cvar->name, "yb_quota") && yb_quota.int_ () <= 0) {
if (strings.matches (cvar->name, "yb_quota") && yb_quota.int_ () <= 0) {
engfuncs.pfnCvar_DirectSet (cvar, value);
continue;
}

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -17,18 +16,6 @@ void MessageDispatcher::netMsgTextMsg () {
return;
}
// bots chatter notification
const auto dispatchChatterMessage = [&] () -> void {
if (yb_radio_mode.int_ () == 2) {
auto notify = bots.findAliveBot ();
if (notify && notify->m_notKilled) {
notify->handleChatter (m_args[msg].chars_);
}
}
};
// lookup cached message
auto cached = m_textMsgCache[m_args[msg].chars_];
@ -50,8 +37,6 @@ void MessageDispatcher::netMsgTextMsg () {
}
else if (cached & TextMsgCache::CounterWin) {
bots.setLastWinner (Team::CT); // update last winner for economics
dispatchChatterMessage ();
resetBombPosition ();
}
else if (cached & TextMsgCache::RestartRound) {
@ -70,8 +55,6 @@ void MessageDispatcher::netMsgTextMsg () {
}
else if (cached & TextMsgCache::TerroristWin) {
bots.setLastWinner (Team::Terrorist); // update last winner for economics
dispatchChatterMessage ();
resetBombPosition ();
}
else if ((cached & TextMsgCache::BombPlanted) && !bots.isBombPlanted ()) {

View file

@ -1,10 +1,9 @@
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -19,7 +18,7 @@ int Bot::findBestGoal () {
int result = kInvalidNodeIndex;
game.searchEntities ("classname", "weaponbox", [&] (edict_t *ent) {
if (strcmp (ent->v.model.chars () + 9, "backpack.mdl") == 0) {
if (strcmp (ent->v.model.chars (9), "backpack.mdl") == 0) {
result = graph.getNearest (game.getEntityWorldOrigin (ent));
if (graph.exists (result)) {
@ -361,7 +360,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
m_isStuck = false;
// if avoiding someone do not consider stuck
TraceResult tr;
TraceResult tr {};
doPlayerAvoidance (dirNormal);
// Standing still, no need to check?
@ -702,7 +701,7 @@ bool Bot::updateNavigation () {
return false;
}
}
TraceResult tr;
TraceResult tr {};
// check if we are going through a door...
if (game.mapIs (MapFlags::HasDoors)) {
@ -849,7 +848,7 @@ bool Bot::updateLiftHandling () {
// update node time set
m_navTimeset = game.time ();
TraceResult tr;
TraceResult tr {};
// wait for something about for lift
auto wait = [&] () {
@ -867,7 +866,7 @@ bool Bot::updateLiftHandling () {
// trace line to door
game.testLine (pev->origin, m_path->origin, TraceIgnore::Everything, ent (), &tr);
if (tr.flFraction < 1.0f && strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) {
if (tr.flFraction < 1.0f && tr.pHit && strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) {
if (m_liftState == LiftState::None) {
m_liftState = LiftState::LookingButtonOutside;
m_liftUsageTime = game.time () + 7.0f;
@ -1817,7 +1816,7 @@ int Bot::findDefendNode (const Vector &origin) {
if (m_currentNodeIndex == kInvalidNodeIndex) {
m_currentNodeIndex = changePointIndex (findNearestNode ());
}
TraceResult tr;
TraceResult tr {};
int nodeIndex[kMaxNodeLinks];
int minDistance[kMaxNodeLinks];
@ -2016,7 +2015,7 @@ int Bot::findCoverNode (float maxDistance) {
}
} while (sorting);
TraceResult tr;
TraceResult tr {};
// take the first one which isn't spotted by the enemy
for (const auto &index : nodeIndex) {
@ -2073,7 +2072,7 @@ bool Bot::advanceMovement () {
if (m_pathWalk.empty ()) {
return false;
}
TraceResult tr;
TraceResult tr {};
m_pathWalk.shift (); // advance in list
m_currentTravelFlags = 0; // reset travel flags (jumping etc)
@ -2392,7 +2391,7 @@ bool Bot::canStrafeRight (TraceResult *tr) {
bool Bot::canJumpUp (const Vector &normal) {
// this function check if bot can jump over some obstacle
TraceResult tr;
TraceResult tr {};
// can't jump if not on ground and not on ladder/swimming
if (!isOnFloor () && (isOnLadder () || !isInWater ())) {
@ -2472,7 +2471,7 @@ bool Bot::doneCanJumpUp (const Vector &normal, const Vector &right) {
Vector src = pev->origin + Vector (0.0f, 0.0f, -36.0f + 63.0f);
Vector dest = src + normal * 32.0f;
TraceResult tr;
TraceResult tr {};
// trace a line forward at maximum jump height...
game.testLine (src, dest, TraceIgnore::Monsters, ent (), &tr);
@ -2541,7 +2540,7 @@ bool Bot::doneCanJumpUp (const Vector &normal, const Vector &right) {
bool Bot::canDuckUnder (const Vector &normal) {
// this function check if bot can duck under obstacle
TraceResult tr;
TraceResult tr {};
Vector baseHeight;
// use center of the body first...
@ -2590,7 +2589,7 @@ bool Bot::canDuckUnder (const Vector &normal) {
}
bool Bot::isBlockedLeft () {
TraceResult tr;
TraceResult tr {};
float direction = 48.0f;
if (m_moveSpeed < 0.0f) {
@ -2603,14 +2602,14 @@ bool Bot::isBlockedLeft () {
game.testLine (pev->origin, forward * direction - right * 48.0f, TraceIgnore::Monsters, ent (), &tr);
// check if the trace hit something...
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) {
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) {
return true; // bot's body will hit something
}
return false;
}
bool Bot::isBlockedRight () {
TraceResult tr;
TraceResult tr {};
float direction = 48.0f;
if (m_moveSpeed < 0.0f) {
@ -2623,14 +2622,14 @@ bool Bot::isBlockedRight () {
game.testLine (pev->origin, pev->origin + forward * direction + right * 48.0f, TraceIgnore::Monsters, ent (), &tr);
// check if the trace hit something...
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && (strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0)) {
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) {
return true; // bot's body will hit something
}
return false;
}
bool Bot::checkWallOnLeft () {
TraceResult tr;
TraceResult tr {};
game.testLine (pev->origin, pev->origin - pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
// check if the trace hit something...
@ -2641,7 +2640,7 @@ bool Bot::checkWallOnLeft () {
}
bool Bot::checkWallOnRight () {
TraceResult tr;
TraceResult tr {};
// do a trace to the right...
game.testLine (pev->origin, pev->origin + pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
@ -2656,7 +2655,7 @@ bool Bot::checkWallOnRight () {
bool Bot::isDeadlyMove (const Vector &to) {
// this function eturns if given location would hurt Bot with falling damage
TraceResult tr;
TraceResult tr {};
const auto &direction = (to - pev->origin).normalize (); // 1 unit long
Vector check = to, down = to;
@ -2984,7 +2983,7 @@ int Bot::getNearestToPlantedBomb () {
// search the bomb on the map
game.searchEntities ("classname", "grenade", [&result] (edict_t *ent) {
if (strcmp (ent->v.model.chars () + 9, "c4.mdl") == 0) {
if (strcmp (ent->v.model.chars (9), "c4.mdl") == 0) {
result = graph.getNearest (game.getEntityWorldOrigin (ent));
if (graph.exists (result)) {
@ -3077,7 +3076,7 @@ bool Bot::isReachableNode (int index) {
}
float ladderDist = (dst - src).length2d ();
TraceResult tr;
TraceResult tr {};
game.testLine (src, dst, TraceIgnore::Monsters, ent (), &tr);
// if node is visible from current position (even behind head)...

View file

@ -1,9 +1,9 @@
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
//
// This software is licensed under the MIT license.
// Additional exceptions apply. For full license details, see LICENSE.txt
//
#include <yapb.h>
@ -115,7 +115,7 @@ bool BotUtils::isVisible (const Vector &origin, edict_t *ent) {
if (game.isNullEntity (ent)) {
return false;
}
TraceResult tr;
TraceResult tr {};
game.testLine (ent->v.origin + ent->v.view_ofs, origin, TraceIgnore::Everything, ent, &tr);
if (tr.flFraction != 1.0f) {