Commit 36b5ce60 authored by Roque's avatar Roque

erp5_officejs_drone_capture_flag: new map randomization strategy

- grid of blocks
- set of block templates
- randomization conditions
- new terrarin texture
- refine enemy drone collision
- more aggressive enemies
parent 26d6772a
......@@ -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;
}());
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1009.37360.49772.3874</string> </value>
<value> <string>1011.20054.25134.60962</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1688571911.82</float>
<float>1695397984.38</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -422,11 +422,11 @@ 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
});
}
}
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1010.45437.13560.55142</string> </value>
<value> <string>1011.5610.25987.56473</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1694531183.74</float>
<float>1695395371.67</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -290,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;
......@@ -601,7 +604,6 @@ var MapManager = /** @class */ (function () {
flag = BABYLON.Mesh.MergeMeshes([flag_a, flag_b, mast]);
flag.id = index;
flag.location = flag_info.position;
//flag.drone_collider_list = [];
flag.weight = flag_info.weight;
flag.score = flag_info.score;
flag.id = index;
......@@ -611,14 +613,6 @@ var MapManager = /** @class */ (function () {
MapManager.prototype.getMapInfo = function () {
return this.map_info;
};
//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) {
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) {
return this.mapUtils.latLonDistance(c1, c2);
};
......@@ -834,44 +828,42 @@ var GameManager = /** @class */ (function () {
flag.weight -= 1;
drone.score += flag.score; // move score to a global place? GM, MM?
}
/*if (!flag.drone_collider_list.includes(drone.id)) {
//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);
}
}*/
}
}
};
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) {
......@@ -1040,19 +1032,6 @@ var GameManager = /** @class */ (function () {
return finish;
};
//game ends due to timeout or all drones stopped/crashed
/*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) {
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.9946.55286.52770</string> </value>
<value> <string>1011.18882.27011.1501</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1694792090.7</float>
<float>1695327797.6</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -242,7 +242,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.8487.12042.61832</string> </value>
<value> <string>1011.18883.7641.45704</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -262,7 +262,7 @@
</tuple>
<state>
<tuple>
<float>1694782467.44</float>
<float>1695327563.61</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -39,7 +39,7 @@ var OperatorAPI = /** @class */ (function () {
//seed
//url_sp = new URLSearchParams(window.location.hash),
//url_seed = url_sp.get("seed"),
SEED = '6!',//url_seed ? url_seed : '6!',
SEED = '123',//'6!',
MAP = {
"height": MAP_HEIGHT,
"start_AMSL": START_AMSL,
......@@ -61,7 +61,8 @@ var OperatorAPI = /** @class */ (function () {
"rotation": {"x": 0, "y": 0, "z": 0}}],
"enemy_list": [{"type": "EnemyDroneAPI",
"position": {"x": 45.6455531,
"y": 14.270231599999988, "z": 15}}],
"y": 14.270747186236491,
"z": 15}}],
"initial_position": {"x": 45.642813275, "y": 14.270231599999988, "z": 15}
},
DEFAULT_SPEED = 16,
......@@ -76,7 +77,7 @@ var OperatorAPI = /** @class */ (function () {
MAX_SINK_RATE = 3,
NUMBER_OF_DRONES = 5,
// Non-inputs parameters
EPSILON = 15,
EPSILON = "15",
DEFAULT_OPERATOR_SCRIPT = 'var map = operator.getMapJSON();\n' +
'operator.sendMsg({flag_positions: map.flag_list});\n',
DEFAULT_SCRIPT_CONTENT =
......
......@@ -246,7 +246,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1011.10069.44691.10922</string> </value>
<value> <string>1011.18818.32686.32580</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1694798760.01</float>
<float>1695397751.99</float>
<string>UTC</string>
</tuple>
</state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment