Changeset View
Standalone View
binaries/data/mods/public/maps/random/rmgen/placer/noncentered/WedgePlacer.js
- This file was added.
/** | |||||
* The WedgePlacer returns all tiles between a center point and two angles. | |||||
*/ | |||||
function WedgePlacer(centerPoint, startAngle, stopAngle, failFraction = 100) { | |||||
lyv: Rather than adding a new placer, its better to instead modify `DiskPlacer` to accept the two… | |||||
this.normalize = 0; | |||||
Not Done Inline ActionsThis doesn't really need n^2 atan2 calls. Given these wedges extend to infinity, they can be considered as triangles with at least one axis aligned edge meaning you can just use a scanline fill. I guess a better consideration would be why this is a non-centered placer. Why not change the DiskPlacer to accept sectors instead? As of now, this seems extremely map specific to the case involving circular sectors of an infinitely large disk I guess. But that shouldn't necessarily be a requirement. lyv: This doesn't really need n^2 atan2 calls. Given these wedges extend to infinity, they can be… | |||||
Done Inline Actions[obligatory "I am not the one reviewing/testing/committing this and that's merely a suggestion"] lyv: [obligatory "I am not the one reviewing/testing/committing this and that's merely a suggestion"] | |||||
Not Done Inline ActionsIt's only used on this map for now, but I'm also using it on other maps in progress. There's an existing, but unused player placement type called "arc" which basically compresses the radial player placement. For example, you can use this wedge placer to define wedges of neutral territory between teams and add more specific resource types to those areas. Like adding more metal in the neutral wedge than you do in the team wedge. kalimaps: It's only used on this map for now, but I'm also using it on other maps in progress. There's an… | |||||
this.centerPoint = centerPoint; | |||||
this.startAngle = startAngle; | |||||
this.stopAngle = stopAngle; | |||||
// add 2 * Math.PI to ensure a positive angle | |||||
if (this.startAngle < 0 || this.stopAngle < 0) { | |||||
this.normalize = 2 * Math.PI; | |||||
this.startAngle = startAngle + this.normalize; | |||||
this.stopAngle = stopAngle + this.normalize; | |||||
} | |||||
this.failFraction = failFraction; | |||||
} | |||||
WedgePlacer.prototype.place = function (constraint) { | |||||
let points = []; | |||||
let count = 0; | |||||
let failed = 0; | |||||
for (let x = 0; x < g_Map.getSize(); ++x) { | |||||
for (let y = 0; y < g_Map.getSize(); ++y) { | |||||
++count; | |||||
let point = new Vector2D(x, y); | |||||
let radians = Math.atan2(point.y - this.centerPoint.y, point.x - this.centerPoint.x) + this.normalize; | |||||
if (radians < 0) { | |||||
radians += 2 * Math.PI; | |||||
} | |||||
// check if this angle is between the two angles (plus an optional full rotation) | |||||
if (g_Map.inMapBounds(point) && ((radians >= this.startAngle && radians < this.stopAngle) || (radians + 2 * Math.PI >= this.startAngle && radians + 2 * Math.PI < this.stopAngle)) && constraint.allows(point)) { | |||||
points.push(point); | |||||
} else { | |||||
++failed; | |||||
} | |||||
} | |||||
} | |||||
return failed <= this.failFraction * count ? points : undefined; | |||||
} |
Rather than adding a new placer, its better to instead modify DiskPlacer to accept the two angle parameters. It would be more generic and can be used for more cases rather than this sole requirement.