@amxts/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/README.ru.md +162 -0
- package/amxmodx/base/include/amxconst.inc +594 -0
- package/amxmodx/base/include/amxmisc.inc +902 -0
- package/amxmodx/base/include/amxmodx.inc +3447 -0
- package/amxmodx/base/include/amxmodx_version.inc +20 -0
- package/amxmodx/base/include/cellarray.inc +525 -0
- package/amxmodx/base/include/cellstack.inc +166 -0
- package/amxmodx/base/include/celltrie.inc +412 -0
- package/amxmodx/base/include/core.inc +202 -0
- package/amxmodx/base/include/csstats.inc +298 -0
- package/amxmodx/base/include/csstats_const.inc +29 -0
- package/amxmodx/base/include/cstrike.inc +1287 -0
- package/amxmodx/base/include/cstrike_const.inc +521 -0
- package/amxmodx/base/include/csx.inc +259 -0
- package/amxmodx/base/include/cvars.inc +547 -0
- package/amxmodx/base/include/datapack.inc +161 -0
- package/amxmodx/base/include/dbi.inc +154 -0
- package/amxmodx/base/include/dodconst.inc +152 -0
- package/amxmodx/base/include/dodfun.inc +152 -0
- package/amxmodx/base/include/dodstats.inc +69 -0
- package/amxmodx/base/include/dodx.inc +161 -0
- package/amxmodx/base/include/engine.inc +1343 -0
- package/amxmodx/base/include/engine_const.inc +310 -0
- package/amxmodx/base/include/engine_stocks.inc +248 -0
- package/amxmodx/base/include/esf.inc +70 -0
- package/amxmodx/base/include/esf_const.inc +74 -0
- package/amxmodx/base/include/fakemeta.inc +1127 -0
- package/amxmodx/base/include/fakemeta_const.inc +793 -0
- package/amxmodx/base/include/fakemeta_stocks.inc +395 -0
- package/amxmodx/base/include/fakemeta_util.inc +882 -0
- package/amxmodx/base/include/file.inc +666 -0
- package/amxmodx/base/include/float.inc +422 -0
- package/amxmodx/base/include/fun.inc +333 -0
- package/amxmodx/base/include/gameconfig.inc +93 -0
- package/amxmodx/base/include/geoip.inc +264 -0
- package/amxmodx/base/include/ham_const.inc +4352 -0
- package/amxmodx/base/include/hamsandwich.inc +439 -0
- package/amxmodx/base/include/hlsdk_const.inc +808 -0
- package/amxmodx/base/include/json.inc +777 -0
- package/amxmodx/base/include/lang.inc +119 -0
- package/amxmodx/base/include/message_const.inc +1130 -0
- package/amxmodx/base/include/message_stocks.inc +161 -0
- package/amxmodx/base/include/messages.inc +604 -0
- package/amxmodx/base/include/newmenus.inc +387 -0
- package/amxmodx/base/include/ns.inc +754 -0
- package/amxmodx/base/include/ns_const.inc +196 -0
- package/amxmodx/base/include/nvault.inc +154 -0
- package/amxmodx/base/include/regex.inc +348 -0
- package/amxmodx/base/include/sockets.inc +183 -0
- package/amxmodx/base/include/sorting.inc +107 -0
- package/amxmodx/base/include/sqlx.inc +582 -0
- package/amxmodx/base/include/string.inc +786 -0
- package/amxmodx/base/include/string_const.inc +156 -0
- package/amxmodx/base/include/string_stocks.inc +325 -0
- package/amxmodx/base/include/textparse_ini.inc +214 -0
- package/amxmodx/base/include/textparse_smc.inc +261 -0
- package/amxmodx/base/include/tfcconst.inc +84 -0
- package/amxmodx/base/include/tfcstats.inc +62 -0
- package/amxmodx/base/include/tfcx.inc +148 -0
- package/amxmodx/base/include/time.inc +118 -0
- package/amxmodx/base/include/tsconst.inc +154 -0
- package/amxmodx/base/include/tsfun.inc +198 -0
- package/amxmodx/base/include/tsstats.inc +65 -0
- package/amxmodx/base/include/tsx.inc +88 -0
- package/amxmodx/base/include/vault.inc +60 -0
- package/amxmodx/base/include/vector.inc +131 -0
- package/amxmodx/base/include/xs.inc +1570 -0
- package/as/amxts.d.ts +153 -0
- package/as/constants.ts +4730 -0
- package/as/effects.ts +1449 -0
- package/as/entities.ts +5482 -0
- package/as/events.ts +3054 -0
- package/as/facade.ts +4639 -0
- package/as/flags.ts +299 -0
- package/as/fs.ts +287 -0
- package/as/hooks.ts +18536 -0
- package/as/kit.ts +25 -0
- package/as/lib/check.ts +86 -0
- package/as/modules/http.ts +184 -0
- package/as/natives.ts +11845 -0
- package/as/os.ts +30 -0
- package/as/promise.ts +1392 -0
- package/as/promise.types.d.ts +82 -0
- package/as/remote.ts +288 -0
- package/as/tsconfig.json +22 -0
- package/as/vector.ts +65 -0
- package/bin/amxts.mjs +10 -0
- package/includes/menu_core.inc +355 -0
- package/includes/order.txt +54 -0
- package/includes/sources.json +27 -0
- package/includes/universal_config.inc +355 -0
- package/lint/oxlint-plugin.mjs +77 -0
- package/node_modules/assemblyscript/LICENSE +201 -0
- package/node_modules/assemblyscript/NOTICE +93 -0
- package/node_modules/assemblyscript/package.json +63 -0
- package/node_modules/assemblyscript/std/README.md +6 -0
- package/node_modules/assemblyscript/std/assembly/array.ts +526 -0
- package/node_modules/assemblyscript/std/assembly/arraybuffer.ts +77 -0
- package/node_modules/assemblyscript/std/assembly/atomics.ts +127 -0
- package/node_modules/assemblyscript/std/assembly/bindings/asyncify.ts +16 -0
- package/node_modules/assemblyscript/std/assembly/bindings/dom.ts +291 -0
- package/node_modules/assemblyscript/std/assembly/bindings/node.ts +6 -0
- package/node_modules/assemblyscript/std/assembly/builtins.ts +2631 -0
- package/node_modules/assemblyscript/std/assembly/compat.ts +2 -0
- package/node_modules/assemblyscript/std/assembly/console.ts +42 -0
- package/node_modules/assemblyscript/std/assembly/crypto.ts +9 -0
- package/node_modules/assemblyscript/std/assembly/dataview.ts +181 -0
- package/node_modules/assemblyscript/std/assembly/date.ts +373 -0
- package/node_modules/assemblyscript/std/assembly/diagnostics.ts +11 -0
- package/node_modules/assemblyscript/std/assembly/error.ts +44 -0
- package/node_modules/assemblyscript/std/assembly/function.ts +38 -0
- package/node_modules/assemblyscript/std/assembly/index.d.ts +2822 -0
- package/node_modules/assemblyscript/std/assembly/iterator.ts +35 -0
- package/node_modules/assemblyscript/std/assembly/map.ts +260 -0
- package/node_modules/assemblyscript/std/assembly/math.ts +3289 -0
- package/node_modules/assemblyscript/std/assembly/memory.ts +123 -0
- package/node_modules/assemblyscript/std/assembly/number.ts +388 -0
- package/node_modules/assemblyscript/std/assembly/object.ts +36 -0
- package/node_modules/assemblyscript/std/assembly/performance.ts +9 -0
- package/node_modules/assemblyscript/std/assembly/polyfills.ts +27 -0
- package/node_modules/assemblyscript/std/assembly/process.ts +50 -0
- package/node_modules/assemblyscript/std/assembly/reference.ts +48 -0
- package/node_modules/assemblyscript/std/assembly/regexp.ts +12 -0
- package/node_modules/assemblyscript/std/assembly/rt/README.md +83 -0
- package/node_modules/assemblyscript/std/assembly/rt/common.ts +81 -0
- package/node_modules/assemblyscript/std/assembly/rt/index-incremental.ts +2 -0
- package/node_modules/assemblyscript/std/assembly/rt/index-minimal.ts +2 -0
- package/node_modules/assemblyscript/std/assembly/rt/index-stub.ts +1 -0
- package/node_modules/assemblyscript/std/assembly/rt/index.d.ts +37 -0
- package/node_modules/assemblyscript/std/assembly/rt/itcms.ts +419 -0
- package/node_modules/assemblyscript/std/assembly/rt/rtrace.ts +15 -0
- package/node_modules/assemblyscript/std/assembly/rt/stub.ts +133 -0
- package/node_modules/assemblyscript/std/assembly/rt/tcms.ts +254 -0
- package/node_modules/assemblyscript/std/assembly/rt/tlsf.ts +592 -0
- package/node_modules/assemblyscript/std/assembly/rt.ts +87 -0
- package/node_modules/assemblyscript/std/assembly/set.ts +220 -0
- package/node_modules/assemblyscript/std/assembly/shared/feature.ts +65 -0
- package/node_modules/assemblyscript/std/assembly/shared/runtime.ts +11 -0
- package/node_modules/assemblyscript/std/assembly/shared/target.ts +11 -0
- package/node_modules/assemblyscript/std/assembly/shared/tsconfig.json +11 -0
- package/node_modules/assemblyscript/std/assembly/shared/typeinfo.ts +72 -0
- package/node_modules/assemblyscript/std/assembly/staticarray.ts +401 -0
- package/node_modules/assemblyscript/std/assembly/string.ts +847 -0
- package/node_modules/assemblyscript/std/assembly/symbol.ts +114 -0
- package/node_modules/assemblyscript/std/assembly/table.ts +16 -0
- package/node_modules/assemblyscript/std/assembly/tsconfig.json +6 -0
- package/node_modules/assemblyscript/std/assembly/typedarray.ts +1945 -0
- package/node_modules/assemblyscript/std/assembly/uri.ts +17 -0
- package/node_modules/assemblyscript/std/assembly/util/bytes.ts +107 -0
- package/node_modules/assemblyscript/std/assembly/util/casemap.ts +497 -0
- package/node_modules/assemblyscript/std/assembly/util/error.ts +54 -0
- package/node_modules/assemblyscript/std/assembly/util/hash.ts +117 -0
- package/node_modules/assemblyscript/std/assembly/util/math.ts +1922 -0
- package/node_modules/assemblyscript/std/assembly/util/memory.ts +290 -0
- package/node_modules/assemblyscript/std/assembly/util/number.ts +873 -0
- package/node_modules/assemblyscript/std/assembly/util/sort.ts +313 -0
- package/node_modules/assemblyscript/std/assembly/util/string.ts +1202 -0
- package/node_modules/assemblyscript/std/assembly/util/uri.ts +275 -0
- package/node_modules/assemblyscript/std/assembly/vector.ts +4 -0
- package/node_modules/assemblyscript/std/assembly.json +16 -0
- package/node_modules/assemblyscript/std/portable/index.d.ts +462 -0
- package/node_modules/assemblyscript/std/portable/index.js +416 -0
- package/node_modules/assemblyscript/std/portable.json +11 -0
- package/node_modules/assemblyscript/std/types/assembly/index.d.ts +1 -0
- package/node_modules/assemblyscript/std/types/assembly/package.json +3 -0
- package/node_modules/assemblyscript/std/types/portable/index.d.ts +1 -0
- package/node_modules/assemblyscript/std/types/portable/package.json +3 -0
- package/node_modules/assemblyscript/tsconfig-base.json +13 -0
- package/package.json +112 -0
- package/runtime/deps/assemblyscript/LICENSE +201 -0
- package/runtime/deps/assemblyscript/NOTICE +93 -0
- package/runtime/deps/assemblyscript/bin/asc.js +35 -0
- package/runtime/deps/assemblyscript/dist/asc.js +25035 -0
- package/runtime/deps/assemblyscript/dist/assemblyscript.js +337 -0
- package/runtime/deps/assemblyscript/node_modules/binaryen/LICENSE +201 -0
- package/runtime/deps/assemblyscript/node_modules/binaryen/index.js +28905 -0
- package/runtime/deps/assemblyscript/node_modules/binaryen/package.json +50 -0
- package/runtime/deps/assemblyscript/node_modules/long/LICENSE +202 -0
- package/runtime/deps/assemblyscript/node_modules/long/index.js +1581 -0
- package/runtime/deps/assemblyscript/node_modules/long/package.json +58 -0
- package/runtime/deps/assemblyscript/package.json +114 -0
- package/runtime/host/amxts.inc +85 -0
- package/runtime/licenses/AMXX-LICENSE.txt +34 -0
- package/runtime/licenses/AssemblyScript-LICENSE +201 -0
- package/runtime/licenses/AssemblyScript-NOTICE +93 -0
- package/runtime/licenses/Binaryen-LICENSE +201 -0
- package/runtime/licenses/Bun-LICENSE.md +84 -0
- package/runtime/licenses/GPL-3.0.txt +674 -0
- package/runtime/licenses/LLVM-LICENSE.TXT +279 -0
- package/runtime/licenses/README.md +25 -0
- package/runtime/licenses/WAMR-LICENSE +219 -0
- package/runtime/natives.txt +1095 -0
- package/runtime/patches/README.md +59 -0
- package/runtime/patches/assemblyscript-0.28.20-amxts.patch +14174 -0
- package/runtime/patches/wamr-2.4.5-amxts.patch +364 -0
- package/scripts/apply-docs.ts +508 -0
- package/scripts/asc.ts +27 -0
- package/scripts/auto-imports.ts +258 -0
- package/scripts/build-wasm.ts +595 -0
- package/scripts/check.ts +93 -0
- package/scripts/compile-cache.ts +179 -0
- package/scripts/compile.ts +401 -0
- package/scripts/docker-server.ts +73 -0
- package/scripts/docs/as/amxts.ts +210 -0
- package/scripts/docs/as/effects.ts +1684 -0
- package/scripts/docs/as/facade.ts +3302 -0
- package/scripts/docs/as/fs.ts +173 -0
- package/scripts/docs/as/lib/check.ts +68 -0
- package/scripts/docs/as/modules/http.ts +66 -0
- package/scripts/docs/as/os.ts +16 -0
- package/scripts/docs/as/promise.ts +132 -0
- package/scripts/docs/as/promise.types.ts +63 -0
- package/scripts/docs/as/vector.ts +48 -0
- package/scripts/docs/entities.ts +2338 -0
- package/scripts/docs/events.ts +245 -0
- package/scripts/docs/game.ts +497 -0
- package/scripts/docs/messages.ts +148 -0
- package/scripts/file-contents.ts +74 -0
- package/scripts/includes.ts +134 -0
- package/scripts/player-fields.ts +866 -0
- package/scripts/plugin-cache.ts +92 -0
- package/scripts/plugin-natives.ts +1157 -0
- package/scripts/prebuilt.ts +268 -0
- package/scripts/prepare.ts +134 -0
- package/scripts/project.ts +973 -0
- package/scripts/run.ts +28 -0
- package/scripts/shared-modules.ts +906 -0
- package/scripts/system.ts +33 -0
- package/scripts/tracked-fs.ts +115 -0
- package/scripts/typed-configs.ts +788 -0
- package/scripts/ui.ts +77 -0
- package/src/cli-api.mjs +175 -0
- package/src/parser/include-parser.ts +506 -0
- package/src/system.mjs +155 -0
- package/src/testing/compile-cache.ts +31 -0
- package/src/testing/compile.ts +222 -0
- package/src/testing/coroutines.ts +191 -0
- package/src/testing/index.ts +39 -0
- package/src/testing/kits.ts +55 -0
- package/src/testing/memory.ts +125 -0
- package/src/testing/natives.ts +925 -0
- package/src/testing/server.ts +1874 -0
- package/src/testing/setup.ts +63 -0
- package/src/testing/tables.ts +139 -0
- package/src/types.ts +51 -0
|
@@ -0,0 +1,1570 @@
|
|
|
1
|
+
// vim: set ts=4 sw=4 tw=99 noet:
|
|
2
|
+
//
|
|
3
|
+
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
|
|
4
|
+
// Copyright (C) The AMX Mod X Development Team.
|
|
5
|
+
// Copyright (C) 2004 Pavol "PM" Marko
|
|
6
|
+
//
|
|
7
|
+
// This software is licensed under the GNU General Public License, version 3 or higher.
|
|
8
|
+
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
|
|
9
|
+
// https://alliedmods.net/amxmodx-license
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* XS Library
|
|
13
|
+
* Version 0.1
|
|
14
|
+
*
|
|
15
|
+
* MACROS THAT YOU CAN DEFINE BEFORE INCLUDING XS.INC:
|
|
16
|
+
* XS_FLEQ_TOLERANCE:
|
|
17
|
+
* Tolerance that is used for XS_FLEQ float nearly-equal comparisions
|
|
18
|
+
* DEFAULT: 0.000005
|
|
19
|
+
* XS_DEBUG
|
|
20
|
+
* Turn debug logging on
|
|
21
|
+
* DEFAULT: 0
|
|
22
|
+
* XS_LOGBUFFER_SIZE
|
|
23
|
+
* Buffer size for logging
|
|
24
|
+
* DEFAULT: 512
|
|
25
|
+
* XS_TASK_MAXPARAMS
|
|
26
|
+
* Maximal parameter count for managed tasks
|
|
27
|
+
* DEFAULT: 8
|
|
28
|
+
* XS_TASK_MAXPARAMSIZE
|
|
29
|
+
* Maximal size of string parameter for tasks
|
|
30
|
+
* Has to be power of 2 and has to be >= 8
|
|
31
|
+
* DEFAULT: 512
|
|
32
|
+
* XS_TASK_MANAGEDIDS
|
|
33
|
+
* Number of managed IDs for tasks.
|
|
34
|
+
* DEFAULT: 2048
|
|
35
|
+
* XS_REPLACEBUF_SIZE
|
|
36
|
+
* DEFAULT: 3072
|
|
37
|
+
*
|
|
38
|
+
* NOTES:
|
|
39
|
+
* On AMX, VexdUM is required for some math functions
|
|
40
|
+
* xs__ / XS__ (2 underscores) stuff is meant to be intern
|
|
41
|
+
* untested: never tested
|
|
42
|
+
* half-tested: succesfully used in other applications; not extensively tested in xs though
|
|
43
|
+
* tested: fully tested
|
|
44
|
+
* If you have any useful functions / ideas for functions, please tell me.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
#if defined _xs_included
|
|
48
|
+
#endinput
|
|
49
|
+
#endif
|
|
50
|
+
#define _xs_included
|
|
51
|
+
|
|
52
|
+
// **** CONFIG CHECK
|
|
53
|
+
|
|
54
|
+
#if !defined XS_FLEQ_TOLERANCE
|
|
55
|
+
#define XS_FLEQ_TOLERANCE 0.000005
|
|
56
|
+
#endif
|
|
57
|
+
|
|
58
|
+
#if !defined XS_DEBUG
|
|
59
|
+
#define XS_DEBUG 0
|
|
60
|
+
#endif
|
|
61
|
+
|
|
62
|
+
#if !defined XS_LOGBUFFER_SIZE
|
|
63
|
+
#define XS_LOGBUFFER_SIZE 512
|
|
64
|
+
#endif
|
|
65
|
+
|
|
66
|
+
#if !defined XS_TASK_MAXPARAMS
|
|
67
|
+
#define XS_TASK_MAXPARAMS 8
|
|
68
|
+
#endif
|
|
69
|
+
|
|
70
|
+
#if !defined XS_TASK_MAXPARAMSIZE
|
|
71
|
+
#define XS_TASK_MAXPARAMSIZE 512
|
|
72
|
+
#endif
|
|
73
|
+
|
|
74
|
+
#if !defined XS_TASK_MANAGEDIDS
|
|
75
|
+
#define XS_TASK_MANAGEDIDS 2048
|
|
76
|
+
#endif
|
|
77
|
+
|
|
78
|
+
#if !defined XS_REPLACEBUF_SIZE
|
|
79
|
+
#define XS_REPLACEBUF_SIZE 3072
|
|
80
|
+
#endif
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
/****** DEBUGGING / LOGING FUNCTIONS ******/
|
|
84
|
+
enum xs_logtypes
|
|
85
|
+
{
|
|
86
|
+
xs_debug,
|
|
87
|
+
xs_message,
|
|
88
|
+
xs_warning,
|
|
89
|
+
xs_error,
|
|
90
|
+
xs_fatalerror,
|
|
91
|
+
xs__assertionfailed,
|
|
92
|
+
|
|
93
|
+
// must come last
|
|
94
|
+
xs_logtypes_count
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
stock const xs__logtypenames[xs_logtypes_count][] = {"DEBUG", "", "WARNING", "ERROR", "FATAL ERROR", "DEBUG ASSERTION FAILED"};
|
|
98
|
+
|
|
99
|
+
// tested
|
|
100
|
+
stock xs_log(xs_logtypes:logtype, any:...)
|
|
101
|
+
{
|
|
102
|
+
// WARNING: Don't try to use assert in here; it uses this func
|
|
103
|
+
|
|
104
|
+
// Don't log debug if not in debug mode
|
|
105
|
+
#if !XS_DEBUG
|
|
106
|
+
if (logtype == xs_debug)
|
|
107
|
+
return;
|
|
108
|
+
#endif
|
|
109
|
+
|
|
110
|
+
new buffer[XS_LOGBUFFER_SIZE+1];
|
|
111
|
+
buffer[XS_LOGBUFFER_SIZE]=0;
|
|
112
|
+
format_args(buffer, XS_LOGBUFFER_SIZE, 1 /* go from SECOND argument*/);
|
|
113
|
+
new bool:addLogTypeName = strlen(xs__logtypenames[logtype]) ? true : false;
|
|
114
|
+
|
|
115
|
+
// Use AMXX's logging system
|
|
116
|
+
log_amx("%s%s%s", addLogTypeName ? xs__logtypenames[logtype] : "",
|
|
117
|
+
addLogTypeName ? ": " : "", buffer);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Assertion
|
|
121
|
+
// tested
|
|
122
|
+
stock xs_assertfunc(any:exp, const desc[])
|
|
123
|
+
{
|
|
124
|
+
// Check exp
|
|
125
|
+
if (exp)
|
|
126
|
+
return 1; // ok
|
|
127
|
+
|
|
128
|
+
// not ok
|
|
129
|
+
|
|
130
|
+
// print info
|
|
131
|
+
xs_log(xs__assertionfailed, "%s", desc);
|
|
132
|
+
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
#define xs_assert(%1,%2) if (!xs_assertfunc(%1,%2)) xs__global_null /= xs__global_null
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
// Assertion; only in debug mode
|
|
139
|
+
// untested; logical flow says it should work
|
|
140
|
+
#if XS_DEBUG
|
|
141
|
+
#define xs_assert_dbg(%1,%2) if (!xs_assertfunc(%1,%2)) xs__global_null /= xs__global_null
|
|
142
|
+
#else
|
|
143
|
+
#define xs_assert_dbg(%1,%2)
|
|
144
|
+
#endif
|
|
145
|
+
|
|
146
|
+
new xs__global_null = 0;
|
|
147
|
+
|
|
148
|
+
/****** MATH FUNCTIONS ******/
|
|
149
|
+
|
|
150
|
+
/****** BASIC STUFF ******/
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Gets the sign of a value.
|
|
154
|
+
*
|
|
155
|
+
* @param num Number to get the sign from.
|
|
156
|
+
*
|
|
157
|
+
* @return -1 if the number is negative,
|
|
158
|
+
* 0 if the number is equal to 0,
|
|
159
|
+
* 1 if the number is positive.
|
|
160
|
+
*/
|
|
161
|
+
stock xs_sign(num)
|
|
162
|
+
{
|
|
163
|
+
return (num < 0) ? -1 : ((num == 0) ? 0 : 1);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Gets the sign of a float value.
|
|
168
|
+
*
|
|
169
|
+
* @param num Number to get the sign from.
|
|
170
|
+
*
|
|
171
|
+
* @return -1 if the number is negative,
|
|
172
|
+
* 0 if the number is equal to 0,
|
|
173
|
+
* 1 if the number is positive.
|
|
174
|
+
*/
|
|
175
|
+
stock xs_fsign(Float:num)
|
|
176
|
+
{
|
|
177
|
+
return (num < 0.0) ? -1 : ((num == 0.0) ? 0 : 1);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Gets the absolute value of a number.
|
|
182
|
+
*
|
|
183
|
+
* @param num Number to get the absolute value from.
|
|
184
|
+
*
|
|
185
|
+
* @return Absolute value of the input number.
|
|
186
|
+
*/
|
|
187
|
+
stock xs_abs(num)
|
|
188
|
+
{
|
|
189
|
+
return (num < 0) ? -num : num;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Checks if the number is a power of 2.
|
|
194
|
+
*
|
|
195
|
+
* @param x Number to check.
|
|
196
|
+
*
|
|
197
|
+
* @return 1 if it is a power of 2, 0 otherwise.
|
|
198
|
+
*/
|
|
199
|
+
stock xs_is_2power(x)
|
|
200
|
+
{
|
|
201
|
+
return (x!=0) && ((x&(x-1))==0);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Converts degrees to radians.
|
|
206
|
+
*
|
|
207
|
+
* @param x Input degrees.
|
|
208
|
+
*
|
|
209
|
+
* @return Degrees converted to radians.
|
|
210
|
+
*/
|
|
211
|
+
stock Float:xs_deg2rad(Float:x)
|
|
212
|
+
{
|
|
213
|
+
return x * 0.017453292519943;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Converts radians to degrees.
|
|
218
|
+
*
|
|
219
|
+
* @param x Input radians.
|
|
220
|
+
*
|
|
221
|
+
* @return Radians converted to degrees.
|
|
222
|
+
*/
|
|
223
|
+
stock Float:xs_rad2deg(Float:x)
|
|
224
|
+
{
|
|
225
|
+
return x * 57.29577951308232;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Converts gradians to radians.
|
|
230
|
+
*
|
|
231
|
+
* @param x Input gradians.
|
|
232
|
+
*
|
|
233
|
+
* @return Gradians converted to radians.
|
|
234
|
+
*/
|
|
235
|
+
stock Float:xs_gra2rad(Float:x)
|
|
236
|
+
{
|
|
237
|
+
return x * 0.015707963267948;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Converts radians to gradians.
|
|
242
|
+
*
|
|
243
|
+
* @param x Input radians.
|
|
244
|
+
*
|
|
245
|
+
* @return Radians converted to gradians.
|
|
246
|
+
*/
|
|
247
|
+
stock Float:xs_rad2gra(Float:x)
|
|
248
|
+
{
|
|
249
|
+
return x * 63.66197723675813;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Checks if two floating point values are nearly equal.
|
|
254
|
+
*
|
|
255
|
+
* @param %1 The first value to compare.
|
|
256
|
+
* @param %2 The second value to compare.
|
|
257
|
+
*
|
|
258
|
+
* @return 1 if they are nearly equal, 0 otherwise.
|
|
259
|
+
*/
|
|
260
|
+
#define XS_FLEQ(%1,%2) (((%1) <= ((%2) + XS_FLEQ_TOLERANCE)) && ((%1) >= ((%2) - XS_FLEQ_TOLERANCE)))
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Calculates the reciprocal of the square root of the input value.
|
|
264
|
+
*
|
|
265
|
+
* @param x The input value.
|
|
266
|
+
*
|
|
267
|
+
* @return The reciprocal of the square root of the input value.
|
|
268
|
+
*/
|
|
269
|
+
stock Float:xs_rsqrt(Float:x)
|
|
270
|
+
{
|
|
271
|
+
return 1.0 / floatsqroot(x);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Calculates the square root of the input value.
|
|
276
|
+
*
|
|
277
|
+
* @note This is an alias for floatsqroot().
|
|
278
|
+
*
|
|
279
|
+
* @param x The input value.
|
|
280
|
+
*
|
|
281
|
+
* @return The square root of the input value.
|
|
282
|
+
*/
|
|
283
|
+
stock Float:xs_sqrt(Float:x)
|
|
284
|
+
{
|
|
285
|
+
return floatsqroot(x);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// These functions generate errors if you use the macros with wrong parameter count.
|
|
289
|
+
stock Float:xs_fabs(Float:pa)
|
|
290
|
+
{
|
|
291
|
+
#pragma unused pa
|
|
292
|
+
new rawr = you_need_one_param_for_fabs;
|
|
293
|
+
rawr = warning_below_shows_line_number;
|
|
294
|
+
#pragma unused rawr
|
|
295
|
+
}
|
|
296
|
+
stock Float:xs_asin(Float:pa,Float:pb)
|
|
297
|
+
{
|
|
298
|
+
#pragma unused pa,pb
|
|
299
|
+
new rawr = you_need_two_params_for_asin;
|
|
300
|
+
rawr = warning_below_shows_line_number;
|
|
301
|
+
#pragma unused rawr
|
|
302
|
+
}
|
|
303
|
+
stock Float:xs_sin(Float:pa,Float:pb)
|
|
304
|
+
{
|
|
305
|
+
#pragma unused pa,pb
|
|
306
|
+
new rawr = you_need_two_params_for_sin;
|
|
307
|
+
#pragma unused rawr
|
|
308
|
+
}
|
|
309
|
+
stock Float:xs_acos(Float:pa,Float:pb)
|
|
310
|
+
{
|
|
311
|
+
#pragma unused pa,pb
|
|
312
|
+
new rawr = you_need_two_params_for_acos;
|
|
313
|
+
rawr = warning_below_shows_line_number;
|
|
314
|
+
#pragma unused rawr
|
|
315
|
+
}
|
|
316
|
+
stock Float:xs_cos(Float:pa,Float:pb)
|
|
317
|
+
{
|
|
318
|
+
#pragma unused pa,pb
|
|
319
|
+
new rawr = you_need_two_params_for_cos;
|
|
320
|
+
rawr = warning_below_shows_line_number;
|
|
321
|
+
#pragma unused rawr
|
|
322
|
+
}
|
|
323
|
+
stock Float:xs_atan(Float:pa,Float:pb)
|
|
324
|
+
{
|
|
325
|
+
#pragma unused pa,pb
|
|
326
|
+
new rawr = you_need_two_params_for_atan;
|
|
327
|
+
rawr = warning_below_shows_line_number;
|
|
328
|
+
#pragma unused rawr
|
|
329
|
+
}
|
|
330
|
+
stock Float:xs_atan2(Float:pa,Float:pb)
|
|
331
|
+
{
|
|
332
|
+
#pragma unused pa,pb
|
|
333
|
+
new rawr = you_need_two_params_for_atan2;
|
|
334
|
+
rawr = warning_below_shows_line_number;
|
|
335
|
+
#pragma unused rawr
|
|
336
|
+
}
|
|
337
|
+
stock Float:xs_tan(Float:pa, Float:pb)
|
|
338
|
+
{
|
|
339
|
+
#pragma unused pa,pb
|
|
340
|
+
new rawr = you_need_two_params_for_tan;
|
|
341
|
+
rawr = warning_below_shows_line_number;
|
|
342
|
+
#pragma unused rawr
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
#define xs_fabs(%1) floatabs(%1)
|
|
346
|
+
#define xs_asin(%1,%2) floatasin(%1, %2)
|
|
347
|
+
#define xs_sin(%1,%2) floatsin(%1, %2)
|
|
348
|
+
#define xs_acos(%1,%2) floatacos(%1, %2)
|
|
349
|
+
#define xs_cos(%1,%2) floatcos(%1, %2)
|
|
350
|
+
#define xs_atan(%1,%2) floatatan(%1, %2)
|
|
351
|
+
#define xs_atan2(%1,%2) floatatan2(%1, %2)
|
|
352
|
+
#define xs_tan(%1,%2) floattan(%1, %2)
|
|
353
|
+
|
|
354
|
+
/****** RANDOM NUMBERS ******/
|
|
355
|
+
// This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
|
|
356
|
+
// (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
|
|
357
|
+
// generator" that has been extended to 31-bits
|
|
358
|
+
|
|
359
|
+
stock xs__internalseed=0x546875;
|
|
360
|
+
|
|
361
|
+
#define XS__IL_RMULT 1103515245
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Sets the seed for the random number generation.
|
|
365
|
+
*
|
|
366
|
+
* @param x The seed to set.
|
|
367
|
+
*
|
|
368
|
+
* @noreturn
|
|
369
|
+
*/
|
|
370
|
+
stock xs_seed(seed)
|
|
371
|
+
{
|
|
372
|
+
xs__internalseed = seed;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Retrieves a random integer.
|
|
377
|
+
*
|
|
378
|
+
* @return A random integer.
|
|
379
|
+
*/
|
|
380
|
+
stock xs_irand()
|
|
381
|
+
{
|
|
382
|
+
new lo, hi, ll, lh, hh, hl;
|
|
383
|
+
new result;
|
|
384
|
+
|
|
385
|
+
lo = xs__internalseed & 0xffff;
|
|
386
|
+
hi = xs__internalseed >> 16;
|
|
387
|
+
xs__internalseed = xs__internalseed * XS__IL_RMULT + 12345;
|
|
388
|
+
ll = lo * (XS__IL_RMULT & 0xffff);
|
|
389
|
+
lh = lo * (XS__IL_RMULT >> 16 );
|
|
390
|
+
hl = hi * (XS__IL_RMULT & 0xffff);
|
|
391
|
+
hh = hi * (XS__IL_RMULT >> 16 );
|
|
392
|
+
result = xs_abs(((ll + 12345) >> 16) + lh + hl + (hh << 16));
|
|
393
|
+
return result;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Retrieves a random float.
|
|
398
|
+
*
|
|
399
|
+
* @return A random float.
|
|
400
|
+
*/
|
|
401
|
+
stock Float:xs_frand()
|
|
402
|
+
{
|
|
403
|
+
return float(xs_irand()) / float(xs_get_maxnum()); // -1/2 should be the biggest possible positive number
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Retrieves a random integer between the specified values.
|
|
408
|
+
*
|
|
409
|
+
* @note @pmax has to be greater than @pmin!
|
|
410
|
+
*
|
|
411
|
+
* @param pmin The minimum value.
|
|
412
|
+
* @param pmax The maximum value.
|
|
413
|
+
*
|
|
414
|
+
* @return A random integer.
|
|
415
|
+
*/
|
|
416
|
+
stock xs_irand_range(pmin, pmax)
|
|
417
|
+
{
|
|
418
|
+
xs_assert_dbg(pmax - pmin >= 0, "xs_irand_range: pmin > pmax");
|
|
419
|
+
new i = pmin + floatround(xs_frand() * float(pmax - pmin));
|
|
420
|
+
if (i > pmax)
|
|
421
|
+
i = pmax;
|
|
422
|
+
return i;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/****** VECTORS & PLANES ******/
|
|
426
|
+
|
|
427
|
+
// *** vectors
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Sets vector's components to specified values.
|
|
431
|
+
*
|
|
432
|
+
* @param vec The vector to set values to.
|
|
433
|
+
* @param x The X component to be set.
|
|
434
|
+
* @param y The Y component to be set.
|
|
435
|
+
* @param z The Z component to be set.
|
|
436
|
+
*
|
|
437
|
+
* @noreturn
|
|
438
|
+
*/
|
|
439
|
+
stock xs_vec_set(Float:vec[], Float:x, Float:y, Float:z)
|
|
440
|
+
{
|
|
441
|
+
vec[0] = x;
|
|
442
|
+
vec[1] = y;
|
|
443
|
+
vec[2] = z;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Adds two vectors.
|
|
448
|
+
*
|
|
449
|
+
* @param in1 The first vector to add.
|
|
450
|
+
* @param in2 The second vector to add.
|
|
451
|
+
* @param out The output vector. Can be one of the input vectors.
|
|
452
|
+
*
|
|
453
|
+
* @noreturn
|
|
454
|
+
*/
|
|
455
|
+
stock xs_vec_add(const Float:in1[], const Float:in2[], Float:out[])
|
|
456
|
+
{
|
|
457
|
+
out[0] = in1[0] + in2[0];
|
|
458
|
+
out[1] = in1[1] + in2[1];
|
|
459
|
+
out[2] = in1[2] + in2[2];
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Subtracts one vector from another one.
|
|
464
|
+
*
|
|
465
|
+
* @param in1 Vector to subtract from.
|
|
466
|
+
* @param in2 Vector to subtract from the first one.
|
|
467
|
+
* @param out The output vector. Can be one of the input vectors.
|
|
468
|
+
*
|
|
469
|
+
* @noreturn
|
|
470
|
+
*/
|
|
471
|
+
stock xs_vec_sub(const Float:in1[], const Float:in2[], Float:out[])
|
|
472
|
+
{
|
|
473
|
+
out[0] = in1[0] - in2[0];
|
|
474
|
+
out[1] = in1[1] - in2[1];
|
|
475
|
+
out[2] = in1[2] - in2[2];
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Adds the second vector scaled by a scalar to the first.
|
|
480
|
+
*
|
|
481
|
+
* @param in1 Vector to add to.
|
|
482
|
+
* @param in2 Vector to scale and add.
|
|
483
|
+
* @param scalar Scalar to scale the second vector with.
|
|
484
|
+
* @param out The output vector. Can be one of the input vectors.
|
|
485
|
+
*
|
|
486
|
+
* @noreturn
|
|
487
|
+
*/
|
|
488
|
+
stock xs_vec_add_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[])
|
|
489
|
+
{
|
|
490
|
+
out[0] = in1[0] + in2[0] * scalar;
|
|
491
|
+
out[1] = in1[1] + in2[1] * scalar;
|
|
492
|
+
out[2] = in1[2] + in2[2] * scalar;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Subtracts the second vector scaled by a scalar from the first one.
|
|
497
|
+
*
|
|
498
|
+
* @param in1 Vector to subtract from.
|
|
499
|
+
* @param in2 Vector to scale and subtract.
|
|
500
|
+
* @param scalar Scalar to scale the second vector with.
|
|
501
|
+
* @param out The output vector. Can be one of the input vectors.
|
|
502
|
+
*
|
|
503
|
+
* @noreturn
|
|
504
|
+
*/
|
|
505
|
+
stock xs_vec_sub_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[])
|
|
506
|
+
{
|
|
507
|
+
out[0] = in1[0] - in2[0] * scalar;
|
|
508
|
+
out[1] = in1[1] - in2[1] * scalar;
|
|
509
|
+
out[2] = in1[2] - in2[2] * scalar;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Checks if two vectors are equal.
|
|
514
|
+
*
|
|
515
|
+
* @note If you need to check if two vectors are nearly equal,
|
|
516
|
+
* take a look at xs_vec_nearlyequal().
|
|
517
|
+
*
|
|
518
|
+
* @param vec1 The first input vector to check.
|
|
519
|
+
* @param vec2 The second input vector to check.
|
|
520
|
+
*
|
|
521
|
+
* @return 1 if vectors are equal, 0 otherwise.
|
|
522
|
+
*/
|
|
523
|
+
stock bool:xs_vec_equal(const Float:vec1[], const Float:vec2[])
|
|
524
|
+
{
|
|
525
|
+
return (vec1[0] == vec2[0]) && (vec1[1] == vec2[1]) && (vec1[2] == vec2[2]);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Checks if two vectors are nearly equal.
|
|
530
|
+
*
|
|
531
|
+
* @note If you need to check if two vectors are exactly equal,
|
|
532
|
+
* take a look at xs_vec_equal().
|
|
533
|
+
*
|
|
534
|
+
* @param vec1 The first input vector to check.
|
|
535
|
+
* @param vec2 The second input vector to check.
|
|
536
|
+
*
|
|
537
|
+
* @return 1 if vectors are equal, 0 otherwise.
|
|
538
|
+
*/
|
|
539
|
+
stock bool:xs_vec_nearlyequal(const Float:vec1[], const Float:vec2[])
|
|
540
|
+
{
|
|
541
|
+
return XS_FLEQ(vec1[0], vec2[0]) && XS_FLEQ(vec1[1], vec2[1]) && XS_FLEQ(vec1[2], vec2[2]);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Multiply a vector by a scalar value.
|
|
546
|
+
*
|
|
547
|
+
* @param vec The vector to be multiplied.
|
|
548
|
+
* @param scalar The scalar value to multiply the vector with.
|
|
549
|
+
* @param out The output vector. Can be the same as the input vector.
|
|
550
|
+
*
|
|
551
|
+
* @noreturn
|
|
552
|
+
*/
|
|
553
|
+
stock xs_vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[])
|
|
554
|
+
{
|
|
555
|
+
out[0] = vec[0] * scalar;
|
|
556
|
+
out[1] = vec[1] * scalar;
|
|
557
|
+
out[2] = vec[2] * scalar;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Divide a vector by a scalar value.
|
|
562
|
+
*
|
|
563
|
+
* @param vec The vector to be divided.
|
|
564
|
+
* @param scalar The scalar value to divide the vector with.
|
|
565
|
+
* @param out The output vector. Can be the same as the input vector.
|
|
566
|
+
*
|
|
567
|
+
* @noreturn
|
|
568
|
+
*/
|
|
569
|
+
stock xs_vec_div_scalar(const Float:vec[], Float:scalar, Float:out[])
|
|
570
|
+
{
|
|
571
|
+
new Float:__tmp = 1.0 / scalar;
|
|
572
|
+
out[0] = vec[0] * __tmp;
|
|
573
|
+
out[1] = vec[1] * __tmp;
|
|
574
|
+
out[2] = vec[2] * __tmp;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Computes the length of a vector.
|
|
579
|
+
*
|
|
580
|
+
* @param vec The vector to compute the length of.
|
|
581
|
+
*
|
|
582
|
+
* @return The length of the input vector.
|
|
583
|
+
*/
|
|
584
|
+
stock Float:xs_vec_len(const Float:vec[])
|
|
585
|
+
{
|
|
586
|
+
return xs_sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Computes the length of a 2D vector.
|
|
591
|
+
*
|
|
592
|
+
* @param vec The vector to compute the length of.
|
|
593
|
+
*
|
|
594
|
+
* @return The length of the input vector.
|
|
595
|
+
*/
|
|
596
|
+
stock Float:xs_vec_len_2d(const Float:vec[])
|
|
597
|
+
{
|
|
598
|
+
return xs_sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Computes the distance between two vectors (points).
|
|
603
|
+
*
|
|
604
|
+
* @param vec1 First vector.
|
|
605
|
+
* @param vec2 Second vector.
|
|
606
|
+
*
|
|
607
|
+
* @return The distance between two vectors.
|
|
608
|
+
*/
|
|
609
|
+
stock Float:xs_vec_distance(const Float:vec1[], const Float:vec2[])
|
|
610
|
+
{
|
|
611
|
+
return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) +
|
|
612
|
+
(vec1[1]-vec2[1]) * (vec1[1]-vec2[1]) +
|
|
613
|
+
(vec1[2]-vec2[2]) * (vec1[2]-vec2[2]));
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Computes the distance between two 2D vectors (points).
|
|
618
|
+
*
|
|
619
|
+
* @param vec1 First vector.
|
|
620
|
+
* @param vec2 Second vector.
|
|
621
|
+
*
|
|
622
|
+
* @return The distance between two vectors.
|
|
623
|
+
*/
|
|
624
|
+
stock Float:xs_vec_distance_2d(const Float:vec1[], const Float:vec2[])
|
|
625
|
+
{
|
|
626
|
+
return xs_sqrt((vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) +
|
|
627
|
+
(vec1[1]-vec2[1]) * (vec1[1]-vec2[1]));
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Computes the square of the distance between two vectors (points).
|
|
632
|
+
* This is faster than the distance.
|
|
633
|
+
*
|
|
634
|
+
* @param vec1 First vector.
|
|
635
|
+
* @param vec2 Second vector.
|
|
636
|
+
*
|
|
637
|
+
* @return The square of the distance between two vectors.
|
|
638
|
+
*/
|
|
639
|
+
stock Float:xs_vec_sqdistance(const Float:vec1[], const Float:vec2[])
|
|
640
|
+
{
|
|
641
|
+
return (vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) +
|
|
642
|
+
(vec1[1]-vec2[1]) * (vec1[1]-vec2[1]) +
|
|
643
|
+
(vec1[2]-vec2[2]) * (vec1[2]-vec2[2]);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Computes the square of the distance between two 2D vectors (points).
|
|
648
|
+
* This is faster than the distance.
|
|
649
|
+
*
|
|
650
|
+
* @param vec1 First vector.
|
|
651
|
+
* @param vec2 Second vector.
|
|
652
|
+
*
|
|
653
|
+
* @return The square of the distance between two vectors.
|
|
654
|
+
*/
|
|
655
|
+
stock Float:xs_vec_sqdistance_2d(const Float:vec1[], const Float:vec2[])
|
|
656
|
+
{
|
|
657
|
+
return (vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) +
|
|
658
|
+
(vec1[1]-vec2[1]) * (vec1[1]-vec2[1]);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Normalizes a vector. Normalized vector is a vector with the length of 1 unit,
|
|
663
|
+
* but with the same direction as the original vector.
|
|
664
|
+
*
|
|
665
|
+
* @param vec The vector to be normalized.
|
|
666
|
+
* @param out The output vector. Can be the same as the input vector.
|
|
667
|
+
*
|
|
668
|
+
* @noreturn
|
|
669
|
+
*/
|
|
670
|
+
stock xs_vec_normalize(const Float:vec[], Float:out[])
|
|
671
|
+
{
|
|
672
|
+
new Float:invlen = xs_rsqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
|
|
673
|
+
out[0] = vec[0] * invlen;
|
|
674
|
+
out[1] = vec[1] * invlen;
|
|
675
|
+
out[2] = vec[2] * invlen;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Computes the cross product of two vectors.
|
|
680
|
+
*
|
|
681
|
+
* @param vec1 The first vector operand of the cross operation.
|
|
682
|
+
* @param vec2 The second vector operand of the cross operation.
|
|
683
|
+
* @param out The output vector. *Can't* be one of the input vectors.
|
|
684
|
+
*
|
|
685
|
+
* @noreturn
|
|
686
|
+
*/
|
|
687
|
+
stock xs_vec_cross(const Float:vec1[], const Float:vec2[], Float:out[])
|
|
688
|
+
{
|
|
689
|
+
out[0] = vec1[1]*vec2[2] - vec1[2]*vec2[1];
|
|
690
|
+
out[1] = vec1[2]*vec2[0] - vec1[0]*vec2[2];
|
|
691
|
+
out[2] = vec1[0]*vec2[1] - vec1[1]*vec2[0];
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Computes the dot product of two vectors.
|
|
696
|
+
*
|
|
697
|
+
* @param vec1 The first vector operand of the dot operation.
|
|
698
|
+
* @param vec2 The second vector operand of the dot operation.
|
|
699
|
+
*
|
|
700
|
+
* @return The dot product of two input vectors.
|
|
701
|
+
*/
|
|
702
|
+
stock Float:xs_vec_dot(const Float:vec1[], const Float:vec2[])
|
|
703
|
+
{
|
|
704
|
+
return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Negates a vector.
|
|
709
|
+
*
|
|
710
|
+
* @param vec The vector to negate.
|
|
711
|
+
* @param out The output vector. Can be the same as the input vector.
|
|
712
|
+
*
|
|
713
|
+
* @noreturn
|
|
714
|
+
*/
|
|
715
|
+
stock xs_vec_neg(const Float:vec[], Float:out[])
|
|
716
|
+
{
|
|
717
|
+
out[0] = -vec[0];
|
|
718
|
+
out[1] = -vec[1];
|
|
719
|
+
out[2] = -vec[2];
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Copies a vector into another one.
|
|
724
|
+
*
|
|
725
|
+
* @param vecIn The vector to copy.
|
|
726
|
+
* @param vecOut The output vector where to copy the input vector.
|
|
727
|
+
*
|
|
728
|
+
* @noreturn
|
|
729
|
+
*/
|
|
730
|
+
stock xs_vec_copy(const Float:vecIn[], Float:vecOut[])
|
|
731
|
+
{
|
|
732
|
+
vecOut[0] = vecIn[0];
|
|
733
|
+
vecOut[1] = vecIn[1];
|
|
734
|
+
vecOut[2] = vecIn[2];
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Computes the angle between two vectors.
|
|
739
|
+
*
|
|
740
|
+
* @param vec1 The first vector.
|
|
741
|
+
* @param vec2 The second vector.
|
|
742
|
+
*
|
|
743
|
+
* @return The angle between two input vectors in degrees.
|
|
744
|
+
*/
|
|
745
|
+
stock Float:xs_vec_angle(const Float:vec1[], const Float:vec2[])
|
|
746
|
+
{
|
|
747
|
+
return xs_rad2deg(xs_acos(xs_vec_dot(vec1, vec2), radian));
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Reflects a vector about a normal.
|
|
752
|
+
*
|
|
753
|
+
* @param vec The vector to be reflected.
|
|
754
|
+
* @param normal The normal vector about which to reflect.
|
|
755
|
+
* @param out The output reflected vector.
|
|
756
|
+
*
|
|
757
|
+
* @noreturn
|
|
758
|
+
*/
|
|
759
|
+
stock xs_vec_reflect(const Float:vec[], const Float:normal[], Float:out[])
|
|
760
|
+
{
|
|
761
|
+
// normalize(vec) - (normal * 2.0 * (tmp . normal)) * length(vec)
|
|
762
|
+
|
|
763
|
+
new Float:tmp1[3];
|
|
764
|
+
xs_vec_normalize(vec, tmp1);
|
|
765
|
+
|
|
766
|
+
// tmp1 - (normal * 2.0 * (tmp . normal)) * length(vec)
|
|
767
|
+
|
|
768
|
+
new Float:tmp2[3];
|
|
769
|
+
xs_vec_mul_scalar(normal, 2.0, tmp2);
|
|
770
|
+
xs_vec_mul_scalar(tmp2, xs_vec_dot(tmp1, normal), tmp2);
|
|
771
|
+
|
|
772
|
+
// tmp1 - tmp2 * length(vec)
|
|
773
|
+
xs_vec_mul_scalar(tmp2, xs_vec_len(vec), tmp2);
|
|
774
|
+
|
|
775
|
+
// tmp1 - tmp2
|
|
776
|
+
xs_vec_sub(tmp1, tmp2, out);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* Turns a 3D vector into a 2D vector.
|
|
781
|
+
*
|
|
782
|
+
* @note This function just ignores the Z (3rd) component of a 3D vector.
|
|
783
|
+
*
|
|
784
|
+
* @param vec A 3D vector to turn into a 2D vector.
|
|
785
|
+
* @param out The output 2D vector.
|
|
786
|
+
*
|
|
787
|
+
* @noreturn
|
|
788
|
+
*/
|
|
789
|
+
stock xs_vec_make2d(const Float:vec[3], Float:out[2])
|
|
790
|
+
{
|
|
791
|
+
out[0] = vec[0];
|
|
792
|
+
out[1] = vec[1];
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// *** planes
|
|
796
|
+
|
|
797
|
+
// normal
|
|
798
|
+
#define XS_PLANE_A 0
|
|
799
|
+
#define XS_PLANE_B 1
|
|
800
|
+
#define XS_PLANE_C 2
|
|
801
|
+
// plane shift distance
|
|
802
|
+
#define XS_PLANE_D 3
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Sets a plane to the specified values.
|
|
807
|
+
*
|
|
808
|
+
* @param plane The plane to set the values to. It's a 4D vector.
|
|
809
|
+
* @param a The first component of a plane to be set.
|
|
810
|
+
* @param b The second component of a plane to be set.
|
|
811
|
+
* @param c The third component of a plane to be set.
|
|
812
|
+
* @param d The fouth component of a plane to be set.
|
|
813
|
+
*
|
|
814
|
+
* @noreturn
|
|
815
|
+
*/
|
|
816
|
+
stock xs_plane_set(Float:plane[], Float:a, Float:b, Float:c, Float:d)
|
|
817
|
+
{
|
|
818
|
+
plane[XS_PLANE_A] = a;
|
|
819
|
+
plane[XS_PLANE_B] = b;
|
|
820
|
+
plane[XS_PLANE_C] = c;
|
|
821
|
+
plane[XS_PLANE_D] = d;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* Constructs a plane out of 4 points in space.
|
|
826
|
+
*
|
|
827
|
+
* @param plane The output plane to store the newly created plane.
|
|
828
|
+
* @param p1 The first point of a plane.
|
|
829
|
+
* @param p2 The second point of a plane.
|
|
830
|
+
* @param p3 The third point of a plane.
|
|
831
|
+
*
|
|
832
|
+
* @noreturn
|
|
833
|
+
*/
|
|
834
|
+
stock xs_plane_3p(Float:plane[], const Float:p1[], const Float:p2[], const Float:p3[])
|
|
835
|
+
{
|
|
836
|
+
new Float:normalA[3], Float:normalB[3];
|
|
837
|
+
|
|
838
|
+
// normalA = Normalize(p3 - p1);
|
|
839
|
+
normalA[0] = p3[0] - p1[0];
|
|
840
|
+
normalA[1] = p3[1] - p1[1];
|
|
841
|
+
normalA[2] = p3[2] - p1[2];
|
|
842
|
+
xs_vec_normalize(normalA, normalA);
|
|
843
|
+
|
|
844
|
+
// normalB = Normalize(p3 - p2);
|
|
845
|
+
normalB[0] = p3[0] - p2[0];
|
|
846
|
+
normalB[1] = p3[1] - p2[1];
|
|
847
|
+
normalB[2] = p3[2] - p2[2];
|
|
848
|
+
xs_vec_normalize(normalB, normalB);
|
|
849
|
+
|
|
850
|
+
// plane normal = Normalize(normalA cross normalB)
|
|
851
|
+
xs_vec_cross(normalA, normalB, plane);
|
|
852
|
+
xs_vec_normalize(plane, plane);
|
|
853
|
+
|
|
854
|
+
// plane shift distance = (-p1) dot plane normal
|
|
855
|
+
new Float:__tmp[3];
|
|
856
|
+
xs_vec_neg(plane, __tmp);
|
|
857
|
+
plane[XS_PLANE_D] = xs_vec_dot(__tmp, p1);
|
|
858
|
+
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* Checks if two planes are equal.
|
|
863
|
+
*
|
|
864
|
+
* @note If you have to check if two planes are just nearly equal,
|
|
865
|
+
* take a look at xs_plane_nearlyequal().
|
|
866
|
+
*
|
|
867
|
+
* @param plane1 The first plane to check.
|
|
868
|
+
* @param plane2 The second plane to check.
|
|
869
|
+
*
|
|
870
|
+
* @return 1 if planes are equal, 0 otherwise.
|
|
871
|
+
*/
|
|
872
|
+
stock bool:xs_plane_equal(const Float:plane1[], const Float:plane2[])
|
|
873
|
+
{
|
|
874
|
+
if ( (plane1[0] == plane2[0]) &&
|
|
875
|
+
(plane1[1] == plane2[1]) &&
|
|
876
|
+
(plane1[2] == plane2[2]) &&
|
|
877
|
+
(plane1[3] == plane2[3]))
|
|
878
|
+
return true;
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Checks if two planes are nearly equal.
|
|
884
|
+
*
|
|
885
|
+
* @note If you have to check if two planes are exactly equal,
|
|
886
|
+
* take a look at xs_plane_equal().
|
|
887
|
+
*
|
|
888
|
+
* @param plane1 The first plane to check.
|
|
889
|
+
* @param plane2 The second plane to check.
|
|
890
|
+
*
|
|
891
|
+
* @return 1 if planes are nearly equal, 0 otherwise.
|
|
892
|
+
*/
|
|
893
|
+
stock bool:xs_plane_nearlyequal(const Float:plane1[], const Float:plane2[])
|
|
894
|
+
{
|
|
895
|
+
if ( XS_FLEQ(plane1[0], plane2[0]) &&
|
|
896
|
+
XS_FLEQ(plane1[1], plane2[1]) &&
|
|
897
|
+
XS_FLEQ(plane1[2], plane2[2]) &&
|
|
898
|
+
XS_FLEQ(plane1[3], plane2[3]))
|
|
899
|
+
return true;
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Computes the distance between a plane and a point.
|
|
905
|
+
*
|
|
906
|
+
* @param plane The plane to check the distance from.
|
|
907
|
+
* @param point The point to check the distance to.
|
|
908
|
+
*
|
|
909
|
+
* @return The distance between the input plane and point.
|
|
910
|
+
*/
|
|
911
|
+
stock Float:xs_plane_dst2point(const Float:plane[], const Float:point[])
|
|
912
|
+
{
|
|
913
|
+
// return normal dot point + D
|
|
914
|
+
return xs_vec_dot(plane, point) + plane[XS_PLANE_D];
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* Checks whether a plane intersects with the ray starting at @rayStart and
|
|
919
|
+
* going to @rayDir direction.
|
|
920
|
+
* If it does intersect, outputs the intersection point in @out.
|
|
921
|
+
*
|
|
922
|
+
* @param plane The plane to check intersection with.
|
|
923
|
+
* @param rayStart The starting point of the ray.
|
|
924
|
+
* @param rayDir Direction in which the ray is going.
|
|
925
|
+
* @param out The vector to copy the intersection point to, if it exists.
|
|
926
|
+
*
|
|
927
|
+
* @return true if they intersect, false otherwise.
|
|
928
|
+
*/
|
|
929
|
+
stock bool:xs_plane_rayintersect(const Float:plane[], const Float:rayStart[], const Float:rayDir[], Float:out[])
|
|
930
|
+
{
|
|
931
|
+
new Float:a = xs_vec_dot(plane, rayDir);
|
|
932
|
+
|
|
933
|
+
if (a == 0.0)
|
|
934
|
+
return false; // ray is parallel to plane
|
|
935
|
+
|
|
936
|
+
// if (distance plane<->(rayStart + rayDir) > distance plane<->rayStart) and both have the same sign, the ray
|
|
937
|
+
// goes away from the plane
|
|
938
|
+
new Float:rsplusrd[3];
|
|
939
|
+
xs_vec_add(rayStart, rayDir, rsplusrd);
|
|
940
|
+
new Float:dst1 = xs_plane_dst2point(plane, rsplusrd);
|
|
941
|
+
new Float:dst2 = xs_plane_dst2point(plane, rayStart);
|
|
942
|
+
if (xs_fabs(dst1) > xs_fabs(dst2) && xs_fsign(dst1) == xs_fsign(dst2))
|
|
943
|
+
return false;
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
// out = rayStart - rayDir * ((distance plane<->rayStart) / a)
|
|
947
|
+
new Float:__tmp[3];
|
|
948
|
+
xs_vec_mul_scalar(rayDir, xs_plane_dst2point(plane, rayStart) / a, __tmp);
|
|
949
|
+
// out = rayStart - tmp
|
|
950
|
+
xs_vec_sub(rayStart, __tmp, out);
|
|
951
|
+
|
|
952
|
+
return true;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/**
|
|
956
|
+
* Checks if a point is on a specified plane.
|
|
957
|
+
*
|
|
958
|
+
* @param plane The plane to check.
|
|
959
|
+
* @param point The point to check.
|
|
960
|
+
*
|
|
961
|
+
* @return true if the point is on the plane, false otherwise.
|
|
962
|
+
*/
|
|
963
|
+
stock bool:xs_point_onplane(const Float:plane[], const Float:point[])
|
|
964
|
+
{
|
|
965
|
+
return XS_FLEQ(xs_plane_dst2point(plane, point), 0.0);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Projects a point on the plane. Stores the projected point in @out.
|
|
970
|
+
*
|
|
971
|
+
* @param plane The plane to project the point onto.
|
|
972
|
+
* @param point The point to project onto the plane.
|
|
973
|
+
* @param out The vector to copy the projected point into.
|
|
974
|
+
*
|
|
975
|
+
* @noreturn
|
|
976
|
+
*/
|
|
977
|
+
stock xs_projpoint_onplane(const Float:plane[], const Float:point[], Float:out[])
|
|
978
|
+
{
|
|
979
|
+
new Float:__tmp[3];
|
|
980
|
+
// out = point - (plane normal * distance point<->plane)
|
|
981
|
+
xs_vec_copy(plane, __tmp);
|
|
982
|
+
xs_vec_mul_scalar(__tmp, xs_plane_dst2point(plane, point), __tmp);
|
|
983
|
+
xs_vec_sub(point, __tmp, out);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Copies a plane.
|
|
988
|
+
*
|
|
989
|
+
* @param planeIn The plane to copy.
|
|
990
|
+
* @param planeOut The plane to store the copy into.
|
|
991
|
+
*
|
|
992
|
+
* @noreturn
|
|
993
|
+
*/
|
|
994
|
+
stock xs_plane_copy(const Float:planeIn[], Float:planeOut[])
|
|
995
|
+
{
|
|
996
|
+
planeOut[0] = planeIn[0];
|
|
997
|
+
planeOut[1] = planeIn[1];
|
|
998
|
+
planeOut[2] = planeIn[2];
|
|
999
|
+
planeOut[3] = planeIn[3];
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/****** HL ENGINE SPECIFIC STUFF ******/
|
|
1003
|
+
|
|
1004
|
+
// angle indexes
|
|
1005
|
+
#define XS_PITCH 0 // up / down
|
|
1006
|
+
#define XS_YAW 1 // left / right
|
|
1007
|
+
#define XS_ROLL 2 // fall over
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* Computes forward, right and up vectors from given angles.
|
|
1011
|
+
*
|
|
1012
|
+
* @param angles Angles to compute vectors from.
|
|
1013
|
+
* @param fwd The vector to store the forward vector into.
|
|
1014
|
+
* @param right The vector to store the right vector into.
|
|
1015
|
+
* @param up The vector to store the up vector into.
|
|
1016
|
+
*
|
|
1017
|
+
* @noreturn
|
|
1018
|
+
*/
|
|
1019
|
+
stock xs_anglevectors(const Float:angles[3], Float:fwd[3], Float:right[3], Float:up[3])
|
|
1020
|
+
{
|
|
1021
|
+
// sin (s) and cos (c) for yaw (y), pitch (p) and roll (r)
|
|
1022
|
+
new Float:sr, Float:sp, Float:sy, Float:cr, Float:cp, Float:cy;
|
|
1023
|
+
|
|
1024
|
+
sy = xs_sin(angles[XS_YAW], degrees);
|
|
1025
|
+
cy = xs_cos(angles[XS_YAW], degrees);
|
|
1026
|
+
sp = xs_sin(angles[XS_PITCH], degrees);
|
|
1027
|
+
cp = xs_cos(angles[XS_PITCH], degrees);
|
|
1028
|
+
sr = xs_sin(angles[XS_ROLL], degrees);
|
|
1029
|
+
cr = xs_cos(angles[XS_ROLL], degrees);
|
|
1030
|
+
|
|
1031
|
+
fwd[0] = cp*cy;
|
|
1032
|
+
fwd[1] = cp*sy;
|
|
1033
|
+
fwd[2] = -sp;
|
|
1034
|
+
|
|
1035
|
+
right[0] = (-1*sr*sp*cy + -1*cr*-sy);
|
|
1036
|
+
right[1] = (-1*sr*sp*sy + -1*cr*cy);
|
|
1037
|
+
right[2] = -1*sr*cp;
|
|
1038
|
+
|
|
1039
|
+
up[0] = (cr*sp*cy + -sr*-sy);
|
|
1040
|
+
up[1] = (cr*sp*sy + -sr*cy);
|
|
1041
|
+
up[2] = cr*cp;
|
|
1042
|
+
}
|
|
1043
|
+
/****** STRING FUNCS *******/
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* Finds a character in a string and returns its position in the string.
|
|
1047
|
+
*
|
|
1048
|
+
* @param str The string to search in.
|
|
1049
|
+
* @param chr The character to search for in the string.
|
|
1050
|
+
*
|
|
1051
|
+
* @return The character position if found, -1 otherwise.
|
|
1052
|
+
*/
|
|
1053
|
+
stock xs_strchr(const str[], chr)
|
|
1054
|
+
{
|
|
1055
|
+
for (new i = 0; str[i] != 0; ++i)
|
|
1056
|
+
{
|
|
1057
|
+
if (str[i] == chr)
|
|
1058
|
+
return i;
|
|
1059
|
+
}
|
|
1060
|
+
return -1;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Remove @charstotrim number of characters from @stringtotrim,
|
|
1065
|
+
* either from the beginning or the end of the string.
|
|
1066
|
+
*
|
|
1067
|
+
* @param stringtotrim The string to be trimmed.
|
|
1068
|
+
* @param charstostrim The number of characters to trim.
|
|
1069
|
+
* @param fromleft If set to true, the string will be trimmer from the left.
|
|
1070
|
+
* If false, it will be trimmed from the right.
|
|
1071
|
+
*
|
|
1072
|
+
* @noreturn
|
|
1073
|
+
*/
|
|
1074
|
+
stock xs_strtrim(stringtotrim[], charstotrim, bool:fromleft = true)
|
|
1075
|
+
{
|
|
1076
|
+
if (charstotrim <= 0)
|
|
1077
|
+
return;
|
|
1078
|
+
|
|
1079
|
+
if (fromleft)
|
|
1080
|
+
{
|
|
1081
|
+
new maxlen = strlen(stringtotrim);
|
|
1082
|
+
if (charstotrim > maxlen)
|
|
1083
|
+
charstotrim = maxlen;
|
|
1084
|
+
|
|
1085
|
+
// In format, input and output regions can overlap
|
|
1086
|
+
format(stringtotrim, maxlen, "%s", stringtotrim[charstotrim]);
|
|
1087
|
+
}
|
|
1088
|
+
else
|
|
1089
|
+
{
|
|
1090
|
+
new maxlen = strlen(stringtotrim) - charstotrim;
|
|
1091
|
+
if (maxlen < 0)
|
|
1092
|
+
maxlen = 0;
|
|
1093
|
+
|
|
1094
|
+
// In format, input and output regions can overlap
|
|
1095
|
+
format(stringtotrim, maxlen, "%s", stringtotrim);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* Copies characters from @oldmsg to @newmsg, starting at @start and ending
|
|
1101
|
+
* at @end (includes the end character).
|
|
1102
|
+
*
|
|
1103
|
+
* @param oldmsg The string to copy from.
|
|
1104
|
+
* @param newmsg The string to copy to.
|
|
1105
|
+
* @param start Starting position of the @oldmsg string to copy from.
|
|
1106
|
+
* @param end Ending position of the @oldmsg string to copy from.
|
|
1107
|
+
* @param outlen If positive, specifies the maximum number of characters
|
|
1108
|
+
* to be copied. Otherwise, the function assumes that
|
|
1109
|
+
* newmsg is at least @end - @start + 1 characters long.
|
|
1110
|
+
*
|
|
1111
|
+
* @noreturn
|
|
1112
|
+
*/
|
|
1113
|
+
stock xs_strmid(const oldmsg[], newmsg[], start, end, outlen=-1)
|
|
1114
|
+
{
|
|
1115
|
+
new len = strlen(oldmsg);
|
|
1116
|
+
|
|
1117
|
+
if(start < 0)
|
|
1118
|
+
start = 0;
|
|
1119
|
+
|
|
1120
|
+
++end; // Include end
|
|
1121
|
+
|
|
1122
|
+
if(end <= start || end > len)
|
|
1123
|
+
end = len;
|
|
1124
|
+
|
|
1125
|
+
new j = 0, i = start;
|
|
1126
|
+
for(; (i < end) && (outlen--);)
|
|
1127
|
+
newmsg[j++] = oldmsg[i++];
|
|
1128
|
+
|
|
1129
|
+
newmsg[j] = 0;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
/**
|
|
1133
|
+
* "Explodes" a string, breaking it at the @delimeter character and putting
|
|
1134
|
+
* each exploded part into the @output array.
|
|
1135
|
+
*
|
|
1136
|
+
* @param input The input string to be exploded.
|
|
1137
|
+
* @param output The output array of string where exploded string will be stored.
|
|
1138
|
+
* @param delimeter The character to break the string at.
|
|
1139
|
+
* @param maxelems Maximum amount of elements in @output.
|
|
1140
|
+
* @param elemsize Maximum size of each string in the @output array.
|
|
1141
|
+
*
|
|
1142
|
+
* @return The number of strings successfully exploded.
|
|
1143
|
+
*/
|
|
1144
|
+
stock xs_explode(const input[], output[][], delimiter, maxelems, elemsize)
|
|
1145
|
+
{
|
|
1146
|
+
new nIdx = 0;
|
|
1147
|
+
new nLen = 0;
|
|
1148
|
+
|
|
1149
|
+
new copied = 0;
|
|
1150
|
+
while(nLen < strlen(input) && nIdx < maxelems)
|
|
1151
|
+
{
|
|
1152
|
+
copied = copyc(output[nIdx++], elemsize, input[nLen], delimiter);
|
|
1153
|
+
if (copied == elemsize)
|
|
1154
|
+
{
|
|
1155
|
+
// maybe it got force-stopped because of maxsize
|
|
1156
|
+
// so check whether we have to skip something
|
|
1157
|
+
if (input[nLen + copied] != delimiter && input[nLen + copied] != 0)
|
|
1158
|
+
{
|
|
1159
|
+
new found = xs_strchr(input[nLen + copied], delimiter);
|
|
1160
|
+
if (found == -1)
|
|
1161
|
+
break;
|
|
1162
|
+
copied += found;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
nLen += copied + 1; // +1: skip delimiter
|
|
1167
|
+
}
|
|
1168
|
+
return nIdx;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* The opposite of xs_explode(). Takes an array of strings and puts them together
|
|
1173
|
+
* in a single string, delimeted by the @delimeter character.
|
|
1174
|
+
*
|
|
1175
|
+
* @param output The string to store the impoded string into.
|
|
1176
|
+
* @param outsize The size of the output buffer.
|
|
1177
|
+
* @param delimeter The character to put between imploded strings.
|
|
1178
|
+
* @param input The array of strings to implode.
|
|
1179
|
+
* @param elemsnum The number of strings in the input array.
|
|
1180
|
+
*
|
|
1181
|
+
* @return The number of characters in the final output buffer.
|
|
1182
|
+
*/
|
|
1183
|
+
stock xs_implode(output[], outsize, delimiter, const input[][], elemsnum)
|
|
1184
|
+
{
|
|
1185
|
+
new pos = 0;
|
|
1186
|
+
new copied;
|
|
1187
|
+
for (new i = 0; i < elemsnum; ++i)
|
|
1188
|
+
{
|
|
1189
|
+
copied = copy(output[pos], outsize - pos, input[i]);
|
|
1190
|
+
pos += copied;
|
|
1191
|
+
if (pos >= outsize)
|
|
1192
|
+
return outsize;
|
|
1193
|
+
// append delimiter
|
|
1194
|
+
output[pos] = delimiter;
|
|
1195
|
+
++pos;
|
|
1196
|
+
// last check
|
|
1197
|
+
if (pos >= outsize)
|
|
1198
|
+
return outsize;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
output[--pos] = 0; // The last char would be delimiter, so skip it.
|
|
1202
|
+
return pos;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
stock xs__replace_buf[XS_REPLACEBUF_SIZE];
|
|
1207
|
+
|
|
1208
|
+
/**
|
|
1209
|
+
* Replaces all occurencies of @what in @text with @with.
|
|
1210
|
+
*
|
|
1211
|
+
* @param text The text to search in.
|
|
1212
|
+
* @param len The maximum size of the @text buffer.
|
|
1213
|
+
* @param what What to search for.
|
|
1214
|
+
* @param with What to replace occurencies with.
|
|
1215
|
+
*
|
|
1216
|
+
* @return Returns the number of replaced items.
|
|
1217
|
+
*/
|
|
1218
|
+
stock xs_replace(text[], len, const what[], const with[])
|
|
1219
|
+
{
|
|
1220
|
+
new occur = 0;
|
|
1221
|
+
new i = 0;
|
|
1222
|
+
new bufPos = 0;
|
|
1223
|
+
new replaceLen = strlen(with);
|
|
1224
|
+
new whatLen = strlen(what);
|
|
1225
|
+
for (; text[i]; ++i)
|
|
1226
|
+
{
|
|
1227
|
+
if (text[i] == what[0])
|
|
1228
|
+
{
|
|
1229
|
+
new posInWhat=0;
|
|
1230
|
+
new j;
|
|
1231
|
+
for (j = i; j-i < replaceLen && text[j]; ++j, ++posInWhat)
|
|
1232
|
+
{
|
|
1233
|
+
if (text[j] != what[posInWhat])
|
|
1234
|
+
break;
|
|
1235
|
+
}
|
|
1236
|
+
if (whatLen == posInWhat)
|
|
1237
|
+
{
|
|
1238
|
+
for (new i2 = 0; i2 < replaceLen && bufPos < XS_REPLACEBUF_SIZE; ++i2)
|
|
1239
|
+
xs__replace_buf[bufPos++] = with[i2];
|
|
1240
|
+
i = j - 1;
|
|
1241
|
+
++occur;
|
|
1242
|
+
if (bufPos >= XS_REPLACEBUF_SIZE)
|
|
1243
|
+
return occur;
|
|
1244
|
+
continue;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
if (bufPos >= XS_REPLACEBUF_SIZE)
|
|
1248
|
+
return occur;
|
|
1249
|
+
xs__replace_buf[bufPos++] = text[i];
|
|
1250
|
+
}
|
|
1251
|
+
xs__replace_buf[bufPos] = 0;
|
|
1252
|
+
copy(text, len, xs__replace_buf);
|
|
1253
|
+
return occur;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
/**
|
|
1257
|
+
* Replaces all occurencies of @what character in @text with @with character.
|
|
1258
|
+
*
|
|
1259
|
+
* @param text The text to search in.
|
|
1260
|
+
* @param len The maximum size of the @text buffer.
|
|
1261
|
+
* @param what What character to search for.
|
|
1262
|
+
* @param with What charactear to replace occurencies with.
|
|
1263
|
+
*
|
|
1264
|
+
* @return The number of replaced characters.
|
|
1265
|
+
*/
|
|
1266
|
+
stock xs_replace_char(text[], len, what, with)
|
|
1267
|
+
{
|
|
1268
|
+
// let the xs_replace function do the work
|
|
1269
|
+
new arr[4];
|
|
1270
|
+
arr[0] = what;
|
|
1271
|
+
arr[1] = 0;
|
|
1272
|
+
arr[2] = with;
|
|
1273
|
+
arr[3] = 0;
|
|
1274
|
+
|
|
1275
|
+
return xs_replace(text, len, arr[0], arr[2]);
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
/****** MISC FUNCS *******/
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* Retrieves the name of a command identified by its ID.
|
|
1282
|
+
*
|
|
1283
|
+
* @param cid The command ID.
|
|
1284
|
+
* @param namestr The buffer where to store command's name.
|
|
1285
|
+
* @param namelen The maximum size of the output buffer.
|
|
1286
|
+
*
|
|
1287
|
+
* @noreturn
|
|
1288
|
+
*/
|
|
1289
|
+
stock xs_concmd_name(cid, namestr[], namelen)
|
|
1290
|
+
{
|
|
1291
|
+
new dummy1;
|
|
1292
|
+
new dummy2[1];
|
|
1293
|
+
get_concmd(cid, namestr, namelen, dummy1, dummy2, 0, 0);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
/**
|
|
1297
|
+
* Checks whether there are at least @num free visible slots.
|
|
1298
|
+
*
|
|
1299
|
+
* @param num The number of slots to check.
|
|
1300
|
+
*
|
|
1301
|
+
* @return true if there are at least that many free, false otherwise.
|
|
1302
|
+
*/
|
|
1303
|
+
stock bool:xs_freevisibleslots(num)
|
|
1304
|
+
{
|
|
1305
|
+
new maxplayers = get_cvar_num("sv_visiblemaxplayers");
|
|
1306
|
+
if (maxplayers <= 0)
|
|
1307
|
+
maxplayers = MaxClients;
|
|
1308
|
+
|
|
1309
|
+
return (get_playersnum(1) <= maxplayers-num) ? true : false;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
stock xs__maxnum = 0;
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* Returns the biggest possible positive number.
|
|
1316
|
+
*
|
|
1317
|
+
* @return The biggest possible positive number.
|
|
1318
|
+
*/
|
|
1319
|
+
stock xs_get_maxnum()
|
|
1320
|
+
{
|
|
1321
|
+
if (!xs__maxnum)
|
|
1322
|
+
{
|
|
1323
|
+
// build it
|
|
1324
|
+
xs__maxnum = ((1 << (cellbits - 2)) - 1 ) | (1 << (cellbits - 2));
|
|
1325
|
+
/*
|
|
1326
|
+
new bits = get_cellsize() * 8 - 1;
|
|
1327
|
+
for (new i = 0; i < bits; ++i)
|
|
1328
|
+
xs__maxnum |= 1 << i;
|
|
1329
|
+
*/
|
|
1330
|
+
}
|
|
1331
|
+
return xs__maxnum;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
/**
|
|
1335
|
+
* Returns the smallest possible negative number.
|
|
1336
|
+
*
|
|
1337
|
+
* @return The smallest possible negative number.
|
|
1338
|
+
*/
|
|
1339
|
+
stock xs_get_minnum()
|
|
1340
|
+
{
|
|
1341
|
+
return xs_get_maxnum() + 1;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
// *** The following two functions were created by Damaged Soul.
|
|
1346
|
+
|
|
1347
|
+
// Max messages reserved by engine (DO NOT MODIFY)
|
|
1348
|
+
#define XS__MAX_ENGINE_MESSAGES 63
|
|
1349
|
+
// Max possible messages for mod, is 255 really the limit?
|
|
1350
|
+
#define XS__MAX_POSSIBLE_MESSAGES 255
|
|
1351
|
+
|
|
1352
|
+
// Returns max number of messages for mod
|
|
1353
|
+
stock xs_get_maxmessages()
|
|
1354
|
+
{
|
|
1355
|
+
new name[2];
|
|
1356
|
+
|
|
1357
|
+
for (new i = XS__MAX_ENGINE_MESSAGES + 1; i <= XS__MAX_POSSIBLE_MESSAGES; i++)
|
|
1358
|
+
if (!get_user_msgname(i, name, 1))
|
|
1359
|
+
return i - 1;
|
|
1360
|
+
|
|
1361
|
+
return XS__MAX_POSSIBLE_MESSAGES;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
// Returns true if msgid is a valid message
|
|
1365
|
+
stock bool:xs_is_msg_valid(msgid)
|
|
1366
|
+
{
|
|
1367
|
+
new name[2];
|
|
1368
|
+
new retval = get_user_msgname(msgid, name, 1);
|
|
1369
|
+
|
|
1370
|
+
if (msgid < 1 || (msgid > XS__MAX_ENGINE_MESSAGES && !retval))
|
|
1371
|
+
return false;
|
|
1372
|
+
|
|
1373
|
+
return true;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/****** MANAGED TASKS ******/
|
|
1377
|
+
|
|
1378
|
+
// ***** managed task ids
|
|
1379
|
+
stock xs_find_freetaskid()
|
|
1380
|
+
{
|
|
1381
|
+
for (new i = 1; i <= XS_TASK_MANAGEDIDS; ++i)
|
|
1382
|
+
{
|
|
1383
|
+
if (!task_exists(i))
|
|
1384
|
+
return i;
|
|
1385
|
+
}
|
|
1386
|
+
return -1;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
// ***** managed tasks
|
|
1390
|
+
enum xs_paramtypes
|
|
1391
|
+
{
|
|
1392
|
+
xs_invalid = 0,
|
|
1393
|
+
xs_int,
|
|
1394
|
+
xs_float,
|
|
1395
|
+
xs_string
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
// new task
|
|
1399
|
+
stock xs__TaskParam[ 1 + // number of parameters
|
|
1400
|
+
XS_TASK_MAXPARAMS + // parameter types
|
|
1401
|
+
(XS_TASK_MAXPARAMSIZE char) * XS_TASK_MAXPARAMS]; // space for len + value
|
|
1402
|
+
|
|
1403
|
+
stock Float:xs__TaskInterval = 0.0;
|
|
1404
|
+
stock xs__TaskFlags[5];
|
|
1405
|
+
stock xs__TaskFunc[48];
|
|
1406
|
+
stock xs__TaskId;
|
|
1407
|
+
stock xs__TaskRepeat;
|
|
1408
|
+
|
|
1409
|
+
#define xs__TaskParamCount xs__TaskParam[0]
|
|
1410
|
+
#define xs__TaskParamType[%1] xs__TaskParam[1 + %1]
|
|
1411
|
+
|
|
1412
|
+
#define xs__TaskParamValue[%1] xs__TaskParam[1 + XS_TASK_MAXPARAMS + (%1 * (XS_TASK_MAXPARAMSIZE char))]
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
// incoming task
|
|
1416
|
+
stock xs__ITaskParam[ 1 + // number of parameters
|
|
1417
|
+
XS_TASK_MAXPARAMS + // parameter types
|
|
1418
|
+
(XS_TASK_MAXPARAMSIZE char) * XS_TASK_MAXPARAMS]; // space for len + value
|
|
1419
|
+
stock xs__ITaskId;
|
|
1420
|
+
|
|
1421
|
+
#define xs__ITaskParamCount xs__ITaskParam[0]
|
|
1422
|
+
#define xs__ITaskParamType[%1] xs__ITaskParam[1 + %1]
|
|
1423
|
+
|
|
1424
|
+
#define xs__ITaskParamValue[%1] xs__ITaskParam[1 + XS_TASK_MAXPARAMS + (%1 * (XS_TASK_MAXPARAMSIZE char))]
|
|
1425
|
+
|
|
1426
|
+
// tested
|
|
1427
|
+
stock xs_task_begin(Float:interval, const func[], id = 0, const flags[] = "", repeat = 0)
|
|
1428
|
+
{
|
|
1429
|
+
xs_assert(xs__TaskInterval == 0.0, "New xs_task_begin called before xs_task_end");
|
|
1430
|
+
|
|
1431
|
+
xs__TaskInterval = interval;
|
|
1432
|
+
if (xs__TaskInterval < 0.1)
|
|
1433
|
+
xs__TaskInterval = 0.1;
|
|
1434
|
+
|
|
1435
|
+
copy(xs__TaskFunc, 47, func);
|
|
1436
|
+
xs__TaskId = id;
|
|
1437
|
+
copy(xs__TaskFlags, 4, flags);
|
|
1438
|
+
xs__TaskRepeat = repeat;
|
|
1439
|
+
|
|
1440
|
+
xs__TaskParamCount = 0;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// tested
|
|
1444
|
+
stock xs_task_pushint(value, bool:__isfl=false /*internal use only*/)
|
|
1445
|
+
{
|
|
1446
|
+
xs_assert(xs__TaskInterval, "xs_task_push* called without xs_task_begin");
|
|
1447
|
+
if (xs__TaskParamCount >= XS_TASK_MAXPARAMS)
|
|
1448
|
+
return 0;
|
|
1449
|
+
|
|
1450
|
+
xs__TaskParamType[xs__TaskParamCount] = __isfl ? xs_float : xs_int;
|
|
1451
|
+
xs__TaskParamValue[xs__TaskParamCount] = value;
|
|
1452
|
+
|
|
1453
|
+
++xs__TaskParamCount;
|
|
1454
|
+
return 1;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
// tested
|
|
1458
|
+
stock xs_task_pushfl(Float:value)
|
|
1459
|
+
{
|
|
1460
|
+
return xs_task_pushint(_:value, true);
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
// tested
|
|
1464
|
+
stock xs_task_pushstr(const value[])
|
|
1465
|
+
{
|
|
1466
|
+
xs_assert(xs__TaskInterval, "xs_task_push* called without xs_task_begin");
|
|
1467
|
+
if (xs__TaskParamCount >= XS_TASK_MAXPARAMS)
|
|
1468
|
+
return 0;
|
|
1469
|
+
|
|
1470
|
+
xs__TaskParamType[xs__TaskParamCount] = xs_string;
|
|
1471
|
+
strpack(xs__TaskParamValue[xs__TaskParamCount], value);
|
|
1472
|
+
++xs__TaskParamCount;
|
|
1473
|
+
return 1;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
// tested
|
|
1477
|
+
stock xs_task_end()
|
|
1478
|
+
{
|
|
1479
|
+
xs_assert(xs__TaskInterval, "xs_task_end called without xs_task_begin");
|
|
1480
|
+
|
|
1481
|
+
// find a task id if needed
|
|
1482
|
+
if (xs__TaskId == -1)
|
|
1483
|
+
{
|
|
1484
|
+
xs__TaskId = xs_find_freetaskid();
|
|
1485
|
+
if (xs__TaskId == -1)
|
|
1486
|
+
{
|
|
1487
|
+
// not found
|
|
1488
|
+
xs__TaskInterval = 0.0;
|
|
1489
|
+
return -1;
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
set_task(xs__TaskInterval, xs__TaskFunc, xs__TaskId, xs__TaskParam,
|
|
1494
|
+
1 + xs__TaskParamCount * (XS_TASK_MAXPARAMSIZE char), xs__TaskFlags, xs__TaskRepeat);
|
|
1495
|
+
|
|
1496
|
+
xs__TaskInterval = 0.0;
|
|
1497
|
+
|
|
1498
|
+
return xs__TaskId;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
// tested
|
|
1503
|
+
#define XS_MAKE_TASKFUNC(%1) public %1(const _xs__taskparam[], _xs__taskid) if(xs__task_setup(_xs__taskparam, _xs__taskid))
|
|
1504
|
+
|
|
1505
|
+
// tested
|
|
1506
|
+
stock xs__task_setup(const param[], taskid)
|
|
1507
|
+
{
|
|
1508
|
+
xs__ITaskId = taskid;
|
|
1509
|
+
new len = 1 + param[0] * (XS_TASK_MAXPARAMSIZE char);
|
|
1510
|
+
for (new i = 0; i < len; ++i)
|
|
1511
|
+
xs__ITaskParam[i] = param[i];
|
|
1512
|
+
return 1;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
// tested
|
|
1516
|
+
stock xs_task_readid()
|
|
1517
|
+
{
|
|
1518
|
+
return xs__ITaskId;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
// tested
|
|
1522
|
+
stock xs_task_paramcount()
|
|
1523
|
+
{
|
|
1524
|
+
return xs__ITaskParamCount;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// tested
|
|
1528
|
+
stock xs_paramtypes:xs_task_paramtype(paramid)
|
|
1529
|
+
{
|
|
1530
|
+
if (paramid < 0 || paramid >= xs__ITaskParamCount)
|
|
1531
|
+
return xs_invalid;
|
|
1532
|
+
|
|
1533
|
+
return xs_paramtypes:xs__ITaskParamType[paramid];
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
// tested
|
|
1537
|
+
stock xs_task_paramint(paramid)
|
|
1538
|
+
{
|
|
1539
|
+
if (paramid < 0 || paramid >= xs__ITaskParamCount)
|
|
1540
|
+
return 0;
|
|
1541
|
+
if (xs__ITaskParamType[paramid] != _:xs_int)
|
|
1542
|
+
return 0;
|
|
1543
|
+
|
|
1544
|
+
return xs__ITaskParamValue[paramid];
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
// tested
|
|
1548
|
+
stock Float:xs_task_paramfl(paramid)
|
|
1549
|
+
{
|
|
1550
|
+
if (paramid < 0 || paramid >= xs__ITaskParamCount)
|
|
1551
|
+
return 0.0;
|
|
1552
|
+
if (xs__ITaskParamType[paramid] != _:xs_float)
|
|
1553
|
+
return 0.0;
|
|
1554
|
+
|
|
1555
|
+
return Float:xs__ITaskParamValue[paramid];
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
// tested
|
|
1559
|
+
stock xs_task_paramstr(paramid, out[], maxlen)
|
|
1560
|
+
{
|
|
1561
|
+
#pragma unused maxlen
|
|
1562
|
+
|
|
1563
|
+
if (paramid < 0 || paramid >= xs__ITaskParamCount)
|
|
1564
|
+
return 0;
|
|
1565
|
+
if (xs__ITaskParamType[paramid] != _:xs_string)
|
|
1566
|
+
return 0;
|
|
1567
|
+
|
|
1568
|
+
strunpack(out, xs__ITaskParamValue[paramid]);
|
|
1569
|
+
return 1;
|
|
1570
|
+
}
|