Use CamelCase for random map files containing the prototype of the same name, refs...
[0ad.git] / binaries / data / mods / public / maps / random / rmgen / Group.js
blobcfbea8e33fd46b01b55212a6706d5ad414a4bae8
1 /**
2  * @file A Group tests if a set of entities specified in the constructor can be placed and
3  * potentially places some of them (typically all or none).
4  *
5  * The location is defined by the x and z property of the Group instance and can be modified externally.
6  * The Group is free to determine whether, where exactly and how many entities to place.
7  *
8  * The Constraint to test against and the future owner of the entities are passed by the caller.
9  * Typically Groups are called from createObjectGroup with the location set in the constructor or
10  * from createObjectGroups that randomizes the x and z property of the Group before calling place.
11  */
13 /**
14  * Places all of the given Objects.
15  *
16  * @param objects - An array of Objects, for instance SimpleObjects.
17  * @param avoidSelf - Objects will not overlap.
18  * @param tileClass - Optional TileClass that tiles with placed entities are marked with.
19  * @param centerPosition - The location the group is placed around. Can be omitted if the property is set externally.
20  */
21 function SimpleGroup(objects, avoidSelf = false, tileClass = undefined, centerPosition = undefined)
23         this.objects = objects;
24         this.tileClass = tileClass;
25         this.avoidSelf = avoidSelf;
26         this.centerPosition = undefined;
28         if (centerPosition)
29                 this.setCenterPosition(centerPosition);
32 SimpleGroup.prototype.setCenterPosition = function(position)
34         this.centerPosition = deepfreeze(position.clone().round());
37 SimpleGroup.prototype.place = function(playerID, constraint)
39         let entitySpecsResult = [];
40         let avoidPositions = this.avoidSelf ? [] : undefined;
42         // Test if the Objects can be placed at the given location
43         // Place none of them if one can't be placed.
44         for (let object of this.objects)
45         {
46                 let entitySpecs = object.place(this.centerPosition, playerID, avoidPositions, constraint, 30);
48                 if (!entitySpecs)
49                         return undefined;
51                 entitySpecsResult = entitySpecsResult.concat(entitySpecs);
53                 if (this.avoidSelf)
54                         avoidPositions = avoidPositions.concat(entitySpecs.map(entitySpec => ({
55                                 "position": entitySpec.position,
56                                 "distance": object.avoidDistance
57                         })));
58         }
60         // Create and place entities as specified
61         let entities = [];
62         for (let entitySpecs of entitySpecsResult)
63         {
64                 // The Object must ensure that non-actor entities are not placed at the impassable map-border
65                 entities.push(
66                         g_Map.placeEntityAnywhere(entitySpecs.templateName, entitySpecs.playerID, entitySpecs.position, entitySpecs.angle));
68                 if (this.tileClass)
69                         this.tileClass.add(entitySpecs.position.clone().floor());
70         }
72         return entities;
75 /**
76  * Randomly choses one of the given Objects and places it just like the SimpleGroup.
77  */
78 function RandomGroup(objects, avoidSelf = false, tileClass = undefined, centerPosition = undefined)
80         this.simpleGroup = new SimpleGroup([pickRandom(objects)], avoidSelf, tileClass, centerPosition);
83 RandomGroup.prototype.setCenterPosition = function(position)
85         this.simpleGroup.setCenterPosition(position);
88 RandomGroup.prototype.place = function(playerID, constraint)
90         return this.simpleGroup.place(playerID, constraint);