forked from mirrors/0ad
Fix Athens not researching civ phase. Make the AI adapt automatically to changing the max gatherers on fields.
Fix auto-researched technologies not being properly researched on init. Fix the tests (amazing!). GarrisonHolder sends which entities were added or removed (mostly for AI purposes but could benefit other things). Streamline AIInterface events. This was SVN commit r14612.
This commit is contained in:
@@ -622,8 +622,9 @@ m.BaseManager.prototype.checkResourceLevels = function (gameState,queues) {
|
||||
numFarms += queues.field.countQueuedUnits();
|
||||
|
||||
// let's see if we need to push new farms.
|
||||
var maxGatherers = gameState.getTemplate(gameState.applyCiv("structures/{civ}_field")).maxGatherers();
|
||||
if (numFd < 2)
|
||||
if (numFarms < Math.round(this.gatherersByType(gameState, "food").length / 4.6) || numFarms < Math.round(this.workers.length / 15.0))
|
||||
if (numFarms < Math.round(this.gatherersByType(gameState, "food").length / (maxGatherers*0.9)) || numFarms < Math.round(this.workers.length / (maxGatherers*3))
|
||||
queues.field.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_field", { "base" : this.ID }));
|
||||
// TODO: refine count to only count my base.
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ m.Army.prototype.update = function (gameState)
|
||||
{
|
||||
var id = this.entities[i];
|
||||
var ent = gameState.getEntityById(id);
|
||||
if (!ent.position) // shouldn't be able to happen but apparently does.
|
||||
if (!ent || !ent.position()) // shouldn't be able to happen but apparently does.
|
||||
continue;
|
||||
if (API3.SquareVectorDistance(ent.position(), this.position) > this.breakawaySize)
|
||||
{
|
||||
|
||||
@@ -157,6 +157,8 @@ m.GameState.prototype.townPhase = function()
|
||||
|
||||
m.GameState.prototype.cityPhase = function()
|
||||
{
|
||||
if (this.playerData.civ == "athen")
|
||||
return "phase_city_athen";
|
||||
return "phase_city_generic";
|
||||
};
|
||||
|
||||
|
||||
@@ -131,8 +131,12 @@ m.SharedScript.prototype.init = function(state) {
|
||||
|
||||
this._entities = {};
|
||||
for (var id in state.entities)
|
||||
{
|
||||
// entropy generator
|
||||
for (var p = 0; p < id; ++p)
|
||||
Math.random();
|
||||
this._entities[id] = new m.Entity(this, state.entities[id]);
|
||||
|
||||
}
|
||||
// entity collection updated on create/destroy event.
|
||||
this.entities = new m.EntityCollection(this, this._entities);
|
||||
|
||||
|
||||
@@ -3,19 +3,26 @@ function AIInterface() {}
|
||||
AIInterface.prototype.Schema =
|
||||
"<a:component type='system'/><empty/>";
|
||||
|
||||
AIInterface.prototype.EventNames = [
|
||||
"Create",
|
||||
"Destroy",
|
||||
"Attacked",
|
||||
"RangeUpdate",
|
||||
"ConstructionFinished",
|
||||
"TrainingFinished",
|
||||
"AIMetadata",
|
||||
"PlayerDefeated",
|
||||
"EntityRenamed",
|
||||
"OwnershipChanged",
|
||||
"Garrison",
|
||||
"UnGarrison"
|
||||
];
|
||||
|
||||
AIInterface.prototype.Init = function()
|
||||
{
|
||||
this.events = {};
|
||||
this.events["Create"] = [];
|
||||
this.events["Destroy"] = [];
|
||||
this.events["Attacked"] = [];
|
||||
this.events["RangeUpdate"] = [];
|
||||
this.events["ConstructionFinished"] = [];
|
||||
this.events["TrainingFinished"] = [];
|
||||
this.events["AIMetadata"] = [];
|
||||
this.events["PlayerDefeated"] = [];
|
||||
this.events["EntityRenamed"] = [];
|
||||
this.events["OwnershipChanged"] = [];
|
||||
for each (var i in this.EventNames)
|
||||
this.events[i] = [];
|
||||
|
||||
this.changedEntities = {};
|
||||
|
||||
@@ -34,28 +41,13 @@ AIInterface.prototype.GetNonEntityRepresentation = function()
|
||||
var state = cmpGuiInterface.GetExtendedSimulationState(-1);
|
||||
|
||||
// Add some extra AI-specific data
|
||||
// add custom events and reset them for the next turn
|
||||
state.events = {};
|
||||
state.events["Create"] = this.events["Create"];
|
||||
state.events["Destroy"] = this.events["Destroy"];
|
||||
state.events["Attacked"] = this.events["Attacked"];
|
||||
state.events["RangeUpdate"] = this.events["RangeUpdate"];
|
||||
state.events["ConstructionFinished"] = this.events["ConstructionFinished"];
|
||||
state.events["TrainingFinished"] = this.events["TrainingFinished"];
|
||||
state.events["AIMetadata"] = this.events["AIMetadata"];
|
||||
state.events["PlayerDefeated"] = this.events["PlayerDefeated"];
|
||||
state.events["EntityRenamed"] = this.events["EntityRenamed"];
|
||||
state.events["OwnershipChanged"] = this.events["OwnershipChanged"];
|
||||
// Reset the event list for the next turn
|
||||
this.events["Create"] = [];
|
||||
this.events["Destroy"] = [];
|
||||
this.events["Attacked"] = [];
|
||||
this.events["RangeUpdate"] = [];
|
||||
this.events["ConstructionFinished"] = [];
|
||||
this.events["TrainingFinished"] = [];
|
||||
this.events["AIMetadata"] = [];
|
||||
this.events["PlayerDefeated"] = [];
|
||||
this.events["EntityRenamed"] = [];
|
||||
this.events["OwnershipChanged"] = [];
|
||||
for each (var i in this.EventNames)
|
||||
{
|
||||
state.events[i] = this.events[i];
|
||||
this.events[i] = [];
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
@@ -90,18 +82,8 @@ AIInterface.prototype.GetFullRepresentation = function(flushEvents)
|
||||
var state = this.GetNonEntityRepresentation();
|
||||
|
||||
if (flushEvents)
|
||||
{
|
||||
state.events["Create"] = [];
|
||||
state.events["Destroy"] = [];
|
||||
state.events["Attacked"] = [];
|
||||
state.events["RangeUpdate"] = [];
|
||||
state.events["ConstructionFinished"] = [];
|
||||
state.events["TrainingFinished"] = [];
|
||||
state.events["AIMetadata"] = [];
|
||||
state.events["PlayerDefeated"] = [];
|
||||
state.events["EntityRenamed"] = [];
|
||||
state.events["OwnershipChanged"] = [];
|
||||
}
|
||||
for each (var i in this.EventNames)
|
||||
state.events[i] = [];
|
||||
|
||||
// Add entity representations
|
||||
Engine.ProfileStart("proxy representations");
|
||||
|
||||
@@ -34,7 +34,8 @@ AIProxy.prototype.Init = function()
|
||||
{
|
||||
this.changes = null;
|
||||
this.needsFullGet = true;
|
||||
this.owner = -1; // for convenience now and then.
|
||||
// cache some data across turns
|
||||
this.owner = -1;
|
||||
|
||||
this.cmpAIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface);
|
||||
|
||||
@@ -76,7 +77,7 @@ AIProxy.prototype.NotifyChange = function()
|
||||
if (!this.changes)
|
||||
{
|
||||
this.changes = {};
|
||||
this.cmpAIInterface.ChangedEntity(this.entity);
|
||||
this.cmpAIInterface.ChangedEntity(this.entity);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -134,6 +135,15 @@ AIProxy.prototype.OnGarrisonedUnitsChanged = function(msg)
|
||||
|
||||
var cmpGarrisonHolder = Engine.QueryInterface(this.entity, IID_GarrisonHolder);
|
||||
this.changes.garrisoned = cmpGarrisonHolder.GetEntities();
|
||||
|
||||
// Send a message telling a unit garrisoned or ungarrisoned.
|
||||
// I won't check if the unit is still alive so it'll be up to the AI.
|
||||
var added = msg.added;
|
||||
var removed = msg.removed;
|
||||
for each (var ent in added)
|
||||
this.cmpAIInterface.PushEvent("Garrison", {"entity" : ent, "holder": this.entity});
|
||||
for each (var ent in removed)
|
||||
this.cmpAIInterface.PushEvent("UnGarrison", {"entity" : ent, "holder": this.entity});
|
||||
};
|
||||
|
||||
AIProxy.prototype.OnResourceSupplyChanged = function(msg)
|
||||
|
||||
@@ -244,7 +244,7 @@ GarrisonHolder.prototype.PerformGarrison = function(entity)
|
||||
if (cmpAura && cmpAura.HasGarrisonAura())
|
||||
cmpAura.ApplyGarrisonBonus(this.entity);
|
||||
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {});
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });
|
||||
|
||||
var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
|
||||
if (cmpUnitAI && cmpUnitAI.GetAlertRaiser())
|
||||
@@ -310,7 +310,7 @@ GarrisonHolder.prototype.Eject = function(entity, forced)
|
||||
cmpNewPosition.JumpTo(pos.x, pos.z);
|
||||
// TODO: what direction should they face in?
|
||||
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {});
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -563,7 +563,7 @@ GarrisonHolder.prototype.OnGlobalOwnershipChanged = function(msg)
|
||||
if (cmpHealth && cmpHealth.GetHitpoints() == 0)
|
||||
{
|
||||
this.entities.splice(entityIndex, 1);
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {});
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] });
|
||||
this.UpdateGarrisonFlag();
|
||||
}
|
||||
else if(!IsOwnedByMutualAllyOfEntity(this.entity, this.entities[entityIndex]))
|
||||
@@ -580,7 +580,7 @@ GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
|
||||
if (entityIndex != -1)
|
||||
{
|
||||
this.entities[entityIndex] = msg.newentity;
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {});
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [msg.newentity], "removed": [msg.entity] });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -628,7 +628,7 @@ GarrisonHolder.prototype.EjectOrKill = function(entities)
|
||||
this.entities.splice(entityIndex, 1);
|
||||
}
|
||||
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, {});
|
||||
Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : entities });
|
||||
this.UpdateGarrisonFlag();
|
||||
};
|
||||
|
||||
|
||||
@@ -49,8 +49,6 @@ TechnologyManager.prototype.Init = function ()
|
||||
if (this.allTechs[key].autoResearch || this.allTechs[key].top)
|
||||
this.autoResearchTech[key] = this.allTechs[key];
|
||||
}
|
||||
|
||||
this.UpdateAutoResearch();
|
||||
};
|
||||
|
||||
TechnologyManager.prototype.OnUpdate = function ()
|
||||
@@ -337,12 +335,12 @@ TechnologyManager.prototype.ResearchTechnology = function (tech)
|
||||
this.UpdateAutoResearch();
|
||||
|
||||
var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
|
||||
if (!cmpPlayer || ! cmpPlayer.GetPlayerID())
|
||||
if (!cmpPlayer || cmpPlayer.GetPlayerID() === undefined)
|
||||
return;
|
||||
var playerID = cmpPlayer.GetPlayerID();
|
||||
var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||
var ents = cmpRangeManager.GetEntitiesByPlayer(playerID);
|
||||
// TODO: Handle technology broadcasting for autoresearch properly (some components might not be initialized currently)
|
||||
|
||||
for (var component in modifiedComponents)
|
||||
{
|
||||
Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Engine.RegisterInterface("GarrisonHolder");
|
||||
|
||||
// Message of the form { } (use GetEntities if you want the current details),
|
||||
// Message of the form { "added":[], "removed":[] } (and use GetEntities if you want the current details),
|
||||
// sent to the current entity whenever the garrisoned units change.
|
||||
Engine.RegisterMessageType("GarrisonedUnitsChanged");
|
||||
|
||||
|
||||
@@ -206,7 +206,6 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
|
||||
entityLimits: {"Foo": 10},
|
||||
entityCounts: {"Foo": 5},
|
||||
entityLimitChangers: {"Foo": {}},
|
||||
techModifications: {},
|
||||
researchQueued: {},
|
||||
researchStarted: {},
|
||||
researchedTechs: {},
|
||||
@@ -235,7 +234,6 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetSimulationState(), {
|
||||
entityLimits: {"Bar": 20},
|
||||
entityCounts: {"Bar": 0},
|
||||
entityLimitChangers: {"Bar": {}},
|
||||
techModifications: {},
|
||||
researchQueued: {},
|
||||
researchStarted: {},
|
||||
researchedTechs: {},
|
||||
@@ -271,7 +269,6 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
|
||||
entityLimits: {"Foo": 10},
|
||||
entityCounts: {"Foo": 5},
|
||||
entityLimitChangers: {"Foo": {}},
|
||||
techModifications: {},
|
||||
researchQueued: {},
|
||||
researchStarted: {},
|
||||
researchedTechs: {},
|
||||
@@ -316,7 +313,6 @@ TS_ASSERT_UNEVAL_EQUALS(cmp.GetExtendedSimulationState(), {
|
||||
entityLimits: {"Bar": 20},
|
||||
entityCounts: {"Bar": 0},
|
||||
entityLimitChangers: {"Bar": {}},
|
||||
techModifications: {},
|
||||
researchQueued: {},
|
||||
researchStarted: {},
|
||||
researchedTechs: {},
|
||||
|
||||
@@ -54,6 +54,11 @@ function LoadPlayerSettings(settings, newPlayers)
|
||||
|
||||
// Add player to player manager
|
||||
cmpPlayerManager.AddPlayer(entID);
|
||||
|
||||
// Properly autoresearch techs on init.
|
||||
var cmpTechManager = Engine.QueryInterface(entID, IID_TechnologyManager);
|
||||
if (cmpTechManager !== undefined)
|
||||
cmpTechManager.UpdateAutoResearch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user