Fix AI errors on skirmish maps.

This was SVN commit r14285.
This commit is contained in:
wraitii 2013-12-04 16:52:44 +00:00
parent 60c986c135
commit 189ef85538
12 changed files with 84 additions and 19 deletions

View File

@ -11,7 +11,7 @@ var baseConfig = {
},
"Economy" : {
"townPhase" : 180, // time to start trying to reach town phase (might be a while after. Still need the requirements + ress )
"cityPhase" : 840000, // time to start trying to reach city phase
"cityPhase" : 840, // time to start trying to reach city phase
"popForMarket" : 80,
"popForFarmstead" : 45,
"dockStartTime" : 240, // Time to wait before building the dock

View File

@ -180,18 +180,14 @@ SharedScript.prototype.initWithState = function(state) {
this._techModifications[o] = state.players[o].techModifications;
this._entities = {};
this.entities = new EntityCollection(this);
/* (var id in state.entities)
for (var id in state.entities)
{
this._entities[id] = new Entity(this, state.entities[id]);
}
// entity collection updated on create/destroy event.
this.entities = new EntityCollection(this, this._entities);
*/
this.ApplyEntitiesDelta(state);
// create the terrain analyzer
this.terrainAnalyzer = new TerrainAnalysis();
this.terrainAnalyzer.init(this, state);
@ -214,8 +210,7 @@ SharedScript.prototype.initWithState = function(state) {
// applies entity deltas, and each gamestate.
SharedScript.prototype.onUpdate = function(state)
{
if (this.turn !== 0)
this.ApplyEntitiesDelta(state);
this.ApplyEntitiesDelta(state);
Engine.ProfileStart("onUpdate");
@ -297,6 +292,16 @@ SharedScript.prototype.ApplyEntitiesDelta = function(state)
for (var i in this._players)
delete this._entityMetadata[this._players[i]][evt.msg.entity];
}
else if (evt.type == "EntityRenamed")
{
// Switch the metadata
for (var i in this._players)
{
warn (uneval(this._entityMetadata[this._players[i]][evt.msg.entity]));
this._entityMetadata[this._players[i]][evt.msg.newentity] = this._entityMetadata[this._players[i]][evt.msg.entity];
this._entityMetadata[this._players[i]][evt.msg.entity] = {};
}
}
else if (evt.type == "TrainingFinished")
{
// Apply metadata stored in training queues

View File

@ -37,7 +37,7 @@ AIInterface.prototype.GetRepresentation = function()
return state;
};
// Intended to be called first, during the map initialization: no caching
AIInterface.prototype.GetFullRepresentation = function()
AIInterface.prototype.GetFullRepresentation = function(flushEvents)
{
var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
@ -46,6 +46,11 @@ AIInterface.prototype.GetFullRepresentation = function()
// Add some extra AI-specific data
state.events = this.events;
if (flushEvents)
{
state.events = [];
this.events = [];
}
// Add entity representations
Engine.ProfileStart("proxy representations");
@ -81,4 +86,9 @@ AIInterface.prototype.OnGlobalPlayerDefeated = function(msg)
this.events.push({"type": "PlayerDefeated", "msg": msg});
};
AIInterface.prototype.OnGlobalEntityRenamed = function(msg)
{
this.events.push({"type": "EntityRenamed", "msg": msg});
};
Engine.RegisterComponentType(IID_AIInterface, "AIInterface", AIInterface);

View File

@ -22,10 +22,7 @@ SkirmishReplacer.prototype.OnOwnershipChanged = function(msg)
warn("Skirmish map elements can only be owned by regular players. Please delete entity "+this.entity+" or change the ownership to a non-gaia player.");
};
/**
* Replace this entity with a civ-specific entity on the first turn
*/
SkirmishReplacer.prototype.OnUpdate = function(msg)
SkirmishReplacer.prototype.ReplaceEntities = function()
{
var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
var civ = cmpPlayer.GetCiv();
@ -54,8 +51,28 @@ SkirmishReplacer.prototype.OnUpdate = function(msg)
var cmpCurOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
var cmpReplacementOwnership = Engine.QueryInterface(replacement, IID_Ownership);
cmpReplacementOwnership.SetOwner(cmpCurOwnership.GetOwner());
Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: replacement});
Engine.DestroyEntity(this.entity);
};
/**
* Replace this entity with a civ-specific entity
* Message is sent right before InitGame() is called, in InitGame.js
* Replacement needs to happen early on real games to not confuse the AI
*/
SkirmishReplacer.prototype.OnSkirmishReplace = function(msg)
{
this.ReplaceEntities();
};
/**
* Replace this entity with a civ-specific entity
* This is needed for Atlas, when the entity isn't replaced before the game starts,
* so it needs to be replaced on the first turn.
*/
SkirmishReplacer.prototype.OnUpdate = function(msg)
{
this.ReplaceEntities();
};
Engine.RegisterComponentType(IID_SkirmishReplacer, "SkirmishReplacer", SkirmishReplacer);

View File

@ -1 +1,2 @@
Engine.RegisterInterface("SkirmishReplacer");
Engine.RegisterMessageType("SkirmishReplace");

View File

@ -1,10 +1,14 @@
function InitGame(settings)
function ReplaceSkirmishGlobals()
{
// This will be called after the map settings have been loaded,
// before the simulation has started.
// This is only called at the start of a new game, not when loading
// a saved game.
Engine.BroadcastMessage(MT_SkirmishReplace, {});
}
function InitGame(settings)
{
// No settings when loading a map in Atlas, so do nothing
if (!settings)
return;
@ -37,4 +41,5 @@ function InitGame(settings)
cmpAIManager.RunGamestateInit();
}
Engine.RegisterGlobal("ReplaceSkirmishGlobals", ReplaceSkirmishGlobals);
Engine.RegisterGlobal("InitGame", InitGame);

View File

@ -48,7 +48,10 @@
#include "simulation2/components/ICmpPlayerManager.h"
#include "soundmanager/ISoundManager.h"
#include "tools/atlas/GameInterface/GameLoop.h"
extern bool g_GameRestarted;
extern GameLoopState* g_AtlasGameLoop;
/**
* Globally accessible pointer to the CGame object.
@ -200,6 +203,16 @@ PSRETURN CGame::ReallyStartGame()
// Call the script function InitGame only for new games, not saved games
if (!m_IsSavedGame)
{
if (!g_AtlasGameLoop->running)
{
// We need to replace skirmish "default" entities with real ones.
// This needs to happen before AI initialization (in InitGame).
// And we need to flush destroyed entities otherwise the AI
// gets the wrong game state in the beginning and a bunch of
// "destroy" messages on turn 0, which just shouldn't happen.
m_Simulation2->ReplaceSkirmishGlobals();
m_Simulation2->FlushDestroyedEntities();
}
CScriptVal settings;
m_Simulation2->GetScriptInterface().GetProperty(m_Simulation2->GetInitAttributes().get(), "settings", settings);
m_Simulation2->InitGame(settings);

View File

@ -647,6 +647,11 @@ ScriptInterface& CSimulation2::GetScriptInterface() const
return m->m_ComponentManager.GetScriptInterface();
}
void CSimulation2::ReplaceSkirmishGlobals()
{
GetScriptInterface().CallFunctionVoid(GetScriptInterface().GetGlobalObject(), "ReplaceSkirmishGlobals");
}
void CSimulation2::InitGame(const CScriptVal& data)
{
GetScriptInterface().CallFunctionVoid(GetScriptInterface().GetGlobalObject(), "InitGame", data);

View File

@ -146,6 +146,14 @@ public:
*/
void ResetState(bool skipScriptedComponents = false, bool skipAI = false);
/**
* Send a message to replace skirmish entities with real ones
* Called right before InitGame, on CGame instantiation.
* (This mustn't be used when e.g. loading saved games, only when starting new ones.)
* This calls the ReplaceSkirmishGlobals function defined in helpers/InitGame.js.
*/
void ReplaceSkirmishGlobals();
/**
* Initialise a new game, based on some script data. (Called on CGame instantiation)
* (This mustn't be used when e.g. loading saved games, only when starting new ones.)

View File

@ -994,7 +994,8 @@ public:
ENSURE(cmpAIInterface);
// Get the game state from AIInterface
CScriptVal state = cmpAIInterface->GetFullRepresentation();
// We flush events from the initialization so we get a clean state now.
CScriptVal state = cmpAIInterface->GetFullRepresentation(true);
// Get the passability data
Grid<u16> dummyGrid;

View File

@ -34,9 +34,9 @@ public:
{
return m_Script.Call<CScriptVal> ("GetRepresentation");
}
virtual CScriptVal GetFullRepresentation()
virtual CScriptVal GetFullRepresentation(bool flushEvents = false)
{
return m_Script.Call<CScriptVal> ("GetFullRepresentation");
return m_Script.Call<CScriptVal> ("GetFullRepresentation",flushEvents);
}
};

View File

@ -32,7 +32,7 @@ public:
* Returns a script object that represents the current world state,
* to be passed to AI scripts. No caching for initialization
*/
virtual CScriptVal GetFullRepresentation() = 0;
virtual CScriptVal GetFullRepresentation(bool flushEvents) = 0;
DECLARE_INTERFACE_TYPE(AIInterface)
};