"+i.content+""+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
+Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/};
diff --git a/.docs/web/js/site.js b/.docs/web/js/site.js
index 0375401..035a762 100644
--- a/.docs/web/js/site.js
+++ b/.docs/web/js/site.js
@@ -1,91 +1,91 @@
-
-document.addEventListener('DOMContentLoaded', function() {
- const themeToggle = document.getElementById('theme-toggle');
- const sunIcon = document.getElementById('sun-icon');
- const moonIcon = document.getElementById('moon-icon');
- if (!themeToggle || !sunIcon || !moonIcon) return;
-
- function setTheme(theme) {
- document.documentElement.setAttribute('data-theme', theme);
- localStorage.setItem('theme', theme);
- sunIcon.style.display = theme === 'light' ? 'block' : 'none';
- moonIcon.style.display = theme === 'light' ? 'none' : 'block';
- }
-
- themeToggle.addEventListener('click', function() {
- const current = document.documentElement.getAttribute('data-theme') || 'dark';
- setTheme(current === 'dark' ? 'light' : 'dark');
- });
-
- // Initialize
- const saved = localStorage.getItem('theme') || 'dark';
- setTheme(saved);
-
- // Set side-nav-title to the first h1's text
- var h1 = document.querySelector('.content-wrapper h1');
- var sideNavTitle = document.querySelector('.side-nav-title');
- if (h1 && sideNavTitle) {
- sideNavTitle.textContent = h1.textContent;
- }
-});
-
-// Highlight sidenav link on scroll (shared for all pages)
-function setupSideNavHighlight() {
- const navLinks = document.querySelectorAll('.side-nav a');
- if (!navLinks.length) return;
- const sections = Array.from(navLinks).map(link => {
- const id = link.getAttribute('href').replace('#', '');
- return document.getElementById(id);
- });
- function getHeaderOffset() {
- const header = document.querySelector('header');
- return header ? header.offsetHeight : 0;
- }
- // Custom scroll on nav click
- navLinks.forEach((link, i) => {
- link.addEventListener('click', function(e) {
- const section = sections[i];
- if (section) {
- e.preventDefault();
- const headerOffset = getHeaderOffset();
- const targetY = window.innerHeight * 0.10;
- const sectionTop = section.getBoundingClientRect().top + window.scrollY;
- const scrollTo = sectionTop - headerOffset - targetY;
- window.scrollTo({ top: scrollTo, behavior: 'smooth' });
- }
- });
- });
- function onScroll() {
- const headerOffset = getHeaderOffset();
- const targetY = window.innerHeight * 0.1; // 30% from the top
- let closestIdx = 0;
- let minDist = Infinity;
- for (let i = 0; i < sections.length; i++) {
- const section = sections[i];
- if (section) {
- const dist = Math.abs(section.getBoundingClientRect().top - headerOffset - targetY);
- if (dist < minDist) {
- minDist = dist;
- closestIdx = i;
- }
- }
- }
- navLinks.forEach((link, i) => {
- if (i === closestIdx) {
- link.classList.add('active');
- } else {
- link.classList.remove('active');
- }
- });
- }
- window.addEventListener('scroll', onScroll, { passive: true });
- window.addEventListener('resize', onScroll);
- onScroll(); // Initial call
-}
-
-// Run on DOMContentLoaded
-if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', setupSideNavHighlight);
-} else {
- setupSideNavHighlight();
+
+document.addEventListener('DOMContentLoaded', function() {
+ const themeToggle = document.getElementById('theme-toggle');
+ const sunIcon = document.getElementById('sun-icon');
+ const moonIcon = document.getElementById('moon-icon');
+ if (!themeToggle || !sunIcon || !moonIcon) return;
+
+ function setTheme(theme) {
+ document.documentElement.setAttribute('data-theme', theme);
+ localStorage.setItem('theme', theme);
+ sunIcon.style.display = theme === 'light' ? 'block' : 'none';
+ moonIcon.style.display = theme === 'light' ? 'none' : 'block';
+ }
+
+ themeToggle.addEventListener('click', function() {
+ const current = document.documentElement.getAttribute('data-theme') || 'dark';
+ setTheme(current === 'dark' ? 'light' : 'dark');
+ });
+
+ // Initialize
+ const saved = localStorage.getItem('theme') || 'dark';
+ setTheme(saved);
+
+ // Set side-nav-title to the first h1's text
+ var h1 = document.querySelector('.content-wrapper h1');
+ var sideNavTitle = document.querySelector('.side-nav-title');
+ if (h1 && sideNavTitle) {
+ sideNavTitle.textContent = h1.textContent;
+ }
+});
+
+// Highlight sidenav link on scroll (shared for all pages)
+function setupSideNavHighlight() {
+ const navLinks = document.querySelectorAll('.side-nav a');
+ if (!navLinks.length) return;
+ const sections = Array.from(navLinks).map(link => {
+ const id = link.getAttribute('href').replace('#', '');
+ return document.getElementById(id);
+ });
+ function getHeaderOffset() {
+ const header = document.querySelector('header');
+ return header ? header.offsetHeight : 0;
+ }
+ // Custom scroll on nav click
+ navLinks.forEach((link, i) => {
+ link.addEventListener('click', function(e) {
+ const section = sections[i];
+ if (section) {
+ e.preventDefault();
+ const headerOffset = getHeaderOffset();
+ const targetY = window.innerHeight * 0.10;
+ const sectionTop = section.getBoundingClientRect().top + window.scrollY;
+ const scrollTo = sectionTop - headerOffset - targetY;
+ window.scrollTo({ top: scrollTo, behavior: 'smooth' });
+ }
+ });
+ });
+ function onScroll() {
+ const headerOffset = getHeaderOffset();
+ const targetY = window.innerHeight * 0.1; // 30% from the top
+ let closestIdx = 0;
+ let minDist = Infinity;
+ for (let i = 0; i < sections.length; i++) {
+ const section = sections[i];
+ if (section) {
+ const dist = Math.abs(section.getBoundingClientRect().top - headerOffset - targetY);
+ if (dist < minDist) {
+ minDist = dist;
+ closestIdx = i;
+ }
+ }
+ }
+ navLinks.forEach((link, i) => {
+ if (i === closestIdx) {
+ link.classList.add('active');
+ } else {
+ link.classList.remove('active');
+ }
+ });
+ }
+ window.addEventListener('scroll', onScroll, { passive: true });
+ window.addEventListener('resize', onScroll);
+ onScroll(); // Initial call
+}
+
+// Run on DOMContentLoaded
+if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', setupSideNavHighlight);
+} else {
+ setupSideNavHighlight();
}
\ No newline at end of file
diff --git a/.docs/web/pages/about_us.html b/.docs/web/pages/about_us.html
index 298cd7b..afd97cf 100644
--- a/.docs/web/pages/about_us.html
+++ b/.docs/web/pages/about_us.html
@@ -37,10 +37,8 @@
Even though, at the time of writing this, I've written every single line of code myself, I could not have done it without the help of these members.
Therefore it's something WE created.
- Our goal was very simple, make it possible to make big dynamic missions, without having to either give away all controll or having to get knee deep into scripting.
- We struck a balance.
-
-
+ Our goal was very simple, make it possible to make big dynamic missions, without having to either give away all control or having to get knee deep into scripting.
+ We struck a balance.
diff --git a/.docs/web/pages/first-start.html b/.docs/web/pages/first-start.html
index 4c68496..917e450 100644
--- a/.docs/web/pages/first-start.html
+++ b/.docs/web/pages/first-start.html
@@ -90,13 +90,13 @@
Missions are also defined by trigger zones.
They'll be picked up by Spearhead when named according to the naming convention:
MISSION_[Type]_[FreeForm]
- Where [Type] is the type of mission.
+ Where [Type] is the type of mission. See all
CAS
- Personally CAS is one of our favorite mission types.
+ Personally CAS is one of my favorite mission types.
Mostly because it's easy to set up and creates a truly immersive experience.
diff --git a/.docs/web/pages/reference.html b/.docs/web/pages/reference.html
index 01e2bf8..34a1228 100644
--- a/.docs/web/pages/reference.html
+++ b/.docs/web/pages/reference.html
@@ -80,11 +80,22 @@
Example: MISSION_DEAD_BYRON
- Missions are completable objectives with specific types, such as DEAD, BAI, STRIKE, or SAM.
+ Missions are completable objectives with specific types.
Randomized missions can be defined using the format: RANDOMMISSION_[Type]_[Name]_[Index] .
+
+ Valid Types:
+
+ SAM
+ DEAD
+ BAI
+ CAS
+ STRIKE
+
+
+
CAP Routes
Format: CAPROUTE_[routeID]_[Name]
diff --git a/.docs/web/pages/spearheadapi.html b/.docs/web/pages/spearheadapi.html
index 3965b3f..3ce88c9 100644
--- a/.docs/web/pages/spearheadapi.html
+++ b/.docs/web/pages/spearheadapi.html
@@ -1,60 +1,60 @@
-
-
-
-
-
-
- Spearhead API
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Spearhead API
-
-
-
NOTE: The Spearhead.API space is only released in the Beta branch at the moment.
-
-
-
Introduction
-
- The Spearhead.API space is specifically created to make sure mission makers can interact with the framework.
-
-
- Simply alter logic, get the current state in Spearhead, and give the whole Mission Editor more control.
-
-
- For example, late activate the entire framework by calling Spearhead.API.Stages.changeStage (1 ) later or on demand and setting the starting config stage to -1 in the Spearhead configuration file.
-
-
-
Stages
-
- @@API_CODE@@
-
-
-
-
-
- © 2025 Spearhead Project
-
-
-
-
+
+
+
+
+
+
+ Spearhead API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Spearhead API
+
+
+
NOTE: The Spearhead.API space is only released in the Beta branch at the moment.
+
+
+
Introduction
+
+ The Spearhead.API space is specifically created to make sure mission makers can interact with the framework.
+
+
+ Simply alter logic, get the current state in Spearhead, and give the whole Mission Editor more control.
+
+
+ For example, late activate the entire framework by calling Spearhead.API.Stages.changeStage (1 ) later or on demand and setting the starting config stage to -1 in the Spearhead configuration file.
+
+
+
Stages
+
+ @@API_CODE@@
+
+
+
+
+
+ © 2025 Spearhead Project
+
+
+
+
\ No newline at end of file
diff --git a/.docs/web/pages/tutorials.html b/.docs/web/pages/tutorials.html
index 218cbbb..7ae7177 100644
--- a/.docs/web/pages/tutorials.html
+++ b/.docs/web/pages/tutorials.html
@@ -41,7 +41,7 @@
Download the latest version of Spearhead. You can choose which version you feel comfortable with.
Versions that end in -rc are not stable. Versions that do not have the "release candidate" (rc) tag are.
- See All releases here
+ See All releases here
diff --git a/.docs/web/style/prism.css b/.docs/web/style/prism.css
index f3b8295..6d98055 100644
--- a/.docs/web/style/prism.css
+++ b/.docs/web/style/prism.css
@@ -1,3 +1,3 @@
-/* PrismJS 1.30.0
-https://prismjs.com/download#themes=prism-okaidia&languages=lua */
-code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
+/* PrismJS 1.30.0
+https://prismjs.com/download#themes=prism-okaidia&languages=lua */
+code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}