Index: ps/trunk/binaries/data/mods/public/maps/random/survivalofthefittest_triggers.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/random/survivalofthefittest_triggers.js +++ ps/trunk/binaries/data/mods/public/maps/random/survivalofthefittest_triggers.js @@ -211,7 +211,11 @@ } // Don't spawn attackers for defeated players and players that lost their cc after win - let playerID = QueryOwnerInterface(point, IID_Player).GetPlayerID(); + let cmpPlayer = QueryOwnerInterface(point, IID_Player); + if (!cmpPlayer) + continue; + + let playerID = cmpPlayer.GetPlayerID(); let civicCentre = this.playerCivicCenter[playerID]; if (!civicCentre) continue; Index: ps/trunk/binaries/data/mods/public/maps/scripts/CaptureTheRelic.js =================================================================== --- ps/trunk/binaries/data/mods/public/maps/scripts/CaptureTheRelic.js +++ ps/trunk/binaries/data/mods/public/maps/scripts/CaptureTheRelic.js @@ -38,7 +38,7 @@ if (data.to == -1) { - warn("Relic entity " + data.entity + " has been destroyed"); + warn("Relic entity " + data.entity + " has been destroyed."); this.relics.splice(this.relics.indexOf(data.entity), 1); } else @@ -130,6 +130,14 @@ } let cmpPlayer = QueryOwnerInterface(this.relics[0], IID_Player); + if (!cmpPlayer) + { + warn("Relic entity " + this.relics[0] + " has no owner."); + this.relics.splice(0, 1); + + this.CheckCaptureTheRelicCountdown(); + return; + } let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); let captureTheRelicDuration = cmpEndGameManager.GetGameSettings().relicDuration; Index: ps/trunk/binaries/data/mods/public/simulation/components/BuildRestrictions.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/BuildRestrictions.js +++ ps/trunk/binaries/data/mods/public/simulation/components/BuildRestrictions.js @@ -92,8 +92,11 @@ "translateParameters": ["name"], }; - // TODO: AI has no visibility info var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); + if (!cmpPlayer) + return result; // Fail + + // TODO: AI has no visibility info if (!cmpPlayer.IsAI()) { // Check whether it's in a visible or fogged region @@ -164,9 +167,8 @@ // Check territory restrictions var cmpTerritoryManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager); - var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); var cmpPosition = Engine.QueryInterface(this.entity, IID_Position); - if (!(cmpTerritoryManager && cmpPlayer && cmpPosition && cmpPosition.IsInWorld())) + if (!cmpTerritoryManager || !cmpPosition || !cmpPosition.IsInWorld()) return result; // Fail var pos = cmpPosition.GetPosition2D(); @@ -239,7 +241,6 @@ if (this.template.Distance) { var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); var cat = this.template.Distance.FromClass; var filter = function(id) Index: ps/trunk/binaries/data/mods/public/simulation/components/Looter.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Looter.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Looter.js @@ -34,7 +34,8 @@ // Transfer resources var cmpPlayer = QueryOwnerInterface(this.entity); - cmpPlayer.AddResources(resources); + if (cmpPlayer) + cmpPlayer.AddResources(resources); // Update statistics var cmpStatisticsTracker = QueryOwnerInterface(this.entity, IID_StatisticsTracker); Index: ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js +++ ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js @@ -303,6 +303,8 @@ return false; let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); + if (!cmpTechnologyManager) + return false; let template = TechnologyTemplates.Get(tech); if (template.top) @@ -323,6 +325,8 @@ // TODO: there should be a way for the GUI to determine whether it's going // to be possible to add a batch (based on resource costs and length limits). let cmpPlayer = QueryOwnerInterface(this.entity); + if (!cmpPlayer) + return; if (this.queue.length < this.MaxQueueSize) { @@ -376,7 +380,8 @@ { let unitCategory = template.TrainingRestrictions.Category; let cmpPlayerEntityLimits = QueryOwnerInterface(this.entity, IID_EntityLimits); - cmpPlayerEntityLimits.ChangeCount(unitCategory, count); + if (cmpPlayerEntityLimits) + cmpPlayerEntityLimits.ChangeCount(unitCategory, count); } let buildTime = ApplyValueModificationsToTemplate( @@ -718,13 +723,12 @@ // since it will be increased by EntityLimits.OnGlobalOwnershipChanged function, // i.e. we replace a 'trained' entity by 'alive' one. // Must be done after spawn check so EntityLimits decrements only if unit spawns. - let cmpTrainingRestrictions = Engine.QueryInterface(ent, IID_TrainingRestrictions); - if (cmpTrainingRestrictions) + if (cmpPlayerEntityLimits) { - let unitCategory = cmpTrainingRestrictions.GetCategory(); - cmpPlayerEntityLimits.ChangeCount(unitCategory, -1); + let cmpTrainingRestrictions = Engine.QueryInterface(ent, IID_TrainingRestrictions); + if (cmpTrainingRestrictions) + cmpPlayerEntityLimits.ChangeCount(cmpTrainingRestrictions.GetCategory(), -1); } - cmpNewOwnership.SetOwner(cmpOwnership.GetOwner()); if (cmpPlayerStatisticsTracker) @@ -773,11 +777,15 @@ // Check if the production is paused (eg the entity is garrisoned) if (this.paused) return; + + let cmpPlayer = QueryOwnerInterface(this.entity); + if (!cmpPlayer) + return; + // Allocate available time to as many queue items as it takes // until we've used up all the time (so that we work accurately // with items that take fractions of a second). let time = this.ProgressInterval; - let cmpPlayer = QueryOwnerInterface(this.entity); let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); while (time > 0 && this.queue.length) @@ -815,7 +823,11 @@ { // Mark the research as started. let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); - cmpTechnologyManager.StartedResearch(item.technologyTemplate, true); + if (cmpTechnologyManager) + cmpTechnologyManager.StartedResearch(item.technologyTemplate, true); + else + warn("Failed to start researching " + item.technologyTemplate + ": No TechnologyManager available."); + this.SetAnimation("researching"); } @@ -877,13 +889,16 @@ else if (item.technologyTemplate) { let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager); - cmpTechnologyManager.ResearchTechnology(item.technologyTemplate); + if (cmpTechnologyManager) + cmpTechnologyManager.ResearchTechnology(item.technologyTemplate); + else + warn("Failed to stop researching " + item.technologyTemplate + ": No TechnologyManager available."); + this.SetAnimation("idle"); let template = TechnologyTemplates.Get(item.technologyTemplate); if (template && template.soundComplete) { let cmpSoundManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_SoundManager); - if (cmpSoundManager) cmpSoundManager.PlaySoundGroup(template.soundComplete, this.entity); } Index: ps/trunk/binaries/data/mods/public/simulation/components/Promotion.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Promotion.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Promotion.js @@ -60,19 +60,23 @@ return; } - this.currentXp += +(amount); - var requiredXp = this.GetRequiredXp(); + this.currentXp += +amount; + let requiredXp = this.GetRequiredXp(); if (this.currentXp >= requiredXp) { - var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); - var playerID = QueryOwnerInterface(this.entity, IID_Player).GetPlayerID(); + let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); + let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); + if (!cmpPlayer) + return; + + let playerID = cmpPlayer.GetPlayerID(); this.currentXp -= requiredXp; - var promotedTemplateName = this.GetPromotedTemplateName(); + let promotedTemplateName = this.GetPromotedTemplateName(); // check if we can upgrade a second time (or even more) while (true) { - var template = cmpTemplateManager.GetTemplate(promotedTemplateName); + let template = cmpTemplateManager.GetTemplate(promotedTemplateName); if (!template.Promotion) break; requiredXp = ApplyValueModificationsToTemplate("Promotion/RequiredXp", +template.Promotion.RequiredXp, playerID, template); Index: ps/trunk/binaries/data/mods/public/simulation/components/ResourceGatherer.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/ResourceGatherer.js +++ ps/trunk/binaries/data/mods/public/simulation/components/ResourceGatherer.js @@ -358,7 +358,8 @@ ResourceGatherer.prototype.OnMultiplierChanged = function(msg) { - if (msg.player == QueryOwnerInterface(this.entity, IID_Player).GetPlayerID()) + let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); + if (cmpPlayer && msg.player == cmpPlayer.GetPlayerID()) this.RecalculateGatherRatesAndCapacities(); }; Index: ps/trunk/binaries/data/mods/public/simulation/components/SkirmishReplacer.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/SkirmishReplacer.js +++ ps/trunk/binaries/data/mods/public/simulation/components/SkirmishReplacer.js @@ -29,6 +29,9 @@ SkirmishReplacer.prototype.ReplaceEntities = function() { var cmpPlayer = QueryOwnerInterface(this.entity); + if (!cmpPlayer) + return; + var civ = cmpPlayer.GetCiv(); var replacementEntities = getReplacementEntities(civ); Index: ps/trunk/binaries/data/mods/public/simulation/components/Trader.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Trader.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Trader.js @@ -81,7 +81,7 @@ this.index = -1; this.markets = []; return true; -} +}; // Set target as target market. // Return true if at least one of markets was changed. @@ -184,7 +184,7 @@ let cmpTraderPlayer = QueryOwnerInterface(this.entity, IID_Player); let cmpTargetPlayer = QueryOwnerInterface(target, IID_Player); - return !cmpTraderPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID()); + return cmpTraderPlayer && cmpTargetPlayer && !cmpTraderPlayer.IsEnemy(cmpTargetPlayer.GetPlayerID()); }; Trader.prototype.AddResources = function(ent, gain) Index: ps/trunk/binaries/data/mods/public/simulation/components/Upgrade.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/components/Upgrade.js +++ ps/trunk/binaries/data/mods/public/simulation/components/Upgrade.js @@ -230,7 +230,7 @@ let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); this.expendedResources = this.GetResourceCosts(template); - if (!cmpPlayer.TrySubtractResources(this.expendedResources)) + if (!cmpPlayer || !cmpPlayer.TrySubtractResources(this.expendedResources)) { this.expendedResources = {}; return false; Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js +++ ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js @@ -296,7 +296,7 @@ if (unitCategory) { var cmpPlayerEntityLimits = QueryOwnerInterface(ent, IID_EntityLimits); - if (!cmpPlayerEntityLimits.AllowedToTrain(unitCategory, cmd.count)) + if (cmpPlayerEntityLimits && !cmpPlayerEntityLimits.AllowedToTrain(unitCategory, cmd.count)) { if (g_DebugCommands) warn(unitCategory + " train limit is reached: " + uneval(cmd)); @@ -305,7 +305,7 @@ } var cmpTechnologyManager = QueryOwnerInterface(ent, IID_TechnologyManager); - if (!cmpTechnologyManager.CanProduce(cmd.template)) + if (cmpTechnologyManager && !cmpTechnologyManager.CanProduce(cmd.template)) { if (g_DebugCommands) warn("Invalid command: training requires unresearched technology: " + uneval(cmd)); @@ -348,7 +348,7 @@ } var cmpTechnologyManager = QueryOwnerInterface(cmd.entity, IID_TechnologyManager); - if (!cmpTechnologyManager.CanResearch(cmd.template)) + if (cmpTechnologyManager && !cmpTechnologyManager.CanResearch(cmd.template)) { if (g_DebugCommands) warn("Invalid command: Requirements to research technology are not met: " + uneval(cmd));