Differential D4053 Diff 17968 binaries/data/mods/public/maps/random/rmgen/placer/noncentered/WedgePlacer.js

# Changeset View

Changeset View

# Standalone 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) { | |||||

this.normalize = 0; | |||||

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… | |||||

Not Done Inline ActionsRather than adding a new placer, its better to instead modify lyv: Rather than adding a new placer, its better to instead modify `DiskPlacer` to accept the two… | |||||

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; | |||||

} |

Wildfire Games · Phabricator

This 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.