Line data Source code
1 : /**
2 : * @file An Object tries to find locations around a location and returns an array of Entity items holding the template names, owners and locations on success.
3 : */
4 :
5 : /**
6 : * The SimpleObject attempts to find locations for a random amount of entities with a random distance to the given center.
7 : */
8 : function SimpleObject(templateName, minCount, maxCount, minDistance, maxDistance, minAngle = 0, maxAngle = 2 * Math.PI, avoidDistance = 1)
9 : {
10 0 : this.templateName = templateName;
11 0 : this.minCount = minCount;
12 0 : this.maxCount = maxCount;
13 0 : this.minDistance = minDistance;
14 0 : this.maxDistance = maxDistance;
15 0 : this.minAngle = minAngle;
16 0 : this.maxAngle = maxAngle;
17 0 : this.avoidDistanceSquared = Math.square(avoidDistance);
18 :
19 0 : if (minCount > maxCount)
20 0 : throw new Error("SimpleObject: minCount should be less than or equal to maxCount");
21 :
22 0 : if (minDistance > maxDistance)
23 0 : throw new Error("SimpleObject: minDistance should be less than or equal to maxDistance");
24 :
25 0 : if (minAngle > maxAngle)
26 0 : throw new Error("SimpleObject: minAngle should be less than or equal to maxAngle");
27 : }
28 :
29 6 : SimpleObject.prototype.place = function(centerPosition, playerID, avoidPositions, constraint, maxRetries)
30 : {
31 0 : let entitySpecs = [];
32 0 : let numRetries = 0;
33 0 : let validTile = pos => this.templateName.startsWith(g_ActorPrefix) ? g_Map.validTile(pos) : g_Map.validTilePassable(pos);
34 :
35 0 : for (let i = 0; i < randIntInclusive(this.minCount, this.maxCount); ++i)
36 0 : while (true)
37 : {
38 0 : let distance = randFloat(this.minDistance, this.maxDistance);
39 0 : let angle = randomAngle();
40 :
41 0 : let position = Vector2D.sum([centerPosition, new Vector2D(0.5, 0.5), new Vector2D(distance, 0).rotate(-angle)]);
42 :
43 0 : if (validTile(position) &&
44 : (!avoidPositions ||
45 0 : entitySpecs.every(entSpec => entSpec.position.distanceToSquared(position) >= this.avoidDistanceSquared) &&
46 0 : avoidPositions.every(avoid => avoid.position.distanceToSquared(position) >= Math.max(this.avoidDistanceSquared, avoid.distanceSquared))) &&
47 : constraint.allows(position.clone().floor()))
48 : {
49 0 : entitySpecs.push({
50 : "templateName": this.templateName,
51 : "playerID": playerID,
52 : "position": position,
53 : "angle": randFloat(this.minAngle, this.maxAngle)
54 : });
55 0 : break;
56 : }
57 :
58 0 : if (numRetries++ > maxRetries)
59 0 : return undefined;
60 : }
61 :
62 0 : return entitySpecs;
63 : };
64 :
65 : /**
66 : * Same as SimpleObject, but choses one of the given templates at random.
67 : */
68 : function RandomObject(templateNames, minCount, maxCount, minDistance, maxDistance, minAngle, maxAngle, avoidDistance = 1)
69 : {
70 0 : this.templateNames = templateNames;
71 0 : this.minCount = minCount;
72 0 : this.maxCount = maxCount;
73 0 : this.minDistance = minDistance;
74 0 : this.maxDistance = maxDistance;
75 0 : this.minAngle = minAngle;
76 0 : this.maxAngle = maxAngle;
77 0 : this.avoidDistance = avoidDistance;
78 : }
79 :
80 6 : RandomObject.prototype.place = function(centerPosition, player, avoidPositions, constraint, maxRetries)
81 : {
82 0 : return new SimpleObject(pickRandom(this.templateNames), this.minCount, this.maxCount, this.minDistance, this.maxDistance, this.minAngle, this.maxAngle, this.avoidDistance).place(
83 : centerPosition, player, avoidPositions, constraint, maxRetries);
84 : };
|