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
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eteri
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 () {
"
use strict
"
;
var
DEFAULT_ACCELERATION
=
1
,
VIEW_SCOPE
=
50
,
VIEW_SCOPE
=
25
,
DEFAULT_SPEED
=
16.5
,
MIN_SPEED
=
12
,
MAX_SPEED
=
26
;
MAX_SPEED
=
26
,
COLLISION_SECTOR
=
10
;
//** CONSTRUCTOR
function
EnemyDroneAPI
(
gameManager
,
drone_info
,
flight_parameters
,
id
)
{
...
...
@@ -21,6 +22,7 @@ var EnemyDroneAPI = /** @class */ (function () {
this
.
_drone_info
=
drone_info
;
this
.
_drone_dict_list
=
[];
this
.
_acceleration
=
DEFAULT_ACCELERATION
;
this
.
_collision_sector
=
COLLISION_SECTOR
;
}
/*
** Function called on start phase of the drone, just before onStart AI script
...
...
@@ -189,15 +191,16 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI
.
prototype
.
getDroneViewInfo
=
function
(
drone
)
{
var
context
=
this
,
result
=
[],
distance
,
drone_position
=
drone
.
position
,
other_position
;
function
calculateDistance
(
a
,
b
)
{
return
Math
.
sqrt
(
Math
.
pow
((
a
.
x
-
b
.
x
),
2
)
+
Math
.
pow
((
a
.
y
-
b
.
y
),
2
)
+
Math
.
pow
((
a
.
z
-
b
.
z
),
2
)
);
function
calculateDistance
(
a
,
b
,
_3D
)
{
var
z
=
(
_3D
?
Math
.
pow
((
a
.
z
-
b
.
z
),
2
)
:
0
);
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
)
{
if
(
other
.
can_play
)
{
other_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
({
position
:
other_position
,
direction
:
other
.
direction
,
...
...
@@ -213,8 +216,7 @@ var EnemyDroneAPI = /** @class */ (function () {
};
EnemyDroneAPI
.
prototype
.
getDroneAI
=
function
()
{
//interception math based on https://www.codeproject.com/Articles/990452/Interception-of-Two-Moving-Objects-in-D-Space
return
'
var BASE_DISTANCE = 300;
\n
'
+
'
function calculateInterception(hunter_position, prey_position, hunter_speed, prey_speed, prey_velocity_vector) {
\n
'
+
return
'
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
'
+
'
function dot(a, b) {
\n
'
+
'
return a.map((x, i) => a[i] * b[i]).reduce((m, n) => m + n);
\n
'
+
...
...
@@ -242,7 +244,6 @@ var EnemyDroneAPI = /** @class */ (function () {
'
}
\n
'
+
'
\n
'
+
'
me.onStart = function () {
\n
'
+
'
me.base = me.position;
\n
'
+
'
me.setDirection(0,0,0);
\n
'
+
'
return;
\n
'
+
'
\n
'
+
...
...
@@ -251,20 +252,6 @@ var EnemyDroneAPI = /** @class */ (function () {
'
me.onUpdate = function (timestamp) {
\n
'
+
'
me.current_position = me.position;
\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
'
+
'
if (drone_view.length) {
\n
'
+
'
drone_position = drone_view[0].position;
\n
'
+
...
...
@@ -273,13 +260,8 @@ var EnemyDroneAPI = /** @class */ (function () {
'
if (!interception_point) {
\n
'
+
'
return;
\n
'
+
'
}
\n
'
+
'
me.chasing = true;
\n
'
+
'
me.setTargetCoordinates(interception_point[0], interception_point[1], interception_point[2]);
\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
()
{
...
...
@@ -330,5 +312,8 @@ var EnemyDroneAPI = /** @class */ (function () {
EnemyDroneAPI
.
prototype
.
getFlightParameters
=
function
()
{
return
this
.
_flight_parameters
;
};
EnemyDroneAPI
.
prototype
.
getCollisionSector
=
function
()
{
return
this
.
_collision_sector
;
};
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 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>
16
88571911.82
</float>
<float>
16
95397984.38
</float>
<string>
UTC
</string>
</tuple>
</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 () {
** Function called on start phase of the drone, just before onStart AI script
*/
FixedWingDroneAPI
.
prototype
.
internal_start
=
function
(
drone
)
{
drone
.
_targetCoordinates
=
drone
.
getCurrentPosition
();
drone
.
_maxDeceleration
=
this
.
getMaxDeceleration
();
if
(
drone
.
_maxDeceleration
<=
0
)
{
throw
new
Error
(
'
max deceleration must be superior to 0
'
);
...
...
@@ -194,6 +193,7 @@ var FixedWingDroneAPI = /** @class */ (function () {
distance
,
distanceCos
,
distanceSin
,
distanceToTarget
,
currentSinLat
,
currentLonRad
,
groundSpeed
,
...
...
@@ -205,11 +205,19 @@ var FixedWingDroneAPI = /** @class */ (function () {
verticalSpeed
,
yawToDirection
;
if
(
this
.
_loiter_mode
&&
Math
.
sqrt
(
Math
.
pow
(
drone
.
_targetCoordinates
.
x
-
drone
.
position
.
x
,
2
)
+
Math
.
pow
(
drone
.
_targetCoordinates
.
y
-
drone
.
position
.
y
,
2
)
)
<=
this
.
_loiter_radius
)
{
newYaw
=
bearing
-
90
;
if
(
this
.
_loiter_mode
)
{
distanceToTarget
=
Math
.
sqrt
(
Math
.
pow
(
drone
.
_targetCoordinates
.
x
-
drone
.
position
.
x
,
2
)
+
Math
.
pow
(
drone
.
_targetCoordinates
.
y
-
drone
.
position
.
y
,
2
)
);
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
{
newYaw
=
this
.
_getNewYaw
(
drone
,
bearing
,
delta_time
);
}
...
...
@@ -414,16 +422,16 @@ var FixedWingDroneAPI = /** @class */ (function () {
distance
=
calculateDistance
(
drone_position
,
other_position
,
context
);
if
(
distance
<=
VIEW_SCOPE
)
{
result
.
drones
.
push
({
position
:
drone
.
getCurrentPosition
(),
direction
:
drone
.
direction
,
rotation
:
drone
.
rotation
,
speed
:
drone
.
speed
,
team
:
drone
.
team
position
:
other
.
getCurrentPosition
(),
direction
:
other
.
direction
,
rotation
:
other
.
rotation
,
speed
:
other
.
speed
,
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
);
if
(
distance
<=
VIEW_SCOPE
)
{
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 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>
169
2366624.83
</float>
<float>
169
5395371.67
</float>
<string>
UTC
</string>
</tuple>
</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,
unparam: true */
...
...
@@ -135,6 +135,7 @@ var DroneManager = /** @class */ (function () {
configurable
:
true
});
DroneManager
.
prototype
.
internal_start
=
function
()
{
this
.
_targetCoordinates
=
this
.
position
;
this
.
_API
.
internal_start
(
this
);
this
.
_canPlay
=
true
;
this
.
_canCommunicate
=
true
;
...
...
@@ -175,14 +176,15 @@ var DroneManager = /** @class */ (function () {
return
;
};
DroneManager
.
prototype
.
internal_update
=
function
(
delta_time
)
{
var
context
=
this
;
var
context
=
this
,
milliseconds
;
if
(
this
.
_controlMesh
)
{
context
.
_API
.
internal_update
(
context
,
delta_time
);
if
(
context
.
_canUpdate
)
{
context
.
_canUpdate
=
false
;
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
context
.
onUpdate
(
context
.
_API
.
_gameManager
.
_game_duration
);
milliseconds
=
Math
.
floor
(
context
.
_API
.
_gameManager
.
_game_duration
);
return
context
.
onUpdate
(
milliseconds
);
})
.
push
(
function
()
{
context
.
_canUpdate
=
true
;
...
...
@@ -288,6 +290,9 @@ var DroneManager = /** @class */ (function () {
DroneManager
.
prototype
.
getInitialAltitude
=
function
()
{
return
this
.
_API
.
getInitialAltitude
();
};
DroneManager
.
prototype
.
getCollisionSector
=
function
()
{
return
this
.
_API
.
getCollisionSector
();
};
DroneManager
.
prototype
.
getAltitudeAbs
=
function
()
{
if
(
this
.
_controlMesh
)
{
var
altitude
=
this
.
_controlMesh
.
position
.
y
;
...
...
@@ -403,20 +408,44 @@ var DroneManager = /** @class */ (function () {
/******************************************************************************/
/******************************** MAP MANAGER *********************************/
var
MapManager
=
/** @class */
(
function
()
{
"
use strict
"
;
var
EPSILON
=
9.9
,
START_Z
=
15
,
R
=
6371
e3
;
var
SEED
=
'
6!
'
,
//default square map
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
function
MapManager
(
scene
)
{
function
MapManager
(
scene
,
map_param
)
{
var
_this
=
this
,
max_sky
,
skybox
,
skyboxMat
,
largeGroundMat
,
flag_material
,
largeGroundBottom
,
width
,
depth
,
terrain
,
max
,
flag_a
,
flag_b
,
mast
,
flag
,
count
=
0
,
new_obstacle
;
this
.
setMapInfo
(
GAMEPARAMETERS
.
map
,
GAMEPARAMETERS
.
initialPosition
);
count
=
0
,
new_obstacle
,
obstacle
,
flag_info
,
enemy
;
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
;
if
(
_this
.
map_info
.
depth
>
max
)
{
max
=
_this
.
map_info
.
depth
;
...
...
@@ -459,9 +488,26 @@ var MapManager = /** @class */ (function () {
terrain
.
position
=
BABYLON
.
Vector3
.
Zero
();
terrain
.
scaling
=
new
BABYLON
.
Vector3
(
depth
/
50000
,
depth
/
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
_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
)
{
case
"
box
"
:
new_obstacle
=
BABYLON
.
MeshBuilder
.
CreateBox
(
"
obs_
"
+
count
,
...
...
@@ -513,7 +559,13 @@ var MapManager = /** @class */ (function () {
'
y
'
:
1
,
'
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
.
alpha
=
1
;
flag_material
.
diffuseColor
=
BABYLON
.
Color3
.
Green
();
...
...
@@ -523,7 +575,7 @@ var MapManager = /** @class */ (function () {
flag_a
.
material
=
flag_material
;
flag_a
.
position
=
new
BABYLON
.
Vector3
(
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_a
.
rotation
=
new
BABYLON
.
Vector3
(
0
,
1
,
0
);
...
...
@@ -533,7 +585,7 @@ var MapManager = /** @class */ (function () {
flag_b
.
material
=
flag_material
;
flag_b
.
position
=
new
BABYLON
.
Vector3
(
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_b
.
rotation
=
new
BABYLON
.
Vector3
(
0
,
4
,
0
);
...
...
@@ -541,7 +593,7 @@ var MapManager = /** @class */ (function () {
{
'
size
'
:
1
},
scene
);
mast
.
position
=
new
BABYLON
.
Vector3
(
flag_info
.
position
.
x
,
FLAG_SIZE
.
z
/
2
,
//swap
flag_info
.
position
.
z
+
FLAG_SIZE
.
z
/
2
,
//swap
flag_info
.
position
.
y
);
mast
.
scaling
=
new
BABYLON
.
Vector3
(
...
...
@@ -551,117 +603,32 @@ var MapManager = /** @class */ (function () {
mast
.
material
=
flag_material
;
flag
=
BABYLON
.
Mesh
.
MergeMeshes
([
flag_a
,
flag_b
,
mast
]);
flag
.
id
=
index
;
//flag.weight = _this.map_info.flag_weight;
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
);
});
}
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
()
{
return
this
.
map_info
;
};
MapManager
.
prototype
.
latLonDistance
=
function
(
c1
,
c2
)
{
return
this
.
mapUtils
.
latLonDistance
(
c1
,
c2
);
};
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
)
{
return
(
this
.
map_info
.
map_size
/
180.0
)
*
(
90
-
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
;
return
this
.
mapUtils
.
latitudeToY
(
lat
);
};
MapManager
.
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
};
return
this
.
mapUtils
.
convertToLocalCoordinates
(
latitude
,
longitude
,
altitude
);
};
MapManager
.
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
};
return
this
.
mapUtils
.
convertToGeoCoordinates
(
x
,
y
,
z
);
};
return
MapManager
;
}());
...
...
@@ -701,8 +668,7 @@ var GameManager = /** @class */ (function () {
header_list
=
[
"
timestamp (ms)
"
,
"
latitude (°)
"
,
"
longitude (°)
"
,
"
AMSL (m)
"
,
"
rel altitude (m)
"
,
"
yaw (°)
"
,
"
ground speed (m/s)
"
,
"
climb rate (m/s)
"
];
drone_count
=
GAMEPARAMETERS
.
map
.
drones
.
user
.
length
+
GAMEPARAMETERS
.
map
.
drones
.
enemy
.
length
;
drone_count
=
GAMEPARAMETERS
.
drone
.
list
.
length
;
for
(
drone
=
0
;
drone
<
drone_count
;
drone
+=
1
)
{
this
.
_flight_log
[
drone
]
=
[];
this
.
_flight_log
[
drone
].
push
(
header_list
);
...
...
@@ -801,7 +767,9 @@ var GameManager = /** @class */ (function () {
};
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
)
{
...
...
@@ -854,45 +822,48 @@ var GameManager = /** @class */ (function () {
//there is not a proper collision
if
(
distance
(
drone
.
position
,
flag
.
location
)
<=
this
.
_mapManager
.
getMapInfo
().
flag_distance_epsilon
)
{
if
(
!
flag
.
drone_collider_list
.
includes
(
drone
.
id
))
{
//TODO notify the drone somehow? Or the AI script is in charge?
//console.log("flag " + flag.id + " hit by drone " + drone.id);
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
'
touched a flag.
'
));
if
(
flag
.
drone_collider_list
.
length
===
0
)
{
drone
.
score
++
;
flag
.
drone_collider_list
.
push
(
drone
.
id
);
}
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
'
touched flag
'
+
flag
.
id
));
if
(
flag
.
weight
>
0
)
{
flag
.
weight
-=
1
;
drone
.
score
+=
flag
.
score
;
// move score to a global place? GM, MM?
}
}
}
};
GameManager
.
prototype
.
_checkCollision
=
function
(
drone
,
other
)
{
if
(
drone
.
colliderMesh
&&
other
.
colliderMesh
&&
drone
.
colliderMesh
.
intersectsMesh
(
other
.
colliderMesh
,
false
))
{
var
angle
=
Math
.
acos
(
BABYLON
.
Vector3
.
Dot
(
drone
.
worldDirection
,
other
.
worldDirection
)
/
(
drone
.
worldDirection
.
length
()
*
other
.
worldDirection
.
length
()));
//TODO is this parameter set? keep it or make 2 drones die when intersect?
if
(
angle
<
GAMEPARAMETERS
.
drone
.
collisionSector
)
{
if
(
drone
.
speed
>
other
.
speed
)
{
other
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
'
bump drone
'
+
other
.
id
+
'
.
'
));
}
else
{
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
other
.
id
+
'
bumped drone
'
+
drone
.
id
+
'
.
'
));
}
if
(
drone
.
team
==
TEAM_ENEMY
&&
other
.
team
==
TEAM_ENEMY
)
return
;
function
distance
(
a
,
b
)
{
return
Math
.
sqrt
(
Math
.
pow
((
a
.
x
-
b
.
x
),
2
)
+
Math
.
pow
((
a
.
y
-
b
.
y
),
2
)
+
Math
.
pow
((
a
.
z
-
b
.
z
),
2
));
}
if
(
drone
.
team
!=
other
.
team
)
{
var
enemy
,
prey
;
if
(
drone
.
team
==
TEAM_ENEMY
)
{
enemy
=
drone
;
prey
=
other
;
}
else
if
(
other
.
team
==
TEAM_ENEMY
)
{
enemy
=
other
;
prey
=
drone
;
}
else
{
drone
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
'
touched drone
'
+
other
.
id
+
'
.
'
));
other
.
_internal_crash
(
new
Error
(
'
Drone
'
+
drone
.
id
+
'
touched drone
'
+
other
.
id
+
'
.
'
));
if
(
drone
.
position
&&
other
.
position
)
{
if
(
distance
(
drone
.
position
,
other
.
position
)
<
enemy
.
getCollisionSector
())
{
drone
.
_internal_crash
(
new
Error
(
'
enemy drone
'
+
enemy
.
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
)
{
...
...
@@ -968,11 +939,11 @@ var GameManager = /** @class */ (function () {
_this
.
_result_message
+=
"
ALL DRONES DOWN!
"
;
return
_this
.
_finish
();
}
if
(
_this
.
_allFlagsCaptured
())
{
/*
if (_this._allFlagsCaptured()) {
console.log("ALL FLAGS CAPTURED");
_this._result_message += "ALL FLAGS CAPTURED!";
return _this._finish();
}
}
*/
});
};
...
...
@@ -1061,24 +1032,10 @@ var GameManager = /** @class */ (function () {
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
()
{
var
score
=
0
;
this
.
_droneList_user
.
forEach
(
function
(
drone
)
{
//if (drone.can_play) {
score
+=
drone
.
score
;
//}
});
return
score
;
};
...
...
@@ -1135,13 +1092,15 @@ var GameManager = /** @class */ (function () {
this
.
_scene
);
hemi_south
.
intensity
=
0.75
;
cam_radius
=
(
GAMEPARAMETERS
.
map
.
map_size
*
1.10
<
6000
)
?
GAMEPARAMETERS
.
map
.
map_size
*
1.10
:
6000
;
//skybox scene limit
//HARDCODE camera to a hardcoded map_size
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
,
BABYLON
.
Vector3
.
Zero
(),
this
.
_scene
);
camera
.
wheelPrecision
=
10
;
//zoom out limit
camera
.
upperRadiusLimit
=
GAMEPARAMETERS
.
map
.
map_size
*
10
;
camera
.
upperRadiusLimit
=
map_size
*
10
;
//scene.activeCamera.upperRadiusLimit = max * 4;
//changed for event handling
//camera.attachControl(this._scene.getEngine().getRenderingCanvas()); //orig
...
...
@@ -1161,10 +1120,10 @@ var GameManager = /** @class */ (function () {
ctx
.
_map_swapped
=
true
;
}
// Init the map
_this
.
_mapManager
=
new
MapManager
(
ctx
.
_scene
);
_this
.
_mapManager
=
new
MapManager
(
ctx
.
_scene
,
GAMEPARAMETERS
.
map
);
ctx
.
_spawnDrones
(
_this
.
_mapManager
.
getMapInfo
().
initial_position
,
GAMEPARAMETERS
.
map
.
drones
.
user
,
TEAM_USER
,
ctx
);
ctx
.
_spawnDrones
(
null
,
GAMEPARAMETERS
.
map
.
drones
.
enemy
,
TEAM_ENEMY
,
ctx
);
GAMEPARAMETERS
.
drone
.
list
,
TEAM_USER
,
ctx
);
ctx
.
_spawnDrones
(
null
,
_this
.
_mapManager
.
_enemy_list
,
TEAM_ENEMY
,
ctx
);
// Hide the drone prefab
DroneManager
.
Prefab
.
isVisible
=
false
;
//Hack to make advanced texture work
...
...
@@ -1246,9 +1205,7 @@ var GameManager = /** @class */ (function () {
drone
.
_tick
=
0
;
promise_list
.
push
(
drone
.
internal_start
());
});
start_msg
=
{
'
flag_positions
'
:
_this
.
_mapManager
.
getMapInfo
().
geo_flag_list
};
start_msg
=
GAMEPARAMETERS
.
operator_init_msg
;
promise_list
.
push
(
_this
.
_droneList_user
[
0
].
sendMsg
(
start_msg
));
_this
.
_droneList_enemy
.
forEach
(
function
(
drone
)
{
drone
.
_tick
=
0
;
...
...
@@ -1259,6 +1216,8 @@ var GameManager = /** @class */ (function () {
.
push
(
function
()
{
_this
.
_canUpdate
=
true
;
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 () {
return
false
;
}
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
)
{
code
=
default_drone_AI
;
}
else
{
code
=
drone_info
.
script_content
;
}
trim
=
code
.
trim
();
if
(
!
trim
)
{
code
=
"
me.onStart = function () { forcedErrorEmptyScript };
"
;
if
(
!
code
.
includes
(
"
me.onStart
"
))
{
code
=
"
me.onStart = function () { me.exit(); };
"
;
}
code_eval
=
"
let drone = new DroneManager(ctx._scene,
"
+
index
+
'
, api, team);
'
+
...
...
@@ -1349,17 +1307,18 @@ var GameManager = /** @class */ (function () {
if
(
x
!==
null
&&
y
!==
null
&&
z
!==
null
)
{
code_eval
+=
"
me.setStartingPosition(
"
+
x
+
"
,
"
+
y
+
"
,
"
+
z
+
"
);
"
;
}
base
=
code_eval
;
//
base = code_eval;
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)
"
;
/*jslint evil: true*/
try
{
eval
(
code_eval
);
/*jslint evil: false*/
/*try {
eval(code_eval);
} catch (error) {
eval(base);
}
/*jslint evil: false*/
}*/
}
function
randomSpherePoint
(
x0
,
y0
,
z0
,
rx0
,
ry0
,
rz0
)
{
var
u
=
Math
.
random
(),
v
=
Math
.
random
(),
...
...
@@ -1388,7 +1347,7 @@ var GameManager = /** @class */ (function () {
position_list
.
push
(
position
);
var
id_offset
=
0
;
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
](
this
,
...
...
@@ -1429,12 +1388,6 @@ var runGame, updateGame;
}
};
/*// Resize canvas on window resize
window.addEventListener('resize', function () {
game_manager_instance._engine.resize();
});*/
}(
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 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>
169
1684378.73
</float>
<float>
169
5327797.6
</float>
<string>
UTC
</string>
</tuple>
</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 @@
margin
:
0
;
}
.documentation
div
{
vertical-align
:
middle
!important
;
}
.documentation
.line
{
width
:
100%
;
height
:
1px
;
...
...
@@ -54,7 +58,6 @@
.item-name
span
:last-of-type
{
font-style
:
italic
;
}
.line
{
width
:
100%
;
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 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -262,7 +262,7 @@
</tuple>
<state>
<tuple>
<float>
169
1176394.73
</float>
<float>
169
4621148.77
</float>
<string>
UTC
</string>
</tuple>
</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 @@
<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>
<h3>
API functions
</h3>
...
...
@@ -442,7 +577,7 @@
<!-- id -->
<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>
...
...
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 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -264,7 +264,7 @@
</tuple>
<state>
<tuple>
<float>
169
1679891.23
</float>
<float>
169
4622336.88
</float>
<string>
UTC
</string>
</tuple>
</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>
<html>
<!--
data-i18n=Others
data-i18n=Tools
-->
<head>
<meta
http-equiv=
"Content-type"
content=
"text/html; charset=utf-8"
/>
<meta
name=
"viewport"
content=
"width=device-width"
/>
<title>
Drone Capture Flag Script Page
</title>
<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 -->
<script
src=
"rsvp.js"
type=
"text/javascript"
></script>
...
...
@@ -18,24 +15,16 @@
<script
src=
"jiodev.js"
type=
"text/javascript"
></script>
<script
src=
"gadget_global.js"
type=
"text/javascript"
></script>
<script
src=
"domsugar.js"
type=
"text/javascript"
></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>
</head>
<body>
<form>
<div
data-gadget-url=
"gadget_erp5_form.html"
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>
<div
class=
"captureflagpageheader"
></div>
<div
class=
"captureflagpagebody"
></div>
</body>
</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 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -264,7 +264,7 @@
</tuple>
<state>
<tuple>
<float>
16
83820259.6
</float>
<float>
16
94194019.23
</float>
<string>
UTC
</string>
</tuple>
</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*/
/*global window, rJS, domsugar, document, URLSearchParams, Blob*/
(
function
(
window
,
rJS
,
domsugar
,
document
,
URLSearchParams
,
Blob
)
{
/*global window, rJS, domsugar, document, Blob, MapUtils, RSVP*/
/******************************* 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
"
;
//Drone default values - TODO: get them from the drone API
var
SIMULATION_SPEED
=
1
0
,
var
SIMULATION_SPEED
=
6
0
,
SIMULATION_TIME
=
270
,
//HARDCODED map size: it is defined by min-max lat-lon distance
//this is done by the map manager (latLonDistance)
//but map_size is needed here for map randomization (location of objects)
//TODO refactor: or randomization is moved to map manager (seed as param)
//or randomization is done here but with geo-coordinates (not meters)
MAP_SIZE
=
900
,
//square map
min_lat
=
45.6419
,
max_lat
=
45.65
,
min_lon
=
14.265
,
max_lon
=
14.2766
,
map_height
=
700
,
start_AMSL
=
595
,
//default square map
MAP_HEIGHT
=
700
,
START_AMSL
=
595
,
MIN_LAT
=
45.6419
,
MAX_LAT
=
45.65
,
MIN_LON
=
14.265
,
MAX_LON
=
14.2766
,
//seed
//url_sp = new URLSearchParams(window.location.hash),
//url_seed = url_sp.get("seed"),
SEED
=
'
123
'
,
//'6!',
MAP
=
{
"
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
,
MAX_ACCELERATION
=
6
,
MAX_DECELERATION
=
1
,
...
...
@@ -29,15 +75,16 @@
MAX_PITCH
=
25
,
MAX_CLIMB_RATE
=
8
,
MAX_SINK_RATE
=
3
,
NUMBER_OF_DRONES
=
10
,
FLAG_WEIGHT
=
5
,
SEED
=
'
6
'
,
NUMBER_OF_DRONES
=
5
,
// Non-inputs parameters
EPSILON
=
"
15
"
,
DEFAULT_OPERATOR_SCRIPT
=
'
var map = operator.getMapJSON();
\n
'
+
'
operator.sendMsg({flag_positions: map.flag_list});
\n
'
,
DEFAULT_SCRIPT_CONTENT
=
'
var EPSILON =
15
,
\n
'
+
'
var EPSILON =
'
+
EPSILON
+
'
,
\n
'
+
'
DODGE_DISTANCE = 100;
\n
'
+
'
\n
'
+
'
function distance(a, b) {
\n
'
+
'
function distance
2D
(a, b) {
\n
'
+
'
var R = 6371e3, // meters
\n
'
+
'
la1 = a.x * Math.PI / 180, // lat, lon in radians
\n
'
+
'
la2 = b.x * Math.PI / 180,
\n
'
+
...
...
@@ -49,6 +96,12 @@
'
return 2 * R * Math.asin(Math.sqrt(h));
\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.direction_set = false;
\n
'
+
'
me.dodging = false;
\n
'
+
...
...
@@ -57,7 +110,7 @@
'
\n
'
+
'
me.onGetMsg = function (msg) {
\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
'
+
'
}
\n
'
+
'
};
\n
'
+
...
...
@@ -79,9 +132,9 @@
'
if (!me.direction_set) {
\n
'
+
'
if (me.next_checkpoint < me.flag_positions.length) {
\n
'
+
'
me.setTargetCoordinates(
\n
'
+
'
me.flag_positions[me.next_checkpoint].x,
\n
'
+
'
me.flag_positions[me.next_checkpoint].y,
\n
'
+
'
me.flag_positions[me.next_checkpoint].z + me.id
\n
'
+
'
me.flag_positions[me.next_checkpoint].
position.
x,
\n
'
+
'
me.flag_positions[me.next_checkpoint].
position.
y,
\n
'
+
'
me.flag_positions[me.next_checkpoint].
position.
z + me.id
\n
'
+
'
);
\n
'
+
//' console.log("[DEMO] Going to Checkpoint %d", me.next_checkpoint);\n' +
'
}
\n
'
+
...
...
@@ -98,7 +151,7 @@
'
me.current_position = me.getCurrentPosition();
\n
'
+
'
me.distance = distance(
\n
'
+
'
me.current_position,
\n
'
+
'
me.flag_positions[me.next_checkpoint]
\n
'
+
'
me.flag_positions[me.next_checkpoint]
.position
\n
'
+
'
);
\n
'
+
'
if (me.distance <= EPSILON) {
\n
'
+
//' console.log("[DEMO] Reached Checkpoint %d", me.next_checkpoint);\n' +
...
...
@@ -107,6 +160,12 @@
'
}
\n
'
+
'
return;
\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
'
+
'
me.onDroneViewInfo = function (drone_view) {
\n
'
+
...
...
@@ -115,7 +174,7 @@
'
me.dodging = drone_view.obstacles[0];
\n
'
+
'
me.direction_set = false;
\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
'
+
'
dodge_point.x = dodge_point.x * -1;
\n
'
+
'
} else {
\n
'
+
...
...
@@ -128,431 +187,616 @@
DRAW
=
true
,
LOG
=
true
,
LOG_TIME
=
1662.7915426540285
,
DRONE_LIST
=
[],
LOGIC_FILE_LIST
=
[
'
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_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
)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.
declareAcquiredMethod
(
"
updateHeader
"
,
"
updateHeader
"
)
.
declareAcquiredMethod
(
"
notifySubmitted
"
,
"
notifySubmitted
"
)
function
renderGadgetHeader
(
gadget
,
loading
)
{
var
element_list
=
[],
game_map_icon
=
'
ui-icon-map-marker
'
,
game_randomize_icon
=
'
ui-icon-random
'
,
game_operator_icon
=
'
ui-icon-rss
'
,
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
()
{
return
this
.
element
.
querySelector
(
'
input[type="submit"]
'
).
click
();
})
if
(
loading
)
{
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
()
{
var
gadget
=
this
;
return
gadget
.
getDeclaredGadget
(
'
form_view
'
)
.
push
(
function
(
form_gadget
)
{
return
form_gadget
.
getContent
();
})
.
push
(
function
(
input
)
{
gadget
.
runGame
(
input
);
});
})
element_list
.
push
(
domsugar
(
'
button
'
,
{
type
:
'
button
'
,
text
:
"
Map
"
,
disabled
:
(
gadget
.
state
.
display_step
===
DISPLAY_MAP_PARAMETER
),
'
class
'
:
'
display-map-parameter-btn ui-btn-icon-left
'
+
game_map_icon
}),
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
()
{
var
gadget
=
this
,
url_sp
=
new
URLSearchParams
(
window
.
location
.
hash
),
url_seed
=
url_sp
.
get
(
"
seed
"
);
return
gadget
.
getDeclaredGadget
(
'
form_view
'
)
.
push
(
function
(
form_gadget
)
{
return
form_gadget
.
render
({
erp5_document
:
{
"
_embedded
"
:
{
"
_view
"
:
{
"
my_simulation_speed
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Simulation Speed
"
,
"
default
"
:
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
"
:
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
"
:
MIN_SPEED
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_min_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
IntegerField
"
},
"
my_drone_speed
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone speed
"
,
"
default
"
:
DEFAULT_SPEED
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
my_drone_max_speed
"
:
{
"
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
:
""
}
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpageheader
'
),
element_list
);
}
function
getContentFromParameterForm
(
gadget
)
{
return
gadget
.
getDeclaredGadget
(
'
parameter_form
'
)
.
push
(
function
(
form_gadget
)
{
return
form_gadget
.
getContent
();
})
.
push
(
function
(
content_dict
)
{
var
key
;
for
(
key
in
content_dict
)
{
if
(
content_dict
.
hasOwnProperty
(
key
))
{
gadget
.
state
[
key
]
=
content_dict
[
key
];
}
}
});
}
//////////////////////////////////////////////////
// Map parameters
//////////////////////////////////////////////////
function
renderMapParameterView
(
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_map_json
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Map JSON
"
,
"
default
"
:
gadget
.
state
.
map_json
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
map_json
"
,
"
hidden
"
:
0
,
"
url
"
:
"
gadget_editor.html
"
,
"
renderjs_extra
"
:
JSON
.
stringify
({
"
maximize
"
:
true
,
"
language
"
:
"
en
"
,
"
editor
"
:
"
codemirror
"
}),
"
type
"
:
"
GadgetField
"
}
}},
"
_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
"
]]
]]
}
}
);
})
.
push
(
function
()
{
return
gadget
.
updateHeader
({
page_title
:
'
Drone Capture Flag
'
,
page_icon
:
'
puzzle-piece
'
}
);
}
,
form_definition
:
{
group_list
:
[[
"
bottom
"
,
[[
"
my_map_json
"
]]
]]
}
});
})
})
.
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
)
{
return
Math
.
floor
(
random_seed
.
quick
()
*
(
max
-
min
+
1
)
+
min
);
}
function
randomPosition
(
random_seed
,
map_size
)
{
var
sign_x
=
random_seed
.
quick
()
<
0.5
?
-
1
:
1
,
sign_y
=
random_seed
.
quick
()
<
0.5
?
-
1
:
1
,
pos_x
=
sign_x
*
random_seed
.
quick
()
*
map_size
/
2
,
pos_y
=
sign_y
*
random_seed
.
quick
()
*
map_size
/
2
;
return
[
pos_x
,
pos_y
];
}
var
seed_value
=
options
.
map_seed
,
random_seed
=
new
Math
.
seedrandom
(
seed_value
),
i
,
n_enemies
=
randomIntFromInterval
(
5
,
10
,
random_seed
),
n_flags
=
randomIntFromInterval
(
5
,
10
,
random_seed
),
n_obstacles
=
randomIntFromInterval
(
5
,
15
,
random_seed
),
flag_list
=
[],
obstacle_list
=
[],
enemy_list
=
[],
random_position
,
obstacles_types
=
[
"
box
"
/*, "sphere"*/
,
"
cylinder
"
],
type
,
obstacle_limit
=
[
options
.
map_size
/
6
,
options
.
map_size
/
100
,
options
.
map_size
/
6
,
30
];
//enemies
for
(
i
=
0
;
i
<
n_enemies
;
i
+=
1
)
{
random_position
=
randomPosition
(
random_seed
,
options
.
map_size
);
enemy_list
.
push
({
"
id
"
:
i
+
parseInt
(
options
.
number_of_drones
),
"
type
"
:
"
EnemyDroneAPI
"
,
"
position
"
:
{
"
x
"
:
random_position
[
0
],
"
y
"
:
random_position
[
1
],
"
z
"
:
15
//TODO random z?
//////////////////////////////////////////////////
// Map parameters
//////////////////////////////////////////////////
function
renderRandomizeView
(
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_map_seed
"
:
{
"
description
"
:
"
Seed value to randomize the map
"
,
"
title
"
:
"
Seed value (ex:
"
+
SEED
+
"
)
"
,
"
default
"
:
gadget
.
state
.
map_seed
,
"
placeholder
"
:
SEED
,
"
css_class
"
:
""
,
"
required
"
:
0
,
"
editable
"
:
1
,
"
key
"
:
"
map_seed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
StringField
"
}
}},
"
_links
"
:
{
"
type
"
:
{
name
:
""
}
}
});
}
//flags
for
(
i
=
0
;
i
<
n_flags
;
i
+=
1
)
{
//avoid flags near the limits
random_position
=
randomPosition
(
random_seed
,
options
.
map_size
*
0.75
);
flag_list
.
push
({
"
position
"
:
{
"
x
"
:
random_position
[
0
],
"
y
"
:
random_position
[
1
],
"
z
"
:
10
},
form_definition
:
{
group_list
:
[[
"
center
"
,
[[
"
my_map_seed
"
]]
]]
}
});
})
.
push
(
function
()
{
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
:
""
}
}
});
}
function
checkDistance
(
position
,
position_list
)
{
function
distance
(
a
,
b
)
{
return
Math
.
sqrt
((
a
.
x
-
b
.
x
)
**
2
+
(
a
.
y
-
b
.
y
)
**
2
);
},
form_definition
:
{
group_list
:
[[
"
bottom
"
,
[[
"
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
)
{
return
true
;
});
})
.
push
(
function
()
{
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
for
(
i
=
0
;
i
<
n_obstacles
;
i
+=
1
)
{
random_position
=
randomPosition
(
random_seed
,
options
.
map_size
);
if
(
checkDistance
({
'
x
'
:
random_position
[
0
],
'
y
'
:
random_position
[
1
]},
flag_list
))
{
i
-=
1
;
}
else
{
type
=
randomIntFromInterval
(
0
,
2
,
random_seed
);
obstacle_list
.
push
({
"
type
"
:
obstacles_types
[
type
],
"
position
"
:
{
"
x
"
:
random_position
[
0
],
"
y
"
:
random_position
[
1
],
"
z
"
:
15
//TODO random z?
});
})
.
push
(
function
()
{
renderGadgetHeader
(
gadget
,
false
);
// Attach the form to the page
domsugar
(
gadget
.
element
.
querySelector
(
'
div.captureflagpagebody
'
),
[
form_gadget
.
element
]);
});
}
//////////////////////////////////////////////////
// Game parameters
//////////////////////////////////////////////////
function
renderGameParameterView
(
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_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
"
:
{
"
x
"
:
randomIntFromInterval
(
20
,
obstacle_limit
[
type
],
random_seed
),
"
y
"
:
randomIntFromInterval
(
20
,
obstacle_limit
[
type
],
random_seed
),
"
z
"
:
randomIntFromInterval
(
5
,
obstacle_limit
[
3
],
random_seed
)
"
my_drone_speed
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone speed
"
,
"
default
"
:
gadget
.
state
.
drone_speed
,
"
css_class
"
:
""
,
"
required
"
:
1
,
"
editable
"
:
1
,
"
key
"
:
"
drone_speed
"
,
"
hidden
"
:
0
,
"
type
"
:
"
FloatField
"
},
"
rotation
"
:
{
"
x
"
:
0
,
"
y
"
:
0
,
"
z
"
:
0
"
my_drone_max_speed
"
:
{
"
description
"
:
""
,
"
title
"
:
"
Drone max speed
"
,
"
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
;
json_map
.
flag_list
=
flag_list
;
return
json_map
;
}
});
})
.
push
(
function
()
{
renderGadgetHeader
(
gadget
,
false
);
// 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
=
{
"
map_size
"
:
parseFloat
(
options
.
map_size
),
"
height
"
:
parseInt
(
options
.
map_height
,
10
),
"
start_AMSL
"
:
parseFloat
(
options
.
start_AMSL
),
"
min_lat
"
:
parseFloat
(
min_lat
),
"
max_lat
"
:
parseFloat
(
max_lat
),
"
min_lon
"
:
parseFloat
(
min_lon
),
"
max_lon
"
:
parseFloat
(
max_lon
),
"
flag_list
"
:
[],
"
obstacle_list
"
:
[],
"
drones
"
:
{
"
user
"
:
DRONE_LIST
,
"
enemy
"
:
[]
/*jslint evil: true*/
try
{
gadget
.
state
.
operator_init_msg
=
new
Function
(
operator_code
)();
}
catch
(
error
)
{
return
gadget
.
notifySubmitted
({
message
:
"
Error in operator script:
"
+
error
.
message
,
status
:
'
error
'
});
}
};
/*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
=
{
"
drone
"
:
{
"
maxAcceleration
"
:
parseInt
(
options
.
drone_max_acceleration
,
10
),
"
maxDeceleration
"
:
parseInt
(
options
.
drone_max_deceleration
,
10
),
"
minSpeed
"
:
parseInt
(
options
.
drone_min_speed
,
10
),
"
speed
"
:
parseFloat
(
options
.
drone_speed
),
"
maxSpeed
"
:
parseInt
(
options
.
drone_max_speed
,
10
),
"
maxRoll
"
:
parseFloat
(
options
.
drone_max_roll
),
"
minPitchAngle
"
:
parseFloat
(
options
.
drone_min_pitch
),
"
maxPitchAngle
"
:
parseFloat
(
options
.
drone_max_pitch
),
"
maxSinkRate
"
:
parseFloat
(
options
.
drone_max_sink_rate
),
"
maxClimbRate
"
:
parseFloat
(
options
.
drone_max_climb_rate
)
"
maxAcceleration
"
:
parseInt
(
gadget
.
state
.
drone_max_acceleration
,
10
),
"
maxDeceleration
"
:
parseInt
(
gadget
.
state
.
drone_max_deceleration
,
10
),
"
minSpeed
"
:
parseInt
(
gadget
.
state
.
drone_min_speed
,
10
),
"
speed
"
:
parseFloat
(
gadget
.
state
.
drone_speed
),
"
maxSpeed
"
:
parseInt
(
gadget
.
state
.
drone_max_speed
,
10
),
"
maxRoll
"
:
parseFloat
(
gadget
.
state
.
drone_max_roll
),
"
minPitchAngle
"
:
parseFloat
(
gadget
.
state
.
drone_min_pitch
),
"
maxPitchAngle
"
:
parseFloat
(
gadget
.
state
.
drone_max_pitch
),
"
maxSinkRate
"
:
parseFloat
(
gadget
.
state
.
drone_max_sink_rate
),
"
maxClimbRate
"
:
parseFloat
(
gadget
.
state
.
drone_max_climb_rate
),
"
list
"
:
drone_list
},
"
gameTime
"
:
parseInt
(
options
.
simulation_time
,
10
),
"
simulation_speed
"
:
parseInt
(
options
.
simulation_speed
,
10
),
"
gameTime
"
:
parseInt
(
gadget
.
state
.
simulation_time
,
10
),
"
simulation_speed
"
:
parseInt
(
gadget
.
state
.
simulation_speed
,
10
),
"
latency
"
:
{
"
information
"
:
0
,
"
communication
"
:
0
},
"
map
"
:
randomizeMap
(
map_json
),
"
map
"
:
parsed_map
,
"
operator_init_msg
"
:
gadget
.
state
.
operator_init_msg
,
"
draw_flight_path
"
:
DRAW
,
"
temp_flight_path
"
:
true
,
"
log_drone_flight
"
:
LOG
,
...
...
@@ -604,9 +848,12 @@
return
form_gadget
.
getContent
();
})
.
push
(
function
(
result
)
{
var
a
,
blob
,
div
,
key
,
log
,
log_content
,
aux
;
var
a
,
blob
,
div
,
key
,
log
,
log_content
,
label
;
i
=
0
;
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
);
for
(
key
in
result
.
content
)
{
if
(
result
.
content
.
hasOwnProperty
(
key
))
{
...
...
@@ -615,17 +862,17 @@
a
=
domsugar
(
'
a
'
,
{
text
:
'
Download Simulation LOG
'
+
i
,
download
:
'
simulation_log_
'
+
i
+
'
_speed_
'
+
game_parameters_json
.
drone
.
speed
+
'
_min-speed_
'
+
game_parameters_json
.
drone
.
minSpeed
+
'
_max-speed_
'
+
game_parameters_json
.
drone
.
maxSpeed
+
'
_max-accel_
'
+
game_parameters_json
.
drone
.
maxAcceleration
+
'
_max-decel_
'
+
game_parameters_json
.
drone
.
maxDeceleration
+
'
_max-roll_
'
+
game_parameters_json
.
drone
.
maxRoll
+
'
_min-pitch_
'
+
game_parameters_json
.
drone
.
minPitchAngle
+
'
_max-pitch_
'
+
game_parameters_json
.
drone
.
maxPitchAngle
+
'
_max-sink_
'
+
game_parameters_json
.
drone
.
maxSinkRate
+
'
_max-climb_
'
+
game_parameters_json
.
drone
.
maxClimbRate
+
'
.txt
'
,
'
_speed_
'
+
game_parameters_json
.
drone
.
speed
+
'
_min-speed_
'
+
game_parameters_json
.
drone
.
minSpeed
+
'
_max-speed_
'
+
game_parameters_json
.
drone
.
maxSpeed
+
'
_max-accel_
'
+
game_parameters_json
.
drone
.
maxAcceleration
+
'
_max-decel_
'
+
game_parameters_json
.
drone
.
maxDeceleration
+
'
_max-roll_
'
+
game_parameters_json
.
drone
.
maxRoll
+
'
_min-pitch_
'
+
game_parameters_json
.
drone
.
minPitchAngle
+
'
_max-pitch_
'
+
game_parameters_json
.
drone
.
maxPitchAngle
+
'
_max-sink_
'
+
game_parameters_json
.
drone
.
maxSinkRate
+
'
_max-climb_
'
+
game_parameters_json
.
drone
.
maxClimbRate
+
'
.txt
'
,
href
:
window
.
URL
.
createObjectURL
(
blob
)
});
log
=
domsugar
(
'
textarea
'
,
...
...
@@ -636,7 +883,7 @@
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
div
);
document
.
querySelector
(
'
.container
'
).
parentNode
.
appendChild
(
log
);
i
+=
1
;
if
(
i
===
DRONE_LIST
.
length
)
{
if
(
i
===
drone_list
.
length
)
{
break
;
//Do not show enemy drone logs for now
/*aux = domsugar('div', { text: "Enemy drones logs:" });
...
...
@@ -648,6 +895,206 @@
return
gadget
.
notifySubmitted
({
message
:
"
Error:
"
+
error
.
message
,
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
));
\ No newline at end of file
}(
window
,
rJS
,
domsugar
,
document
,
Blob
,
MapUtils
,
RSVP
));
\ 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 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>
169
1681704.91
</float>
<float>
169
5397751.99
</float>
<string>
UTC
</string>
</tuple>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_site_module/officejs_drone_capture_flag.xml
View file @
3a9d947c
...
...
@@ -277,7 +277,7 @@
</item>
<item>
<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>
<key>
<string>
configuration_latest_document_version
</string>
</key>
...
...
@@ -538,7 +538,7 @@
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -558,7 +558,7 @@
</tuple>
<state>
<tuple>
<float>
16
82433351.46
</float>
<float>
16
92976685.9
</float>
<string>
UTC
</string>
</tuple>
</state>
...
...
bt5/erp5_officejs_drone_capture_flag/PathTemplateItem/web_site_module/officejs_drone_capture_flag/app.xml
View file @
3a9d947c
...
...
@@ -246,7 +246,7 @@
</item>
<item>
<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>
<key>
<string>
configuration_default_view_action_reference
</string>
</key>
...
...
@@ -502,7 +502,7 @@ WebSection_getDroneCaptureFlagPrecacheManifestList</string> </value>
</item>
<item>
<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>
<key>
<string>
state
</string>
</key>
...
...
@@ -522,7 +522,7 @@ WebSection_getDroneCaptureFlagPrecacheManifestList</string> </value>
</tuple>
<state>
<tuple>
<float>
16
82433685.5
</float>
<float>
16
92976699.18
</float>
<string>
UTC
</string>
</tuple>
</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 = [
"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.js"
,
"gadget_erp5_page_drone_capture_flag_script_page.css"
,
"gadget_erp5_panel_drone_capture_flag.html"
,
"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_enemydrone.js"
,
"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