Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Roque
erp5
Commits
3a9d947c
Commit
3a9d947c
authored
Oct 02, 2023
by
Roque
Browse files
Options
Browse Files
Download
Plain Diff
Capture the flag game new features
See merge request
nexedi/erp5!1824
parents
41270486
36b5ce60
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
2320 additions
and
698 deletions
+2320
-698
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.js
...eItem/web_page_module/drone_capture_flag_enemydrone_js.js
+13
-28
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.xml
...Item/web_page_module/drone_capture_flag_enemydrone_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.js
...m/web_page_module/drone_capture_flag_fixedwingdrone_js.js
+20
-12
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.xml
.../web_page_module/drone_capture_flag_fixedwingdrone_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.js
...mplateItem/web_page_module/drone_capture_flag_logic_js.js
+138
-185
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.xml
...plateItem/web_page_module/drone_capture_flag_logic_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_map_utils_js.js
...teItem/web_page_module/drone_capture_flag_map_utils_js.js
+389
-0
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_map_utils_js.xml
...eItem/web_page_module/drone_capture_flag_map_utils_js.xml
+344
-0
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_css.css
...m/web_page_module/ojs_drone_capture_flag_API_page_css.css
+4
-1
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_css.xml
...m/web_page_module/ojs_drone_capture_flag_API_page_css.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.html
...web_page_module/ojs_drone_capture_flag_API_page_html.html
+136
-1
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.xml
.../web_page_module/ojs_drone_capture_flag_API_page_html.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_css.css
...eb_page_module/ojs_drone_capture_flag_script_page_css.css
+23
-0
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_css.xml
...eb_page_module/ojs_drone_capture_flag_script_page_css.xml
+344
-0
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_html.html
..._page_module/ojs_drone_capture_flag_script_page_html.html
+6
-17
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_html.xml
...b_page_module/ojs_drone_capture_flag_script_page_html.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_js.js
.../web_page_module/ojs_drone_capture_flag_script_page_js.js
+881
-434
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_js.xml
...web_page_module/ojs_drone_capture_flag_script_page_js.xml
+2
-2
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_site_module/officejs_drone_capture_flag.xml
...plateItem/web_site_module/officejs_drone_capture_flag.xml
+3
-3
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_site_module/officejs_drone_capture_flag/app.xml
...eItem/web_site_module/officejs_drone_capture_flag/app.xml
+3
-3
bt5/erp5_officejs_drone_capture_flag/SkinTemplateItem/portal_skins/erp5_drone_capture_flag/assets/map/terrain.jpg.jpg
..._skins/erp5_drone_capture_flag/assets/map/terrain.jpg.jpg
+0
-0
bt5/erp5_officejs_drone_capture_flag/SkinTemplateItem/portal_skins/erp5_officejs_drone_capture_flag/WebSection_getDroneCaptureFlagPrecacheManifestList.py
...lag/WebSection_getDroneCaptureFlagPrecacheManifestList.py
+2
-0
No files found.
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.js
View file @
3a9d947c
...
@@ -6,10 +6,11 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -6,10 +6,11 @@ var EnemyDroneAPI = /** @class */ (function () {
"
use strict
"
;
"
use strict
"
;
var
DEFAULT_ACCELERATION
=
1
,
var
DEFAULT_ACCELERATION
=
1
,
VIEW_SCOPE
=
50
,
VIEW_SCOPE
=
25
,
DEFAULT_SPEED
=
16.5
,
DEFAULT_SPEED
=
16.5
,
MIN_SPEED
=
12
,
MIN_SPEED
=
12
,
MAX_SPEED
=
26
;
MAX_SPEED
=
26
,
COLLISION_SECTOR
=
10
;
//** CONSTRUCTOR
//** CONSTRUCTOR
function
EnemyDroneAPI
(
gameManager
,
drone_info
,
flight_parameters
,
id
)
{
function
EnemyDroneAPI
(
gameManager
,
drone_info
,
flight_parameters
,
id
)
{
...
@@ -21,6 +22,7 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -21,6 +22,7 @@ var EnemyDroneAPI = /** @class */ (function () {
this
.
_drone_info
=
drone_info
;
this
.
_drone_info
=
drone_info
;
this
.
_drone_dict_list
=
[];
this
.
_drone_dict_list
=
[];
this
.
_acceleration
=
DEFAULT_ACCELERATION
;
this
.
_acceleration
=
DEFAULT_ACCELERATION
;
this
.
_collision_sector
=
COLLISION_SECTOR
;
}
}
/*
/*
** Function called on start phase of the drone, just before onStart AI script
** Function called on start phase of the drone, just before onStart AI script
...
@@ -189,15 +191,16 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -189,15 +191,16 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI
.
prototype
.
getDroneViewInfo
=
function
(
drone
)
{
EnemyDroneAPI
.
prototype
.
getDroneViewInfo
=
function
(
drone
)
{
var
context
=
this
,
result
=
[],
distance
,
var
context
=
this
,
result
=
[],
distance
,
drone_position
=
drone
.
position
,
other_position
;
drone_position
=
drone
.
position
,
other_position
;
function
calculateDistance
(
a
,
b
)
{
function
calculateDistance
(
a
,
b
,
_3D
)
{
return
Math
.
sqrt
(
Math
.
pow
((
a
.
x
-
b
.
x
),
2
)
+
Math
.
pow
((
a
.
y
-
b
.
y
),
2
)
+
var
z
=
(
_3D
?
Math
.
pow
((
a
.
z
-
b
.
z
),
2
)
:
0
);
Math
.
pow
((
a
.
z
-
b
.
z
),
2
)
);
return
Math
.
sqrt
(
Math
.
pow
((
a
.
x
-
b
.
x
),
2
)
+
Math
.
pow
((
a
.
y
-
b
.
y
),
2
)
+
z
);
}
}
context
.
_gameManager
.
_droneList_user
.
forEach
(
function
(
other
)
{
context
.
_gameManager
.
_droneList_user
.
forEach
(
function
(
other
)
{
if
(
other
.
can_play
)
{
if
(
other
.
can_play
)
{
other_position
=
other
.
position
;
other_position
=
other
.
position
;
distance
=
calculateDistance
(
drone_position
,
other_position
);
distance
=
calculateDistance
(
drone_position
,
other_position
);
if
(
distance
<=
VIEW_SCOPE
)
{
//the higher the drone, the easier to detect
if
(
distance
/
(
other_position
.
z
*
0.05
)
<=
VIEW_SCOPE
)
{
result
.
push
({
result
.
push
({
position
:
other_position
,
position
:
other_position
,
direction
:
other
.
direction
,
direction
:
other
.
direction
,
...
@@ -213,8 +216,7 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -213,8 +216,7 @@ var EnemyDroneAPI = /** @class */ (function () {
};
};
EnemyDroneAPI
.
prototype
.
getDroneAI
=
function
()
{
EnemyDroneAPI
.
prototype
.
getDroneAI
=
function
()
{
//interception math based on https://www.codeproject.com/Articles/990452/Interception-of-Two-Moving-Objects-in-D-Space
//interception math based on https://www.codeproject.com/Articles/990452/Interception-of-Two-Moving-Objects-in-D-Space
return
'
var BASE_DISTANCE = 300;
\n
'
+
return
'
function calculateInterception(hunter_position, prey_position, hunter_speed, prey_speed, prey_velocity_vector) {
\n
'
+
'
function calculateInterception(hunter_position, prey_position, hunter_speed, prey_speed, prey_velocity_vector) {
\n
'
+
'
var vector_from_drone, distance_to_prey, distance_to_prey_vector, a, b, c, t1, t2, interception_time, interception_point;
\n
'
+
'
var vector_from_drone, distance_to_prey, distance_to_prey_vector, a, b, c, t1, t2, interception_time, interception_point;
\n
'
+
'
function dot(a, b) {
\n
'
+
'
function dot(a, b) {
\n
'
+
'
return a.map((x, i) => a[i] * b[i]).reduce((m, n) => m + n);
\n
'
+
'
return a.map((x, i) => a[i] * b[i]).reduce((m, n) => m + n);
\n
'
+
...
@@ -242,7 +244,6 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -242,7 +244,6 @@ var EnemyDroneAPI = /** @class */ (function () {
'
}
\n
'
+
'
}
\n
'
+
'
\n
'
+
'
\n
'
+
'
me.onStart = function () {
\n
'
+
'
me.onStart = function () {
\n
'
+
'
me.base = me.position;
\n
'
+
'
me.setDirection(0,0,0);
\n
'
+
'
me.setDirection(0,0,0);
\n
'
+
'
return;
\n
'
+
'
return;
\n
'
+
'
\n
'
+
'
\n
'
+
...
@@ -251,20 +252,6 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -251,20 +252,6 @@ var EnemyDroneAPI = /** @class */ (function () {
'
me.onUpdate = function (timestamp) {
\n
'
+
'
me.onUpdate = function (timestamp) {
\n
'
+
'
me.current_position = me.position;
\n
'
+
'
me.current_position = me.position;
\n
'
+
'
var drone_position, drone_velocity_vector, interception_point, drone_view,
\n
'
+
'
var drone_position, drone_velocity_vector, interception_point, drone_view,
\n
'
+
'
dist = distance(
\n
'
+
'
me.current_position,
\n
'
+
'
me.base
\n
'
+
'
);
\n
'
+
// return to base point if drone is too far
'
if (dist >= BASE_DISTANCE) {
\n
'
+
'
me.chasing = false;
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
'
me.base.x,
\n
'
+
'
me.base.y,
\n
'
+
'
me.base.z
\n
'
+
'
);
\n
'
+
'
return;
\n
'
+
'
}
\n
'
+
'
drone_view = me.getDroneViewInfo();
\n
'
+
'
drone_view = me.getDroneViewInfo();
\n
'
+
'
if (drone_view.length) {
\n
'
+
'
if (drone_view.length) {
\n
'
+
'
drone_position = drone_view[0].position;
\n
'
+
'
drone_position = drone_view[0].position;
\n
'
+
...
@@ -273,13 +260,8 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -273,13 +260,8 @@ var EnemyDroneAPI = /** @class */ (function () {
'
if (!interception_point) {
\n
'
+
'
if (!interception_point) {
\n
'
+
'
return;
\n
'
+
'
return;
\n
'
+
'
}
\n
'
+
'
}
\n
'
+
'
me.chasing = true;
\n
'
+
'
me.setTargetCoordinates(interception_point[0], interception_point[1], interception_point[2]);
\n
'
+
'
me.setTargetCoordinates(interception_point[0], interception_point[1], interception_point[2]);
\n
'
+
'
}
\n
'
+
'
}
\n
'
+
// return to base point if drone is too far
'
if (!me.chasing && dist <= 10) {
\n
'
+
'
me.setDirection(0,0,0);
\n
'
+
'
}
\n
'
+
'
};
'
;
'
};
'
;
};
};
EnemyDroneAPI
.
prototype
.
getMinSpeed
=
function
()
{
EnemyDroneAPI
.
prototype
.
getMinSpeed
=
function
()
{
...
@@ -330,5 +312,8 @@ var EnemyDroneAPI = /** @class */ (function () {
...
@@ -330,5 +312,8 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI
.
prototype
.
getFlightParameters
=
function
()
{
EnemyDroneAPI
.
prototype
.
getFlightParameters
=
function
()
{
return
this
.
_flight_parameters
;
return
this
.
_flight_parameters
;
};
};
EnemyDroneAPI
.
prototype
.
getCollisionSector
=
function
()
{
return
this
.
_collision_sector
;
};
return
EnemyDroneAPI
;
return
EnemyDroneAPI
;
}());
}());
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_enemydrone_js.xml
View file @
3a9d947c
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
10
09.37360.49772.3874
</string>
</value>
<value>
<string>
10
11.20054.25134.60962
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
16
88571911.82
</float>
<float>
16
95397984.38
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.js
View file @
3a9d947c
...
@@ -36,7 +36,6 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -36,7 +36,6 @@ var FixedWingDroneAPI = /** @class */ (function () {
** Function called on start phase of the drone, just before onStart AI script
** Function called on start phase of the drone, just before onStart AI script
*/
*/
FixedWingDroneAPI
.
prototype
.
internal_start
=
function
(
drone
)
{
FixedWingDroneAPI
.
prototype
.
internal_start
=
function
(
drone
)
{
drone
.
_targetCoordinates
=
drone
.
getCurrentPosition
();
drone
.
_maxDeceleration
=
this
.
getMaxDeceleration
();
drone
.
_maxDeceleration
=
this
.
getMaxDeceleration
();
if
(
drone
.
_maxDeceleration
<=
0
)
{
if
(
drone
.
_maxDeceleration
<=
0
)
{
throw
new
Error
(
'
max deceleration must be superior to 0
'
);
throw
new
Error
(
'
max deceleration must be superior to 0
'
);
...
@@ -194,6 +193,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -194,6 +193,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
distance
,
distance
,
distanceCos
,
distanceCos
,
distanceSin
,
distanceSin
,
distanceToTarget
,
currentSinLat
,
currentSinLat
,
currentLonRad
,
currentLonRad
,
groundSpeed
,
groundSpeed
,
...
@@ -205,11 +205,19 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -205,11 +205,19 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed
,
verticalSpeed
,
yawToDirection
;
yawToDirection
;
if
(
this
.
_loiter_mode
&&
Math
.
sqrt
(
if
(
this
.
_loiter_mode
)
{
Math
.
pow
(
drone
.
_targetCoordinates
.
x
-
drone
.
position
.
x
,
2
)
+
distanceToTarget
=
Math
.
sqrt
(
Math
.
pow
(
drone
.
_targetCoordinates
.
y
-
drone
.
position
.
y
,
2
)
Math
.
pow
(
drone
.
_targetCoordinates
.
x
-
drone
.
position
.
x
,
2
)
)
<=
this
.
_loiter_radius
)
{
+
Math
.
pow
(
drone
.
_targetCoordinates
.
y
-
drone
.
position
.
y
,
2
)
newYaw
=
bearing
-
90
;
);
if
(
Math
.
abs
(
distanceToTarget
-
this
.
_loiter_radius
)
<=
1
)
{
newYaw
=
bearing
-
90
;
}
else
if
(
distanceToTarget
<
this
.
_loiter_radius
)
{
newYaw
=
bearing
-
135
;
}
else
{
newYaw
=
this
.
_getNewYaw
(
drone
,
bearing
,
delta_time
);
}
}
else
{
}
else
{
newYaw
=
this
.
_getNewYaw
(
drone
,
bearing
,
delta_time
);
newYaw
=
this
.
_getNewYaw
(
drone
,
bearing
,
delta_time
);
}
}
...
@@ -414,16 +422,16 @@ var FixedWingDroneAPI = /** @class */ (function () {
...
@@ -414,16 +422,16 @@ var FixedWingDroneAPI = /** @class */ (function () {
distance
=
calculateDistance
(
drone_position
,
other_position
,
context
);
distance
=
calculateDistance
(
drone_position
,
other_position
,
context
);
if
(
distance
<=
VIEW_SCOPE
)
{
if
(
distance
<=
VIEW_SCOPE
)
{
result
.
drones
.
push
({
result
.
drones
.
push
({
position
:
drone
.
getCurrentPosition
(),
position
:
other
.
getCurrentPosition
(),
direction
:
drone
.
direction
,
direction
:
other
.
direction
,
rotation
:
drone
.
rotation
,
rotation
:
other
.
rotation
,
speed
:
drone
.
speed
,
speed
:
other
.
speed
,
team
:
drone
.
team
team
:
other
.
team
});
});
}
}
}
}
});
});
context
.
_map_dict
.
geo_
obstacle_list
.
forEach
(
function
(
obstacle
)
{
context
.
_map_dict
.
obstacle_list
.
forEach
(
function
(
obstacle
)
{
distance
=
calculateDistance
(
drone_position
,
obstacle
.
position
,
context
);
distance
=
calculateDistance
(
drone_position
,
obstacle
.
position
,
context
);
if
(
distance
<=
VIEW_SCOPE
)
{
if
(
distance
<=
VIEW_SCOPE
)
{
result
.
obstacles
.
push
(
obstacle
);
result
.
obstacles
.
push
(
obstacle
);
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_fixedwingdrone_js.xml
View file @
3a9d947c
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
101
0.35063.25322.10700
</string>
</value>
<value>
<string>
101
1.5610.25987.56473
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
169
2366624.83
</float>
<float>
169
5395371.67
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.js
View file @
3a9d947c
/*global BABYLON, RSVP, console, FixedWingDroneAPI, EnemyDroneAPI, document*/
/*global BABYLON, RSVP, console, FixedWingDroneAPI, EnemyDroneAPI, document
, MapUtils
*/
/*jslint nomen: true, indent: 2, maxlen: 80, todo: true,
/*jslint nomen: true, indent: 2, maxlen: 80, todo: true,
unparam: true */
unparam: true */
...
@@ -135,6 +135,7 @@ var DroneManager = /** @class */ (function () {
...
@@ -135,6 +135,7 @@ var DroneManager = /** @class */ (function () {
configurable
:
true
configurable
:
true
});
});
DroneManager
.
prototype
.
internal_start
=
function
()
{
DroneManager
.
prototype
.
internal_start
=
function
()
{
this
.
_targetCoordinates
=
this
.
position
;
this
.
_API
.
internal_start
(
this
);
this
.
_API
.
internal_start
(
this
);
this
.
_canPlay
=
true
;
this
.
_canPlay
=
true
;
this
.
_canCommunicate
=
true
;
this
.
_canCommunicate
=
true
;
...
@@ -175,14 +176,15 @@ var DroneManager = /** @class */ (function () {
...
@@ -175,14 +176,15 @@ var DroneManager = /** @class */ (function () {
return
;
return
;
};
};
DroneManager
.
prototype
.
internal_update
=
function
(
delta_time
)
{
DroneManager
.
prototype
.
internal_update
=
function
(
delta_time
)
{
var
context
=
this
;
var
context
=
this
,
milliseconds
;
if
(
this
.
_controlMesh
)
{
if
(
this
.
_controlMesh
)
{
context
.
_API
.
internal_update
(
context
,
delta_time
);
context
.
_API
.
internal_update
(
context
,
delta_time
);
if
(
context
.
_canUpdate
)
{
if
(
context
.
_canUpdate
)
{
context
.
_canUpdate
=
false
;
context
.
_canUpdate
=
false
;
return
new
RSVP
.
Queue
()
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
.
push
(
function
()
{
return
context
.
onUpdate
(
context
.
_API
.
_gameManager
.
_game_duration
);
milliseconds
=
Math
.
floor
(
context
.
_API
.
_gameManager
.
_game_duration
);
return
context
.
onUpdate
(
milliseconds
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
context
.
_canUpdate
=
true
;
context
.
_canUpdate
=
true
;
...
@@ -288,6 +290,9 @@ var DroneManager = /** @class */ (function () {
...
@@ -288,6 +290,9 @@ var DroneManager = /** @class */ (function () {
DroneManager
.
prototype
.
getInitialAltitude
=
function
()
{
DroneManager
.
prototype
.
getInitialAltitude
=
function
()
{
return
this
.
_API
.
getInitialAltitude
();
return
this
.
_API
.
getInitialAltitude
();
};
};
DroneManager
.
prototype
.
getCollisionSector
=
function
()
{
return
this
.
_API
.
getCollisionSector
();
};
DroneManager
.
prototype
.
getAltitudeAbs
=
function
()
{
DroneManager
.
prototype
.
getAltitudeAbs
=
function
()
{
if
(
this
.
_controlMesh
)
{
if
(
this
.
_controlMesh
)
{
var
altitude
=
this
.
_controlMesh
.
position
.
y
;
var
altitude
=
this
.
_controlMesh
.
position
.
y
;
...
@@ -403,20 +408,44 @@ var DroneManager = /** @class */ (function () {
...
@@ -403,20 +408,44 @@ var DroneManager = /** @class */ (function () {
/******************************************************************************/
/******************************************************************************/
/******************************** MAP MANAGER *********************************/
/******************************** MAP MANAGER *********************************/
var
MapManager
=
/** @class */
(
function
()
{
var
MapManager
=
/** @class */
(
function
()
{
"
use strict
"
;
"
use strict
"
;
var
EPSILON
=
9.9
,
var
SEED
=
'
6!
'
,
START_Z
=
15
,
//default square map
R
=
6371
e3
;
MAP_HEIGHT
=
700
,
START_AMSL
=
595
,
MIN_LAT
=
45.6419
,
MAX_LAT
=
45.65
,
MIN_LON
=
14.265
,
MAX_LON
=
14.2766
,
MAP
=
{
"
height
"
:
MAP_HEIGHT
,
"
start_AMSL
"
:
START_AMSL
,
"
map_seed
"
:
SEED
,
"
min_lat
"
:
MIN_LAT
,
"
max_lat
"
:
MAX_LAT
,
"
min_lon
"
:
MIN_LON
,
"
max_lon
"
:
MAX_LON
};
//** CONSTRUCTOR
//** CONSTRUCTOR
function
MapManager
(
scene
)
{
function
MapManager
(
scene
,
map_param
)
{
var
_this
=
this
,
max_sky
,
skybox
,
skyboxMat
,
largeGroundMat
,
flag_material
,
var
_this
=
this
,
max_sky
,
skybox
,
skyboxMat
,
largeGroundMat
,
flag_material
,
largeGroundBottom
,
width
,
depth
,
terrain
,
max
,
flag_a
,
flag_b
,
mast
,
flag
,
largeGroundBottom
,
width
,
depth
,
terrain
,
max
,
flag_a
,
flag_b
,
mast
,
flag
,
count
=
0
,
new_obstacle
;
count
=
0
,
new_obstacle
,
obstacle
,
flag_info
,
enemy
;
this
.
setMapInfo
(
GAMEPARAMETERS
.
map
,
GAMEPARAMETERS
.
initialPosition
);
if
(
!
map_param
)
{
// Use default map base parameters
map_param
=
MAP
;
}
_this
.
mapUtils
=
new
MapUtils
(
map_param
);
_this
.
map_info
=
map_param
;
Object
.
assign
(
_this
.
map_info
,
_this
.
mapUtils
.
map_info
);
_this
.
map_info
.
initial_position
=
_this
.
mapUtils
.
convertToLocalCoordinates
(
_this
.
map_info
.
initial_position
.
x
,
_this
.
map_info
.
initial_position
.
y
,
_this
.
map_info
.
initial_position
.
z
);
max
=
_this
.
map_info
.
width
;
max
=
_this
.
map_info
.
width
;
if
(
_this
.
map_info
.
depth
>
max
)
{
if
(
_this
.
map_info
.
depth
>
max
)
{
max
=
_this
.
map_info
.
depth
;
max
=
_this
.
map_info
.
depth
;
...
@@ -459,9 +488,26 @@ var MapManager = /** @class */ (function () {
...
@@ -459,9 +488,26 @@ var MapManager = /** @class */ (function () {
terrain
.
position
=
BABYLON
.
Vector3
.
Zero
();
terrain
.
position
=
BABYLON
.
Vector3
.
Zero
();
terrain
.
scaling
=
new
BABYLON
.
Vector3
(
depth
/
50000
,
depth
/
50000
,
terrain
.
scaling
=
new
BABYLON
.
Vector3
(
depth
/
50000
,
depth
/
50000
,
width
/
50000
);
width
/
50000
);
// Enemies
_this
.
_enemy_list
=
[];
_this
.
map_info
.
enemy_list
.
forEach
(
function
(
geo_enemy
)
{
enemy
=
{};
Object
.
assign
(
enemy
,
geo_enemy
);
enemy
.
position
=
_this
.
mapUtils
.
convertToLocalCoordinates
(
geo_enemy
.
position
.
x
,
geo_enemy
.
position
.
y
,
geo_enemy
.
position
.
z
);
_this
.
_enemy_list
.
push
(
enemy
);
});
// Obstacles
// Obstacles
_this
.
_obstacle_list
=
[];
_this
.
_obstacle_list
=
[];
_this
.
map_info
.
obstacle_list
.
forEach
(
function
(
obstacle
)
{
_this
.
map_info
.
obstacle_list
.
forEach
(
function
(
geo_obstacle
)
{
obstacle
=
{};
Object
.
assign
(
obstacle
,
geo_obstacle
);
obstacle
.
position
=
_this
.
mapUtils
.
convertToLocalCoordinates
(
geo_obstacle
.
position
.
x
,
geo_obstacle
.
position
.
y
,
geo_obstacle
.
position
.
z
);
switch
(
obstacle
.
type
)
{
switch
(
obstacle
.
type
)
{
case
"
box
"
:
case
"
box
"
:
new_obstacle
=
BABYLON
.
MeshBuilder
.
CreateBox
(
"
obs_
"
+
count
,
new_obstacle
=
BABYLON
.
MeshBuilder
.
CreateBox
(
"
obs_
"
+
count
,
...
@@ -513,7 +559,13 @@ var MapManager = /** @class */ (function () {
...
@@ -513,7 +559,13 @@ var MapManager = /** @class */ (function () {
'
y
'
:
1
,
'
y
'
:
1
,
'
z
'
:
6
'
z
'
:
6
};
};
_this
.
map_info
.
flag_list
.
forEach
(
function
(
flag_info
,
index
)
{
_this
.
map_info
.
flag_list
.
forEach
(
function
(
geo_flag
,
index
)
{
flag_info
=
{};
Object
.
assign
(
flag_info
,
geo_flag
);
flag_info
.
position
=
_this
.
mapUtils
.
convertToLocalCoordinates
(
geo_flag
.
position
.
x
,
geo_flag
.
position
.
y
,
geo_flag
.
position
.
z
);
flag_material
=
new
BABYLON
.
StandardMaterial
(
"
flag_mat_
"
+
index
,
scene
);
flag_material
=
new
BABYLON
.
StandardMaterial
(
"
flag_mat_
"
+
index
,
scene
);
flag_material
.
alpha
=
1
;
flag_material
.
alpha
=
1
;
flag_material
.
diffuseColor
=
BABYLON
.
Color3
.
Green
();
flag_material
.
diffuseColor
=
BABYLON
.
Color3
.
Green
();
...
@@ -523,7 +575,7 @@ var MapManager = /** @class */ (function () {
...
@@ -523,7 +575,7 @@ var MapManager = /** @class */ (function () {
flag_a
.
material
=
flag_material
;
flag_a
.
material
=
flag_material
;
flag_a
.
position
=
new
BABYLON
.
Vector3
(
flag_a
.
position
=
new
BABYLON
.
Vector3
(
flag_info
.
position
.
x
+
1
,
flag_info
.
position
.
x
+
1
,
FLAG_SIZE
.
z
+
1
,
//swap
flag_info
.
position
.
z
+
FLAG_SIZE
.
z
+
1
,
//swap
flag_info
.
position
.
y
-
1
flag_info
.
position
.
y
-
1
);
);
flag_a
.
rotation
=
new
BABYLON
.
Vector3
(
0
,
1
,
0
);
flag_a
.
rotation
=
new
BABYLON
.
Vector3
(
0
,
1
,
0
);
...
@@ -533,7 +585,7 @@ var MapManager = /** @class */ (function () {
...
@@ -533,7 +585,7 @@ var MapManager = /** @class */ (function () {
flag_b
.
material
=
flag_material
;
flag_b
.
material
=
flag_material
;
flag_b
.
position
=
new
BABYLON
.
Vector3
(
flag_b
.
position
=
new
BABYLON
.
Vector3
(
flag_info
.
position
.
x
-
1
,
flag_info
.
position
.
x
-
1
,
FLAG_SIZE
.
z
+
1
,
//swap
flag_info
.
position
.
z
+
FLAG_SIZE
.
z
+
1
,
//swap
flag_info
.
position
.
y
+
1
flag_info
.
position
.
y
+
1
);
);
flag_b
.
rotation
=
new
BABYLON
.
Vector3
(
0
,
4
,
0
);
flag_b
.
rotation
=
new
BABYLON
.
Vector3
(
0
,
4
,
0
);
...
@@ -541,7 +593,7 @@ var MapManager = /** @class */ (function () {
...
@@ -541,7 +593,7 @@ var MapManager = /** @class */ (function () {
{
'
size
'
:
1
},
scene
);
{
'
size
'
:
1
},
scene
);
mast
.
position
=
new
BABYLON
.
Vector3
(
mast
.
position
=
new
BABYLON
.
Vector3
(
flag_info
.
position
.
x
,
flag_info
.
position
.
x
,
FLAG_SIZE
.
z
/
2
,
//swap
flag_info
.
position
.
z
+
FLAG_SIZE
.
z
/
2
,
//swap
flag_info
.
position
.
y
flag_info
.
position
.
y
);
);
mast
.
scaling
=
new
BABYLON
.
Vector3
(
mast
.
scaling
=
new
BABYLON
.
Vector3
(
...
@@ -551,117 +603,32 @@ var MapManager = /** @class */ (function () {
...
@@ -551,117 +603,32 @@ var MapManager = /** @class */ (function () {
mast
.
material
=
flag_material
;
mast
.
material
=
flag_material
;
flag
=
BABYLON
.
Mesh
.
MergeMeshes
([
flag_a
,
flag_b
,
mast
]);
flag
=
BABYLON
.
Mesh
.
MergeMeshes
([
flag_a
,
flag_b
,
mast
]);
flag
.
id
=
index
;
flag
.
id
=
index
;
//flag.weight = _this.map_info.flag_weight;
flag
.
location
=
flag_info
.
position
;
flag
.
location
=
flag_info
.
position
;
flag
.
drone_collider_list
=
[];
flag
.
weight
=
flag_info
.
weight
;
flag
.
score
=
flag_info
.
score
;
flag
.
id
=
index
;
_this
.
_flag_list
.
push
(
flag
);
_this
.
_flag_list
.
push
(
flag
);
});
});
}
}
MapManager
.
prototype
.
setMapInfo
=
function
(
map_dict
,
initial_position
)
{
var
max_width
=
this
.
latLonDistance
([
map_dict
.
min_lat
,
map_dict
.
min_lon
],
[
map_dict
.
min_lat
,
map_dict
.
max_lon
]),
max_height
=
this
.
latLonDistance
([
map_dict
.
min_lat
,
map_dict
.
min_lon
],
[
map_dict
.
max_lat
,
map_dict
.
min_lon
]),
map_size
=
Math
.
ceil
(
Math
.
max
(
max_width
,
max_height
)),
starting_point
=
map_size
/
2
*
-
0.75
;
this
.
map_info
=
{
"
depth
"
:
map_size
,
"
height
"
:
map_dict
.
height
,
"
width
"
:
map_size
,
"
map_size
"
:
map_size
,
"
start_AMSL
"
:
map_dict
.
start_AMSL
,
"
flag_list
"
:
map_dict
.
flag_list
,
"
geo_flag_list
"
:
[],
"
flag_distance_epsilon
"
:
map_dict
.
flag_distance_epsilon
||
EPSILON
,
"
obstacle_list
"
:
map_dict
.
obstacle_list
,
"
geo_obstacle_list
"
:
[],
"
initial_position
"
:
{
"
x
"
:
0
,
"
y
"
:
starting_point
,
"
z
"
:
START_Z
}
};
this
.
map_info
.
min_x
=
this
.
longitudToX
(
map_dict
.
min_lon
);
this
.
map_info
.
min_y
=
this
.
latitudeToY
(
map_dict
.
min_lat
);
this
.
map_info
.
max_x
=
this
.
longitudToX
(
map_dict
.
max_lon
);
this
.
map_info
.
max_y
=
this
.
latitudeToY
(
map_dict
.
max_lat
);
var
map
=
this
;
map_dict
.
flag_list
.
forEach
(
function
(
flag_info
,
index
)
{
map
.
map_info
.
geo_flag_list
.
push
(
map
.
convertToGeoCoordinates
(
flag_info
.
position
.
x
,
flag_info
.
position
.
y
,
flag_info
.
position
.
z
));
});
map_dict
.
obstacle_list
.
forEach
(
function
(
obstacle_info
,
index
)
{
var
geo_obstacle
=
{};
Object
.
assign
(
geo_obstacle
,
obstacle_info
);
geo_obstacle
.
position
=
map
.
convertToGeoCoordinates
(
obstacle_info
.
position
.
x
,
obstacle_info
.
position
.
y
,
obstacle_info
.
position
.
z
);
map
.
map_info
.
geo_obstacle_list
.
push
(
geo_obstacle
);
});
};
MapManager
.
prototype
.
getMapInfo
=
function
()
{
MapManager
.
prototype
.
getMapInfo
=
function
()
{
return
this
.
map_info
;
return
this
.
map_info
;
};
};
MapManager
.
prototype
.
latLonDistance
=
function
(
c1
,
c2
)
{
return
this
.
mapUtils
.
latLonDistance
(
c1
,
c2
);
};
MapManager
.
prototype
.
longitudToX
=
function
(
lon
)
{
MapManager
.
prototype
.
longitudToX
=
function
(
lon
)
{
return
(
this
.
map_info
.
map_size
/
360.0
)
*
(
180
+
lon
);
return
this
.
mapUtils
.
longitudToX
(
lon
);
};
};
MapManager
.
prototype
.
latitudeToY
=
function
(
lat
)
{
MapManager
.
prototype
.
latitudeToY
=
function
(
lat
)
{
return
(
this
.
map_info
.
map_size
/
180.0
)
*
(
90
-
lat
);
return
this
.
mapUtils
.
latitudeToY
(
lat
);
};
//TODO refactor latLonOffset, should be the reverse of lat-lon distance
//then map_size can be used as parameter (get max lat-lon from map_size)
/*MapManager.prototype.latLonOffset = function (lat, lon, offset_in_mt) {
var R = 6371e3, //Earth radius
lat_offset = offset_in_mt / R,
lon_offset = offset_in_mt / (R * Math.cos(Math.PI * lat / 180));
return [lat + lat_offset * 180 / Math.PI,
lon + lon_offset * 180 / Math.PI];
};*/
MapManager
.
prototype
.
latLonDistance
=
function
(
c1
,
c2
)
{
var
q1
=
c1
[
0
]
*
Math
.
PI
/
180
,
q2
=
c2
[
0
]
*
Math
.
PI
/
180
,
dq
=
(
c2
[
0
]
-
c1
[
0
])
*
Math
.
PI
/
180
,
dl
=
(
c2
[
1
]
-
c1
[
1
])
*
Math
.
PI
/
180
,
a
=
Math
.
sin
(
dq
/
2
)
*
Math
.
sin
(
dq
/
2
)
+
Math
.
cos
(
q1
)
*
Math
.
cos
(
q2
)
*
Math
.
sin
(
dl
/
2
)
*
Math
.
sin
(
dl
/
2
),
c
=
2
*
Math
.
atan2
(
Math
.
sqrt
(
a
),
Math
.
sqrt
(
1
-
a
));
return
R
*
c
;
};
};
MapManager
.
prototype
.
convertToLocalCoordinates
=
MapManager
.
prototype
.
convertToLocalCoordinates
=
function
(
latitude
,
longitude
,
altitude
)
{
function
(
latitude
,
longitude
,
altitude
)
{
var
map_info
=
this
.
map_info
,
return
this
.
mapUtils
.
convertToLocalCoordinates
(
x
=
this
.
longitudToX
(
longitude
),
latitude
,
longitude
,
altitude
);
y
=
this
.
latitudeToY
(
latitude
);
return
{
x
:
((
x
-
map_info
.
min_x
)
/
(
map_info
.
max_x
-
map_info
.
min_x
))
*
1000
-
map_info
.
width
/
2
,
y
:
((
y
-
map_info
.
min_y
)
/
(
map_info
.
max_y
-
map_info
.
min_y
))
*
1000
-
map_info
.
depth
/
2
,
z
:
altitude
};
};
};
MapManager
.
prototype
.
convertToGeoCoordinates
=
function
(
x
,
y
,
z
)
{
MapManager
.
prototype
.
convertToGeoCoordinates
=
function
(
x
,
y
,
z
)
{
var
lon
=
x
+
this
.
map_info
.
width
/
2
,
return
this
.
mapUtils
.
convertToGeoCoordinates
(
x
,
y
,
z
);
lat
=
y
+
this
.
map_info
.
depth
/
2
;
lon
=
lon
/
1000
;
lon
=
lon
*
(
this
.
map_info
.
max_x
-
this
.
map_info
.
min_x
)
+
this
.
map_info
.
min_x
;
lon
=
lon
/
(
this
.
map_info
.
map_size
/
360.0
)
-
180
;
lat
=
lat
/
1000
;
lat
=
lat
*
(
this
.
map_info
.
max_y
-
this
.
map_info
.
min_y
)
+
this
.
map_info
.
min_y
;
lat
=
90
-
lat
/
(
this
.
map_info
.
map_size
/
180.0
);
return
{
x
:
lat
,
y
:
lon
,
z
:
z
};
};
};
return
MapManager
;
return
MapManager
;
}());
}());
...
@@ -701,8 +668,7 @@ var GameManager = /** @class */ (function () {
...
@@ -701,8 +668,7 @@ var GameManager = /** @class */ (function () {
header_list
=
[
"
timestamp (ms)
"
,
"
latitude (°)
"
,
"
longitude (°)
"
,
header_list
=
[
"
timestamp (ms)
"
,
"
latitude (°)
"
,
"
longitude (°)
"
,
"
AMSL (m)
"
,
"
rel altitude (m)
"
,
"
yaw (°)
"
,
"
AMSL (m)
"
,
"
rel altitude (m)
"
,
"
yaw (°)
"
,
"
ground speed (m/s)
"
,
"
climb rate (m/s)
"
];
"
ground speed (m/s)
"
,
"
climb rate (m/s)
"
];
drone_count
=
GAMEPARAMETERS
.
map
.
drones
.
user
.
length
+
drone_count
=
GAMEPARAMETERS
.
drone
.
list
.
length
;
GAMEPARAMETERS
.
map
.
drones
.
enemy
.
length
;
for
(
drone
=
0
;
drone
<
drone_count
;
drone
+=
1
)
{
for
(
drone
=
0
;
drone
<
drone_count
;
drone
+=
1
)
{
this
.
_flight_log
[
drone
]
=
[];
this
.
_flight_log
[
drone
]
=
[];
this
.
_flight_log
[
drone
].
push
(
header_list
);
this
.
_flight_log
[
drone
].
push
(
header_list
);
...
@@ -801,7 +767,9 @@ var GameManager = /** @class */ (function () {
...
@@ -801,7 +767,9 @@ var GameManager = /** @class */ (function () {
};
};
GameManager
.
prototype
.
logError
=
function
(
drone
,
error
)
{
GameManager
.
prototype
.
logError
=
function
(
drone
,
error
)
{
this
.
_flight_log
[
drone
.
_id
].
push
(
error
.
stack
);
if
(
drone
.
_id
<
this
.
_flight_log
.
length
)
{
// don't log enemies
this
.
_flight_log
[
drone
.
_id
].
push
(
error
.
stack
);
}
};
};
GameManager
.
prototype
.
_checkDroneOut
=
function
(
drone
)
{
GameManager
.
prototype
.
_checkDroneOut
=
function
(
drone
)
{
...
@@ -854,45 +822,48 @@ var GameManager = /** @class */ (function () {
...
@@ -854,45 +822,48 @@ var GameManager = /** @class */ (function () {
//there is not a proper collision
//there is not a proper collision
if
(
distance
(
drone
.
position
,
flag
.
location
)
<=
if
(
distance
(
drone
.
position
,
flag
.
location
)
<=
this
.
_mapManager
.
getMapInfo
().
flag_distance_epsilon
)
{
this
.
_mapManager
.
getMapInfo
().
flag_distance_epsilon
)
{
if
(
!
flag
.
drone_collider_list
.
includes
(
drone
.
id
))
{
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
//TODO notify the drone somehow? Or the AI script is in charge?
'
touched flag
'
+
flag
.
id
));
//console.log("flag " + flag.id + " hit by drone " + drone.id);
if
(
flag
.
weight
>
0
)
{
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
flag
.
weight
-=
1
;
'
touched a flag.
'
));
drone
.
score
+=
flag
.
score
;
// move score to a global place? GM, MM?
if
(
flag
.
drone_collider_list
.
length
===
0
)
{
drone
.
score
++
;
flag
.
drone_collider_list
.
push
(
drone
.
id
);
}
}
}
}
}
}
}
};
};
GameManager
.
prototype
.
_checkCollision
=
function
(
drone
,
other
)
{
GameManager
.
prototype
.
_checkCollision
=
function
(
drone
,
other
)
{
if
(
drone
.
colliderMesh
&&
other
.
colliderMesh
&&
if
(
drone
.
team
==
TEAM_ENEMY
&&
other
.
team
==
TEAM_ENEMY
)
return
;
drone
.
colliderMesh
.
intersectsMesh
(
other
.
colliderMesh
,
false
))
{
function
distance
(
a
,
b
)
{
var
angle
=
Math
.
acos
(
BABYLON
.
Vector3
.
Dot
(
drone
.
worldDirection
,
return
Math
.
sqrt
(
Math
.
pow
((
a
.
x
-
b
.
x
),
2
)
+
Math
.
pow
((
a
.
y
-
b
.
y
),
2
)
+
other
.
worldDirection
)
/
Math
.
pow
((
a
.
z
-
b
.
z
),
2
));
(
drone
.
worldDirection
.
length
()
*
}
other
.
worldDirection
.
length
()));
if
(
drone
.
team
!=
other
.
team
)
{
//TODO is this parameter set? keep it or make 2 drones die when intersect?
var
enemy
,
prey
;
if
(
angle
<
GAMEPARAMETERS
.
drone
.
collisionSector
)
{
if
(
drone
.
team
==
TEAM_ENEMY
)
{
if
(
drone
.
speed
>
other
.
speed
)
{
enemy
=
drone
;
other
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
prey
=
other
;
'
bump drone
'
+
other
.
id
+
'
.
'
));
}
else
if
(
other
.
team
==
TEAM_ENEMY
)
{
}
enemy
=
other
;
else
{
prey
=
drone
;
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
other
.
id
+
'
bumped drone
'
+
drone
.
id
+
'
.
'
));
}
}
}
else
{
if
(
drone
.
position
&&
other
.
position
)
{
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
if
(
distance
(
drone
.
position
,
other
.
position
)
<
'
touched drone
'
+
other
.
id
+
'
.
'
));
enemy
.
getCollisionSector
())
{
other
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
drone
.
_internal_crash
(
new
Error
(
'
enemy drone
'
+
enemy
.
id
+
'
touched drone
'
+
other
.
id
+
'
.
'
));
'
bumped drone
'
+
prey
.
id
+
'
.
'
));
other
.
_internal_crash
(
new
Error
(
'
enemy drone
'
+
enemy
.
id
+
'
bumped drone
'
+
prey
.
id
+
'
.
'
));
}
}
}
}
}
if
(
drone
.
colliderMesh
&&
other
.
colliderMesh
&&
drone
.
colliderMesh
.
intersectsMesh
(
other
.
colliderMesh
,
false
))
{
drone
.
_internal_crash
(
new
Error
(
'
drone
'
+
drone
.
id
+
'
touched drone
'
+
other
.
id
+
'
.
'
));
other
.
_internal_crash
(
new
Error
(
'
drone
'
+
drone
.
id
+
'
touched drone
'
+
other
.
id
+
'
.
'
));
}
};
};
GameManager
.
prototype
.
_update
=
function
(
delta_time
,
fullscreen
)
{
GameManager
.
prototype
.
_update
=
function
(
delta_time
,
fullscreen
)
{
...
@@ -968,11 +939,11 @@ var GameManager = /** @class */ (function () {
...
@@ -968,11 +939,11 @@ var GameManager = /** @class */ (function () {
_this
.
_result_message
+=
"
ALL DRONES DOWN!
"
;
_this
.
_result_message
+=
"
ALL DRONES DOWN!
"
;
return
_this
.
_finish
();
return
_this
.
_finish
();
}
}
if
(
_this
.
_allFlagsCaptured
())
{
/*
if (_this._allFlagsCaptured()) {
console.log("ALL FLAGS CAPTURED");
console.log("ALL FLAGS CAPTURED");
_this._result_message += "ALL FLAGS CAPTURED!";
_this._result_message += "ALL FLAGS CAPTURED!";
return _this._finish();
return _this._finish();
}
}
*/
});
});
};
};
...
@@ -1061,24 +1032,10 @@ var GameManager = /** @class */ (function () {
...
@@ -1061,24 +1032,10 @@ var GameManager = /** @class */ (function () {
return
finish
;
return
finish
;
};
};
GameManager
.
prototype
.
_allFlagsCaptured
=
function
()
{
var
finish
=
true
;
this
.
_mapManager
.
_flag_list
.
forEach
(
function
(
flag
)
{
//do not use flag weight for now, just 1 hit is enough
if
(
flag
.
drone_collider_list
.
length
===
0
)
{
//if (flag.drone_collider_list.length < flag.weight) {
finish
=
false
;
}
});
return
finish
;
};
GameManager
.
prototype
.
_calculateUserScore
=
function
()
{
GameManager
.
prototype
.
_calculateUserScore
=
function
()
{
var
score
=
0
;
var
score
=
0
;
this
.
_droneList_user
.
forEach
(
function
(
drone
)
{
this
.
_droneList_user
.
forEach
(
function
(
drone
)
{
//if (drone.can_play) {
score
+=
drone
.
score
;
score
+=
drone
.
score
;
//}
});
});
return
score
;
return
score
;
};
};
...
@@ -1135,13 +1092,15 @@ var GameManager = /** @class */ (function () {
...
@@ -1135,13 +1092,15 @@ var GameManager = /** @class */ (function () {
this
.
_scene
this
.
_scene
);
);
hemi_south
.
intensity
=
0.75
;
hemi_south
.
intensity
=
0.75
;
cam_radius
=
(
GAMEPARAMETERS
.
map
.
map_size
*
1.10
<
6000
)
?
//HARDCODE camera to a hardcoded map_size
GAMEPARAMETERS
.
map
.
map_size
*
1.10
:
6000
;
//skybox scene limit
var
map_size
=
900
;
//GAMEPARAMETERS.map.map_size
//skybox scene limit
cam_radius
=
(
map_size
*
1.10
<
6000
)
?
map_size
*
1.10
:
6000
;
camera
=
new
BABYLON
.
ArcRotateCamera
(
"
camera
"
,
0
,
1.25
,
cam_radius
,
camera
=
new
BABYLON
.
ArcRotateCamera
(
"
camera
"
,
0
,
1.25
,
cam_radius
,
BABYLON
.
Vector3
.
Zero
(),
this
.
_scene
);
BABYLON
.
Vector3
.
Zero
(),
this
.
_scene
);
camera
.
wheelPrecision
=
10
;
camera
.
wheelPrecision
=
10
;
//zoom out limit
//zoom out limit
camera
.
upperRadiusLimit
=
GAMEPARAMETERS
.
map
.
map_size
*
10
;
camera
.
upperRadiusLimit
=
map_size
*
10
;
//scene.activeCamera.upperRadiusLimit = max * 4;
//scene.activeCamera.upperRadiusLimit = max * 4;
//changed for event handling
//changed for event handling
//camera.attachControl(this._scene.getEngine().getRenderingCanvas()); //orig
//camera.attachControl(this._scene.getEngine().getRenderingCanvas()); //orig
...
@@ -1161,10 +1120,10 @@ var GameManager = /** @class */ (function () {
...
@@ -1161,10 +1120,10 @@ var GameManager = /** @class */ (function () {
ctx
.
_map_swapped
=
true
;
ctx
.
_map_swapped
=
true
;
}
}
// Init the map
// Init the map
_this
.
_mapManager
=
new
MapManager
(
ctx
.
_scene
);
_this
.
_mapManager
=
new
MapManager
(
ctx
.
_scene
,
GAMEPARAMETERS
.
map
);
ctx
.
_spawnDrones
(
_this
.
_mapManager
.
getMapInfo
().
initial_position
,
ctx
.
_spawnDrones
(
_this
.
_mapManager
.
getMapInfo
().
initial_position
,
GAMEPARAMETERS
.
map
.
drones
.
user
,
TEAM_USER
,
ctx
);
GAMEPARAMETERS
.
drone
.
list
,
TEAM_USER
,
ctx
);
ctx
.
_spawnDrones
(
null
,
GAMEPARAMETERS
.
map
.
drones
.
enemy
,
TEAM_ENEMY
,
ctx
);
ctx
.
_spawnDrones
(
null
,
_this
.
_mapManager
.
_enemy_list
,
TEAM_ENEMY
,
ctx
);
// Hide the drone prefab
// Hide the drone prefab
DroneManager
.
Prefab
.
isVisible
=
false
;
DroneManager
.
Prefab
.
isVisible
=
false
;
//Hack to make advanced texture work
//Hack to make advanced texture work
...
@@ -1246,9 +1205,7 @@ var GameManager = /** @class */ (function () {
...
@@ -1246,9 +1205,7 @@ var GameManager = /** @class */ (function () {
drone
.
_tick
=
0
;
drone
.
_tick
=
0
;
promise_list
.
push
(
drone
.
internal_start
());
promise_list
.
push
(
drone
.
internal_start
());
});
});
start_msg
=
{
start_msg
=
GAMEPARAMETERS
.
operator_init_msg
;
'
flag_positions
'
:
_this
.
_mapManager
.
getMapInfo
().
geo_flag_list
};
promise_list
.
push
(
_this
.
_droneList_user
[
0
].
sendMsg
(
start_msg
));
promise_list
.
push
(
_this
.
_droneList_user
[
0
].
sendMsg
(
start_msg
));
_this
.
_droneList_enemy
.
forEach
(
function
(
drone
)
{
_this
.
_droneList_enemy
.
forEach
(
function
(
drone
)
{
drone
.
_tick
=
0
;
drone
.
_tick
=
0
;
...
@@ -1259,6 +1216,8 @@ var GameManager = /** @class */ (function () {
...
@@ -1259,6 +1216,8 @@ var GameManager = /** @class */ (function () {
.
push
(
function
()
{
.
push
(
function
()
{
_this
.
_canUpdate
=
true
;
_this
.
_canUpdate
=
true
;
return
_this
.
finish_deferred
.
promise
;
return
_this
.
finish_deferred
.
promise
;
},
function
(
error
)
{
throw
new
Error
(
'
Error on drone initialization msg -
'
+
error
.
message
);
});
});
};
};
...
@@ -1321,15 +1280,14 @@ var GameManager = /** @class */ (function () {
...
@@ -1321,15 +1280,14 @@ var GameManager = /** @class */ (function () {
return
false
;
return
false
;
}
}
function
spawnDrone
(
x
,
y
,
z
,
index
,
drone_info
,
api
,
team
)
{
function
spawnDrone
(
x
,
y
,
z
,
index
,
drone_info
,
api
,
team
)
{
var
default_drone_AI
=
api
.
getDroneAI
(),
code
,
base
,
code_eval
,
trim
;
var
default_drone_AI
=
api
.
getDroneAI
(),
code
,
code_eval
;
if
(
default_drone_AI
)
{
if
(
default_drone_AI
)
{
code
=
default_drone_AI
;
code
=
default_drone_AI
;
}
else
{
}
else
{
code
=
drone_info
.
script_content
;
code
=
drone_info
.
script_content
;
}
}
trim
=
code
.
trim
();
if
(
!
code
.
includes
(
"
me.onStart
"
))
{
if
(
!
trim
)
{
code
=
"
me.onStart = function () { me.exit(); };
"
;
code
=
"
me.onStart = function () { forcedErrorEmptyScript };
"
;
}
}
code_eval
=
"
let drone = new DroneManager(ctx._scene,
"
+
code_eval
=
"
let drone = new DroneManager(ctx._scene,
"
+
index
+
'
, api, team);
'
+
index
+
'
, api, team);
'
+
...
@@ -1349,17 +1307,18 @@ var GameManager = /** @class */ (function () {
...
@@ -1349,17 +1307,18 @@ var GameManager = /** @class */ (function () {
if
(
x
!==
null
&&
y
!==
null
&&
z
!==
null
)
{
if
(
x
!==
null
&&
y
!==
null
&&
z
!==
null
)
{
code_eval
+=
"
me.setStartingPosition(
"
+
x
+
"
,
"
+
y
+
"
,
"
+
z
+
"
);
"
;
code_eval
+=
"
me.setStartingPosition(
"
+
x
+
"
,
"
+
y
+
"
,
"
+
z
+
"
);
"
;
}
}
base
=
code_eval
;
//
base = code_eval;
code_eval
+=
code
+
"
}; droneMe(Date, drone, Math, {});
"
;
code_eval
+=
code
+
"
}; droneMe(Date, drone, Math, {});
"
;
base
+=
"
};ctx._droneList_
"
+
team
+
"
.push(drone)
"
;
//
base += "};ctx._droneList_" + team + ".push(drone)";
code_eval
+=
"
ctx._droneList_
"
+
team
+
"
.push(drone)
"
;
code_eval
+=
"
ctx._droneList_
"
+
team
+
"
.push(drone)
"
;
/*jslint evil: true*/
/*jslint evil: true*/
try
{
eval
(
code_eval
);
/*jslint evil: false*/
/*try {
eval(code_eval);
eval(code_eval);
} catch (error) {
} catch (error) {
eval(base);
eval(base);
}
}*/
/*jslint evil: false*/
}
}
function
randomSpherePoint
(
x0
,
y0
,
z0
,
rx0
,
ry0
,
rz0
)
{
function
randomSpherePoint
(
x0
,
y0
,
z0
,
rx0
,
ry0
,
rz0
)
{
var
u
=
Math
.
random
(),
v
=
Math
.
random
(),
var
u
=
Math
.
random
(),
v
=
Math
.
random
(),
...
@@ -1388,7 +1347,7 @@ var GameManager = /** @class */ (function () {
...
@@ -1388,7 +1347,7 @@ var GameManager = /** @class */ (function () {
position_list
.
push
(
position
);
position_list
.
push
(
position
);
var
id_offset
=
0
;
var
id_offset
=
0
;
if
(
team
==
TEAM_ENEMY
)
{
if
(
team
==
TEAM_ENEMY
)
{
id_offset
=
GAMEPARAMETERS
.
map
.
drones
.
user
.
length
;
id_offset
=
GAMEPARAMETERS
.
drone
.
list
.
length
;
}
}
api
=
new
this
.
APIs_dict
[
drone_list
[
i
].
type
](
api
=
new
this
.
APIs_dict
[
drone_list
[
i
].
type
](
this
,
this
,
...
@@ -1429,12 +1388,6 @@ var runGame, updateGame;
...
@@ -1429,12 +1388,6 @@ var runGame, updateGame;
}
}
};
};
/*// Resize canvas on window resize
window.addEventListener('resize', function () {
game_manager_instance._engine.resize();
});*/
}(
this
));
}(
this
));
/******************************************************************************/
/******************************************************************************/
\ No newline at end of file
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_logic_js.xml
View file @
3a9d947c
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
101
0.23697.26501.43008
</string>
</value>
<value>
<string>
101
1.18882.27011.1501
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
169
1684378.73
</float>
<float>
169
5327797.6
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_map_utils_js.js
0 → 100644
View file @
3a9d947c
/******************************* MAP UTILS ************************************/
var
MapUtils
=
/** @class */
(
function
()
{
"
use strict
"
;
var
FLAG_EPSILON
=
15
,
R
=
6371
e3
;
//** CONSTRUCTOR
function
MapUtils
(
map_param
)
{
var
_this
=
this
,
max_width
=
_this
.
latLonDistance
(
[
map_param
.
min_lat
,
map_param
.
min_lon
],
[
map_param
.
min_lat
,
map_param
.
max_lon
]),
max_depth
=
_this
.
latLonDistance
(
[
map_param
.
min_lat
,
map_param
.
min_lon
],
[
map_param
.
max_lat
,
map_param
.
min_lon
]),
map_size
=
Math
.
ceil
(
Math
.
max
(
max_width
,
max_depth
));
_this
.
map_param
=
{};
_this
.
map_param
.
height
=
map_param
.
height
;
_this
.
map_param
.
start_AMSL
=
map_param
.
start_AMSL
;
_this
.
map_param
.
min_lat
=
map_param
.
min_lat
;
_this
.
map_param
.
max_lat
=
map_param
.
max_lat
;
_this
.
map_param
.
min_lon
=
map_param
.
min_lon
;
_this
.
map_param
.
max_lon
=
map_param
.
max_lon
;
_this
.
map_param
.
depth
=
map_size
;
_this
.
map_param
.
width
=
map_size
;
_this
.
map_param
.
map_size
=
map_size
;
_this
.
map_info
=
{
"
depth
"
:
_this
.
map_param
.
depth
,
"
width
"
:
_this
.
map_param
.
width
,
"
flag_distance_epsilon
"
:
map_param
.
flag_distance_epsilon
||
FLAG_EPSILON
};
_this
.
map_info
.
map_size
=
_this
.
map_param
.
map_size
;
_this
.
map_info
.
height
=
_this
.
map_param
.
height
;
_this
.
map_info
.
start_AMSL
=
_this
.
map_param
.
start_AMSL
;
_this
.
map_info
.
min_x
=
_this
.
longitudToX
(
map_param
.
min_lon
);
_this
.
map_info
.
min_y
=
_this
.
latitudeToY
(
map_param
.
min_lat
);
_this
.
map_info
.
max_x
=
_this
.
longitudToX
(
map_param
.
max_lon
);
_this
.
map_info
.
max_y
=
_this
.
latitudeToY
(
map_param
.
max_lat
);
}
MapUtils
.
prototype
.
latLonDistance
=
function
(
c1
,
c2
)
{
var
q1
=
c1
[
0
]
*
Math
.
PI
/
180
,
q2
=
c2
[
0
]
*
Math
.
PI
/
180
,
dq
=
(
c2
[
0
]
-
c1
[
0
])
*
Math
.
PI
/
180
,
dl
=
(
c2
[
1
]
-
c1
[
1
])
*
Math
.
PI
/
180
,
a
=
Math
.
sin
(
dq
/
2
)
*
Math
.
sin
(
dq
/
2
)
+
Math
.
cos
(
q1
)
*
Math
.
cos
(
q2
)
*
Math
.
sin
(
dl
/
2
)
*
Math
.
sin
(
dl
/
2
),
c
=
2
*
Math
.
atan2
(
Math
.
sqrt
(
a
),
Math
.
sqrt
(
1
-
a
));
return
R
*
c
;
};
MapUtils
.
prototype
.
longitudToX
=
function
(
lon
)
{
return
(
this
.
map_info
.
map_size
/
360.0
)
*
(
180
+
lon
);
};
MapUtils
.
prototype
.
latitudeToY
=
function
(
lat
)
{
return
(
this
.
map_info
.
map_size
/
180.0
)
*
(
90
-
lat
);
};
MapUtils
.
prototype
.
convertToLocalCoordinates
=
function
(
latitude
,
longitude
,
altitude
)
{
var
map_info
=
this
.
map_info
,
x
=
this
.
longitudToX
(
longitude
),
y
=
this
.
latitudeToY
(
latitude
);
return
{
x
:
((
x
-
map_info
.
min_x
)
/
(
map_info
.
max_x
-
map_info
.
min_x
))
*
1000
-
map_info
.
width
/
2
,
y
:
((
y
-
map_info
.
min_y
)
/
(
map_info
.
max_y
-
map_info
.
min_y
))
*
1000
-
map_info
.
depth
/
2
,
z
:
altitude
};
};
MapUtils
.
prototype
.
convertToGeoCoordinates
=
function
(
x
,
y
,
z
)
{
var
lon
=
x
+
this
.
map_info
.
width
/
2
,
lat
=
y
+
this
.
map_info
.
depth
/
2
;
lon
=
lon
/
1000
;
lon
=
lon
*
(
this
.
map_info
.
max_x
-
this
.
map_info
.
min_x
)
+
this
.
map_info
.
min_x
;
lon
=
lon
/
(
this
.
map_info
.
map_size
/
360.0
)
-
180
;
lat
=
lat
/
1000
;
lat
=
lat
*
(
this
.
map_info
.
max_y
-
this
.
map_info
.
min_y
)
+
this
.
map_info
.
min_y
;
lat
=
90
-
lat
/
(
this
.
map_info
.
map_size
/
180.0
);
return
{
x
:
lat
,
y
:
lon
,
z
:
z
};
};
/*
** Randomizes all map elements: starting point, enemies, flags, obstacles
*/
MapUtils
.
prototype
.
randomizeByBlockTemplates
=
function
(
seed
)
{
function
normalize
(
x
,
min
,
max
)
{
return
min
+
(
max
-
min
)
*
x
/
100
;
}
function
fillTemplate
(
template
,
min_x
,
min_y
,
max_x
,
max_y
)
{
function
fillFlagList
(
list
,
min_x
,
min_y
,
max_x
,
max_y
)
{
var
i
,
el
,
result_list
=
[];
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
el
=
{
"
position
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
},
"
score
"
:
list
[
i
].
score
,
"
weight
"
:
list
[
i
].
weight
};
el
.
position
.
x
=
normalize
(
list
[
i
].
position
.
x
,
min_x
,
max_x
);
el
.
position
.
y
=
normalize
(
list
[
i
].
position
.
y
,
min_y
,
max_y
);
//TODO normalize z to map height?
el
.
position
.
z
=
list
[
i
].
position
.
z
;
result_list
.
push
(
el
);
}
return
result_list
;
}
function
fillEnemyList
(
list
,
min_x
,
min_y
,
max_x
,
max_y
)
{
var
i
,
el
,
result_list
=
[];
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
el
=
{
"
position
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
},
"
type
"
:
list
[
i
].
type
};
el
.
position
.
x
=
normalize
(
list
[
i
].
position
.
x
,
min_x
,
max_x
);
el
.
position
.
y
=
normalize
(
list
[
i
].
position
.
y
,
min_y
,
max_y
);
//TODO normalize z to map height?
el
.
position
.
z
=
list
[
i
].
position
.
z
;
result_list
.
push
(
el
);
}
return
result_list
;
}
function
fillObstacleList
(
list
,
min_x
,
min_y
,
max_x
,
max_y
)
{
var
i
,
el
,
result_list
=
[];
for
(
i
=
0
;
i
<
list
.
length
;
i
+=
1
)
{
el
=
{
"
position
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
},
"
scale
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
},
"
type
"
:
list
[
i
].
type
};
if
(
list
[
i
].
rotation
)
{
el
.
rotation
=
{
"
x
"
:
list
[
i
].
rotation
.
x
,
"
y
"
:
list
[
i
].
rotation
.
y
,
"
z
"
:
list
[
i
].
rotation
.
z
};
}
el
.
position
.
x
=
normalize
(
list
[
i
].
position
.
x
,
min_x
,
max_x
);
el
.
position
.
y
=
normalize
(
list
[
i
].
position
.
y
,
min_y
,
max_y
);
//TODO normalize z to map height?
el
.
position
.
z
=
list
[
i
].
position
.
z
;
el
.
scale
.
x
=
normalize
(
list
[
i
].
scale
.
x
,
0
,
Math
.
abs
(
max_x
-
min_x
));
el
.
scale
.
y
=
normalize
(
list
[
i
].
scale
.
y
,
0
,
Math
.
abs
(
max_x
-
min_x
));
//TODO normalize z to map height?
el
.
scale
.
z
=
list
[
i
].
scale
.
z
;
result_list
.
push
(
el
);
}
return
result_list
;
}
return
{
"
flag_list
"
:
fillFlagList
(
template
.
flag_list
,
min_x
,
min_y
,
max_x
,
max_y
),
"
obstacle_list
"
:
fillObstacleList
(
template
.
obstacle_list
,
min_x
,
min_y
,
max_x
,
max_y
),
"
enemy_list
"
:
fillEnemyList
(
template
.
enemy_list
,
min_x
,
min_y
,
max_x
,
max_y
)
};
}
// 4x4 grid
var
GRID
=
4
,
i
,
j
,
map_size
=
this
.
map_info
.
map_size
,
initial_block
,
x1
,
y1
,
x2
,
y2
,
block_result
,
index
,
block_size
=
map_size
/
GRID
,
result_map
,
BLOCK_TEMPLATE_LIST
=
[{
"
flag_list
"
:
[{
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
50
,
"
z
"
:
10
},
"
score
"
:
1
,
"
weight
"
:
1
}],
"
obstacle_list
"
:
[{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
70
,
"
z
"
:
20
},
"
scale
"
:
{
"
x
"
:
80
,
"
y
"
:
4
,
"
z
"
:
40
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}}],
"
enemy_list
"
:
[{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
30
,
"
z
"
:
10
}}
]
},
{
"
flag_list
"
:
[],
"
obstacle_list
"
:
[{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
20
,
"
y
"
:
65
,
"
z
"
:
20
},
"
scale
"
:
{
"
x
"
:
4
,
"
y
"
:
70
,
"
z
"
:
40
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}},
{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
35
,
"
z
"
:
20
},
"
scale
"
:
{
"
x
"
:
4
,
"
y
"
:
70
,
"
z
"
:
40
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}},
{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
80
,
"
y
"
:
65
,
"
z
"
:
20
},
"
scale
"
:
{
"
x
"
:
4
,
"
y
"
:
70
,
"
z
"
:
40
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}}],
"
enemy_list
"
:
[]
},
{
"
flag_list
"
:
[],
"
obstacle_list
"
:
[{
"
type
"
:
"
mountain
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
50
,
"
z
"
:
200
},
"
scale
"
:
{
"
x
"
:
80
,
"
y
"
:
80
,
"
z
"
:
400
}
//this.map_info.height?
}],
"
enemy_list
"
:
[]
},
{
"
flag_list
"
:
[],
"
obstacle_list
"
:
[],
"
enemy_list
"
:
[{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
20
,
"
y
"
:
20
,
"
z
"
:
10
}},
{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
20
,
"
y
"
:
80
,
"
z
"
:
10
}},
{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
80
,
"
y
"
:
20
,
"
z
"
:
10
}},
{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
80
,
"
y
"
:
80
,
"
z
"
:
10
}}]
},
{
"
flag_list
"
:
[{
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
50
,
"
z
"
:
10
},
"
score
"
:
1
,
"
weight
"
:
1
}],
"
obstacle_list
"
:
[],
"
enemy_list
"
:
[]
},
{
"
flag_list
"
:
[{
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
50
,
"
z
"
:
10
},
"
score
"
:
1
,
"
weight
"
:
1
}],
"
obstacle_list
"
:
[],
"
enemy_list
"
:
[{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
20
,
"
z
"
:
10
}},
{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
80
,
"
z
"
:
10
}}]
},
{
"
flag_list
"
:
[{
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
50
,
"
z
"
:
10
},
"
score
"
:
1
,
"
weight
"
:
1
}],
"
obstacle_list
"
:
[{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
10
,
"
z
"
:
25
},
"
scale
"
:
{
"
x
"
:
80
,
"
y
"
:
2
,
"
z
"
:
50
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}},
{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
10
,
"
y
"
:
50
,
"
z
"
:
25
},
"
scale
"
:
{
"
x
"
:
2
,
"
y
"
:
80
,
"
z
"
:
50
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}},
{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
50
,
"
y
"
:
90
,
"
z
"
:
25
},
"
scale
"
:
{
"
x
"
:
80
,
"
y
"
:
2
,
"
z
"
:
50
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}},
{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
90
,
"
y
"
:
50
,
"
z
"
:
25
},
"
scale
"
:
{
"
x
"
:
2
,
"
y
"
:
80
,
"
z
"
:
50
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}}],
"
enemy_list
"
:
[]
},
{
"
flag_list
"
:
[],
"
obstacle_list
"
:
[],
"
enemy_list
"
:
[]
}];
function
getInitialBlock
(
GRID
)
{
var
x
,
y
;
do
{
x
=
Math
.
floor
(
seed
.
quick
()
*
GRID
);
y
=
Math
.
floor
(
seed
.
quick
()
*
GRID
);
//ensure intial block is in the edge of map
}
while
(
x
!==
0
&&
x
!==
GRID
-
1
&&
y
!==
0
&&
y
!==
GRID
-
1
);
return
{
x
:
x
,
y
:
y
};
}
initial_block
=
getInitialBlock
(
GRID
);
function
checkConditions
(
json_map
,
GRID
)
{
if
(
!
json_map
)
return
false
;
// set ~20% of the blocks with flags
if
(
json_map
.
flag_list
.
length
!==
Math
.
round
(
GRID
*
GRID
*
0.2
))
return
false
;
// limit n_mountains
if
(
json_map
.
obstacle_list
.
length
>
3
)
{
var
i
,
n_mountains
=
0
;
for
(
i
=
0
;
i
<
json_map
.
obstacle_list
.
length
;
i
+=
1
)
{
if
(
json_map
.
obstacle_list
[
i
].
type
===
"
mountain
"
)
{
n_mountains
+=
1
;
if
(
n_mountains
>
3
)
{
return
false
;
}
json_map
.
obstacle_list
[
i
].
type
=
"
box
"
;
}
}
}
var
f
;
// at least one flag in the oposite side of drones initial position
for
(
f
=
0
;
f
<
json_map
.
flag_list
.
length
;
f
+=
1
)
{
if
((
json_map
.
flag_list
[
f
].
position
.
x
*
json_map
.
initial_position
.
x
)
<
0
||
(
json_map
.
flag_list
[
f
].
position
.
y
*
json_map
.
initial_position
.
y
)
<
0
)
{
return
true
;
}
}
return
false
;
}
do
{
result_map
=
{
"
flag_list
"
:
[],
"
obstacle_list
"
:
[],
"
enemy_list
"
:
[]
};
for
(
i
=
0
;
i
<
GRID
;
i
+=
1
)
{
for
(
j
=
0
;
j
<
GRID
;
j
+=
1
)
{
index
=
Math
.
floor
(
seed
.
quick
()
*
BLOCK_TEMPLATE_LIST
.
length
);
x1
=
block_size
*
i
-
map_size
/
2
;
y1
=
block_size
*
j
-
map_size
/
2
;
x2
=
block_size
*
i
+
block_size
-
map_size
/
2
;
y2
=
block_size
*
j
+
block_size
-
map_size
/
2
;
if
(
initial_block
.
x
===
i
&&
initial_block
.
y
===
j
)
{
result_map
.
initial_position
=
{
x
:
normalize
(
50
,
x1
,
x2
),
y
:
normalize
(
50
,
y1
,
y2
),
z
:
15
};
}
else
{
block_result
=
fillTemplate
(
BLOCK_TEMPLATE_LIST
[
index
],
x1
,
y1
,
x2
,
y2
);
result_map
.
flag_list
=
result_map
.
flag_list
.
concat
(
block_result
.
flag_list
);
result_map
.
obstacle_list
=
result_map
.
obstacle_list
.
concat
(
block_result
.
obstacle_list
);
result_map
.
enemy_list
=
result_map
.
enemy_list
.
concat
(
block_result
.
enemy_list
);
}
}
}
}
while
(
!
checkConditions
(
result_map
,
GRID
));
return
result_map
;
};
/*
** Generates a random map json
*/
MapUtils
.
prototype
.
randomize
=
function
(
seed
)
{
//TODO randomize start_ASML, map height, depth and width?
var
_this
=
this
,
flag_list
,
obstacle_list
,
enemy_list
,
geo_flag_info
,
geo_obstacle
,
geo_enemy
,
coordinates
,
random_seed
=
new
Math
.
seedrandom
(
seed
),
randomized_map
=
_this
.
randomizeByBlockTemplates
(
random_seed
);
obstacle_list
=
randomized_map
.
obstacle_list
;
enemy_list
=
randomized_map
.
enemy_list
;
flag_list
=
randomized_map
.
flag_list
;
_this
.
map_param
.
obstacle_list
=
[];
_this
.
map_param
.
enemy_list
=
[];
_this
.
map_param
.
flag_list
=
[];
//convert all map elements positions to geo coordinates
_this
.
map_info
.
initial_position
=
_this
.
convertToGeoCoordinates
(
randomized_map
.
initial_position
.
x
,
randomized_map
.
initial_position
.
y
,
randomized_map
.
initial_position
.
z
);
Object
.
assign
(
_this
.
map_info
,
_this
.
map_param
);
flag_list
.
forEach
(
function
(
flag_info
,
index
)
{
coordinates
=
_this
.
convertToGeoCoordinates
(
flag_info
.
position
.
x
,
flag_info
.
position
.
y
,
flag_info
.
position
.
z
);
geo_flag_info
=
{
'
id
'
:
flag_info
.
id
,
'
score
'
:
flag_info
.
score
,
'
weight
'
:
flag_info
.
weight
,
'
position
'
:
{
'
x
'
:
coordinates
.
x
,
'
y
'
:
coordinates
.
y
,
'
z
'
:
coordinates
.
z
}
};
_this
.
map_info
.
flag_list
.
push
(
geo_flag_info
);
});
obstacle_list
.
forEach
(
function
(
obstacle_info
,
index
)
{
geo_obstacle
=
{};
Object
.
assign
(
geo_obstacle
,
obstacle_info
);
geo_obstacle
.
position
=
_this
.
convertToGeoCoordinates
(
obstacle_info
.
position
.
x
,
obstacle_info
.
position
.
y
,
obstacle_info
.
position
.
z
);
_this
.
map_info
.
obstacle_list
.
push
(
geo_obstacle
);
});
enemy_list
.
forEach
(
function
(
enemy_info
,
index
)
{
geo_enemy
=
{};
Object
.
assign
(
geo_enemy
,
enemy_info
);
geo_enemy
.
position
=
_this
.
convertToGeoCoordinates
(
enemy_info
.
position
.
x
,
enemy_info
.
position
.
y
,
enemy_info
.
position
.
z
);
_this
.
map_info
.
enemy_list
.
push
(
geo_enemy
);
});
//return only base parameters
randomized_map
.
min_lat
=
_this
.
map_info
.
min_lat
;
randomized_map
.
max_lat
=
_this
.
map_info
.
max_lat
;
randomized_map
.
min_lon
=
_this
.
map_info
.
min_lon
;
randomized_map
.
max_lon
=
_this
.
map_info
.
max_lon
;
randomized_map
.
height
=
_this
.
map_info
.
height
;
randomized_map
.
start_AMSL
=
_this
.
map_info
.
start_AMSL
;
randomized_map
.
flag_list
=
_this
.
map_info
.
flag_list
;
randomized_map
.
obstacle_list
=
_this
.
map_info
.
obstacle_list
;
randomized_map
.
enemy_list
=
_this
.
map_info
.
enemy_list
;
randomized_map
.
initial_position
=
_this
.
map_info
.
initial_position
;
return
randomized_map
;
};
return
MapUtils
;
}());
/******************************************************************************/
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/drone_capture_flag_map_utils_js.xml
0 → 100644
View file @
3a9d947c
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Web Script"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_Access_contents_information_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Add_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Change_local_roles_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Modify_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_View_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
content_md5
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
gadget_erp5_page_drone_capture_map_utils.js
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
drone_capture_flag_map_utils_js
</string>
</value>
</item>
<item>
<key>
<string>
language
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
short_title
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Drone Capture Map Utils
</string>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
document_publication_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
edit_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
processing_status_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAU=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
publish_alive
</string>
</value>
</item>
<item>
<key>
<string>
actor
</string>
</key>
<value>
<unicode>
zope
</unicode>
</value>
</item>
<item>
<key>
<string>
comment
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
error_message
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
time
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"DateTime"
module=
"DateTime.DateTime"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<tuple>
<float>
1694185956.38
</float>
<string>
UTC
</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
published_alive
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
edit
</string>
</value>
</item>
<item>
<key>
<string>
actor
</string>
</key>
<value>
<unicode>
zope
</unicode>
</value>
</item>
<item>
<key>
<string>
comment
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
error_message
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1011.18883.7641.45704
</string>
</value>
</item>
<item>
<key>
<string>
state
</string>
</key>
<value>
<string>
current
</string>
</value>
</item>
<item>
<key>
<string>
time
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"DateTime"
module=
"DateTime.DateTime"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<tuple>
<float>
1695327563.61
</float>
<string>
UTC
</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"5"
aka=
"AAAAAAAAAAU="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
actor
</string>
</key>
<value>
<unicode>
zope
</unicode>
</value>
</item>
<item>
<key>
<string>
comment
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
error_message
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_processing_state
</string>
</key>
<value>
<string>
empty
</string>
</value>
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
0.0.0.0
</string>
</value>
</item>
<item>
<key>
<string>
time
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"DateTime"
module=
"DateTime.DateTime"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<tuple>
<float>
1694185881.0
</float>
<string>
UTC
</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_css.css
View file @
3a9d947c
...
@@ -29,6 +29,10 @@
...
@@ -29,6 +29,10 @@
margin
:
0
;
margin
:
0
;
}
}
.documentation
div
{
vertical-align
:
middle
!important
;
}
.documentation
.line
{
.documentation
.line
{
width
:
100%
;
width
:
100%
;
height
:
1px
;
height
:
1px
;
...
@@ -54,7 +58,6 @@
...
@@ -54,7 +58,6 @@
.item-name
span
:last-of-type
{
.item-name
span
:last-of-type
{
font-style
:
italic
;
}
font-style
:
italic
;
}
.line
{
.line
{
width
:
100%
;
width
:
100%
;
height
:
1px
;
height
:
1px
;
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_css.xml
View file @
3a9d947c
...
@@ -242,7 +242,7 @@
...
@@ -242,7 +242,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
101
0.15231.63877.58538
</string>
</value>
<value>
<string>
101
1.7107.64372.12151
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -262,7 +262,7 @@
...
@@ -262,7 +262,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
169
1176394.73
</float>
<float>
169
4621148.77
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.html
View file @
3a9d947c
...
@@ -10,6 +10,141 @@
...
@@ -10,6 +10,141 @@
<div
class=
"documentation"
>
<div
class=
"documentation"
>
<h1>
Game specifications
</h1>
<!-- Map JSON -->
<h3>
Map parameter dictionary (JSON)
</h3>
<div>
<h5
class=
"item-param-1"
>
Map dictionary entries
</h5>
<p
class=
"item-descr"
></p>
</div>
<div>
<h5
class=
"item-param-1"
>
Key
</h5>
<h5
class=
"item-param-2"
>
Description
</h5>
</div>
<div>
<p
class=
"item-param-1"
>
min_lat, max_lat, min_lon, max_lon: Float
</p>
<p
class=
"item-param-2"
>
Min and max latitude and longitude coordinates of the map
</p>
</div>
<div>
<p
class=
"item-param-1"
>
map_size: Integer
</p>
<p
class=
"item-param-2"
>
Map size in meters (calculated from coordinates)
</p>
</div>
<div>
<p
class=
"item-param-1"
>
width, depth: Integer
</p>
<p
class=
"item-param-2"
>
Map width and depth in meters (calculated from coordinates)
</p>
</div>
<div>
<p
class=
"item-param-1"
>
height: Integer
</p>
<p
class=
"item-param-2"
>
Map height in meters
</p>
</div>
<div>
<p
class=
"item-param-1"
>
start_AMSL: Integer
</p>
<p
class=
"item-param-2"
>
Map height above mean sea level in meters
</p>
</div>
<div>
<p
class=
"item-param-1"
>
initial_position: dictionary
</p>
<p
class=
"item-param-2"
>
Drones starting point coordinates
</p>
<p
class=
"item-param-2"
>
{
<br>
x: number, //latitude (in degrees)
<br>
y: number, //longitude (in degrees)
<br>
z: number //altitude (in meters)
<br>
}
<br>
</p>
</div>
<div>
<p
class=
"item-param-1"
>
flag_list: list
</p>
<p
class=
"item-param-2"
>
List of flags, each element:
</p>
<p
class=
"item-param-2"
>
{
<br>
position {x,y,z}:
<br>
latitude, longitude and altitude
<br>
score: number
<br>
weight: number
<br>
}
<br>
</p>
</div>
<div>
<p
class=
"item-param-1"
>
obstacle_list: list
</p>
<p
class=
"item-param-2"
>
List of obstacles, each element:
</p>
<p
class=
"item-param-2"
>
{
<br>
position {x,y,z}:
<br>
latitude, longitude and altitude
<br>
type: [box, cilinder, sphere]
<br>
scale: {x,y,z}
<br>
rotation: {x,y,z}
<br>
}
<br>
</p>
</div>
<div>
<p
class=
"item-param-1"
>
enemy_list: list
</p>
<p
class=
"item-param-2"
>
List of enemies, each element:
</p>
<p
class=
"item-param-2"
>
{
<br>
position {x,y,z}:
<br>
latitude, longitude and altitude
<br>
type: drone-type
<br>
id: number
<br>
}
<br>
</p>
</div>
<div
class=
"line"
></div>
<h3>
Operator script
</h3>
<!-- Operator script -->
<h4
class=
"item-name"
id=
"scoring"
><span>
Operator
</span></h4>
<p
class=
"item-descr"
>
The purpose of this script is to set the initial message that all the drones will get at the beginning of the game.
</p>
<p
class=
"item-descr"
>
The map parameter dictionary can be accessed to get any relevant info.
</p>
<p
class=
"item-descr"
>
An API is provided through the object
<em>
operator
</em>
that allows to get the map json and set the intial message.
</p>
<h4
class=
"item-name"
id=
"scoring"
><span>
API
</span></h4>
<div>
<p
class=
"item-param-1"
>
getMapJSON(): dictionary
</p>
<p
class=
"item-param-2"
>
Get the map JSON dictionary
</p>
</div>
<div>
<p
class=
"item-param-1"
>
sendMsg(msg): void
</p>
<p
class=
"item-param-2"
>
Set the initial msg all the drones will get at the start.
</p>
<p
class=
"item-param-2"
>
Message parameter msg must be a dictionary
</p>
</div>
<h5
class=
"item-param-1"
>
Example
</h5>
<p
class=
"item-example"
>
var map = operator.getMapJSON();
<br>
operator.sendMsg({flag_positions: map.flag_list});
</p>
<div
class=
"line"
></div>
<h3>
Game scoring
</h3>
<!-- Scoring -->
<h4
class=
"item-name"
id=
"scoring"
><span>
Score
</span></h4>
<p
class=
"item-descr"
>
Every flag has a score, every drone hit on the flag will give it that score value.
</p>
<p
class=
"item-descr"
>
The number of hits on a flag is determined by its weight.
</p>
<p
class=
"item-descr"
>
Once the number of hits is equal to the flag weight, no more score will be given on following hits.
</p>
<p
class=
"item-descr"
>
Total score is the sum of all drones score when the game finishes.
</p>
<h5
class=
"item-param-1"
>
Example
</h5>
<p
class=
"item-example"
>
A flag with score=3 and weight=2 will grant 3 score points on every drone hit, up to 2 hits.
</p>
<div
class=
"line"
></div>
<h1>
Fixed Wings Drone API
</h1>
<h1>
Fixed Wings Drone API
</h1>
<h3>
API functions
</h3>
<h3>
API functions
</h3>
...
@@ -442,7 +577,7 @@
...
@@ -442,7 +577,7 @@
<!-- id -->
<!-- id -->
<h4
class=
"item-name"
id=
"id"
><span>
id
</span><span>
: number
</span></h4>
<h4
class=
"item-name"
id=
"id"
><span>
id
</span><span>
: number
</span></h4>
<p
class=
"item-descr"
>
Drone unique numeric identifier
: from 0 to 9
.
</p>
<p
class=
"item-descr"
>
Drone unique numeric identifier.
</p>
<h5
class=
"item-param-1"
>
Example
</h5>
<h5
class=
"item-param-1"
>
Example
</h5>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_API_page_html.xml
View file @
3a9d947c
...
@@ -244,7 +244,7 @@
...
@@ -244,7 +244,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
101
0.23624.18144.48810
</string>
</value>
<value>
<string>
101
1.7129.2983.29201
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -264,7 +264,7 @@
...
@@ -264,7 +264,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
169
1679891.23
</float>
<float>
169
4622336.88
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_css.css
0 → 100644
View file @
3a9d947c
div
[
data-gadget-url
$
=
"gadget_erp5_page_drone_capture_flag_script_page.html"
]
.item-label
{
background-color
:
#F8F8F8
;
padding
:
8px
;
margin
:
8px
0
;
font-size
:
1.2em
;
font-weight
:
bold
;
}
div
[
data-gadget-url
$
=
"gadget_erp5_page_drone_capture_flag_script_page.html"
]
button
{
color
:
#212529
;
padding
:
3pt
;
border
:
1px
solid
rgba
(
0
,
0
,
0
,
0.14
);
border-radius
:
0.325em
;
display
:
inline-block
;
margin-right
:
6pt
;
}
div
[
data-gadget-url
$
=
"gadget_erp5_page_drone_capture_flag_script_page.html"
]
button
:disabled
,
div
[
data-gadget-url
$
=
"gadget_erp5_page_drone_capture_flag_script_page.html"
]
button
[
disabled
]
{
color
:
#999999
;
}
div
[
data-gadget-url
$
=
"gadget_erp5_page_drone_capture_flag_script_page.html"
]
button
:before
{
padding-right
:
0.2em
;
}
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_css.xml
0 → 100644
View file @
3a9d947c
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"Web Style"
module=
"erp5.portal_type"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_Access_contents_information_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Add_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Change_local_roles_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_Modify_portal_content_Permission
</string>
</key>
<value>
<tuple>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
_View_Permission
</string>
</key>
<value>
<tuple>
<string>
Anonymous
</string>
<string>
Assignee
</string>
<string>
Assignor
</string>
<string>
Associate
</string>
<string>
Auditor
</string>
<string>
Manager
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
content_md5
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
default_reference
</string>
</key>
<value>
<string>
gadget_erp5_page_drone_capture_flag_script_page.css
</string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
ojs_drone_capture_flag_script_page_css
</string>
</value>
</item>
<item>
<key>
<string>
language
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
short_title
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Drone Capture Flag Script Page CSS
</string>
</value>
</item>
<item>
<key>
<string>
version
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
workflow_history
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"PersistentMapping"
module=
"Persistence.mapping"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
data
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
document_publication_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAM=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
edit_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAQ=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
processing_status_workflow
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAU=
</string>
</persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"3"
aka=
"AAAAAAAAAAM="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
publish_alive
</string>
</value>
</item>
<item>
<key>
<string>
actor
</string>
</key>
<value>
<unicode>
zope
</unicode>
</value>
</item>
<item>
<key>
<string>
comment
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
error_message
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
time
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"DateTime"
module=
"DateTime.DateTime"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<tuple>
<float>
1693841614.38
</float>
<string>
UTC
</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
validation_state
</string>
</key>
<value>
<string>
published_alive
</string>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"4"
aka=
"AAAAAAAAAAQ="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<string>
edit
</string>
</value>
</item>
<item>
<key>
<string>
actor
</string>
</key>
<value>
<unicode>
zope
</unicode>
</value>
</item>
<item>
<key>
<string>
comment
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
error_message
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
1010.65016.4453.48725
</string>
</value>
</item>
<item>
<key>
<string>
state
</string>
</key>
<value>
<string>
current
</string>
</value>
</item>
<item>
<key>
<string>
time
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"DateTime"
module=
"DateTime.DateTime"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<tuple>
<float>
1694183879.39
</float>
<string>
UTC
</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"5"
aka=
"AAAAAAAAAAU="
>
<pickle>
<global
name=
"WorkflowHistoryList"
module=
"Products.ERP5Type.Workflow"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_log
</string>
</key>
<value>
<list>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
actor
</string>
</key>
<value>
<unicode>
zope
</unicode>
</value>
</item>
<item>
<key>
<string>
comment
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
error_message
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
external_processing_state
</string>
</key>
<value>
<string>
empty
</string>
</value>
</item>
<item>
<key>
<string>
serial
</string>
</key>
<value>
<string>
0.0.0.0
</string>
</value>
</item>
<item>
<key>
<string>
time
</string>
</key>
<value>
<object>
<klass>
<global
name=
"_reconstructor"
module=
"copy_reg"
/>
</klass>
<tuple>
<global
name=
"DateTime"
module=
"DateTime.DateTime"
/>
<global
name=
"object"
module=
"__builtin__"
/>
<none/>
</tuple>
<state>
<tuple>
<float>
1693841589.15
</float>
<string>
UTC
</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_html.html
View file @
3a9d947c
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<html>
<!--
data-i18n=Others
data-i18n=Tools
-->
<head>
<head>
<meta
http-equiv=
"Content-type"
content=
"text/html; charset=utf-8"
/>
<meta
http-equiv=
"Content-type"
content=
"text/html; charset=utf-8"
/>
<meta
name=
"viewport"
content=
"width=device-width"
/>
<meta
name=
"viewport"
content=
"width=device-width"
/>
<title>
Drone Capture Flag Script Page
</title>
<title>
Drone Capture Flag Script Page
</title>
<link
rel=
"http://www.renderjs.org/rel/interface"
href=
"interface_page.html"
>
<link
rel=
"http://www.renderjs.org/rel/interface"
href=
"interface_page.html"
>
<link
rel=
"stylesheet"
type=
"text/css"
href=
"gadget_erp5_page_drone_capture_flag_script_page.css"
>
<!-- renderjs -->
<!-- renderjs -->
<script
src=
"rsvp.js"
type=
"text/javascript"
></script>
<script
src=
"rsvp.js"
type=
"text/javascript"
></script>
...
@@ -18,24 +15,16 @@
...
@@ -18,24 +15,16 @@
<script
src=
"jiodev.js"
type=
"text/javascript"
></script>
<script
src=
"jiodev.js"
type=
"text/javascript"
></script>
<script
src=
"gadget_global.js"
type=
"text/javascript"
></script>
<script
src=
"gadget_global.js"
type=
"text/javascript"
></script>
<script
src=
"domsugar.js"
type=
"text/javascript"
></script>
<script
src=
"domsugar.js"
type=
"text/javascript"
></script>
<script
type=
"text/javascript"
src=
"./libraries/seedrandom.min.js"
></script>
<script
type=
"text/javascript"
src=
"./libraries/seedrandom.min.js"
></script>
<script
src=
"gadget_erp5_page_drone_capture_map_utils.js"
type=
"text/javascript"
></script>
<script
src=
"gadget_erp5_page_drone_capture_flag_script_page.js"
type=
"text/javascript"
></script>
<script
src=
"gadget_erp5_page_drone_capture_flag_script_page.js"
type=
"text/javascript"
></script>
</head>
</head>
<body>
<body>
<form>
<div
class=
"captureflagpageheader"
></div>
<div
data-gadget-url=
"gadget_erp5_form.html"
<div
class=
"captureflagpagebody"
></div>
data-gadget-scope=
"form_view"
data-gadget-sandbox=
"public"
>
</div>
<input
name=
"action_run"
class=
"dialogconfirm"
type=
"submit"
value=
"Run"
style=
"margin-bottom: 20pt;margin-top: 20pt;"
>
<a
data-i18n=
"Storages"
></a>
<!-- for zelenium test common macro -->
<div
class=
"simulator_div"
></div>
<div
data-gadget-url=
"gadget_erp5_form.html"
data-gadget-scope=
"form_view_babylonjs"
data-gadget-sandbox=
"public"
>
</div>
</form>
</body>
</body>
</html>
</html>
\ No newline at end of file
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_html.xml
View file @
3a9d947c
...
@@ -244,7 +244,7 @@
...
@@ -244,7 +244,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
10
08.22253.2281.60074
</string>
</value>
<value>
<string>
10
10.65526.46361.27613
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -264,7 +264,7 @@
...
@@ -264,7 +264,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
16
83820259.6
</float>
<float>
16
94194019.23
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_js.js
View file @
3a9d947c
/*jslint indent: 2, maxlen: 100*/
/*jslint indent: 2, maxlen: 100*/
/*global window, rJS, domsugar, document, URLSearchParams, Blob*/
/*global window, rJS, domsugar, document, Blob, MapUtils, RSVP*/
(
function
(
window
,
rJS
,
domsugar
,
document
,
URLSearchParams
,
Blob
)
{
/******************************* OPERATOR API ********************************/
var
OperatorAPI
=
/** @class */
(
function
()
{
"
use strict
"
;
//** CONSTRUCTOR
function
OperatorAPI
(
json_map
)
{
this
.
message
=
"
default init message
"
;
this
.
json_map
=
json_map
;
}
OperatorAPI
.
prototype
.
getMapJSON
=
function
()
{
return
this
.
json_map
;
};
OperatorAPI
.
prototype
.
sendMsg
=
function
(
msg
)
{
this
.
message
=
msg
;
};
OperatorAPI
.
prototype
.
getDroneStartMessage
=
function
()
{
return
this
.
message
;
};
return
OperatorAPI
;
}());
(
function
(
window
,
rJS
,
domsugar
,
document
,
Blob
,
MapUtils
,
RSVP
)
{
"
use strict
"
;
"
use strict
"
;
//Drone default values - TODO: get them from the drone API
//Drone default values - TODO: get them from the drone API
var
SIMULATION_SPEED
=
1
0
,
var
SIMULATION_SPEED
=
6
0
,
SIMULATION_TIME
=
270
,
SIMULATION_TIME
=
270
,
//HARDCODED map size: it is defined by min-max lat-lon distance
//default square map
//this is done by the map manager (latLonDistance)
MAP_HEIGHT
=
700
,
//but map_size is needed here for map randomization (location of objects)
START_AMSL
=
595
,
//TODO refactor: or randomization is moved to map manager (seed as param)
MIN_LAT
=
45.6419
,
//or randomization is done here but with geo-coordinates (not meters)
MAX_LAT
=
45.65
,
MAP_SIZE
=
900
,
MIN_LON
=
14.265
,
//square map
MAX_LON
=
14.2766
,
min_lat
=
45.6419
,
//seed
max_lat
=
45.65
,
//url_sp = new URLSearchParams(window.location.hash),
min_lon
=
14.265
,
//url_seed = url_sp.get("seed"),
max_lon
=
14.2766
,
SEED
=
'
123
'
,
//'6!',
map_height
=
700
,
MAP
=
{
start_AMSL
=
595
,
"
height
"
:
MAP_HEIGHT
,
"
start_AMSL
"
:
START_AMSL
,
"
min_lat
"
:
MIN_LAT
,
"
max_lat
"
:
MAX_LAT
,
"
min_lon
"
:
MIN_LON
,
"
max_lon
"
:
MAX_LON
,
"
flag_list
"
:
[{
"
position
"
:
{
"
x
"
:
45.6464947316632
,
"
y
"
:
14.270747186236491
,
"
z
"
:
10
},
"
score
"
:
1
,
"
weight
"
:
1
}],
"
obstacle_list
"
:
[{
"
type
"
:
"
box
"
,
"
position
"
:
{
"
x
"
:
45.6456815316444
,
"
y
"
:
14.274667031215898
,
"
z
"
:
15
},
"
scale
"
:
{
"
x
"
:
132
,
"
y
"
:
56
,
"
z
"
:
10
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
}}],
"
enemy_list
"
:
[{
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
45.6455531
,
"
y
"
:
14.270747186236491
,
"
z
"
:
15
}}],
"
initial_position
"
:
{
"
x
"
:
45.642813275
,
"
y
"
:
14.270231599999988
,
"
z
"
:
15
}
},
DEFAULT_SPEED
=
16
,
DEFAULT_SPEED
=
16
,
MAX_ACCELERATION
=
6
,
MAX_ACCELERATION
=
6
,
MAX_DECELERATION
=
1
,
MAX_DECELERATION
=
1
,
...
@@ -29,15 +75,16 @@
...
@@ -29,15 +75,16 @@
MAX_PITCH
=
25
,
MAX_PITCH
=
25
,
MAX_CLIMB_RATE
=
8
,
MAX_CLIMB_RATE
=
8
,
MAX_SINK_RATE
=
3
,
MAX_SINK_RATE
=
3
,
NUMBER_OF_DRONES
=
10
,
NUMBER_OF_DRONES
=
5
,
FLAG_WEIGHT
=
5
,
SEED
=
'
6
'
,
// Non-inputs parameters
// Non-inputs parameters
EPSILON
=
"
15
"
,
DEFAULT_OPERATOR_SCRIPT
=
'
var map = operator.getMapJSON();
\n
'
+
'
operator.sendMsg({flag_positions: map.flag_list});
\n
'
,
DEFAULT_SCRIPT_CONTENT
=
DEFAULT_SCRIPT_CONTENT
=
'
var EPSILON =
15
,
\n
'
+
'
var EPSILON =
'
+
EPSILON
+
'
,
\n
'
+
'
DODGE_DISTANCE = 100;
\n
'
+
'
DODGE_DISTANCE = 100;
\n
'
+
'
\n
'
+
'
\n
'
+
'
function distance(a, b) {
\n
'
+
'
function distance
2D
(a, b) {
\n
'
+
'
var R = 6371e3, // meters
\n
'
+
'
var R = 6371e3, // meters
\n
'
+
'
la1 = a.x * Math.PI / 180, // lat, lon in radians
\n
'
+
'
la1 = a.x * Math.PI / 180, // lat, lon in radians
\n
'
+
'
la2 = b.x * Math.PI / 180,
\n
'
+
'
la2 = b.x * Math.PI / 180,
\n
'
+
...
@@ -49,6 +96,12 @@
...
@@ -49,6 +96,12 @@
'
return 2 * R * Math.asin(Math.sqrt(h));
\n
'
+
'
return 2 * R * Math.asin(Math.sqrt(h));
\n
'
+
'
}
\n
'
+
'
}
\n
'
+
'
\n
'
+
'
\n
'
+
'
function distance(a, b) {
\n
'
+
'
return Math.sqrt(
\n
'
+
'
Math.pow(a.z - b.z, 2) + Math.pow(distance2D(a, b), 2)
\n
'
+
'
);
\n
'
+
'
}
\n
'
+
'
\n
'
+
'
me.onStart = function () {
\n
'
+
'
me.onStart = function () {
\n
'
+
'
me.direction_set = false;
\n
'
+
'
me.direction_set = false;
\n
'
+
'
me.dodging = false;
\n
'
+
'
me.dodging = false;
\n
'
+
...
@@ -57,7 +110,7 @@
...
@@ -57,7 +110,7 @@
'
\n
'
+
'
\n
'
+
'
me.onGetMsg = function (msg) {
\n
'
+
'
me.onGetMsg = function (msg) {
\n
'
+
'
if (msg && msg.flag_positions) {
\n
'
+
'
if (msg && msg.flag_positions) {
\n
'
+
'
me.flag_positions = msg.flag_positions
\n
'
+
'
me.flag_positions = msg.flag_positions
;
\n
'
+
'
me.next_checkpoint = me.id % me.flag_positions.length;
\n
'
+
'
me.next_checkpoint = me.id % me.flag_positions.length;
\n
'
+
'
}
\n
'
+
'
}
\n
'
+
'
};
\n
'
+
'
};
\n
'
+
...
@@ -79,9 +132,9 @@
...
@@ -79,9 +132,9 @@
'
if (!me.direction_set) {
\n
'
+
'
if (!me.direction_set) {
\n
'
+
'
if (me.next_checkpoint < me.flag_positions.length) {
\n
'
+
'
if (me.next_checkpoint < me.flag_positions.length) {
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
'
me.flag_positions[me.next_checkpoint].x,
\n
'
+
'
me.flag_positions[me.next_checkpoint].
position.
x,
\n
'
+
'
me.flag_positions[me.next_checkpoint].y,
\n
'
+
'
me.flag_positions[me.next_checkpoint].
position.
y,
\n
'
+
'
me.flag_positions[me.next_checkpoint].z + me.id
\n
'
+
'
me.flag_positions[me.next_checkpoint].
position.
z + me.id
\n
'
+
'
);
\n
'
+
'
);
\n
'
+
//' console.log("[DEMO] Going to Checkpoint %d", me.next_checkpoint);\n' +
//' console.log("[DEMO] Going to Checkpoint %d", me.next_checkpoint);\n' +
'
}
\n
'
+
'
}
\n
'
+
...
@@ -98,7 +151,7 @@
...
@@ -98,7 +151,7 @@
'
me.current_position = me.getCurrentPosition();
\n
'
+
'
me.current_position = me.getCurrentPosition();
\n
'
+
'
me.distance = distance(
\n
'
+
'
me.distance = distance(
\n
'
+
'
me.current_position,
\n
'
+
'
me.current_position,
\n
'
+
'
me.flag_positions[me.next_checkpoint]
\n
'
+
'
me.flag_positions[me.next_checkpoint]
.position
\n
'
+
'
);
\n
'
+
'
);
\n
'
+
'
if (me.distance <= EPSILON) {
\n
'
+
'
if (me.distance <= EPSILON) {
\n
'
+
//' console.log("[DEMO] Reached Checkpoint %d", me.next_checkpoint);\n' +
//' console.log("[DEMO] Reached Checkpoint %d", me.next_checkpoint);\n' +
...
@@ -107,6 +160,12 @@
...
@@ -107,6 +160,12 @@
'
}
\n
'
+
'
}
\n
'
+
'
return;
\n
'
+
'
return;
\n
'
+
'
}
\n
'
+
'
}
\n
'
+
'
if (me.next_checkpoint == me.flag_positions.length) {
\n
'
+
'
me.triggerParachute();
\n
'
+
'
}
\n
'
+
'
if (me.landed()) {
\n
'
+
'
me.exit();
\n
'
+
'
}
\n
'
+
'
};
\n
'
+
'
};
\n
'
+
'
\n
'
+
'
\n
'
+
'
me.onDroneViewInfo = function (drone_view) {
\n
'
+
'
me.onDroneViewInfo = function (drone_view) {
\n
'
+
...
@@ -115,7 +174,7 @@
...
@@ -115,7 +174,7 @@
'
me.dodging = drone_view.obstacles[0];
\n
'
+
'
me.dodging = drone_view.obstacles[0];
\n
'
+
'
me.direction_set = false;
\n
'
+
'
me.direction_set = false;
\n
'
+
'
var random = Math.random() < 0.5, dodge_point = {};
\n
'
+
'
var random = Math.random() < 0.5, dodge_point = {};
\n
'
+
'
Object.assign(dodge_point, me.flag_positions[me.next_checkpoint]);
\n
'
+
'
Object.assign(dodge_point, me.flag_positions[me.next_checkpoint]
.position
);
\n
'
+
'
if (random) {
\n
'
+
'
if (random) {
\n
'
+
'
dodge_point.x = dodge_point.x * -1;
\n
'
+
'
dodge_point.x = dodge_point.x * -1;
\n
'
+
'
} else {
\n
'
+
'
} else {
\n
'
+
...
@@ -128,431 +187,616 @@
...
@@ -128,431 +187,616 @@
DRAW
=
true
,
DRAW
=
true
,
LOG
=
true
,
LOG
=
true
,
LOG_TIME
=
1662.7915426540285
,
LOG_TIME
=
1662.7915426540285
,
DRONE_LIST
=
[],
LOGIC_FILE_LIST
=
[
LOGIC_FILE_LIST
=
[
'
gadget_erp5_page_drone_capture_flag_logic.js
'
,
'
gadget_erp5_page_drone_capture_flag_logic.js
'
,
'
gadget_erp5_page_drone_capture_map_utils.js
'
,
'
gadget_erp5_page_drone_capture_flag_fixedwingdrone.js
'
,
'
gadget_erp5_page_drone_capture_flag_fixedwingdrone.js
'
,
'
gadget_erp5_page_drone_capture_flag_enemydrone.js
'
'
gadget_erp5_page_drone_capture_flag_enemydrone.js
'
];
],
DISPLAY_MAP_PARAMETER
=
'
display_map_parameter
'
,
DISPLAY_RANDOMIZE
=
'
display_randomize
'
,
DISPLAY_OPERATOR_PARAMETER
=
'
display_operator_parameter
'
,
DISPLAY_DRONE_PARAMETER
=
'
display_drone_parameter
'
,
DISPLAY_GAME_PARAMETER
=
'
display_game_parameter
'
,
DISPLAY_PLAY
=
"
display_play
"
;
rJS
(
window
)
function
renderGadgetHeader
(
gadget
,
loading
)
{
/////////////////////////////////////////////////////////////////
var
element_list
=
[],
// Acquired methods
game_map_icon
=
'
ui-icon-map-marker
'
,
/////////////////////////////////////////////////////////////////
game_randomize_icon
=
'
ui-icon-random
'
,
.
declareAcquiredMethod
(
"
updateHeader
"
,
"
updateHeader
"
)
game_operator_icon
=
'
ui-icon-rss
'
,
.
declareAcquiredMethod
(
"
notifySubmitted
"
,
"
notifySubmitted
"
)
game_drone_icon
=
'
ui-icon-paper-plane
'
,
game_parameter_icon
=
'
ui-icon-gears
'
,
game_play_icon
=
'
ui-icon-play
'
;
.
allowPublicAcquisition
(
'
notifySubmit
'
,
function
()
{
return
this
.
triggerSubmit
();
})
.
declareMethod
(
"
triggerSubmit
"
,
function
()
{
if
(
loading
)
{
return
this
.
element
.
querySelector
(
'
input[type="submit"]
'
).
click
();
if
(
gadget
.
state
.
display_step
===
DISPLAY_MAP_PARAMETER
)
{
})
game_map_icon
=
'
ui-icon-spinner
'
;
}
else
if
(
gadget
.
state
.
display_step
===
DISPLAY_RANDOMIZE
)
{
game_randomize_icon
=
'
ui-icon-spinner
'
;
}
else
if
(
gadget
.
state
.
display_step
===
DISPLAY_OPERATOR_PARAMETER
)
{
game_operator_icon
=
'
ui-icon-spinner
'
;
}
else
if
(
gadget
.
state
.
display_step
===
DISPLAY_DRONE_PARAMETER
)
{
game_drone_icon
=
'
ui-icon-spinner
'
;
}
else
if
(
gadget
.
state
.
display_step
===
DISPLAY_GAME_PARAMETER
)
{
game_parameter_icon
=
'
ui-icon-spinner
'
;
}
else
if
(
gadget
.
state
.
display_step
===
DISPLAY_PLAY
)
{
game_play_icon
=
'
ui-icon-spinner
'
;
}
else
{
throw
new
Error
(
"
Can't render header state
"
+
gadget
.
state
.
display_step
);
}
}
.
onEvent
(
'
submit
'
,
function
()
{
element_list
.
push
(
var
gadget
=
this
;
domsugar
(
'
button
'
,
{
return
gadget
.
getDeclaredGadget
(
'
form_view
'
)
type
:
'
button
'
,
.
push
(
function
(
form_gadget
)
{
text
:
"
Map
"
,
return
form_gadget
.
getContent
();
disabled
:
(
gadget
.
state
.
display_step
===
DISPLAY_MAP_PARAMETER
),
})
'
class
'
:
'
display-map-parameter-btn ui-btn-icon-left
'
+
game_map_icon
.
push
(
function
(
input
)
{
}),
gadget
.
runGame
(
input
);
domsugar
(
'
button
'
,
{
});
type
:
'
button
'
,
})
text
:
"
Randomize
"
,
disabled
:
(
gadget
.
state
.
display_step
===
DISPLAY_RANDOMIZE
),
'
class
'
:
'
display-randomize-btn ui-btn-icon-left
'
+
game_randomize_icon
}),
domsugar
(
'
button
'
,
{
type
:
'
button
'
,
text
:
"
Parameters
"
,
disabled
:
(
gadget
.
state
.
display_step
===
DISPLAY_GAME_PARAMETER
),
'
class
'
:
'
display-game-parameter-btn ui-btn-icon-left
'
+
game_parameter_icon
}),
domsugar
(
'
button
'
,
{
type
:
'
button
'
,
text
:
"
Operator Script
"
,
disabled
:
(
gadget
.
state
.
display_step
===
DISPLAY_OPERATOR_PARAMETER
),
'
class
'
:
'
display-operator-script-btn ui-btn-icon-left
'
+
game_operator_icon
}),
domsugar
(
'
button
'
,
{
type
:
'
button
'
,
text
:
"
Drone Script
"
,
disabled
:
(
gadget
.
state
.
display_step
===
DISPLAY_DRONE_PARAMETER
),
'
class
'
:
'
display-drone-script-btn ui-btn-icon-left
'
+
game_drone_icon
}),
domsugar
(
'
button
'
,
{
type
:
'
button
'
,
text
:
"
Run
"
,
// Always make this button clickable, so that user can run it twice
// disabled: (gadget.state.display_step === DISPLAY_PLAY),
'
class
'
:
'
display-play-btn ui-btn-icon-left
'
+
game_play_icon
})
);
.
declareMethod
(
'
render
'
,
function
render
()
{
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpageheader
'
),
element_list
);
var
gadget
=
this
,
url_sp
=
new
URLSearchParams
(
window
.
location
.
hash
),
}
url_seed
=
url_sp
.
get
(
"
seed
"
);
return
gadget
.
getDeclaredGadget
(
'
form_view
'
)
function
getContentFromParameterForm
(
gadget
)
{
.
push
(
function
(
form_gadget
)
{
return
gadget
.
getDeclaredGadget
(
'
parameter_form
'
)
return
form_gadget
.
render
({
.
push
(
function
(
form_gadget
)
{
erp5_document
:
{
return
form_gadget
.
getContent
();
"
_embedded
"
:
{
"
_view
"
:
{
})
"
my_simulation_speed
"
:
{
.
push
(
function
(
content_dict
)
{
"
description
"
:
""
,
var
key
;
"
title
"
:
"
Simulation Speed
"
,
for
(
key
in
content_dict
)
{
"
default
"
:
SIMULATION_SPEED
,
if
(
content_dict
.
hasOwnProperty
(
key
))
{
"
css_class
"
:
""
,
gadget
.
state
[
key
]
=
content_dict
[
key
];
"
required
"
:
1
,
}
"
editable
"
:
1
,
}
"
key
"
:
"
simulation_speed
"
,
});
"
hidden
"
:
0
,
}
"
type
"
:
"
IntegerField
"
},
//////////////////////////////////////////////////
"
my_simulation_time
"
:
{
// Map parameters
"
description
"
:
"
Duration of the simulation (in seconds)
"
,
//////////////////////////////////////////////////
"
title
"
:
"
Simulation Time
"
,
function
renderMapParameterView
(
gadget
)
{
"
default
"
:
SIMULATION_TIME
,
var
form_gadget
;
"
css_class
"
:
""
,
renderGadgetHeader
(
gadget
,
true
);
"
required
"
:
1
,
return
gadget
.
declareGadget
(
"
gadget_erp5_form.html
"
,
{
"
editable
"
:
1
,
scope
:
"
parameter_form
"
"
key
"
:
"
simulation_time
"
,
})
"
hidden
"
:
0
,
.
push
(
function
(
sub_gadget
)
{
"
type
"
:
"
IntegerField
"
form_gadget
=
sub_gadget
;
},
return
form_gadget
.
render
({
"
my_drone_min_speed
"
:
{
erp5_document
:
{
"
description
"
:
""
,
"
_embedded
"
:
{
"
_view
"
:
{
"
title
"
:
"
Drone min speed
"
,
"
my_map_json
"
:
{
"
default
"
:
MIN_SPEED
,
"
description
"
:
""
,
"
css_class
"
:
""
,
"
title
"
:
"
Map JSON
"
,
"
required
"
:
1
,
"
default
"
:
gadget
.
state
.
map_json
,
"
editable
"
:
1
,
"
css_class
"
:
""
,
"
key
"
:
"
drone_min_speed
"
,
"
required
"
:
1
,
"
hidden
"
:
0
,
"
editable
"
:
1
,
"
type
"
:
"
IntegerField
"
"
key
"
:
"
map_json
"
,
},
"
hidden
"
:
0
,
"
my_drone_speed
"
:
{
"
url
"
:
"
gadget_editor.html
"
,
"
description
"
:
""
,
"
renderjs_extra
"
:
JSON
.
stringify
({
"
title
"
:
"
Drone speed
"
,
"
maximize
"
:
true
,
"
default
"
:
DEFAULT_SPEED
,
"
language
"
:
"
en
"
,
"
css_class
"
:
""
,
"
editor
"
:
"
codemirror
"
"
required
"
:
1
,
}),
"
editable
"
:
1
,
"
type
"
:
"
GadgetField
"
"
key
"
:
"
drone_speed
"
,
}
"
hidden
"
:
0
,
}},
"
type
"
:
"
FloatField
"
"
_links
"
:
{
},
"
type
"
:
{
"
my_drone_max_speed
"
:
{
name
:
""
"
description
"
:
""
,
"
title
"
:
"
Drone max speed
"
,
"
default
"
:
MAX_SPEED
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_max_acceleration
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max Acceleration
"
,
"
default
"
:
MAX_ACCELERATION
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_acceleration
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_max_deceleration
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max Deceleration
"
,
"
default
"
:
MAX_DECELERATION
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_deceleration
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_max_roll
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max roll
"
,
"
default
"
:
MAX_ROLL
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_roll
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_min_pitch
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone min pitch
"
,
"
default
"
:
MIN_PITCH
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_min_pitch
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_max_pitch
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max pitch
"
,
"
default
"
:
MAX_PITCH
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_pitch
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_max_sink_rate
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max sink rate
"
,
"
default
"
:
MAX_SINK_RATE
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_sink_rate
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_max_climb_rate
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max climb rate
"
,
"
default
"
:
MAX_CLIMB_RATE
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_climb_rate
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
/*"my_map_size": {
"description": "",
"title": "Map size",
"default": MAP_SIZE,
"css_class": "",
"required": 1,
"editable": 1,
"key": "map_size",
"hidden": 0,
"type": "FloatField"
},*/
"
my_start_AMSL
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Start AMSL
"
,
"
default
"
:
start_AMSL
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
start_AMSL
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_map_seed
"
:
{
"
description
"
:
"
Seed value to randomize the map
"
,
"
title
"
:
"
Seed value
"
,
"
default
"
:
url_seed
?
url_seed
:
SEED
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
map_seed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
StringField
"
},
"
my_map_height
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Map Height
"
,
"
default
"
:
map_height
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
map_height
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
/*"my_flag_weight": {
"description": "",
"title": "Flag Weight",
"default": FLAG_WEIGHT,
"css_class": "",
"required": 1,
"editable": 1,
"key": "flag_weight",
"hidden": 0,
"type": "IntegerField"
},*/
"
my_number_of_drones
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Number of drones
"
,
"
default
"
:
NUMBER_OF_DRONES
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
number_of_drones
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_script
"
:
{
"
default
"
:
DEFAULT_SCRIPT_CONTENT
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
script
"
,
"
hidden
"
:
0
,
"
type
"
:
"
GadgetField
"
,
"
renderjs_extra
"
:
'
{"editor": "codemirror", "maximize": true}
'
,
"
url
"
:
"
gadget_editor.html
"
,
"
sandbox
"
:
"
public
"
}
}},
"
_links
"
:
{
"
type
"
:
{
name
:
""
}
}
}
},
form_definition
:
{
group_list
:
[[
"
left
"
,
[[
"
my_simulation_speed
"
],
[
"
my_simulation_time
"
],
[
"
my_number_of_drones
"
],
/*["my_map_size"], */
[
"
my_map_height
"
],
// ["my_flag_weight"],
[
"
my_start_AMSL
"
],
[
"
my_map_seed
"
]]
],
[
"
right
"
,
[[
"
my_drone_min_speed
"
],
[
"
my_drone_speed
"
],
[
"
my_drone_max_speed
"
],
[
"
my_drone_max_acceleration
"
],
[
"
my_drone_max_deceleration
"
],
[
"
my_drone_max_roll
"
],
[
"
my_drone_min_pitch
"
],
[
"
my_drone_max_pitch
"
],
[
"
my_drone_max_sink_rate
"
],
[
"
my_drone_max_climb_rate
"
]]
],
[
"
bottom
"
,
[[
"
my_script
"
]]
]]
}
}
}
);
}
,
})
form_definition
:
{
.
push
(
function
()
{
group_list
:
[[
return
gadget
.
updateHeader
({
"
bottom
"
,
page_title
:
'
Drone Capture Flag
'
,
[[
"
my_map_json
"
]]
page_icon
:
'
puzzle-piece
'
]]
}
);
}
});
});
})
})
.
push
(
function
()
{
renderGadgetHeader
(
gadget
,
false
);
// Attach the form to the page
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpagebody
'
),
[
form_gadget
.
element
]);
});
}
.
declareJob
(
'
runGame
'
,
function
runGame
(
options
)
{
var
gadget
=
this
,
i
,
fragment
=
gadget
.
element
.
querySelector
(
'
.simulator_div
'
),
game_parameters_json
,
map_json
;
options
.
map_size
=
MAP_SIZE
;
DRONE_LIST
=
[];
fragment
=
domsugar
(
gadget
.
element
.
querySelector
(
'
.simulator_div
'
),
[
domsugar
(
'
div
'
)]).
firstElementChild
;
for
(
i
=
0
;
i
<
options
.
number_of_drones
;
i
+=
1
)
{
DRONE_LIST
[
i
]
=
{
"
id
"
:
i
,
"
type
"
:
"
FixedWingDroneAPI
"
,
"
script_content
"
:
options
.
script
};
}
function
randomizeMap
(
json_map
)
{
//////////////////////////////////////////////////
function
randomIntFromInterval
(
min
,
max
,
random_seed
)
{
// Map parameters
return
Math
.
floor
(
random_seed
.
quick
()
*
(
max
-
min
+
1
)
+
min
);
//////////////////////////////////////////////////
}
function
renderRandomizeView
(
gadget
)
{
function
randomPosition
(
random_seed
,
map_size
)
{
var
form_gadget
;
var
sign_x
=
random_seed
.
quick
()
<
0.5
?
-
1
:
1
,
renderGadgetHeader
(
gadget
,
true
);
sign_y
=
random_seed
.
quick
()
<
0.5
?
-
1
:
1
,
return
gadget
.
declareGadget
(
"
gadget_erp5_form.html
"
,
{
pos_x
=
sign_x
*
random_seed
.
quick
()
*
map_size
/
2
,
scope
:
"
parameter_form
"
pos_y
=
sign_y
*
random_seed
.
quick
()
*
map_size
/
2
;
})
return
[
pos_x
,
pos_y
];
.
push
(
function
(
sub_gadget
)
{
}
form_gadget
=
sub_gadget
;
var
seed_value
=
options
.
map_seed
,
return
form_gadget
.
render
({
random_seed
=
new
Math
.
seedrandom
(
seed_value
),
i
,
erp5_document
:
{
n_enemies
=
randomIntFromInterval
(
5
,
10
,
random_seed
),
"
_embedded
"
:
{
"
_view
"
:
{
n_flags
=
randomIntFromInterval
(
5
,
10
,
random_seed
),
"
my_map_seed
"
:
{
n_obstacles
=
randomIntFromInterval
(
5
,
15
,
random_seed
),
"
description
"
:
"
Seed value to randomize the map
"
,
flag_list
=
[],
obstacle_list
=
[],
enemy_list
=
[],
random_position
,
"
title
"
:
"
Seed value (ex:
"
+
SEED
+
"
)
"
,
obstacles_types
=
[
"
box
"
/*, "sphere"*/
,
"
cylinder
"
],
type
,
"
default
"
:
gadget
.
state
.
map_seed
,
obstacle_limit
=
[
options
.
map_size
/
6
,
options
.
map_size
/
100
,
"
placeholder
"
:
SEED
,
options
.
map_size
/
6
,
30
];
"
css_class
"
:
""
,
//enemies
"
required
"
:
0
,
for
(
i
=
0
;
i
<
n_enemies
;
i
+=
1
)
{
"
editable
"
:
1
,
random_position
=
randomPosition
(
random_seed
,
options
.
map_size
);
"
key
"
:
"
map_seed
"
,
enemy_list
.
push
({
"
hidden
"
:
0
,
"
id
"
:
i
+
parseInt
(
options
.
number_of_drones
),
"
type
"
:
"
StringField
"
"
type
"
:
"
EnemyDroneAPI
"
,
}
"
position
"
:
{
}},
"
x
"
:
random_position
[
0
],
"
_links
"
:
{
"
y
"
:
random_position
[
1
],
"
type
"
:
{
"
z
"
:
15
//TODO random z?
name
:
""
}
}
}
});
},
}
form_definition
:
{
//flags
group_list
:
[[
for
(
i
=
0
;
i
<
n_flags
;
i
+=
1
)
{
"
center
"
,
//avoid flags near the limits
[[
"
my_map_seed
"
]]
random_position
=
randomPosition
(
random_seed
,
options
.
map_size
*
0.75
);
]]
flag_list
.
push
({
}
"
position
"
:
{
});
"
x
"
:
random_position
[
0
],
})
"
y
"
:
random_position
[
1
],
.
push
(
function
()
{
"
z
"
:
10
renderGadgetHeader
(
gadget
,
false
);
// Attach the form to the page
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpagebody
'
),
[
/*
domsugar('label', {
'class': 'item-label',
text: 'Map'
}),*/
form_gadget
.
element
]);
});
}
//////////////////////////////////////////////////
// Operator parameters
//////////////////////////////////////////////////
function
renderOperatorParameterView
(
gadget
)
{
var
form_gadget
;
renderGadgetHeader
(
gadget
,
true
);
return
gadget
.
declareGadget
(
"
gadget_erp5_form.html
"
,
{
scope
:
"
parameter_form
"
})
.
push
(
function
(
sub_gadget
)
{
form_gadget
=
sub_gadget
;
return
form_gadget
.
render
({
erp5_document
:
{
"
_embedded
"
:
{
"
_view
"
:
{
"
my_operator_script
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Operator script
"
,
"
default
"
:
gadget
.
state
.
operator_script
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
operator_script
"
,
"
hidden
"
:
0
,
"
url
"
:
"
gadget_editor.html
"
,
"
renderjs_extra
"
:
JSON
.
stringify
({
"
maximize
"
:
true
,
"
language
"
:
"
en
"
,
"
portal_type
"
:
"
Web Script
"
,
"
editor
"
:
"
codemirror
"
}),
"
type
"
:
"
GadgetField
"
}
}},
"
_links
"
:
{
"
type
"
:
{
name
:
""
}
}
}
});
},
}
form_definition
:
{
function
checkDistance
(
position
,
position_list
)
{
group_list
:
[[
function
distance
(
a
,
b
)
{
"
bottom
"
,
return
Math
.
sqrt
((
a
.
x
-
b
.
x
)
**
2
+
(
a
.
y
-
b
.
y
)
**
2
);
[[
"
my_operator_script
"
]]
]]
}
}
var
el
;
});
for
(
el
=
0
;
el
<
position_list
.
length
;
el
+=
1
)
{
})
if
(
distance
(
position
,
position_list
[
el
].
position
)
<
options
.
map_size
/
6
)
{
.
push
(
function
()
{
return
true
;
renderGadgetHeader
(
gadget
,
false
);
// Attach the form to the page
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpagebody
'
),
[
form_gadget
.
element
]);
});
}
//////////////////////////////////////////////////
// Drone script parameter
//////////////////////////////////////////////////
function
renderDroneParameterView
(
gadget
)
{
var
form_gadget
;
renderGadgetHeader
(
gadget
,
true
);
return
gadget
.
declareGadget
(
"
gadget_erp5_form.html
"
,
{
scope
:
"
parameter_form
"
})
.
push
(
function
(
sub_gadget
)
{
form_gadget
=
sub_gadget
;
return
form_gadget
.
render
({
erp5_document
:
{
"
_embedded
"
:
{
"
_view
"
:
{
"
my_drone_script
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone script
"
,
"
default
"
:
gadget
.
state
.
drone_script
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_script
"
,
"
hidden
"
:
0
,
"
url
"
:
"
gadget_editor.html
"
,
"
renderjs_extra
"
:
JSON
.
stringify
({
"
maximize
"
:
true
,
"
language
"
:
"
en
"
,
"
portal_type
"
:
"
Web Script
"
,
"
editor
"
:
"
codemirror
"
}),
"
type
"
:
"
GadgetField
"
}
}},
"
_links
"
:
{
"
type
"
:
{
name
:
""
}
}
}
},
form_definition
:
{
group_list
:
[[
"
bottom
"
,
[[
"
my_drone_script
"
]]
]]
}
}
return
false
;
});
}
})
//obstacles
.
push
(
function
()
{
for
(
i
=
0
;
i
<
n_obstacles
;
i
+=
1
)
{
renderGadgetHeader
(
gadget
,
false
);
random_position
=
randomPosition
(
random_seed
,
options
.
map_size
);
// Attach the form to the page
if
(
checkDistance
({
'
x
'
:
random_position
[
0
],
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpagebody
'
),
[
'
y
'
:
random_position
[
1
]},
flag_list
))
{
form_gadget
.
element
i
-=
1
;
]);
}
else
{
});
type
=
randomIntFromInterval
(
0
,
2
,
random_seed
);
}
obstacle_list
.
push
({
"
type
"
:
obstacles_types
[
type
],
//////////////////////////////////////////////////
"
position
"
:
{
// Game parameters
"
x
"
:
random_position
[
0
],
//////////////////////////////////////////////////
"
y
"
:
random_position
[
1
],
function
renderGameParameterView
(
gadget
)
{
"
z
"
:
15
//TODO random z?
var
form_gadget
;
renderGadgetHeader
(
gadget
,
true
);
return
gadget
.
declareGadget
(
"
gadget_erp5_form.html
"
,
{
scope
:
"
parameter_form
"
})
.
push
(
function
(
sub_gadget
)
{
form_gadget
=
sub_gadget
;
return
form_gadget
.
render
({
erp5_document
:
{
"
_embedded
"
:
{
"
_view
"
:
{
"
my_simulation_speed
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Simulation Speed
"
,
"
default
"
:
gadget
.
state
.
simulation_speed
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
simulation_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_simulation_time
"
:
{
"
description
"
:
"
Duration of the simulation (in seconds)
"
,
"
title
"
:
"
Simulation Time
"
,
"
default
"
:
gadget
.
state
.
simulation_time
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
simulation_time
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_min_speed
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone min speed
"
,
"
default
"
:
gadget
.
state
.
drone_min_speed
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_min_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
},
"
scale
"
:
{
"
my_drone_speed
"
:
{
"
x
"
:
randomIntFromInterval
(
20
,
obstacle_limit
[
type
],
random_seed
),
"
description
"
:
""
,
"
y
"
:
randomIntFromInterval
(
20
,
obstacle_limit
[
type
],
random_seed
),
"
title
"
:
"
Drone speed
"
,
"
z
"
:
randomIntFromInterval
(
5
,
obstacle_limit
[
3
],
random_seed
)
"
default
"
:
gadget
.
state
.
drone_speed
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
},
"
rotation
"
:
{
"
my_drone_max_speed
"
:
{
"
x
"
:
0
,
"
description
"
:
""
,
"
y
"
:
0
,
"
title
"
:
"
Drone max speed
"
,
"
z
"
:
0
"
default
"
:
gadget
.
state
.
drone_max_speed
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_max_acceleration
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max Acceleration
"
,
"
default
"
:
gadget
.
state
.
drone_max_acceleration
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_acceleration
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_max_deceleration
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max Deceleration
"
,
"
default
"
:
gadget
.
state
.
drone_max_deceleration
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_deceleration
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_max_roll
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max roll
"
,
"
default
"
:
gadget
.
state
.
drone_max_roll
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_roll
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_min_pitch
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone min pitch
"
,
"
default
"
:
gadget
.
state
.
drone_min_pitch
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_min_pitch
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_max_pitch
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max pitch
"
,
"
default
"
:
gadget
.
state
.
drone_max_pitch
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_pitch
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_max_sink_rate
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max sink rate
"
,
"
default
"
:
gadget
.
state
.
drone_max_sink_rate
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_sink_rate
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_max_climb_rate
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max climb rate
"
,
"
default
"
:
gadget
.
state
.
drone_max_climb_rate
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_max_climb_rate
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_number_of_drones
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Number of drones
"
,
"
default
"
:
gadget
.
state
.
number_of_drones
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
number_of_drones
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
}
}
});
}},
"
_links
"
:
{
"
type
"
:
{
name
:
""
}
}
},
form_definition
:
{
group_list
:
[[
"
left
"
,
[[
"
my_simulation_speed
"
],
[
"
my_simulation_time
"
],
[
"
my_number_of_drones
"
],
[
"
my_map_seed
"
]]
],
[
"
right
"
,
[[
"
my_drone_min_speed
"
],
[
"
my_drone_speed
"
],
[
"
my_drone_max_speed
"
],
[
"
my_drone_max_acceleration
"
],
[
"
my_drone_max_deceleration
"
],
[
"
my_drone_max_roll
"
],
[
"
my_drone_min_pitch
"
],
[
"
my_drone_max_pitch
"
],
[
"
my_drone_max_sink_rate
"
],
[
"
my_drone_max_climb_rate
"
]]
]]
}
}
}
});
json_map
.
obstacle_list
=
obstacle_list
;
})
json_map
.
drones
.
enemy
=
enemy_list
;
.
push
(
function
()
{
json_map
.
flag_list
=
flag_list
;
renderGadgetHeader
(
gadget
,
false
);
return
json_map
;
// Attach the form to the page
}
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpagebody
'
),
[
form_gadget
.
element
]);
});
}
//////////////////////////////////////////////////
// Play
//////////////////////////////////////////////////
function
renderPlayView
(
gadget
)
{
renderGadgetHeader
(
gadget
,
true
);
// XXX Load babylonjs and run game
return
gadget
.
declareGadget
(
"
gadget_erp5_form.html
"
,
{
scope
:
"
form_view_babylonjs
"
})
.
push
(
function
(
sub_gadget
)
{
renderGadgetHeader
(
gadget
,
false
);
// Attach the form to the page
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpagebody
'
),
[
domsugar
(
'
div
'
,
{
'
class
'
:
'
simulator_div
'
}),
sub_gadget
.
element
]);
var
operator_code
=
"
let operator = function(operator){
"
+
gadget
.
state
.
operator_script
+
"
return operator.getDroneStartMessage();
"
+
"
}; return operator(new OperatorAPI(
"
+
gadget
.
state
.
map_json
+
"
));
"
;
map_json
=
{
/*jslint evil: true*/
"
map_size
"
:
parseFloat
(
options
.
map_size
),
try
{
"
height
"
:
parseInt
(
options
.
map_height
,
10
),
gadget
.
state
.
operator_init_msg
=
new
Function
(
operator_code
)();
"
start_AMSL
"
:
parseFloat
(
options
.
start_AMSL
),
}
catch
(
error
)
{
"
min_lat
"
:
parseFloat
(
min_lat
),
return
gadget
.
notifySubmitted
({
message
:
"
Error in operator script:
"
+
"
max_lat
"
:
parseFloat
(
max_lat
),
error
.
message
,
status
:
'
error
'
});
"
min_lon
"
:
parseFloat
(
min_lon
),
"
max_lon
"
:
parseFloat
(
max_lon
),
"
flag_list
"
:
[],
"
obstacle_list
"
:
[],
"
drones
"
:
{
"
user
"
:
DRONE_LIST
,
"
enemy
"
:
[]
}
}
};
/*jslint evil: false*/
gadget
.
runGame
();
});
}
rJS
(
window
)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.
declareAcquiredMethod
(
"
updateHeader
"
,
"
updateHeader
"
)
.
declareAcquiredMethod
(
"
notifySubmitted
"
,
"
notifySubmitted
"
)
.
allowPublicAcquisition
(
'
notifySubmit
'
,
function
()
{
return
this
.
triggerSubmit
();
})
.
declareMethod
(
"
triggerSubmit
"
,
function
()
{
return
;
})
.
declareJob
(
'
runGame
'
,
function
runGame
(
do_nothing
)
{
if
(
do_nothing
)
{
// Cancel the previous job execution
return
;
}
var
gadget
=
this
,
i
,
parsed_map
,
fragment
=
gadget
.
element
.
querySelector
(
'
.simulator_div
'
),
game_parameters_json
,
drone_list
=
[];
fragment
=
domsugar
(
gadget
.
element
.
querySelector
(
'
.simulator_div
'
),
[
domsugar
(
'
div
'
)]).
firstElementChild
;
for
(
i
=
0
;
i
<
gadget
.
state
.
number_of_drones
;
i
+=
1
)
{
drone_list
[
i
]
=
{
"
id
"
:
i
,
"
type
"
:
"
FixedWingDroneAPI
"
,
"
script_content
"
:
gadget
.
state
.
drone_script
};
}
try
{
parsed_map
=
JSON
.
parse
(
gadget
.
state
.
map_json
);
}
catch
(
error
)
{
return
gadget
.
notifySubmitted
({
message
:
"
Error:
"
+
error
.
message
,
status
:
'
error
'
});
}
game_parameters_json
=
{
game_parameters_json
=
{
"
drone
"
:
{
"
drone
"
:
{
"
maxAcceleration
"
:
parseInt
(
options
.
drone_max_acceleration
,
10
),
"
maxAcceleration
"
:
parseInt
(
gadget
.
state
.
drone_max_acceleration
,
10
),
"
maxDeceleration
"
:
parseInt
(
options
.
drone_max_deceleration
,
10
),
"
maxDeceleration
"
:
parseInt
(
gadget
.
state
.
drone_max_deceleration
,
10
),
"
minSpeed
"
:
parseInt
(
options
.
drone_min_speed
,
10
),
"
minSpeed
"
:
parseInt
(
gadget
.
state
.
drone_min_speed
,
10
),
"
speed
"
:
parseFloat
(
options
.
drone_speed
),
"
speed
"
:
parseFloat
(
gadget
.
state
.
drone_speed
),
"
maxSpeed
"
:
parseInt
(
options
.
drone_max_speed
,
10
),
"
maxSpeed
"
:
parseInt
(
gadget
.
state
.
drone_max_speed
,
10
),
"
maxRoll
"
:
parseFloat
(
options
.
drone_max_roll
),
"
maxRoll
"
:
parseFloat
(
gadget
.
state
.
drone_max_roll
),
"
minPitchAngle
"
:
parseFloat
(
options
.
drone_min_pitch
),
"
minPitchAngle
"
:
parseFloat
(
gadget
.
state
.
drone_min_pitch
),
"
maxPitchAngle
"
:
parseFloat
(
options
.
drone_max_pitch
),
"
maxPitchAngle
"
:
parseFloat
(
gadget
.
state
.
drone_max_pitch
),
"
maxSinkRate
"
:
parseFloat
(
options
.
drone_max_sink_rate
),
"
maxSinkRate
"
:
parseFloat
(
gadget
.
state
.
drone_max_sink_rate
),
"
maxClimbRate
"
:
parseFloat
(
options
.
drone_max_climb_rate
)
"
maxClimbRate
"
:
parseFloat
(
gadget
.
state
.
drone_max_climb_rate
),
"
list
"
:
drone_list
},
},
"
gameTime
"
:
parseInt
(
options
.
simulation_time
,
10
),
"
gameTime
"
:
parseInt
(
gadget
.
state
.
simulation_time
,
10
),
"
simulation_speed
"
:
parseInt
(
options
.
simulation_speed
,
10
),
"
simulation_speed
"
:
parseInt
(
gadget
.
state
.
simulation_speed
,
10
),
"
latency
"
:
{
"
latency
"
:
{
"
information
"
:
0
,
"
information
"
:
0
,
"
communication
"
:
0
"
communication
"
:
0
},
},
"
map
"
:
randomizeMap
(
map_json
),
"
map
"
:
parsed_map
,
"
operator_init_msg
"
:
gadget
.
state
.
operator_init_msg
,
"
draw_flight_path
"
:
DRAW
,
"
draw_flight_path
"
:
DRAW
,
"
temp_flight_path
"
:
true
,
"
temp_flight_path
"
:
true
,
"
log_drone_flight
"
:
LOG
,
"
log_drone_flight
"
:
LOG
,
...
@@ -604,9 +848,12 @@
...
@@ -604,9 +848,12 @@
return
form_gadget
.
getContent
();
return
form_gadget
.
getContent
();
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
var
a
,
blob
,
div
,
key
,
log
,
log_content
,
aux
;
var
a
,
blob
,
div
,
key
,
log
,
log_content
,
label
;
i
=
0
;
i
=
0
;
div
=
domsugar
(
'
div
'
,
{
text
:
result
.
message
});
div
=
domsugar
(
'
div
'
,
{
text
:
result
.
message
});
label
=
domsugar
(
'
label
'
,
{
text
:
"
Results
"
});
label
.
classList
.
add
(
"
item-label
"
);
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
label
);
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
div
);
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
div
);
for
(
key
in
result
.
content
)
{
for
(
key
in
result
.
content
)
{
if
(
result
.
content
.
hasOwnProperty
(
key
))
{
if
(
result
.
content
.
hasOwnProperty
(
key
))
{
...
@@ -615,17 +862,17 @@
...
@@ -615,17 +862,17 @@
a
=
domsugar
(
'
a
'
,
{
a
=
domsugar
(
'
a
'
,
{
text
:
'
Download Simulation LOG
'
+
i
,
text
:
'
Download Simulation LOG
'
+
i
,
download
:
'
simulation_log_
'
+
i
+
download
:
'
simulation_log_
'
+
i
+
'
_speed_
'
+
game_parameters_json
.
drone
.
speed
+
'
_speed_
'
+
game_parameters_json
.
drone
.
speed
+
'
_min-speed_
'
+
game_parameters_json
.
drone
.
minSpeed
+
'
_min-speed_
'
+
game_parameters_json
.
drone
.
minSpeed
+
'
_max-speed_
'
+
game_parameters_json
.
drone
.
maxSpeed
+
'
_max-speed_
'
+
game_parameters_json
.
drone
.
maxSpeed
+
'
_max-accel_
'
+
game_parameters_json
.
drone
.
maxAcceleration
+
'
_max-accel_
'
+
game_parameters_json
.
drone
.
maxAcceleration
+
'
_max-decel_
'
+
game_parameters_json
.
drone
.
maxDeceleration
+
'
_max-decel_
'
+
game_parameters_json
.
drone
.
maxDeceleration
+
'
_max-roll_
'
+
game_parameters_json
.
drone
.
maxRoll
+
'
_max-roll_
'
+
game_parameters_json
.
drone
.
maxRoll
+
'
_min-pitch_
'
+
game_parameters_json
.
drone
.
minPitchAngle
+
'
_min-pitch_
'
+
game_parameters_json
.
drone
.
minPitchAngle
+
'
_max-pitch_
'
+
game_parameters_json
.
drone
.
maxPitchAngle
+
'
_max-pitch_
'
+
game_parameters_json
.
drone
.
maxPitchAngle
+
'
_max-sink_
'
+
game_parameters_json
.
drone
.
maxSinkRate
+
'
_max-sink_
'
+
game_parameters_json
.
drone
.
maxSinkRate
+
'
_max-climb_
'
+
game_parameters_json
.
drone
.
maxClimbRate
+
'
_max-climb_
'
+
game_parameters_json
.
drone
.
maxClimbRate
+
'
.txt
'
,
'
.txt
'
,
href
:
window
.
URL
.
createObjectURL
(
blob
)
href
:
window
.
URL
.
createObjectURL
(
blob
)
});
});
log
=
domsugar
(
'
textarea
'
,
log
=
domsugar
(
'
textarea
'
,
...
@@ -636,7 +883,7 @@
...
@@ -636,7 +883,7 @@
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
div
);
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
div
);
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
log
);
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
log
);
i
+=
1
;
i
+=
1
;
if
(
i
===
DRONE_LIST
.
length
)
{
if
(
i
===
drone_list
.
length
)
{
break
;
break
;
//Do not show enemy drone logs for now
//Do not show enemy drone logs for now
/*aux = domsugar('div', { text: "Enemy drones logs:" });
/*aux = domsugar('div', { text: "Enemy drones logs:" });
...
@@ -648,6 +895,206 @@
...
@@ -648,6 +895,206 @@
return
gadget
.
notifySubmitted
({
message
:
"
Error:
"
+
error
.
message
,
return
gadget
.
notifySubmitted
({
message
:
"
Error:
"
+
error
.
message
,
status
:
'
error
'
});
status
:
'
error
'
});
});
});
});
})
.
setState
({
operator_script
:
DEFAULT_OPERATOR_SCRIPT
,
drone_script
:
DEFAULT_SCRIPT_CONTENT
,
number_of_drones
:
NUMBER_OF_DRONES
,
drone_max_climb_rate
:
MAX_CLIMB_RATE
,
drone_max_sink_rate
:
MAX_SINK_RATE
,
drone_max_pitch
:
MAX_PITCH
,
drone_min_pitch
:
MIN_PITCH
,
drone_max_roll
:
MAX_ROLL
,
drone_max_deceleration
:
MAX_DECELERATION
,
drone_max_acceleration
:
MAX_ACCELERATION
,
drone_max_speed
:
MAX_SPEED
,
drone_speed
:
DEFAULT_SPEED
,
drone_min_speed
:
MIN_SPEED
,
simulation_time
:
SIMULATION_TIME
,
simulation_speed
:
SIMULATION_SPEED
,
operator_init_msg
:
{},
// Force user to fill a value, to prevent
// deleting the map by accident
map_seed
:
null
,
map_json
:
JSON
.
stringify
(
MAP
,
undefined
,
4
)
})
.
declareMethod
(
'
render
'
,
function
render
()
{
var
gadget
=
this
;
return
gadget
.
changeState
({
display_step
:
DISPLAY_PLAY
})
.
push
(
function
()
{
return
gadget
.
updateHeader
({
page_title
:
'
Drone Capture Flag
'
,
page_icon
:
'
puzzle-piece
'
});
});
})
.
onStateChange
(
function
(
modification_dict
)
{
var
gadget
=
this
;
if
(
gadget
.
state
.
display_step
===
DISPLAY_MAP_PARAMETER
)
{
if
(
modification_dict
.
hasOwnProperty
(
'
display_step
'
))
{
// do not update the form if it is already displayed
return
renderMapParameterView
(
gadget
);
}
}
if
(
gadget
.
state
.
display_step
===
DISPLAY_RANDOMIZE
)
{
if
(
modification_dict
.
hasOwnProperty
(
'
display_step
'
))
{
// do not update the form if it is already displayed
return
renderRandomizeView
(
gadget
);
}
}
if
(
gadget
.
state
.
display_step
===
DISPLAY_GAME_PARAMETER
)
{
if
(
modification_dict
.
hasOwnProperty
(
'
display_step
'
))
{
// do not update the form if it is already displayed
return
renderGameParameterView
(
gadget
);
}
}
if
(
gadget
.
state
.
display_step
===
DISPLAY_OPERATOR_PARAMETER
)
{
if
(
modification_dict
.
hasOwnProperty
(
'
display_step
'
))
{
// do not update the form if it is already displayed
return
renderOperatorParameterView
(
gadget
);
}
}
if
(
gadget
.
state
.
display_step
===
DISPLAY_DRONE_PARAMETER
)
{
if
(
modification_dict
.
hasOwnProperty
(
'
display_step
'
))
{
// do not update the form if it is already displayed
return
renderDroneParameterView
(
gadget
);
}
}
if
(
gadget
.
state
.
display_step
===
DISPLAY_PLAY
)
{
return
renderPlayView
(
gadget
);
}
if
(
modification_dict
.
hasOwnProperty
(
'
display_step
'
))
{
throw
new
Error
(
'
Unhandled display step:
'
+
gadget
.
state
.
display_step
);
}
})
//////////////////////////////////////////////////
// Used when submitting the form
//////////////////////////////////////////////////
.
declareMethod
(
'
getContent
'
,
function
()
{
var
gadget
=
this
,
display_step
=
gadget
.
state
.
display_step
,
queue
;
if
([
DISPLAY_OPERATOR_PARAMETER
,
DISPLAY_DRONE_PARAMETER
,
DISPLAY_MAP_PARAMETER
,
DISPLAY_GAME_PARAMETER
].
indexOf
(
gadget
.
state
.
display_step
)
!==
-
1
)
{
queue
=
new
RSVP
.
Queue
(
getContentFromParameterForm
(
gadget
));
}
else
if
(
gadget
.
state
.
display_step
===
DISPLAY_RANDOMIZE
)
{
// Randomizing function is called, only if user entered a feed
queue
=
new
RSVP
.
Queue
(
getContentFromParameterForm
(
gadget
))
.
push
(
function
()
{
if
(
gadget
.
state
.
map_seed
)
{
gadget
.
state
.
map_json
=
JSON
.
stringify
(
new
MapUtils
(
MAP
).
randomize
(
gadget
.
state
.
map_seed
),
undefined
,
4
);
}
});
}
else
if
(
gadget
.
state
.
display_step
===
DISPLAY_PLAY
)
{
// Cancel the run execution, by triggering the job again
// Out job does nothing if no parameter is passed
gadget
.
runGame
(
true
);
// Nothing to store in the play view
queue
=
new
RSVP
.
Queue
();
}
else
{
throw
new
Error
(
'
getContent form not handled:
'
+
display_step
);
}
return
queue
;
},
{
mutex
:
'
changestate
'
})
.
onEvent
(
"
click
"
,
function
(
evt
)
{
// Only handle click on BUTTON element
var
gadget
=
this
,
tag_name
=
evt
.
target
.
tagName
,
queue
;
if
(
tag_name
!==
'
BUTTON
'
)
{
return
;
}
// Disable any button. It must be managed by this gadget
evt
.
preventDefault
();
// Always get content to ensure the possible displayed form
// is checked and content propagated to the gadget state value
queue
=
gadget
.
getContent
();
if
(
evt
.
target
.
className
.
indexOf
(
"
display-map-parameter-btn
"
)
!==
-
1
)
{
return
queue
.
push
(
function
()
{
return
gadget
.
changeState
({
display_step
:
DISPLAY_MAP_PARAMETER
});
});
}
if
(
evt
.
target
.
className
.
indexOf
(
"
display-randomize-btn
"
)
!==
-
1
)
{
return
queue
.
push
(
function
()
{
return
gadget
.
changeState
({
display_step
:
DISPLAY_RANDOMIZE
});
});
}
if
(
evt
.
target
.
className
.
indexOf
(
"
display-operator-script-btn
"
)
!==
-
1
)
{
return
queue
.
push
(
function
()
{
return
gadget
.
changeState
({
display_step
:
DISPLAY_OPERATOR_PARAMETER
});
});
}
if
(
evt
.
target
.
className
.
indexOf
(
"
display-drone-script-btn
"
)
!==
-
1
)
{
return
queue
.
push
(
function
()
{
return
gadget
.
changeState
({
display_step
:
DISPLAY_DRONE_PARAMETER
});
});
}
if
(
evt
.
target
.
className
.
indexOf
(
"
display-game-parameter-btn
"
)
!==
-
1
)
{
return
queue
.
push
(
function
()
{
return
gadget
.
changeState
({
display_step
:
DISPLAY_GAME_PARAMETER
});
});
}
if
(
evt
.
target
.
className
.
indexOf
(
"
display-play-btn
"
)
!==
-
1
)
{
return
queue
.
push
(
function
()
{
return
gadget
.
changeState
({
display_step
:
DISPLAY_PLAY
,
force_timestamp
:
new
Date
()
});
});
}
throw
new
Error
(
'
Unhandled button:
'
+
evt
.
target
.
textContent
);
},
false
,
false
);
}(
window
,
rJS
,
domsugar
,
document
,
URLSearchParams
,
Blob
));
}(
window
,
rJS
,
domsugar
,
document
,
Blob
,
MapUtils
,
RSVP
));
\ No newline at end of file
\ No newline at end of file
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_page_module/ojs_drone_capture_flag_script_page_js.xml
View file @
3a9d947c
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
101
0.23654.50890.2036
0
</string>
</value>
<value>
<string>
101
1.18818.32686.3258
0
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -266,7 +266,7 @@
...
@@ -266,7 +266,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
169
1681704.91
</float>
<float>
169
5397751.99
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_site_module/officejs_drone_capture_flag.xml
View file @
3a9d947c
...
@@ -277,7 +277,7 @@
...
@@ -277,7 +277,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
configuration_content_security_policy
</string>
</key>
<key>
<string>
configuration_content_security_policy
</string>
</key>
<value>
<string>
default-src \'self\'; img-src \'self\' data:; media-src \'self\' blob:;
connect-src \'self\' https://content.dropboxapi.com https://api.dropboxapi.com mail.tiolive.com data: *.host.vifib.net *.node.vifib.com *.erp5.net *.nexedi.net https://netdna.bootstrapcdn.com; script-src \'self\' \'unsafe-eval\' \'unsafe-inline\'; font-src \'self\' netdna.bootstrapcdn.com; style-src \'self\' netdna.bootstrapcdn.com \'unsafe-inline\' data:; frame-src \'self\' data:
</string>
</value>
<value>
<string>
default-src \'self\'; img-src \'self\' data:; media-src \'self\' blob:;
script-src \'self\' \'unsafe-eval\';
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
configuration_latest_document_version
</string>
</key>
<key>
<string>
configuration_latest_document_version
</string>
</key>
...
@@ -538,7 +538,7 @@
...
@@ -538,7 +538,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
10
07.63243.40091.31010
</string>
</value>
<value>
<string>
10
10.35278.59853.35635
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -558,7 +558,7 @@
...
@@ -558,7 +558,7 @@
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
16
82433351.46
</float>
<float>
16
92976685.9
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_site_module/officejs_drone_capture_flag/app.xml
View file @
3a9d947c
...
@@ -246,7 +246,7 @@
...
@@ -246,7 +246,7 @@
</item>
</item>
<item>
<item>
<key>
<string>
configuration_content_security_policy
</string>
</key>
<key>
<string>
configuration_content_security_policy
</string>
</key>
<value>
<string>
default-src \'self\'; img-src \'self\' data:; media-src \'self\' blob:;
connect-src \'self\' https://content.dropboxapi.com https://api.dropboxapi.com mail.tiolive.com data: *.host.vifib.net *.node.vifib.com *.erp5.net *.nexedi.net https://netdna.bootstrapcdn.com; script-src \'self\' \'unsafe-eval\' \'unsafe-inline\'; font-src \'self\' netdna.bootstrapcdn.com; style-src \'self\' netdna.bootstrapcdn.com \'unsafe-inline\' data:; frame-src \'self\' data:
</string>
</value>
<value>
<string>
default-src \'self\'; img-src \'self\' data:; media-src \'self\' blob:;
script-src \'self\' \'unsafe-eval\';
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
configuration_default_view_action_reference
</string>
</key>
<key>
<string>
configuration_default_view_action_reference
</string>
</key>
...
@@ -502,7 +502,7 @@ WebSection_getDroneCaptureFlagPrecacheManifestList</string> </value>
...
@@ -502,7 +502,7 @@ WebSection_getDroneCaptureFlagPrecacheManifestList</string> </value>
</item>
</item>
<item>
<item>
<key>
<string>
serial
</string>
</key>
<key>
<string>
serial
</string>
</key>
<value>
<string>
10
07.63247.30934.52258
</string>
</value>
<value>
<string>
10
10.35278.59853.35635
</string>
</value>
</item>
</item>
<item>
<item>
<key>
<string>
state
</string>
</key>
<key>
<string>
state
</string>
</key>
...
@@ -522,7 +522,7 @@ WebSection_getDroneCaptureFlagPrecacheManifestList</string> </value>
...
@@ -522,7 +522,7 @@ WebSection_getDroneCaptureFlagPrecacheManifestList</string> </value>
</tuple>
</tuple>
<state>
<state>
<tuple>
<tuple>
<float>
16
82433685.5
</float>
<float>
16
92976699.18
</float>
<string>
UTC
</string>
<string>
UTC
</string>
</tuple>
</tuple>
</state>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/SkinTemplateItem/portal_skins/erp5_drone_capture_flag/assets/map/terrain.jpg.jpg
View replaced file @
41270486
View file @
3a9d947c
264 KB
|
W:
|
H:
74.5 KB
|
W:
|
H:
2-up
Swipe
Onion skin
bt5/erp5_officejs_drone_capture_flag/SkinTemplateItem/portal_skins/erp5_officejs_drone_capture_flag/WebSection_getDroneCaptureFlagPrecacheManifestList.py
View file @
3a9d947c
...
@@ -4,8 +4,10 @@ url_list = [
...
@@ -4,8 +4,10 @@ url_list = [
"gadget_erp5_page_drone_capture_flag_logic.js"
,
"gadget_erp5_page_drone_capture_flag_logic.js"
,
"gadget_erp5_page_drone_capture_flag_script_page.html"
,
"gadget_erp5_page_drone_capture_flag_script_page.html"
,
"gadget_erp5_page_drone_capture_flag_script_page.js"
,
"gadget_erp5_page_drone_capture_flag_script_page.js"
,
"gadget_erp5_page_drone_capture_flag_script_page.css"
,
"gadget_erp5_panel_drone_capture_flag.html"
,
"gadget_erp5_panel_drone_capture_flag.html"
,
"gadget_erp5_panel_drone_capture_flag.js"
,
"gadget_erp5_panel_drone_capture_flag.js"
,
"gadget_erp5_page_drone_capture_map_utils.js"
,
"gadget_erp5_page_drone_capture_flag_fixedwingdrone.js"
,
"gadget_erp5_page_drone_capture_flag_fixedwingdrone.js"
,
"gadget_erp5_page_drone_capture_flag_enemydrone.js"
,
"gadget_erp5_page_drone_capture_flag_enemydrone.js"
,
"gadget_erp5_page_drone_capture_flag_api_page.html"
,
"gadget_erp5_page_drone_capture_flag_api_page.html"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment