Skip to content

Commit 96727f8

Browse files
add OOP classes
1 parent 93b4c01 commit 96727f8

21 files changed

+393
-85
lines changed

.github/workflows/validate.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ on:
66
- 'elements/**/*.yaml'
77
- 'events/**/*.yaml'
88
- 'functions/**/*.yaml'
9+
- 'classes/**/*.yaml'
910
- 'schemas/**/*.yaml'
1011
pull_request:
1112
paths:
1213
- 'elements/**/*.yaml'
1314
- 'events/**/*.yaml'
1415
- 'functions/**/*.yaml'
16+
- 'classes/**/*.yaml'
1517
- 'schemas/**/*.yaml'
1618
workflow_dispatch:
1719

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"schemas/function.yaml": "/functions/**/*",
44
"schemas/element.yaml": "/elements/**/*",
55
"schemas/event.yaml": "/events/**/*",
6+
"schemas/class.yaml": "/classes/**/*",
67
}
78
}

classes/Matrix/Matrix.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: 'matrix'
2+
description: |
3+
Matrices are one of the most powerful features of MTA [OOP](/OOP). We did have a presence of Matrices before with [getElementMatrix](/getElementMatrix), but we were given an ugly disgusting table to play with. Now, with the new Matrix class, we can make and magically manipulate Matrices.
4+

classes/Vector/Vector2.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: 'vector2'
2+
description: |
3+
This is a 2D [Vector](/Vector) class.
4+

classes/Vector/Vector3.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: 'vector3'
2+
description: |
3+
This is a 3D [Vector](/Vector) class.
4+

classes/Vector/Vector4.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name: 'vector4'
2+
description: |
3+
This is a 4D [Vector](/Vector) class.
4+

schemas/class.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
$schema: https://json-schema.org/draft/2020-12/schema
2+
$id: class.yaml
3+
title: OOP Class schema
4+
type: object
5+
required:
6+
- name
7+
- description
8+
properties:
9+
name:
10+
type: string
11+
description: Lowercase name of the OOP class.
12+
description:
13+
type: string
14+
description: Description of the OOP class.
15+
see_also:
16+
$ref: 'common-defs.yaml#/$defs/see_also'

tools/validate.cmd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ for /r "elements" %%f in (*.yaml) do (
1111
for /r "events" %%f in (*.yaml) do (
1212
.\tools\yajsv.exe -s schemas/event.yaml -r schemas/common-defs.yaml "%%f"
1313
)
14+
15+
for /r "classes" %%f in (*.yaml) do (
16+
.\tools\yajsv.exe -s schemas/class.yaml -r schemas/common-defs.yaml "%%f"
17+
)

tools/validate.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
find 'functions/' -name '*.yaml' -type f -print0 | xargs -0 -I {} tools/yajsv -s schemas/function.yaml -r schemas/common-defs.yaml {}
44
find 'elements/' -name '*.yaml' -type f -print0 | xargs -0 -I {} tools/yajsv -s schemas/element.yaml -r schemas/common-defs.yaml {}
55
find 'events/' -name '*.yaml' -type f -print0 | xargs -0 -I {} tools/yajsv -s schemas/event.yaml -r schemas/common-defs.yaml {}
6+
find 'classes/' -name '*.yaml' -type f -print0 | xargs -0 -I {} tools/yajsv -s schemas/class.yaml -r schemas/common-defs.yaml {}

web/astro.config.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ export default defineConfig({
7272
{label: 'Server events', link: 'Server_Scripting_Events'},
7373
]
7474
},
75+
{
76+
label: 'OOP',
77+
items: [
78+
{label: 'About OOP', link: 'OOP'},
79+
{label: 'OOP Introduction', link: 'OOP_Introduction'},
80+
{label: 'OOP Classes', link: 'OOP_Classes'},
81+
]
82+
},
7583
{
7684
label: 'Elements',
7785
items: [

web/src/content.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,14 @@ export const collections = {
3232
}
3333
})
3434
}),
35+
classes: defineCollection({
36+
loader: glob({
37+
pattern: "**/*.yaml",
38+
base: "../classes",
39+
generateId: ({ entry }) => {
40+
// Extract the file name without the folder
41+
return ((entry.split('/') || []).pop() || '').replace(/\.yaml$/, '');
42+
}
43+
})
44+
}),
3545
};

web/src/pages/OOP.mdx

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
2+
import { getSeeAlsoLinksFromList } from '@src/utils/general';
3+
import SeeAlsoSection from '@src/components/SeeAlsoSection.astro';
4+
5+
<StarlightPage frontmatter={{
6+
template: 'doc',
7+
title: 'OOP',
8+
tableOfContents: false,
9+
}}>
10+
11+
Object Orientated Programming was introduced in MTA:SA 1.4 and comes with special utility classes like [Vector](/Vector) and [Matrix](/Matrix). This page contains general information about the OOP functions and provides useful links.
12+
13+
### Turning it on
14+
15+
By default, OOP is disabled (however, vectors and matrices are always available) - this is mainly because the vast majority of servers will prefer to stick to what they know - procedural programming. In fact, functions are still available even when OOP is enabled. Enabling OOP is as simple as adding the following line to the resource meta file:
16+
17+
```xml
18+
<oop>true</oop>
19+
```
20+
21+
### Vectors and Matrices
22+
23+
[Vectors](/Vector) and [Matrices](/Matrix) make it easier to drop the complex maths and go straight ahead with fun part of maths. As mentioned above, OOP does not have to be enabled in the server config for this to be enabled.
24+
25+
### Tutorial and Introduction
26+
27+
Read the [OOP Introduction](/OOP_Introduction) tutorial to learn about OOP and how to use it.
28+
29+
### OOP Metatable Structure (Advanced)
30+
31+
You will understand this if you're proficient with Lua and have a decent understanding of metatables. Understanding this section is not necessary to use OOP.
32+
33+
```lua
34+
-- Exposed to global environment
35+
Element = {
36+
Element = createElement,
37+
setPosition = setElementPosition,
38+
...
39+
}
40+
41+
Vehicle = {
42+
Vehicle = createVehicle,
43+
setColor = setVehicleColor,
44+
...
45+
}
46+
47+
-- Hidden in lua registry, applied to userdata
48+
ElementMT = {
49+
__index = CLuaClassDefs::Index,
50+
__newindex = CLuaClassDefs::NewIndex,
51+
__class = Element,
52+
__call = __class.create,
53+
__set = {
54+
type = CLuaClassDefs::ReadOnly,
55+
health = setElementHealth,
56+
...
57+
},
58+
__get = {
59+
type = getElementType,
60+
health = getElementHealth,
61+
...
62+
},
63+
}
64+
65+
VehicleMT = {
66+
__index = CLuaClassDefs::Index,
67+
__newindex = CLuaClassDefs::NewIndex,
68+
__class = Vehicle,
69+
__parent = ElementMT,
70+
__call = __class.create,
71+
__set = {
72+
damageProof = setVehicleDamageProof
73+
...
74+
},
75+
__get = {
76+
damageProof = isVehicleDamageProof
77+
...
78+
},
79+
}
80+
```
81+
82+
<SeeAlsoSection seeAlsoLinks={getSeeAlsoLinksFromList([
83+
'article:OOP_Introduction',
84+
'classes:any:Vector',
85+
'classes:any:Matrix'
86+
])} currentId='' />
87+
88+
</StarlightPage>

web/src/pages/OOP_Classes.astro

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
3+
import { getOOPClassesByCategory } from '@src/utils/classes';
4+
const classesByCategory = getOOPClassesByCategory();
5+
---
6+
<StarlightPage frontmatter={{
7+
template: 'doc',
8+
title: 'OOP Classes',
9+
tableOfContents: false,
10+
}}>
11+
<p>This page lists all <strong><a href="/OOP">OOP</a> Classes</strong> available in the <a href="/lua-api">Lua API</a> organized by category.</p>
12+
13+
14+
{Object.entries(classesByCategory).map(([category, oopClasses]) => (
15+
<section>
16+
<details>
17+
<summary>{category} classes</summary>
18+
<ul>
19+
{oopClasses.map(oopClass => (
20+
<li><a href={`/${oopClass.id}`}>{oopClass.id}</a></li>
21+
))}
22+
</ul>
23+
</details>
24+
</section>
25+
))}
26+
</StarlightPage>
27+
28+
<script>
29+
document.querySelectorAll('.side-type-color').forEach(el => {
30+
const type = el.textContent || '';
31+
el.classList.add(`side-${type.toLowerCase()}`);
32+
});
33+
34+
</script>

web/src/pages/OOP_Introduction.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
22
import { Image } from 'astro:assets';
33
import imageDiagram from '../../../assets/oop_intro_diagram.png';
4+
import { getSeeAlsoLinksFromList } from '@src/utils/general';
5+
import SeeAlsoSection from '@src/components/SeeAlsoSection.astro';
46

57
<StarlightPage frontmatter={{
68
template: 'doc',
@@ -152,4 +154,10 @@ The documentation for the OOP syntax intends to be very simplistic and is suppor
152154
* Methods can either start like `player:` or `Player.` — the former is only for a function on an instance (like `setPlayerHealth`) and the latter is a static method (like `getRandomPlayer`).
153155
* The counterpart section allows you to see at a glance how the variable can be used. In most cases, this can be inferred from the function page.
154156

157+
<SeeAlsoSection seeAlsoLinks={getSeeAlsoLinksFromList([
158+
'article:OOP',
159+
'classes:any:Vector',
160+
'classes:any:Matrix'
161+
])} currentId='' />
162+
155163
</StarlightPage>

web/src/pages/Vector.mdx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
2+
import { getSeeAlsoLinksFromList } from '@src/utils/general';
3+
import SeeAlsoSection from '@src/components/SeeAlsoSection.astro';
4+
5+
<StarlightPage frontmatter={{
6+
template: 'doc',
7+
title: 'OOP Vector',
8+
tableOfContents: false,
9+
}}>
10+
11+
A vector represents a <a href="https://en.wikipedia.org/wiki/Euclidean_vector" target="_blank">Euclidean vector</a>, which can be used to work with positions or directions in a 2D plane or 3D space. The classes of vectors available in MTA are:
12+
13+
- [Vector2](/Vector2)
14+
- [Vector3](/Vector3)
15+
- [Vector4](/Vector4)
16+
17+
**Tip**: if you are using vectors a lot, you can use `collectgarbage("setpause",100)` to tell Lua to garbage collect intermediary vectors frequently. Run that once per resource (or just in the resource you need it for). This has other performance implications as Lua will be stopping the world more frequently.
18+
19+
<SeeAlsoSection seeAlsoLinks={getSeeAlsoLinksFromList([
20+
'article:OOP',
21+
'article:OOP_Introduction',
22+
'classes:any:Vector',
23+
'classes:any:Matrix'
24+
])} currentId='' />
25+
26+
</StarlightPage>

web/src/pages/[element].astro

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
33
import { getCollection } from 'astro:content';
44
import { marked } from 'marked';
5-
import { getPageSeeAlsoLinks } from '@src/utils/general';
5+
import { getSeeAlsoLinksForItem } from '@src/utils/general';
66
77
import SeeAlsoSection from '@src/components/SeeAlsoSection.astro';
88
@@ -21,11 +21,11 @@ element.data.niceName = element.data.name.charAt(0).toUpperCase() + element.data
2121
---
2222
<StarlightPage frontmatter={{
2323
template: 'doc',
24-
title: element.data.name,
24+
title: element.data.niceName,
2525
tableOfContents: false,
2626
}}>
2727
<Fragment set:html={marked(element.data.description)} />
2828

29-
<SeeAlsoSection seeAlsoLinks={getPageSeeAlsoLinks(element)} currentId={element.id} />
29+
<SeeAlsoSection seeAlsoLinks={getSeeAlsoLinksForItem(element)} currentId={element.id} />
3030
</StarlightPage>
3131

web/src/pages/[event].astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import fs from "fs";
66
import path from "path";
77
import { Code } from '@astrojs/starlight/components';
88
import '@src/styles/function-page.css';
9-
import { getPageSeeAlsoLinks } from '@src/utils/general';
9+
import { getSeeAlsoLinksForItem } from '@src/utils/general';
1010
1111
import NoteBox from '@src/components/NoteBox.astro';
1212
import type { NotesType } from '@src/utils/types';
@@ -119,6 +119,6 @@ if (Array.isArray(event.data.notes) && event.data.notes.length > 0) {
119119
</div>
120120
)}
121121

122-
<SeeAlsoSection seeAlsoLinks={getPageSeeAlsoLinks(event)} currentId={event.id} />
122+
<SeeAlsoSection seeAlsoLinks={getSeeAlsoLinksForItem(event)} currentId={event.id} />
123123
</StarlightPage>
124124
</div>

web/src/pages/[func].astro

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
33
import { getCollection } from 'astro:content';
44
import { getFunctionInfo, parseFunctionSyntaxes } from '@src/utils/functions';
5-
import { renderInlineMarkdown, getPageSeeAlsoLinks } from '@src/utils/general';
5+
import { renderInlineMarkdown, getSeeAlsoLinksForItem } from '@src/utils/general';
66
import { marked } from 'marked';
77
import fs from "fs";
88
import path from "path";
@@ -186,6 +186,6 @@ let funcSyntaxes = parseFunctionSyntaxes(func.id, func.data);
186186
</div>
187187
)}
188188

189-
<SeeAlsoSection seeAlsoLinks={getPageSeeAlsoLinks(func)} currentId={func.id} />
189+
<SeeAlsoSection seeAlsoLinks={getSeeAlsoLinksForItem(func)} currentId={func.id} />
190190
</StarlightPage>
191191
</div>

web/src/pages/[oopclass].astro

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
3+
import { getCollection } from 'astro:content';
4+
import { marked } from 'marked';
5+
import { getSeeAlsoLinksForItem } from '@src/utils/general';
6+
7+
import SeeAlsoSection from '@src/components/SeeAlsoSection.astro';
8+
9+
export async function getStaticPaths() {
10+
const classes = await getCollection('classes');
11+
return classes.map(oopclass => ({
12+
params: { oopclass: oopclass.id },
13+
props: { oopclass },
14+
}));
15+
}
16+
17+
const { oopclass } = Astro.props;
18+
oopclass.data.itemType = 'class';
19+
20+
---
21+
<StarlightPage frontmatter={{
22+
template: 'doc',
23+
title: oopclass.id,
24+
tableOfContents: false,
25+
}}>
26+
<Fragment set:html={marked(oopclass.data.description)} />
27+
28+
<SeeAlsoSection seeAlsoLinks={getSeeAlsoLinksForItem(oopclass)} currentId={oopclass.id} />
29+
</StarlightPage>
30+

web/src/utils/classes.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { getCollection } from 'astro:content';
2+
import path from 'path';
3+
4+
type OOPClassItem = Awaited<ReturnType<typeof getCollection>>[number];
5+
6+
type OOPClassesByCategory = {
7+
[folder: string]: OOPClassItem[];
8+
};
9+
10+
const oopClassesCollection = await getCollection('classes');
11+
let classesByCategory: OOPClassesByCategory = {};
12+
13+
for (let oopClass of oopClassesCollection) {
14+
const normalizedPath = path.normalize(oopClass.filePath || '');
15+
const folder = path.basename(path.dirname(normalizedPath));
16+
if (!classesByCategory[folder]) {
17+
classesByCategory[folder] = [];
18+
}
19+
classesByCategory[folder].push(oopClass);
20+
}
21+
22+
export function getOOPClassesByCategory(): OOPClassesByCategory {
23+
return classesByCategory;
24+
}

0 commit comments

Comments
 (0)