const debugLog = false; var attackerTemplate = "trigger/fauna_wolf_snow_attack"; var minWaveSize = 1; var maxWaveSize = 3; var firstWaveTime = 5; var minWaveTime = 2; var maxWaveTime = 4; /** * Attackers will focus the targetCount closest units that have the targetClasses type. */ var targetClasses = "Organic+!Domestic"; var targetCount = 3; var disabledTechnologies = [ "gather_lumbering_ironaxes", "gather_lumbering_sharpaxes", "gather_lumbering_strongeraxes" ]; Trigger.prototype.InitDisableTechnologies = function() { for (let i = 1; i < TriggerHelper.GetNumberOfPlayers(); ++i) QueryPlayerIDInterface(i).SetDisabledTechnologies(disabledTechnologies); }; Trigger.prototype.SpawnWolvesAndAttack = function() { let waveSize = Math.round(Math.random() * (maxWaveSize - minWaveSize) + minWaveSize); let attackers = TriggerHelper.SpawnUnitsFromTriggerPoints("A", attackerTemplate, waveSize, 0); if (debugLog) print("Spawned " + waveSize + " " + attackerTemplate + " at " + Object.keys(attackers).length + " points\n"); let allTargets = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager).GetNonGaiaEntities().filter(ent => { let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); return cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses); }); let cmpDamage = Engine.QueryInterface(SYSTEM_ENTITY, IID_Damage); let players = new Array(TriggerHelper.GetNumberOfPlayers()).fill(0).map((v, i) => i + 1); for (let spawnPoint in attackers) { // TriggerHelper.SpawnUnits is guaranteed to spawn let firstAttacker = attackers[spawnPoint][0]; if (!firstAttacker) continue; let cmpAttackerPos = Engine.QueryInterface(firstAttacker, IID_Position); if (!cmpAttackerPos || !cmpAttackerPos.IsInWorld()) continue; // The returned entities are sorted by the rangemanager already let targets = cmpDamage.EntitiesNearPoint(cmpAttackerPos.GetPosition2D(), 200, players).filter(ent => { let cmpIdentity = Engine.QueryInterface(ent, IID_Identity); return cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), targetClasses); }); let good_targets = targets.slice(0,targetCount); // Look through all targets if there weren't enough nearby ones if (good_targets.length < targetCount) { let attackerPos = cmpAttackerPos.GetPosition2D(); let getDistance = target => { let cmpPositionTarget = Engine.QueryInterface(target, IID_Position); if (!cmpPositionTarget || !cmpPositionTarget.IsInWorld()) return Infinity; return attackerPos.distanceToSquared(cmpPositionTarget.GetPosition2D()); }; good_targets = []; let good_dists = []; for (let target of allTargets) { let dist = getDistance(target); let i = good_dists.findIndex(element => dist < element); if (i != -1 || good_targets.length < targetCount) { if (i == -1) i = targetCount; good_targets.splice(i, 0, target); good_dists.splice(i, 0, dist); if (good_targets.length > targetCount) { good_targets.pop(); good_dists.pop(); } } } } for (let target of good_targets) ProcessCommand(0, { "type": "attack", "entities": attackers[spawnPoint], "target": target, "queued": true }); } this.DoAfterDelay((Math.random() * (maxWaveTime - minWaveTime) + minWaveTime) * 60 * 1000, "SpawnWolvesAndAttack", {}); }; { let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); cmpTrigger.InitDisableTechnologies(); cmpTrigger.DoAfterDelay(firstWaveTime * 60 * 1000, "SpawnWolvesAndAttack", {}); }