custom drawings and animations for video
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,721 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor",
|
||||
"elements": [
|
||||
{
|
||||
"id": "HiVK1huIbL16ZCy3rz5t8",
|
||||
"type": "rectangle",
|
||||
"x": 1622.7441591132324,
|
||||
"y": 984.6777917946865,
|
||||
"width": 1578.7433546522943,
|
||||
"height": 836.7851776620863,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2L",
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 645107296,
|
||||
"version": 227,
|
||||
"versionNonce": 1642809248,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "lTQAmT-q3EhB8l4OFoV4r",
|
||||
"type": "rectangle",
|
||||
"x": 2308.0518724509566,
|
||||
"y": 1544.7916707023237,
|
||||
"width": 211.02211156486123,
|
||||
"height": 96.5527520526872,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2M",
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 28492384,
|
||||
"version": 449,
|
||||
"versionNonce": 702648928,
|
||||
"isDeleted": false,
|
||||
"boundElements": [
|
||||
{
|
||||
"id": "23RNiECmee0GZfyG42WJU",
|
||||
"type": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "AS-wLfqmrJICLegtTjwKA",
|
||||
"type": "arrow"
|
||||
}
|
||||
],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "9aRWFt8Ol6hDDEvOstOxf",
|
||||
"type": "text",
|
||||
"x": 2340.7060558234443,
|
||||
"y": 1563.9495282342684,
|
||||
"width": 154.26666259765625,
|
||||
"height": 55.62747030529269,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2N",
|
||||
"roundness": null,
|
||||
"seed": 384530016,
|
||||
"version": 204,
|
||||
"versionNonce": 2083905440,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "Mission",
|
||||
"fontSize": 44.50197624423415,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Mission",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "23RNiECmee0GZfyG42WJU",
|
||||
"type": "arrow",
|
||||
"x": 2519.9815623115946,
|
||||
"y": 1608.9632387014556,
|
||||
"width": 185.6851361459012,
|
||||
"height": 84.58953522783993,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2O",
|
||||
"roundness": {
|
||||
"type": 2
|
||||
},
|
||||
"seed": 1793960544,
|
||||
"version": 1436,
|
||||
"versionNonce": 1331590752,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
132.75987383519941,
|
||||
-15.5442452755197
|
||||
],
|
||||
[
|
||||
185.6851361459012,
|
||||
-84.58953522783993
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "lTQAmT-q3EhB8l4OFoV4r",
|
||||
"focus": 0.46767568934546344,
|
||||
"gap": 1
|
||||
},
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": false
|
||||
},
|
||||
{
|
||||
"id": "K6jAODe27_os5DPh8967u",
|
||||
"type": "text",
|
||||
"x": 2689.444812908036,
|
||||
"y": 1465.552661128815,
|
||||
"width": 222.53535431824844,
|
||||
"height": 54.779302679674046,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2P",
|
||||
"roundness": null,
|
||||
"seed": 1753833056,
|
||||
"version": 808,
|
||||
"versionNonce": 1186625440,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "The Story",
|
||||
"fontSize": 43.823442143739236,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "The Story",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "AS-wLfqmrJICLegtTjwKA",
|
||||
"type": "arrow",
|
||||
"x": 2384.330334167984,
|
||||
"y": 1544.3197414150743,
|
||||
"width": 49.364397989861686,
|
||||
"height": 80.37199821269722,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2Q",
|
||||
"roundness": {
|
||||
"type": 2
|
||||
},
|
||||
"seed": 546214496,
|
||||
"version": 1667,
|
||||
"versionNonce": 1614569056,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
-38.3710655807796,
|
||||
-28.81586470940509
|
||||
],
|
||||
[
|
||||
-49.364397989861686,
|
||||
-80.37199821269722
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "lTQAmT-q3EhB8l4OFoV4r",
|
||||
"focus": 0.21013738563944281,
|
||||
"gap": 1
|
||||
},
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": false
|
||||
},
|
||||
{
|
||||
"id": "m8Er51Ess3j92_Q_brntE",
|
||||
"type": "rectangle",
|
||||
"x": 2159.6497125177334,
|
||||
"y": 1335.721614644765,
|
||||
"width": 363.99766551946664,
|
||||
"height": 127.50624664551411,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [
|
||||
"cNSAgbnsi3PlOKVDl2tCl"
|
||||
],
|
||||
"frameId": null,
|
||||
"index": "b2R",
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"seed": 164447840,
|
||||
"version": 969,
|
||||
"versionNonce": 2063142816,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "XCGW5ooPSVuaaam9AVDz-",
|
||||
"type": "text",
|
||||
"x": 2173.9396997857207,
|
||||
"y": 1357.9865705806305,
|
||||
"width": 333.6248911062344,
|
||||
"height": 83.92658771184712,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [
|
||||
"cNSAgbnsi3PlOKVDl2tCl"
|
||||
],
|
||||
"frameId": null,
|
||||
"index": "b2S",
|
||||
"roundness": null,
|
||||
"seed": 1091926624,
|
||||
"version": 1089,
|
||||
"versionNonce": 1148591008,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "Spearhead",
|
||||
"fontSize": 67.14127016947768,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Spearhead",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "moW1_uGfHzYIjzGogGQGK",
|
||||
"type": "text",
|
||||
"x": 2104.0596241560615,
|
||||
"y": 1034.5614167492809,
|
||||
"width": 646.7199096679688,
|
||||
"height": 64.22500341608406,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2T",
|
||||
"roundness": null,
|
||||
"seed": 1228353120,
|
||||
"version": 349,
|
||||
"versionNonce": 1920051104,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "Mission making, made easy",
|
||||
"fontSize": 51.380002732867254,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Mission making, made easy",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "o2jZSQLCW3jrv6pCqie6_",
|
||||
"type": "arrow",
|
||||
"x": 2159.733022744733,
|
||||
"y": 1387.9176228888964,
|
||||
"width": 160.53319080851742,
|
||||
"height": 70.53888252157658,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2U",
|
||||
"roundness": {
|
||||
"type": 2
|
||||
},
|
||||
"seed": 1258447456,
|
||||
"version": 260,
|
||||
"versionNonce": 1897640864,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
-92.03884598362902,
|
||||
-5.663893806853778
|
||||
],
|
||||
[
|
||||
-160.53319080851742,
|
||||
-70.53888252157658
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": false
|
||||
},
|
||||
{
|
||||
"id": "W9vcoug4Anqo3kphgtT9I",
|
||||
"type": "text",
|
||||
"x": 1878.031940531582,
|
||||
"y": 1271.37874036732,
|
||||
"width": 241.1999053955078,
|
||||
"height": 45,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2V",
|
||||
"roundness": null,
|
||||
"seed": 1430722144,
|
||||
"version": 123,
|
||||
"versionNonce": 648298400,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "quick creation",
|
||||
"fontSize": 36,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "quick creation",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "vKiHSOYVz3WA8hsPa4Gz_",
|
||||
"type": "text",
|
||||
"x": 2048.097445465383,
|
||||
"y": 1156.4671681391064,
|
||||
"width": 291.2398681640625,
|
||||
"height": 45,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2W",
|
||||
"roundness": null,
|
||||
"seed": 483740256,
|
||||
"version": 118,
|
||||
"versionNonce": 859524000,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "multiplayer ready",
|
||||
"fontSize": 36,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "multiplayer ready",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "slm2yLO4dbFEB4unTSEBM",
|
||||
"type": "arrow",
|
||||
"x": 2272.711713817616,
|
||||
"y": 1335.0347744783633,
|
||||
"width": 66.5822620861594,
|
||||
"height": 126.32077628211141,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2X",
|
||||
"roundness": {
|
||||
"type": 2
|
||||
},
|
||||
"seed": 1014824544,
|
||||
"version": 263,
|
||||
"versionNonce": 823187360,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
-54.89666258783586,
|
||||
-52.65193572538732
|
||||
],
|
||||
[
|
||||
-66.5822620861594,
|
||||
-126.32077628211141
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": false
|
||||
},
|
||||
{
|
||||
"id": "AzL0eyJGalMEJhcGJm2_F",
|
||||
"type": "arrow",
|
||||
"x": 2416.5200398307725,
|
||||
"y": 1335.3880374127152,
|
||||
"width": 114.58165799006088,
|
||||
"height": 125.00113779000418,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2Y",
|
||||
"roundness": {
|
||||
"type": 2
|
||||
},
|
||||
"seed": 1963864672,
|
||||
"version": 298,
|
||||
"versionNonce": 1951720352,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1107899245286,
|
||||
-56.913107137971394
|
||||
],
|
||||
[
|
||||
114.58165799006088,
|
||||
-125.00113779000418
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": false
|
||||
},
|
||||
{
|
||||
"id": "9XYksy7fqu89wA1b8KHk4",
|
||||
"type": "text",
|
||||
"x": 2479.4611352261527,
|
||||
"y": 1164.386899622711,
|
||||
"width": 122.79595947265625,
|
||||
"height": 45,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2Z",
|
||||
"roundness": null,
|
||||
"seed": 1834542688,
|
||||
"version": 150,
|
||||
"versionNonce": 1261924256,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "flexible",
|
||||
"fontSize": 36,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "flexible",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
},
|
||||
{
|
||||
"id": "O8kJBNxfzL8ncxdD2kZRM",
|
||||
"type": "arrow",
|
||||
"x": 2527.9914421715134,
|
||||
"y": 1376.2823093418706,
|
||||
"width": 161.921133337549,
|
||||
"height": 61.23797674760587,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2a",
|
||||
"roundness": {
|
||||
"type": 2
|
||||
},
|
||||
"seed": 1915558496,
|
||||
"version": 341,
|
||||
"versionNonce": 1038646176,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
110.30502983196084,
|
||||
-8.630813890686284
|
||||
],
|
||||
[
|
||||
161.921133337549,
|
||||
-61.23797674760587
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"elbowed": false
|
||||
},
|
||||
{
|
||||
"id": "1SS8AR95vxynNN_GgSOm-",
|
||||
"type": "text",
|
||||
"x": 2670.559620709462,
|
||||
"y": 1266.635895233043,
|
||||
"width": 207.61192321777344,
|
||||
"height": 45,
|
||||
"angle": 0,
|
||||
"strokeColor": "#ffffff",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"frameId": null,
|
||||
"index": "b2b",
|
||||
"roundness": null,
|
||||
"seed": 911920736,
|
||||
"version": 322,
|
||||
"versionNonce": 1318586272,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1766927996013,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "easy to use",
|
||||
"fontSize": 36,
|
||||
"fontFamily": 5,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "easy to use",
|
||||
"autoResize": true,
|
||||
"lineHeight": 1.25
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": 20,
|
||||
"gridStep": 5,
|
||||
"gridModeEnabled": false,
|
||||
"viewBackgroundColor": "#1b1d27"
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
+78
-1
@@ -53,6 +53,83 @@ do -- env
|
||||
env = env
|
||||
end
|
||||
|
||||
do -- Mission table
|
||||
|
||||
---@class Mission
|
||||
---@field drawings Array<DrawingObject>
|
||||
|
||||
---@alias PrimitiveType
|
||||
---| "Polygon"
|
||||
---| "Line"
|
||||
---| "TextBox"
|
||||
|
||||
---@alias PolygonMode
|
||||
---| "circle"
|
||||
---| "free"
|
||||
---| "oval"
|
||||
---| "rect"
|
||||
---| "arrow"
|
||||
|
||||
---@alias LineMode
|
||||
---| "segment"
|
||||
---| "segments"
|
||||
---| "free"
|
||||
|
||||
---@class DrawingObject
|
||||
---@field primitiveType PrimitiveType
|
||||
---@field name string
|
||||
---@field visible boolean
|
||||
---@field layerName string?
|
||||
---@field mapX number
|
||||
---@field mapY number
|
||||
---@field colorString string Hex ARGB color
|
||||
---@field style string
|
||||
---@field thickness number
|
||||
|
||||
---@class Polygon : DrawingObject
|
||||
---@field polygonMode PolygonMode
|
||||
---@field fillColorString string?
|
||||
|
||||
---@class Circle : Polygon
|
||||
---@field radius number
|
||||
|
||||
---@class Free : Polygon
|
||||
---@field points Array<Vec2>
|
||||
|
||||
---@class Oval : Polygon
|
||||
---@field r1 number
|
||||
---@field r2 number
|
||||
---@field angle number?
|
||||
|
||||
---@class Rect : Polygon
|
||||
---@field width number
|
||||
---@field height number
|
||||
---@field angle number?
|
||||
|
||||
---@class Arrow : Polygon
|
||||
---@field length number
|
||||
---@field angle number?
|
||||
|
||||
---@class Line : DrawingObject
|
||||
---@field primitiveType PrimitiveType # PrimitiveType.Line
|
||||
---@field lineMode LineMode
|
||||
---@field closed boolean
|
||||
---@field points Array<Vec2>
|
||||
|
||||
---@class Segment : Line
|
||||
|
||||
---@class Segments : Line
|
||||
|
||||
---@class FreeLine : Line
|
||||
|
||||
---@class TextBox : DrawingObject
|
||||
---@field fontSize number
|
||||
---@field text string
|
||||
---@field fillColorString string
|
||||
---@field borderThickness number
|
||||
|
||||
end
|
||||
|
||||
do -- timer
|
||||
---@class timer
|
||||
---@field getTime fun() : number returns the time in the mission (in seconds. 3 decimals)
|
||||
@@ -358,7 +435,7 @@ do -- trigger
|
||||
---@field circleToAll fun(coalition: DrawCoalition, id: number, center: Vec3 , radius: number, color: table , fillColor: table , lineType: LineType , readOnly: boolean?, message: string?) Creates a circle on the map with a given radius, color, fill color, and outline.
|
||||
---@field rectToAll fun(coalition:DrawCoalition, id:number, startPoint: Vec3, endPoint:Vec3, color: table, fillColor: table, lineType: LineType , readOnly: boolean?, message: string?) Creates a rectangle on the map from the startpoint in one corner to the endPoint in the opposite corner.
|
||||
---@field quadToAll fun(coalition:DrawCoalition, id:number, point1: Vec3, point2:Vec3, point3:Vec3, point4:Vec3,color: table, fillColor: table, lineType: LineType , readOnly: boolean?, message: string?) Creates a shape defined by the 4 points on the F10 map.
|
||||
---@field textToAll fun(coalition:DrawCoalition, id: number, point:Vec3, color: table, fillColor: table, fontSize:table, readOnly:boolean, text:string) Creates a text imposed on the map at a given point. Text scales with the map.
|
||||
---@field textToAll fun(coalition:DrawCoalition, id: number, point:Vec3, color: table, fillColor: table, fontSize:number, readOnly:boolean, text:string) Creates a text imposed on the map at a given point. Text scales with the map.
|
||||
---@field arrowToAll fun(coalition:DrawCoalition, id: number, startPoint:Vec3, endPoint:Vec3, color:table, fillColor:table, lineType:LineType, readonly:boolean?, message: string?) Creates an arrow from the startPoint to the endPoint on the F10 map. The arrow will be "pointing at" the startPoint
|
||||
---@field setMarkupRadius fun(id:number, radius:number) Updates the radius of the specified mark to be the new value.
|
||||
---@field setMarkupText fun(id:number, text: string) Updates the text value of the passed mark to the passed text value.
|
||||
|
||||
@@ -18,8 +18,9 @@ class Header extends HTMLElement {
|
||||
<a href="/pages/tutorials.html">Tutorials</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="/pages/tutorials.html">Quick Starts</a>
|
||||
<a href="/pages/advanced/CAP.html">Advanced: CAP</a>
|
||||
<a href="/pages/advanced/missions.html">Advanced: Missions</a>
|
||||
<a href="/pages/advanced/CAP.html">Advanced: CAP</a>
|
||||
<a href="/pages/advanced/missions.html">Advanced: Missions</a>
|
||||
<a href="/pages/advanced/custom-drawings.html">Custom Drawings</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -63,5 +63,4 @@
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
</html>
|
||||
@@ -220,5 +220,4 @@
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
</html>
|
||||
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-theme="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Spearhead Missions</title>
|
||||
<link rel="stylesheet" href="/style/style.css">
|
||||
<script src="/js/site.js"></script>
|
||||
<style>
|
||||
.side-nav a.active {
|
||||
font-weight: bold;
|
||||
color: #4fc3f7;
|
||||
}
|
||||
</style>
|
||||
<script type="module" src="/js/components.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<app-header></app-header>
|
||||
</header>
|
||||
<main>
|
||||
<div class="reference-container">
|
||||
<app-sidebar></app-sidebar>
|
||||
|
||||
<div class="content-wrapper">
|
||||
<h1>Advanced Tutorial: Custom Drawings</h1>
|
||||
|
||||
<p>
|
||||
Drawings can be very powerful in DCS missions. <br>
|
||||
They can guide players towards the right objectives or warn them of dangers ahead. <br>
|
||||
In Spearhead, we provide an easy way to manage and update these drawings dynamically as the mission progresses. <br>
|
||||
</p>
|
||||
|
||||
<h2 id="custom_drawings_how_to">How to</h2>
|
||||
<p>
|
||||
Adding a custom drawing is easy. <br>
|
||||
Simply create the drawing and then name it according to the following convention: <br>
|
||||
<code-inline>DRAWING_[a]:[b]_[FreeForm]</starting></code-inline> <br>
|
||||
Where:
|
||||
<ul>
|
||||
<li><strong>[a]</strong> is the stage number at which the drawing should appear.</li>
|
||||
<li><strong>[b]</strong> is the stage number at which the drawing should be removed again.</li>
|
||||
<li><strong>[FreeForm]</strong> is any name you want to make it unique or findables.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<note-box type="warning" title="Author Layer">
|
||||
The custom drawings need to be in the "Author" layer of the mission editor to be managed by Spearhead.
|
||||
This is due to other layers being visible by default and cannot be as easily removed when not needed.
|
||||
The author layer is not visible by default in multiplayer, making it perfect for this use case.
|
||||
</note-box>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<footer>
|
||||
<p>© 2025 Spearhead Project</p>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -68,5 +68,4 @@
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
</html>
|
||||
@@ -123,4 +123,3 @@
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
@@ -270,11 +270,11 @@ header nav a:hover::after {
|
||||
border-radius: 8px;
|
||||
|
||||
max-height: 0px;
|
||||
transition: all 1.5s ease;
|
||||
transition: all 1s ease;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-content {
|
||||
max-height: 200px;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
header.collapsible {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
---@field MissionZoneData table<string, MissionZoneData>
|
||||
---@field FarpZoneData table<string,FarpZoneData>
|
||||
---@field missionCodes table<string, boolean>
|
||||
|
||||
---@field CustomDrawings Array<CustomDrawing>
|
||||
|
||||
---@class CapRoute
|
||||
---@field zones Array<SpearheadTriggerZone>
|
||||
@@ -99,7 +99,8 @@ function Database.New(Logger)
|
||||
MissionZoneData = {},
|
||||
FarpZoneData = {},
|
||||
missionCodes = {},
|
||||
SupplyHubZones = {}
|
||||
SupplyHubZones = {},
|
||||
CustomDrawings = {}
|
||||
}
|
||||
|
||||
Database.__index = Database
|
||||
@@ -215,6 +216,23 @@ function Database.New(Logger)
|
||||
end
|
||||
end
|
||||
|
||||
---@type table<integer, boolean>
|
||||
do -- custom drawings
|
||||
if env.mission.drawings and env.mission.drawings.layers then
|
||||
for i, layer in pairs(env.mission.drawings.layers) do
|
||||
if string.lower(layer.name) == "author" then
|
||||
for key, layer_object in pairs(layer.objects) do
|
||||
if Spearhead.Util.startswith(layer_object.name, "drawing_", true) then
|
||||
local object = layer_object --[[@as DrawingObject]]
|
||||
local customDrawing = Spearhead.classes.stageClasses.drawings.CustomDrawing.New(object)
|
||||
table.insert(self._tables.CustomDrawings, customDrawing)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@type table<string, boolean>
|
||||
local availableSupplyHubs = {}
|
||||
for _, supplyHubZoneName in pairs(self._tables.SupplyHubZones) do
|
||||
@@ -593,6 +611,14 @@ function Database:loadBlueSamUnits()
|
||||
end
|
||||
end
|
||||
|
||||
---@return Array<CustomDrawing>
|
||||
function Database:getCustomDrawings()
|
||||
if self._tables.CustomDrawings == nil then
|
||||
return {}
|
||||
end
|
||||
return self._tables.CustomDrawings
|
||||
end
|
||||
|
||||
---Loads all units, data and briefings
|
||||
---@private
|
||||
function Database:LoadZoneData(missionZoneName)
|
||||
|
||||
@@ -13,8 +13,12 @@ local WaitingStagesByIndex = {}
|
||||
|
||||
local currentStage = -99
|
||||
|
||||
|
||||
GlobalStageManager = {}
|
||||
---@class GlobalStageManager : StageCompleteListener
|
||||
---@field private database Database
|
||||
---@field private logger Logger
|
||||
---@field private stageConfig StageConfig
|
||||
local GlobalStageManager = {}
|
||||
GlobalStageManager.__index = GlobalStageManager
|
||||
|
||||
---comment
|
||||
---@param database Database
|
||||
@@ -22,13 +26,14 @@ GlobalStageManager = {}
|
||||
---@param logLevel LogLevel
|
||||
---@param spawnManager SpawnManager
|
||||
---@return nil
|
||||
function GlobalStageManager:NewAndStart(database, stageConfig, logLevel, spawnManager)
|
||||
function GlobalStageManager.NewAndStart(database, stageConfig, logLevel, spawnManager)
|
||||
local logger = Spearhead.LoggerTemplate.new("StageManager", logLevel)
|
||||
logger:info("Using Stage Log Level: " .. logLevel)
|
||||
local o = {}
|
||||
setmetatable(o, { __index = self })
|
||||
local self = setmetatable({}, GlobalStageManager)
|
||||
self.database = database
|
||||
self.stageConfig = stageConfig
|
||||
|
||||
o.logger = logger
|
||||
self.logger = logger
|
||||
if stageConfig.isAutoStages ~= true then
|
||||
logger:warn("Spearhead will not automatically progress stages due to the given settings. If you manually have implemented this, please ignore this message")
|
||||
end
|
||||
@@ -42,53 +47,6 @@ function GlobalStageManager:NewAndStart(database, stageConfig, logLevel, spawnMa
|
||||
|
||||
Spearhead.Events.AddStageNumberChangedListener(OnStageNumberChangedListener)
|
||||
|
||||
---@type StageCompleteListener
|
||||
local OnStageCompleteListener = {
|
||||
OnStageComplete = function(self, stage)
|
||||
logger:debug("Receiving stage complete event from: " .. stage.zoneName)
|
||||
|
||||
local anyIncomplete = false
|
||||
logger:debug("Checking stages for index: " .. tostring(currentStage))
|
||||
for index, stage in pairs(StagesByIndex[tostring(currentStage)]) do
|
||||
if stage:IsComplete() == false then
|
||||
anyIncomplete = true
|
||||
logger:debug("Need to wait for Stage " .. stage.zoneName .. " to be completed")
|
||||
else
|
||||
logger:debug("Stage verified to be completed: " .. stage.zoneName)
|
||||
end
|
||||
end
|
||||
|
||||
if anyIncomplete == false and stageConfig.isAutoStages == true then
|
||||
|
||||
-- CHECK WAITING STAGES
|
||||
local nextStage = currentStage + 1
|
||||
|
||||
if WaitingStagesByIndex[tostring(nextStage)] then
|
||||
for _, waitingStage in pairs(WaitingStagesByIndex[tostring(nextStage)]) do
|
||||
if waitingStage:IsActive() == false then
|
||||
waitingStage:ActivateStage()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local anyWaiting = false
|
||||
if WaitingStagesByIndex[tostring(nextStage)] then
|
||||
for _, waitingStage in pairs(WaitingStagesByIndex[tostring(nextStage)]) do
|
||||
if waitingStage:IsComplete() == false then
|
||||
anyWaiting = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if anyWaiting == false then
|
||||
logger:debug("Setting next stage to: " .. tostring(currentStage + 1))
|
||||
Spearhead.Events.PublishStageNumberChanged(currentStage + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
for _, stageName in pairs(database:getStagezoneNames()) do
|
||||
logger:debug("Found stage zone with name: " .. stageName)
|
||||
|
||||
@@ -136,13 +94,13 @@ function GlobalStageManager:NewAndStart(database, stageConfig, logLevel, spawnMa
|
||||
|
||||
if isSideStage == true then
|
||||
local stage = Spearhead.classes.stageClasses.Stages.ExtraStage.New(database, stageConfig, stagelogger, initData, spawnManager)
|
||||
stage:AddStageCompleteListener(OnStageCompleteListener)
|
||||
stage:AddStageCompleteListener(self)
|
||||
|
||||
if SideStageByIndex[tostring(orderNumber)] == nil then SideStageByIndex[tostring(orderNumber)] = {} end
|
||||
table.insert(SideStageByIndex[tostring(orderNumber)], stage)
|
||||
else
|
||||
local stage = Spearhead.classes.stageClasses.Stages.PrimaryStage.New(database, stageConfig, stagelogger, initData, spawnManager)
|
||||
stage:AddStageCompleteListener(OnStageCompleteListener)
|
||||
stage:AddStageCompleteListener(self)
|
||||
|
||||
if StagesByIndex[tostring(orderNumber)] == nil then StagesByIndex[tostring(orderNumber)] = {} end
|
||||
table.insert(StagesByIndex[tostring(orderNumber)], stage)
|
||||
@@ -193,15 +151,71 @@ function GlobalStageManager:NewAndStart(database, stageConfig, logLevel, spawnMa
|
||||
end
|
||||
table.insert(WaitingStagesByIndex[tostring(stageIndex)], waitingStage)
|
||||
|
||||
waitingStage:AddStageCompleteListener(OnStageCompleteListener)
|
||||
waitingStage:AddStageCompleteListener(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function GlobalStageManager:OnStageComplete(stage)
|
||||
self.logger:debug("Receiving stage complete event from: " .. stage.zoneName)
|
||||
|
||||
return o
|
||||
local anyIncomplete = false
|
||||
self.logger:debug("Checking stages for index: " .. tostring(currentStage))
|
||||
for index, stage in pairs(StagesByIndex[tostring(currentStage)]) do
|
||||
if stage:IsComplete() == false then
|
||||
anyIncomplete = true
|
||||
self.logger:debug("Need to wait for Stage " .. stage.zoneName .. " to be completed")
|
||||
else
|
||||
self.logger:debug("Stage verified to be completed: " .. stage.zoneName)
|
||||
end
|
||||
end
|
||||
|
||||
if anyIncomplete == false and self.stageConfig.isAutoStages == true then
|
||||
|
||||
-- CHECK WAITING STAGES
|
||||
local nextStage = currentStage + 1
|
||||
|
||||
if WaitingStagesByIndex[tostring(nextStage)] then
|
||||
for _, waitingStage in pairs(WaitingStagesByIndex[tostring(nextStage)]) do
|
||||
if waitingStage:IsActive() == false then
|
||||
waitingStage:ActivateStage()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local anyWaiting = false
|
||||
if WaitingStagesByIndex[tostring(nextStage)] then
|
||||
for _, waitingStage in pairs(WaitingStagesByIndex[tostring(nextStage)]) do
|
||||
if waitingStage:IsComplete() == false then
|
||||
anyWaiting = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if anyWaiting == false then
|
||||
local newStageNumber = currentStage + 1
|
||||
self:UpdateDrawings(newStageNumber)
|
||||
self.logger:debug("Setting next stage to: " .. tostring(newStageNumber))
|
||||
Spearhead.Events.PublishStageNumberChanged(newStageNumber)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@private
|
||||
function GlobalStageManager:UpdateDrawings(stageNumber)
|
||||
local drawings = self.database:getCustomDrawings()
|
||||
for _, drawing in pairs(drawings) do
|
||||
local startStage, stopStage = drawing:GetStartAndStop()
|
||||
if stageNumber >= startStage and stageNumber < stopStage then
|
||||
drawing:Draw()
|
||||
else
|
||||
drawing:Remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
|
||||
---@class CustomDrawing
|
||||
---@field private _id integer?
|
||||
---@field private _drawingObject DrawingObject
|
||||
---@field private _helper DrawingHelper
|
||||
---@field private _startingStage number
|
||||
---@field private _removeAtStage number
|
||||
local CustomDrawing = {}
|
||||
CustomDrawing.__index = CustomDrawing
|
||||
|
||||
|
||||
---@param drawingObject DrawingObject
|
||||
---@param id integer?
|
||||
---@return CustomDrawing
|
||||
function CustomDrawing.New(drawingObject, id)
|
||||
local self = setmetatable({}, CustomDrawing)
|
||||
self._drawingObject = drawingObject
|
||||
self._id = id
|
||||
self._helper = Spearhead.classes.stageClasses.drawings.helper.DrawingHelper
|
||||
|
||||
local name = drawingObject.name
|
||||
local split = Spearhead.Util.split_string(name or "", "_")
|
||||
local secondPart = split[2] or "1"
|
||||
local splitPart = Spearhead.Util.split_string(secondPart, ":")
|
||||
self._startingStage = tonumber(splitPart[1]) or 1
|
||||
self._removeAtStage = tonumber(splitPart[2]) or math.huge
|
||||
return self
|
||||
end
|
||||
|
||||
---@return number start
|
||||
---@return number stop
|
||||
function CustomDrawing:GetStartAndStop()
|
||||
return self._startingStage, self._removeAtStage
|
||||
end
|
||||
|
||||
function CustomDrawing:Draw()
|
||||
self._id = self._helper.Draw(self._drawingObject)
|
||||
end
|
||||
|
||||
function CustomDrawing:Remove()
|
||||
if self._id ~= nil then
|
||||
self._helper.Remove(self._id)
|
||||
self._id = nil
|
||||
end
|
||||
end
|
||||
|
||||
if not Spearhead then Spearhead = {} end
|
||||
if not Spearhead.classes then Spearhead.classes = {} end
|
||||
if not Spearhead.classes.stageClasses then Spearhead.classes.stageClasses = {} end
|
||||
if not Spearhead.classes.stageClasses.drawings then Spearhead.classes.stageClasses.drawings = {} end
|
||||
Spearhead.classes.stageClasses.drawings.CustomDrawing = CustomDrawing
|
||||
@@ -0,0 +1,228 @@
|
||||
|
||||
|
||||
---@class DrawingHelper
|
||||
local DrawingHelper = {}
|
||||
DrawingHelper.__index = DrawingHelper
|
||||
|
||||
local customDrawingIdIncrementer = 4210
|
||||
|
||||
---@param object DrawingObject
|
||||
---@return integer? id
|
||||
function DrawingHelper.Draw(object)
|
||||
if object == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
local id = DrawingHelper.GetAndAddId()
|
||||
if(object.primitiveType == "Polygon") then
|
||||
DrawingHelper.DrawPolygon(object--[[@as Polygon]], id)
|
||||
elseif(object.primitiveType == "Line") then
|
||||
DrawingHelper.DrawLine(object--[[@as Line]], id)
|
||||
elseif(object.primitiveType == "TextBox") then
|
||||
DrawingHelper.DrawTextBox(object--[[@as TextBox]], id)
|
||||
end
|
||||
|
||||
return id
|
||||
end
|
||||
|
||||
function DrawingHelper.GetAndAddId()
|
||||
customDrawingIdIncrementer = customDrawingIdIncrementer + 1
|
||||
return customDrawingIdIncrementer
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param shapeID ShapeId
|
||||
---@param drawID integer
|
||||
---@param points Array<Vec3>
|
||||
---@param fillColor table
|
||||
---@param lineColor table
|
||||
local function MarkupToAll(shapeID, drawID, points, fillColor, lineColor, lineStyle)
|
||||
|
||||
local functionString = "trigger.action.markupToAll(" .. shapeID .. ", -1, " .. drawID .. ","
|
||||
for _, point in ipairs(points) do
|
||||
functionString = functionString .. " { x=" .. point.x .. ", y=0,z=" .. point.z .. "},"
|
||||
end
|
||||
functionString = functionString ..
|
||||
"{ " .. lineColor[1] .. "," .. lineColor[2] .. "," .. lineColor[3] .. "," .. lineColor[4] .. "}, " ..
|
||||
"{ " .. fillColor[1] .. "," .. fillColor[2] .. "," .. fillColor[3] .. "," .. fillColor[4] .. "}, " ..
|
||||
lineStyle .. ")"
|
||||
|
||||
---@diagnostic disable-next-line: deprecated
|
||||
local f, err = loadstring(functionString)
|
||||
if f then
|
||||
f()
|
||||
else
|
||||
env.error("Something failed when drawing complex drawing" .. err)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param object Polygon
|
||||
---@param id integer
|
||||
function DrawingHelper.DrawPolygon(object, id)
|
||||
if object == nil then
|
||||
return
|
||||
end
|
||||
|
||||
---@param circle Circle
|
||||
local function DrawCircle(circle)
|
||||
local vec3 = { x = circle.mapX, y = 0, z = circle.mapY }
|
||||
local fillColor = DrawingHelper.ColorToColorTable(circle.fillColorString)
|
||||
local colorString = DrawingHelper.ColorToColorTable(circle.colorString)
|
||||
local style = DrawingHelper.ToLineStyleInteger(circle.style)
|
||||
trigger.action.circleToAll(-1, id, vec3, circle.radius, colorString, fillColor, style, true)
|
||||
end
|
||||
|
||||
---@param oval Oval
|
||||
local function DrawOval(oval)
|
||||
---@type Array<Vec3>
|
||||
local points = {}
|
||||
local pointsNo = 30
|
||||
local angleStep = (2 * math.pi) / points
|
||||
|
||||
local fillColor = DrawingHelper.ColorToColorTable(oval.fillColorString)
|
||||
local color = DrawingHelper.ColorToColorTable(oval.colorString)
|
||||
local lineStyle = DrawingHelper.ToLineStyleInteger(oval.style)
|
||||
|
||||
for i = 1, pointsNo do
|
||||
local angle = i * angleStep
|
||||
local x = oval.mapX + (oval.r1 * math.cos(angle))
|
||||
local y = oval.mapY + (oval.r2 * math.sin(angle))
|
||||
table.insert(points, { x = x, y = 0, z = y } )
|
||||
end
|
||||
MarkupToAll(7, id, points, fillColor, color, lineStyle)
|
||||
end
|
||||
|
||||
---@param free Free
|
||||
local function DrawFree(free)
|
||||
local fillColor = DrawingHelper.ColorToColorTable(free.fillColorString)
|
||||
local color = DrawingHelper.ColorToColorTable(free.colorString)
|
||||
local lineStyle = DrawingHelper.ToLineStyleInteger(free.style)
|
||||
|
||||
local points = {}
|
||||
for _, point in ipairs(free.points) do
|
||||
table.insert(points, { x = point.x, y = 0, z = point.y } )
|
||||
end
|
||||
MarkupToAll(7, id, points, fillColor, color, lineStyle)
|
||||
end
|
||||
|
||||
---@param rect Rect
|
||||
local function DrawRect(rect)
|
||||
local fillColor = DrawingHelper.ColorToColorTable(rect.fillColorString)
|
||||
local color = DrawingHelper.ColorToColorTable(rect.colorString)
|
||||
local lineStyle = DrawingHelper.ToLineStyleInteger(rect.style)
|
||||
|
||||
local pointA = { x = rect.mapX, y = 0, z = rect.mapY }
|
||||
local pointB = { x = rect.mapX + rect.width, y = 0, z = rect.mapY + rect.height }
|
||||
trigger.action.rectToAll(-1, id, pointA, pointB, color, fillColor, lineStyle, true)
|
||||
end
|
||||
|
||||
---@param arrow Arrow
|
||||
local function DrawArrow(arrow)
|
||||
local fillColor = DrawingHelper.ColorToColorTable(arrow.fillColorString)
|
||||
local color = DrawingHelper.ColorToColorTable(arrow.colorString)
|
||||
local lineStyle = DrawingHelper.ToLineStyleInteger(arrow.style)
|
||||
|
||||
local startPoint = { x = arrow.mapX, y = 0, z = arrow.mapY }
|
||||
local rad = math.rad(arrow.angle or 0)
|
||||
local length = arrow.length or 100
|
||||
local endPoint = { x = arrow.mapX + length * math.cos(rad), y = 0, z = arrow.mapY + length * math.sin(rad) }
|
||||
trigger.action.arrowToAll(-1, id, startPoint, endPoint, color, fillColor, lineStyle, true)
|
||||
end
|
||||
|
||||
if object.polygonMode == "circle" then
|
||||
DrawCircle(object--[[@as Circle]])
|
||||
elseif object.polygonMode == "oval" then
|
||||
DrawOval(object--[[@as Oval]])
|
||||
elseif object.polygonMode == "free" then
|
||||
DrawFree(object--[[@as Free]])
|
||||
elseif object.polygonMode == "rect" then
|
||||
DrawRect(object--[[@as Rect]])
|
||||
elseif object.polygonMode == "arrow" then
|
||||
DrawArrow(object--[[@as Arrow]])
|
||||
end
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param object Line
|
||||
---@param id integer
|
||||
function DrawingHelper.DrawLine(object, id)
|
||||
|
||||
---@type Array<Vec3>
|
||||
local points = {}
|
||||
|
||||
for _, point in ipairs(object.points) do
|
||||
table.insert(points, { x = point.x, y = 0, z = point.y } )
|
||||
end
|
||||
|
||||
local color = DrawingHelper.ColorToColorTable(object.colorString)
|
||||
local lineStyle = DrawingHelper.ToLineStyleInteger(object.style)
|
||||
MarkupToAll(1, id, points, color, color, lineStyle)
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param object TextBox
|
||||
---@param id integer
|
||||
function DrawingHelper.DrawTextBox(object, id)
|
||||
trigger.action.textToAll(-1, id, { x= object.mapX, y = 0, z = object.mapY },
|
||||
DrawingHelper.ColorToColorTable(object.colorString),
|
||||
DrawingHelper.ColorToColorTable(object.fillColorString),
|
||||
object.fontSize or 12,
|
||||
true,
|
||||
object.text or "")
|
||||
end
|
||||
|
||||
function DrawingHelper.Remove(id)
|
||||
trigger.action.removeMark(id)
|
||||
end
|
||||
|
||||
|
||||
|
||||
---@param hexStr string
|
||||
---@return table
|
||||
function DrawingHelper.ColorToColorTable(hexStr)
|
||||
hexStr = hexStr:gsub("0x", "")
|
||||
local a = tonumber(hexStr:sub(1, 2), 16) / 255
|
||||
local r = tonumber(hexStr:sub(3, 4), 16) / 255
|
||||
local g = tonumber(hexStr:sub(5, 6), 16) / 255
|
||||
local b = tonumber(hexStr:sub(7, 8), 16) / 255
|
||||
|
||||
return { r, g , b , a }
|
||||
end
|
||||
|
||||
---@param lineStyle string
|
||||
function DrawingHelper.ToLineStyleInteger(lineStyle)
|
||||
lineStyle = lineStyle:lower()
|
||||
if lineStyle == "no line" then
|
||||
return 0
|
||||
elseif lineStyle == "solid" then
|
||||
return 1
|
||||
elseif lineStyle == "dashed" then
|
||||
return 2
|
||||
elseif lineStyle == "dotted" then
|
||||
return 3
|
||||
elseif lineStyle == "dot dash" then
|
||||
return 4
|
||||
elseif lineStyle == "long dash" then
|
||||
return 5
|
||||
elseif lineStyle == "two dash" then
|
||||
return 6
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
---@class ARGB
|
||||
---@field public a number
|
||||
---@field public r number
|
||||
---@field public g number
|
||||
---@field public b number
|
||||
|
||||
|
||||
if not Spearhead then Spearhead = {} end
|
||||
if not Spearhead.classes then Spearhead.classes = {} end
|
||||
if not Spearhead.classes.stageClasses then Spearhead.classes.stageClasses = {} end
|
||||
if not Spearhead.classes.stageClasses.drawings then Spearhead.classes.stageClasses.drawings = {} end
|
||||
if not Spearhead.classes.stageClasses.drawings.helper then Spearhead.classes.stageClasses.drawings.helper = {} end
|
||||
Spearhead.classes.stageClasses.drawings.helper.DrawingHelper = DrawingHelper
|
||||
@@ -39,7 +39,7 @@ local detectionLogger = Spearhead.LoggerTemplate.new("DetectionManager", default
|
||||
local detectionManager = Spearhead.classes.capClasses.detection.DetectionManager.New(detectionLogger)
|
||||
|
||||
Spearhead.classes.capClasses.GlobalCapManager.start(databaseManager, capConfig, detectionManager, stageConfig, defaultLogLevel, spawnManager)
|
||||
Spearhead.internal.GlobalStageManager:NewAndStart(databaseManager, stageConfig, defaultLogLevel, spawnManager)
|
||||
Spearhead.internal.GlobalStageManager.NewAndStart(databaseManager, stageConfig, defaultLogLevel, spawnManager)
|
||||
|
||||
Spearhead.internal.GlobalFleetManager.start(databaseManager)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user