1
0
forked from 0ad/0ad

Move placement options from rmgen2 to rmgen-common

Move the placement functions and the getTeamArray from rmgen2 to
rmgen-common, so that those maps can use the placement options as well,
without having to load the whole rmgen2 library.

Differential revision: https://code.wildfiregames.com/D4948
This was SVN commit r27941.
This commit is contained in:
marder 2023-11-19 11:30:04 +00:00
parent 6002acf833
commit 3c1436223f
2 changed files with 110 additions and 110 deletions

View File

@ -568,6 +568,37 @@ function partitionPlayers(playerIDs)
[[], []]);
}
/**
* Return an array where each element is an array of playerIndices of a team.
*/
function getTeamsArray()
{
var playerIDs = sortAllPlayers();
var numPlayers = getNumPlayers();
// Group players by team
var teams = [];
for (let i = 0; i < numPlayers; ++i)
{
let team = getPlayerTeam(playerIDs[i]);
if (team == -1)
continue;
if (!teams[team])
teams[team] = [];
teams[team].push(playerIDs[i]);
}
// Players without a team get a custom index
for (let i = 0; i < numPlayers; ++i)
if (getPlayerTeam(playerIDs[i]) == -1)
teams.push([playerIDs[i]]);
// Remove unused indices
return teams.filter(team => true);
}
/**
* Determine player starting positions on a circular pattern.
*/
@ -675,6 +706,85 @@ function playerPlacementLine(angle, center, width)
return playerPosition;
}
/**
* Place teams in a line-pattern.
*
* @param {Array} playerIDs - typically randomized indices of players of a single team
* @param {number} distance - radial distance from the center of the map
* @param {number} groupedDistance - distance between players
* @param {number} startAngle - determined by the map that might want to place something between players.
*
* @returns {Array} - contains id, angle, x, z for every player
*/
function placeLine(teamsArray, distance, groupedDistance, startAngle)
{
let playerIDs = [];
let playerPosition = [];
let mapCenter = g_Map.getCenter();
let dist = fractionToTiles(0.45);
for (let i = 0; i < teamsArray.length; ++i)
{
var safeDist = distance;
if (distance + teamsArray[i].length * groupedDistance > dist)
safeDist = dist - teamsArray[i].length * groupedDistance;
var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length;
for (let p = 0; p < teamsArray[i].length; ++p)
{
playerIDs.push(teamsArray[i][p]);
playerPosition.push(Vector2D.add(mapCenter, new Vector2D(safeDist + p * groupedDistance, 0).rotate(-teamAngle)).round());
}
}
return [playerIDs, playerPosition];
}
/**
* Place given players in a stronghold-pattern.
*
* @param teamsArray - each item is an array of playerIDs placed per stronghold
* @param distance - radial distance from the center of the map
* @param groupedDistance - distance between neighboring players
* @param {number} startAngle - determined by the map that might want to place something between players
*/
function placeStronghold(teamsArray, distance, groupedDistance, startAngle)
{
var mapCenter = g_Map.getCenter();
let playerIDs = [];
let playerPosition = [];
for (let i = 0; i < teamsArray.length; ++i)
{
var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length;
var teamPosition = Vector2D.add(mapCenter, new Vector2D(distance, 0).rotate(-teamAngle));
var teamGroupDistance = groupedDistance;
// If we have a team of above average size, make sure they're spread out
if (teamsArray[i].length > 4)
teamGroupDistance = Math.max(fractionToTiles(0.08), groupedDistance);
// If we have a solo player, place them on the center of the team's location
if (teamsArray[i].length == 1)
teamGroupDistance = fractionToTiles(0);
// TODO: Ensure players are not placed outside of the map area, similar to placeLine
// Create player base
for (var p = 0; p < teamsArray[i].length; ++p)
{
var angle = startAngle + (p + 1) * 2 * Math.PI / teamsArray[i].length;
playerIDs.push(teamsArray[i][p]);
playerPosition.push(Vector2D.add(teamPosition, new Vector2D(teamGroupDistance, 0).rotate(-angle)).round());
}
}
return [playerIDs, playerPosition];
}
/**
* Returns a random location for each player that meets the given constraints and
* orders the playerIDs so that players become grouped by team.

View File

@ -205,116 +205,6 @@ function createBase(playerID, playerPosition, walls)
});
}
/**
* Return an array where each element is an array of playerIndices of a team.
*/
function getTeamsArray()
{
var playerIDs = sortAllPlayers();
var numPlayers = getNumPlayers();
// Group players by team
var teams = [];
for (let i = 0; i < numPlayers; ++i)
{
let team = getPlayerTeam(playerIDs[i]);
if (team == -1)
continue;
if (!teams[team])
teams[team] = [];
teams[team].push(playerIDs[i]);
}
// Players without a team get a custom index
for (let i = 0; i < numPlayers; ++i)
if (getPlayerTeam(playerIDs[i]) == -1)
teams.push([playerIDs[i]]);
// Remove unused indices
return teams.filter(team => true);
}
/**
* Place teams in a line-pattern.
*
* @param {Array} playerIDs - typically randomized indices of players of a single team
* @param {number} distance - radial distance from the center of the map
* @param {number} groupedDistance - distance between players
* @param {number} startAngle - determined by the map that might want to place something between players.
*
* @returns {Array} - contains id, angle, x, z for every player
*/
function placeLine(teamsArray, distance, groupedDistance, startAngle)
{
let playerIDs = [];
let playerPosition = [];
let mapCenter = g_Map.getCenter();
let dist = fractionToTiles(0.45);
for (let i = 0; i < teamsArray.length; ++i)
{
var safeDist = distance;
if (distance + teamsArray[i].length * groupedDistance > dist)
safeDist = dist - teamsArray[i].length * groupedDistance;
var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length;
for (let p = 0; p < teamsArray[i].length; ++p)
{
playerIDs.push(teamsArray[i][p]);
playerPosition.push(Vector2D.add(mapCenter, new Vector2D(safeDist + p * groupedDistance, 0).rotate(-teamAngle)).round());
}
}
return [playerIDs, playerPosition];
}
/**
* Place given players in a stronghold-pattern.
*
* @param teamsArray - each item is an array of playerIDs placed per stronghold
* @param distance - radial distance from the center of the map
* @param groupedDistance - distance between neighboring players
* @param {number} startAngle - determined by the map that might want to place something between players
*/
function placeStronghold(teamsArray, distance, groupedDistance, startAngle)
{
var mapCenter = g_Map.getCenter();
let playerIDs = [];
let playerPosition = [];
for (let i = 0; i < teamsArray.length; ++i)
{
var teamAngle = startAngle + (i + 1) * 2 * Math.PI / teamsArray.length;
var teamPosition = Vector2D.add(mapCenter, new Vector2D(distance, 0).rotate(-teamAngle));
var teamGroupDistance = groupedDistance;
// If we have a team of above average size, make sure they're spread out
if (teamsArray[i].length > 4)
teamGroupDistance = Math.max(fractionToTiles(0.08), groupedDistance);
// If we have a solo player, place them on the center of the team's location
if (teamsArray[i].length == 1)
teamGroupDistance = fractionToTiles(0);
// TODO: Ensure players are not placed outside of the map area, similar to placeLine
// Create player base
for (var p = 0; p < teamsArray[i].length; ++p)
{
var angle = startAngle + (p + 1) * 2 * Math.PI / teamsArray[i].length;
playerIDs.push(teamsArray[i][p]);
playerPosition.push(Vector2D.add(teamPosition, new Vector2D(teamGroupDistance, 0).rotate(-angle)).round());
}
}
return [playerIDs, playerPosition];
}
/**
* Creates tileClass for the default classes and every class given.
*