gtac-types 0.0.1
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 +201 -0
- package/README.md +435 -0
- package/bin/gtac.js +35 -0
- package/index.js +6 -0
- package/lib/build.js +186 -0
- package/package.json +51 -0
- package/src/index.d.ts +22 -0
- package/src/runtime/shared/constants.ts +146 -0
- package/src/runtime/shared/utils.ts +26 -0
- package/src/types/client/animations.d.ts +902 -0
- package/src/types/client/events.d.ts +809 -0
- package/src/types/client/functions.d.ts +715 -0
- package/src/types/client/gta.d.ts +724 -0
- package/src/types/client/natives.d.ts +1091 -0
- package/src/types/element.d.ts +853 -0
- package/src/types/event.d.ts +100 -0
- package/src/types/misc.d.ts +256 -0
- package/src/types/resource.d.ts +252 -0
- package/src/types/server/client.d.ts +144 -0
- package/src/types/server/events.d.ts +407 -0
- package/src/types/server/functions.d.ts +890 -0
- package/src/types/vec.d.ts +594 -0
- package/src/types/xml.d.ts +232 -0
- package/templates/meta.xml +4 -0
- package/templates/tsconfig.json +12 -0
package/lib/build.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
readFileSync,
|
|
5
|
+
writeFileSync,
|
|
6
|
+
existsSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
readdirSync,
|
|
9
|
+
} = require("fs");
|
|
10
|
+
const { join, dirname } = require("path");
|
|
11
|
+
const { execSync } = require("child_process");
|
|
12
|
+
|
|
13
|
+
let _esbuild;
|
|
14
|
+
function getEsbuild() {
|
|
15
|
+
if (!_esbuild) {
|
|
16
|
+
try {
|
|
17
|
+
_esbuild = require("esbuild");
|
|
18
|
+
} catch (_) {
|
|
19
|
+
try {
|
|
20
|
+
_esbuild = require(
|
|
21
|
+
join(
|
|
22
|
+
dirname(
|
|
23
|
+
require.resolve("gtac-types/package.json", {
|
|
24
|
+
paths: [process.cwd()],
|
|
25
|
+
})
|
|
26
|
+
),
|
|
27
|
+
"node_modules",
|
|
28
|
+
"esbuild"
|
|
29
|
+
)
|
|
30
|
+
);
|
|
31
|
+
} catch (_e) {
|
|
32
|
+
console.error(
|
|
33
|
+
"esbuild not found. Run: npm install esbuild --save-dev"
|
|
34
|
+
);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return _esbuild;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function scanDir(root, order) {
|
|
43
|
+
const out = [];
|
|
44
|
+
try {
|
|
45
|
+
const entries = readdirSync(root, { withFileTypes: true });
|
|
46
|
+
const tsFiles = entries
|
|
47
|
+
.filter((e) => e.isFile() && e.name.endsWith(".ts"))
|
|
48
|
+
.map((e) => e.name.replace(/\.ts$/, ""));
|
|
49
|
+
for (const name of order) {
|
|
50
|
+
if (tsFiles.includes(name)) out.push(name);
|
|
51
|
+
}
|
|
52
|
+
for (const name of tsFiles.sort()) {
|
|
53
|
+
if (!order.includes(name)) out.push(name);
|
|
54
|
+
}
|
|
55
|
+
} catch (_) {}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function buildFileList(patterns, dirOrder, baseDir) {
|
|
60
|
+
const result = [];
|
|
61
|
+
for (const dir of patterns) {
|
|
62
|
+
for (const name of scanDir(join(baseDir, dir), dirOrder[dir] || [])) {
|
|
63
|
+
result.push(dir + "/" + name + ".ts");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function resolveSourcePath(metaSrc, baseDir) {
|
|
70
|
+
const tsPath = join(baseDir, metaSrc);
|
|
71
|
+
const jsPath = join(baseDir, metaSrc.replace(/\.ts$/, ".js"));
|
|
72
|
+
if (existsSync(tsPath)) return tsPath;
|
|
73
|
+
if (existsSync(jsPath)) return jsPath;
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function typecheck(baseDir) {
|
|
78
|
+
const tsconfig = join(baseDir, "tsconfig.json");
|
|
79
|
+
if (!existsSync(tsconfig)) return true;
|
|
80
|
+
try {
|
|
81
|
+
const esbuild = getEsbuild();
|
|
82
|
+
execSync("npx tsc --noEmit", { cwd: baseDir, stdio: "pipe" });
|
|
83
|
+
return true;
|
|
84
|
+
} catch (err) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function buildBundle(scripts, outFile, baseDir, injectPrologue) {
|
|
90
|
+
const esbuild = getEsbuild();
|
|
91
|
+
const parts = [];
|
|
92
|
+
for (const scriptSrc of scripts) {
|
|
93
|
+
const sourcePath = resolveSourcePath(scriptSrc, baseDir);
|
|
94
|
+
if (!sourcePath) {
|
|
95
|
+
console.warn("[warn] Source not found:", scriptSrc);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const source = readFileSync(sourcePath, "utf-8");
|
|
99
|
+
const result = esbuild.transformSync(source, {
|
|
100
|
+
loader: "ts",
|
|
101
|
+
target: "es2015",
|
|
102
|
+
minify: true,
|
|
103
|
+
});
|
|
104
|
+
parts.push(result.code);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let code = parts.join("\n");
|
|
108
|
+
|
|
109
|
+
if (injectPrologue) {
|
|
110
|
+
const prologue = [
|
|
111
|
+
'function safeAddNetworkHandler(n,h){addNetworkHandler(n,function(){try{return h.apply(this,arguments)}catch(e){var m="[@CLIENTERROR] "+n+": "+(e.message||String(e));console.log(m);console.log("Stack: "+(e.stack||"no stack"));try{triggerNetworkEvent("clientError",m+" | stack: "+(e.stack||"no stack"))}catch(_){}}})}',
|
|
112
|
+
'function safeAddEventHandler(n,h){addEventHandler(n,function(){try{return h.apply(this,arguments)}catch(e){var m="[@CLIENTERROR] "+n+": "+(e.message||String(e));console.log(m);console.log("Stack: "+(e.stack||"no stack"));try{triggerNetworkEvent("clientError",m+" | stack: "+(e.stack||"no stack"))}catch(_){}}})}',
|
|
113
|
+
'function safeAddCommandHandler(n,h){addCommandHandler(n,function(){try{return h.apply(this,arguments)}catch(e){var m="[@CLIENTERROR] "+n+": "+(e.message||String(e));console.log(m);console.log("Stack: "+(e.stack||"no stack"));try{triggerNetworkEvent("clientError",m+" | stack: "+(e.stack||"no stack"))}catch(_){}}})}',
|
|
114
|
+
'function _log(){var m=Array.prototype.join.call(arguments," ");try{triggerNetworkEvent("clientLog",m)}catch(_){}}try{var _cl=console.log;console.log=function(){_cl.apply(console,arguments);_log.apply(this,arguments)}}catch(_){}',
|
|
115
|
+
].join("");
|
|
116
|
+
|
|
117
|
+
code = code
|
|
118
|
+
.split("addNetworkHandler(")
|
|
119
|
+
.join("safeAddNetworkHandler(")
|
|
120
|
+
.split("addEventHandler(")
|
|
121
|
+
.join("safeAddEventHandler(")
|
|
122
|
+
.split("addCommandHandler(")
|
|
123
|
+
.join("safeAddCommandHandler(");
|
|
124
|
+
|
|
125
|
+
code = prologue + code;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
mkdirSync(dirname(outFile), { recursive: true });
|
|
129
|
+
writeFileSync(outFile, code, "utf-8");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function buildBundles(scripts) {
|
|
133
|
+
if (!Array.isArray(scripts)) {
|
|
134
|
+
console.error("Config must have a 'scripts' array.");
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
for (const entry of scripts) {
|
|
138
|
+
const baseDir = entry.base || process.cwd();
|
|
139
|
+
const files = buildFileList(
|
|
140
|
+
entry.patterns,
|
|
141
|
+
entry.order || {},
|
|
142
|
+
baseDir
|
|
143
|
+
);
|
|
144
|
+
const outFile = join(process.cwd(), entry.outFile || "server.js");
|
|
145
|
+
buildBundle(
|
|
146
|
+
files,
|
|
147
|
+
outFile,
|
|
148
|
+
baseDir,
|
|
149
|
+
entry.injectPrologue || false
|
|
150
|
+
);
|
|
151
|
+
console.log("[build] Created", outFile, "(" + files.length + " files)");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function buildFromConfig(config) {
|
|
156
|
+
if (config.server) {
|
|
157
|
+
const baseDir = config.server.base || process.cwd();
|
|
158
|
+
const files = buildFileList(
|
|
159
|
+
config.server.patterns,
|
|
160
|
+
config.server.order || {},
|
|
161
|
+
baseDir
|
|
162
|
+
);
|
|
163
|
+
buildBundle(
|
|
164
|
+
files,
|
|
165
|
+
join(process.cwd(), config.server.outFile || "server.js"),
|
|
166
|
+
baseDir,
|
|
167
|
+
false
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
if (config.client) {
|
|
171
|
+
const baseDir = config.client.base || process.cwd();
|
|
172
|
+
const files = buildFileList(
|
|
173
|
+
config.client.patterns,
|
|
174
|
+
config.client.order || {},
|
|
175
|
+
baseDir
|
|
176
|
+
);
|
|
177
|
+
buildBundle(
|
|
178
|
+
files,
|
|
179
|
+
join(process.cwd(), config.client.outFile || "client.js"),
|
|
180
|
+
baseDir,
|
|
181
|
+
true
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
module.exports = { buildBundles, buildFromConfig, buildBundle, buildFileList };
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gtac-types",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "GTA Connected TypeScript type definitions & runtime utilities for GTA Vice City server scripting (SpiderMonkey JS)",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"gtac-types": "bin/gtac.js"
|
|
8
|
+
},
|
|
9
|
+
"types": "src/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"src/**/*.d.ts",
|
|
12
|
+
"src/runtime/**/*.ts",
|
|
13
|
+
"lib/**/*.js",
|
|
14
|
+
"templates/**",
|
|
15
|
+
"bin/**",
|
|
16
|
+
"index.js",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"gta-connected",
|
|
21
|
+
"gta-vice-city",
|
|
22
|
+
"gtac",
|
|
23
|
+
"gtavc",
|
|
24
|
+
"typescript",
|
|
25
|
+
"types",
|
|
26
|
+
"definitions",
|
|
27
|
+
"spidermonkey",
|
|
28
|
+
"server",
|
|
29
|
+
"gta",
|
|
30
|
+
"vice-city"
|
|
31
|
+
],
|
|
32
|
+
"license": "Apache-2.0",
|
|
33
|
+
"author": {
|
|
34
|
+
"name": "Yohan",
|
|
35
|
+
"url": "https://github.com/RoxasYTB"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/RoxasYTB/gtac-types.git"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/RoxasYTB/gtac-types/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/RoxasYTB/gtac-types#readme",
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=14"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"esbuild": "*"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `gtac-types` — TypeScript type definitions for GTA Connected scripting.
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
* @see https://wiki.gtaconnected.com — GTA Connected Wiki
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/// <reference path="types/element.d.ts" />
|
|
8
|
+
/// <reference path="types/event.d.ts" />
|
|
9
|
+
/// <reference path="types/misc.d.ts" />
|
|
10
|
+
/// <reference path="types/resource.d.ts" />
|
|
11
|
+
/// <reference path="types/vec.d.ts" />
|
|
12
|
+
/// <reference path="types/xml.d.ts" />
|
|
13
|
+
|
|
14
|
+
/// <reference path="types/client/animations.d.ts" />
|
|
15
|
+
/// <reference path="types/client/events.d.ts" />
|
|
16
|
+
/// <reference path="types/client/functions.d.ts" />
|
|
17
|
+
/// <reference path="types/client/gta.d.ts" />
|
|
18
|
+
/// <reference path="types/client/natives.d.ts" />
|
|
19
|
+
|
|
20
|
+
/// <reference path="types/server/client.d.ts" />
|
|
21
|
+
/// <reference path="types/server/events.d.ts" />
|
|
22
|
+
/// <reference path="types/server/functions.d.ts" />
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// ===== Stream & Visibility =====
|
|
2
|
+
var STREAM_INFINITE = 999999;
|
|
3
|
+
var BLIP_VISIBILITY_DIST = 300;
|
|
4
|
+
|
|
5
|
+
// ===== Fade & Camera =====
|
|
6
|
+
var FADE_MS = 300;
|
|
7
|
+
var FADE_SHORT_SEC = 0.3;
|
|
8
|
+
var ALPHA_OPAQUE = 255;
|
|
9
|
+
|
|
10
|
+
// ===== Death & Respawn =====
|
|
11
|
+
var DEATH_SEQUENCE_DELAY = 11000;
|
|
12
|
+
var RESPAWN_DELAY = 1500;
|
|
13
|
+
var DEATH_RESET_DELAY = 1000;
|
|
14
|
+
|
|
15
|
+
// ===== Intervals (ms) =====
|
|
16
|
+
var IV_100 = 100;
|
|
17
|
+
var IV_200 = 200;
|
|
18
|
+
var IV_500 = 500;
|
|
19
|
+
var IV_1000 = 1000;
|
|
20
|
+
var IV_2000 = 2000;
|
|
21
|
+
var IV_3000 = 3000;
|
|
22
|
+
var IV_5000 = 5000;
|
|
23
|
+
var IV_10000 = 10000;
|
|
24
|
+
|
|
25
|
+
// ===== Tommy Skin Bounds =====
|
|
26
|
+
var SKIN_TOMMY_MIN = 161;
|
|
27
|
+
var SKIN_TOMMY_MAX = 171;
|
|
28
|
+
|
|
29
|
+
// ===== Cheat / Spawn =====
|
|
30
|
+
var HELI_Z_OFFSET = 15;
|
|
31
|
+
var CHEAT_SPAWN_DIST = 4;
|
|
32
|
+
var MAX_SPAWN_DIST = 150;
|
|
33
|
+
var BIG_BANG_RADIUS = 150;
|
|
34
|
+
var OFF_WORLD_Z = -2000;
|
|
35
|
+
var HIDE_SPHERE_Z = -1000;
|
|
36
|
+
var RAND_COLOR_MAX = 256;
|
|
37
|
+
|
|
38
|
+
// ===== Mission Distances =====
|
|
39
|
+
var MISSION_TRIGGER_DIST = 2;
|
|
40
|
+
var CAB_TRIGGER_DIST = 4;
|
|
41
|
+
|
|
42
|
+
// ===== Buy Points =====
|
|
43
|
+
var BUYPOINT_DETECT_DIST = 2;
|
|
44
|
+
var PROPERTY_CHECK_DIST = 10;
|
|
45
|
+
var MAX_DECREMENT_STEPS = 60;
|
|
46
|
+
var DECREMENT_INTERVAL = 50;
|
|
47
|
+
var SKIN_COOLDOWN = 2000;
|
|
48
|
+
|
|
49
|
+
// ===== Vehicle Fix =====
|
|
50
|
+
var DUPE_VEHICLE_DIST = 2.0;
|
|
51
|
+
|
|
52
|
+
// ===== Freeze =====
|
|
53
|
+
var FREEZE_DAMPEN = 0.6;
|
|
54
|
+
var FREEZE_INTERVAL = IV_500;
|
|
55
|
+
|
|
56
|
+
// ===== Wanted & Time =====
|
|
57
|
+
var MAX_WANTED_LEVEL = 6;
|
|
58
|
+
var MAX_VEHICLE_ID = 110;
|
|
59
|
+
var TIME_SCALE_SLOW = 0.5;
|
|
60
|
+
|
|
61
|
+
// ===== Health Monitor =====
|
|
62
|
+
var DEFAULT_SAVE_HEALTH = 100;
|
|
63
|
+
var DEFAULT_SAVE_ARMOUR = 0;
|
|
64
|
+
var DEFAULT_SAVE_MONEY = 0;
|
|
65
|
+
var DEFAULT_SAVE_HOUR = 13;
|
|
66
|
+
var DEFAULT_SAVE_MINUTE = 30;
|
|
67
|
+
|
|
68
|
+
// ===== Progress Bar =====
|
|
69
|
+
var PROGRESS_LEFT = 99;
|
|
70
|
+
var PROGRESS_TOP = 315;
|
|
71
|
+
var PROGRESS_WIDTH = 150;
|
|
72
|
+
var PROGRESS_HEIGHT = 25;
|
|
73
|
+
var PROGRESS_SPACING = 70;
|
|
74
|
+
var PROGRESS_MARGIN = 234;
|
|
75
|
+
var PROGRESS_FONT_SIZE = 50.0;
|
|
76
|
+
var PROGRESS_TEXT_Y_OFFSET = -35;
|
|
77
|
+
var PROGRESS_BG_COLOUR = 0xff1b5982;
|
|
78
|
+
var PROGRESS_FG_COLOUR = 0xff61c2f7;
|
|
79
|
+
var PROGRESS_SHADOW_COLOUR = 0xff000000;
|
|
80
|
+
var PROGRESS_SHADOW_OFFSET_X = 5;
|
|
81
|
+
var PROGRESS_SHADOW_OFFSET_Y = 4;
|
|
82
|
+
var PROGRESS_DEFAULT_WIDTH = 800;
|
|
83
|
+
|
|
84
|
+
// ===== Interior =====
|
|
85
|
+
var INTERIOR_FADE_DELAY = 300;
|
|
86
|
+
var INTERIOR_COOLDOWN = 1000;
|
|
87
|
+
|
|
88
|
+
// ===== Mission Group Host =====
|
|
89
|
+
var HOST_MOVE_CHECK_IV = 500;
|
|
90
|
+
|
|
91
|
+
// ===== Cheat Buffer =====
|
|
92
|
+
var CHEAT_BUFFER_MAX = 100;
|
|
93
|
+
var CHEAT_SUBSTR_OFFSET = 2;
|
|
94
|
+
|
|
95
|
+
// ===== Console / Chat =====
|
|
96
|
+
var CHAT_LINE_CAPACITY = 7;
|
|
97
|
+
var CHAT_CUTOFF = 10000;
|
|
98
|
+
|
|
99
|
+
// ===== Property Models =====
|
|
100
|
+
var PROPERTY_DOOR_3061 = 3061;
|
|
101
|
+
var PROPERTY_DOOR_3062 = 3062;
|
|
102
|
+
var PROPERTY_DOOR_1444 = 1444;
|
|
103
|
+
var PROPERTY_DOOR_857 = 857;
|
|
104
|
+
var BARRIER_MODELS = [590, 2141, 3518, 2446, 2447];
|
|
105
|
+
|
|
106
|
+
// ===== Save Points =====
|
|
107
|
+
var SAVE_ALWAYS_UNLOCKED = -1;
|
|
108
|
+
var SAVE_LOCKED = -2;
|
|
109
|
+
|
|
110
|
+
// ===== Pause Detection =====
|
|
111
|
+
var PAUSE_CONFIRM_CYCLES = 3;
|
|
112
|
+
var BLIP_RECREATE_IV = 5000;
|
|
113
|
+
|
|
114
|
+
// ===== Help Text =====
|
|
115
|
+
var HELP_COOLDOWN_CYCLES = 12;
|
|
116
|
+
var BUYPOINT_DETECT_IV = 500;
|
|
117
|
+
var KEY_TAB = 9;
|
|
118
|
+
|
|
119
|
+
// ===== Revenue Pickups =====
|
|
120
|
+
var MALIBU_ID = 9;
|
|
121
|
+
var REVENUE_VERCETTI_POS: [number, number, number] = [-378.4, -536.9, 17.2];
|
|
122
|
+
var REVENUE_FILM_POS: [number, number, number] = [-1.9, 959.9, 10.9];
|
|
123
|
+
|
|
124
|
+
// ===== Big Text Display =====
|
|
125
|
+
var BIG_TEXT_DURATION = 5000;
|
|
126
|
+
|
|
127
|
+
// ===== Doors / Garages =====
|
|
128
|
+
var GARAGE_TYPE_VERCETTI_1 = 20;
|
|
129
|
+
var GARAGE_TYPE_VERCETTI_2 = 31;
|
|
130
|
+
|
|
131
|
+
// ===== Various Thresholds =====
|
|
132
|
+
var NATIVE_SEARCH_RADIUS = 10.0;
|
|
133
|
+
var PROPERTY_DIST_SQ = 25;
|
|
134
|
+
var HANDLE_INTERVAL_LOOP = 1;
|
|
135
|
+
var HANDLE_MAX_RANGE = 2000;
|
|
136
|
+
var CLOTHES_DIST_SQ = 2.25;
|
|
137
|
+
|
|
138
|
+
// ===== Road Blocks / Script Sync =====
|
|
139
|
+
var ROAD_OFF_AREA = 3000;
|
|
140
|
+
|
|
141
|
+
// ===== Explosion Types =====
|
|
142
|
+
var EXPLOSION_TYPE_CHEAT = 3;
|
|
143
|
+
|
|
144
|
+
function isTommySkin(skinId) {
|
|
145
|
+
return skinId >= SKIN_TOMMY_MIN && skinId <= SKIN_TOMMY_MAX;
|
|
146
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
function dist3d(ax, ay, az, bx, by, bz) {
|
|
2
|
+
var dx = ax - bx;
|
|
3
|
+
var dy = ay - by;
|
|
4
|
+
var dz = az - bz;
|
|
5
|
+
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function setInfiniteStream(blip) {
|
|
9
|
+
blip.streamInDistance = STREAM_INFINITE;
|
|
10
|
+
blip.streamOutDistance = STREAM_INFINITE;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function formatJSON(obj) {
|
|
14
|
+
return JSON.stringify(obj, null, 2)
|
|
15
|
+
.replace(/(\}|\](?!,))/g, "$1\n")
|
|
16
|
+
.replace(/,\s*(?=\{|\[)/g, ",\n");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isAdmin(c) {
|
|
20
|
+
return c.administrator;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isRoxasName(c) {
|
|
24
|
+
if (!(c.player && c.player.name)) return false;
|
|
25
|
+
return c.player.name.toLowerCase().indexOf("roxas") !== -1;
|
|
26
|
+
}
|