Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/simulation2/components/CCmpAIManager.cpp
Show First 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
class CAIWorker | class CAIWorker | ||||
{ | { | ||||
private: | private: | ||||
class CAIPlayer | class CAIPlayer | ||||
{ | { | ||||
NONCOPYABLE(CAIPlayer); | NONCOPYABLE(CAIPlayer); | ||||
public: | public: | ||||
CAIPlayer(CAIWorker& worker, const std::wstring& aiName, player_id_t player, u8 difficulty, | CAIPlayer(CAIWorker& worker, const std::wstring& aiName, player_id_t player, u8 difficulty, const std::wstring& behavior, | ||||
shared_ptr<ScriptInterface> scriptInterface) : | shared_ptr<ScriptInterface> scriptInterface) : | ||||
m_Worker(worker), m_AIName(aiName), m_Player(player), m_Difficulty(difficulty), | m_Worker(worker), m_AIName(aiName), m_Player(player), m_Difficulty(difficulty), m_Behavior(behavior), | ||||
m_ScriptInterface(scriptInterface), m_Obj(scriptInterface->GetJSRuntime()) | m_ScriptInterface(scriptInterface), m_Obj(scriptInterface->GetJSRuntime()) | ||||
{ | { | ||||
} | } | ||||
bool Initialise() | bool Initialise() | ||||
{ | { | ||||
// LoadScripts will only load each script once even though we call it for each player | // LoadScripts will only load each script once even though we call it for each player | ||||
if (!m_Worker.LoadScripts(m_AIName)) | if (!m_Worker.LoadScripts(m_AIName)) | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | bool Initialise() | ||||
m_ScriptInterface->GetProperty(metadata, "useShared", m_UseSharedComponent); | m_ScriptInterface->GetProperty(metadata, "useShared", m_UseSharedComponent); | ||||
// Set up the data to pass as the constructor argument | // Set up the data to pass as the constructor argument | ||||
JS::RootedValue settings(cx); | JS::RootedValue settings(cx); | ||||
m_ScriptInterface->Eval(L"({})", &settings); | m_ScriptInterface->Eval(L"({})", &settings); | ||||
m_ScriptInterface->SetProperty(settings, "player", m_Player, false); | m_ScriptInterface->SetProperty(settings, "player", m_Player, false); | ||||
m_ScriptInterface->SetProperty(settings, "difficulty", m_Difficulty, false); | m_ScriptInterface->SetProperty(settings, "difficulty", m_Difficulty, false); | ||||
m_ScriptInterface->SetProperty(settings, "behavior", m_Behavior, false); | |||||
if (!m_UseSharedComponent) | if (!m_UseSharedComponent) | ||||
{ | { | ||||
ENSURE(m_Worker.m_HasLoadedEntityTemplates); | ENSURE(m_Worker.m_HasLoadedEntityTemplates); | ||||
m_ScriptInterface->SetProperty(settings, "templates", m_Worker.m_EntityTemplates, false); | m_ScriptInterface->SetProperty(settings, "templates", m_Worker.m_EntityTemplates, false); | ||||
} | } | ||||
JS::AutoValueVector argv(cx); | JS::AutoValueVector argv(cx); | ||||
argv.append(settings.get()); | argv.append(settings.get()); | ||||
Show All 24 Lines | void InitAI(JS::HandleValue state, JS::HandleValue SharedAI) | ||||
m_Commands.clear(); | m_Commands.clear(); | ||||
m_ScriptInterface->CallFunctionVoid(m_Obj, "Init", state, m_Player, SharedAI); | m_ScriptInterface->CallFunctionVoid(m_Obj, "Init", state, m_Player, SharedAI); | ||||
} | } | ||||
CAIWorker& m_Worker; | CAIWorker& m_Worker; | ||||
std::wstring m_AIName; | std::wstring m_AIName; | ||||
player_id_t m_Player; | player_id_t m_Player; | ||||
u8 m_Difficulty; | u8 m_Difficulty; | ||||
std::wstring m_Behavior; | |||||
bool m_UseSharedComponent; | bool m_UseSharedComponent; | ||||
// Take care to keep this declaration before heap rooted members. Destructors of heap rooted | // Take care to keep this declaration before heap rooted members. Destructors of heap rooted | ||||
// members have to be called before the runtime destructor. | // members have to be called before the runtime destructor. | ||||
shared_ptr<ScriptInterface> m_ScriptInterface; | shared_ptr<ScriptInterface> m_ScriptInterface; | ||||
JS::PersistentRootedValue m_Obj; | JS::PersistentRootedValue m_Obj; | ||||
std::vector<shared_ptr<ScriptInterface::StructuredClone> > m_Commands; | std::vector<shared_ptr<ScriptInterface::StructuredClone> > m_Commands; | ||||
▲ Show 20 Lines • Show All 273 Lines • ▼ Show 20 Lines | bool TryLoadSharedComponent(bool hasTechs) | ||||
{ | { | ||||
LOGERROR("Failed to create shared AI component: %s: error calling constructor '%s'", path.string8(), "SharedScript"); | LOGERROR("Failed to create shared AI component: %s: error calling constructor '%s'", path.string8(), "SharedScript"); | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool AddPlayer(const std::wstring& aiName, player_id_t player, u8 difficulty) | bool AddPlayer(const std::wstring& aiName, player_id_t player, u8 difficulty, const std::wstring& behavior) | ||||
{ | { | ||||
shared_ptr<CAIPlayer> ai(new CAIPlayer(*this, aiName, player, difficulty, m_ScriptInterface)); | shared_ptr<CAIPlayer> ai(new CAIPlayer(*this, aiName, player, difficulty, behavior, m_ScriptInterface)); | ||||
if (!ai->Initialise()) | if (!ai->Initialise()) | ||||
return false; | return false; | ||||
// this will be set to true if we need to load the shared Component. | // this will be set to true if we need to load the shared Component. | ||||
if (!m_HasSharedComponent) | if (!m_HasSharedComponent) | ||||
m_HasSharedComponent = ai->m_UseSharedComponent; | m_HasSharedComponent = ai->m_UseSharedComponent; | ||||
m_Players.push_back(ai); | m_Players.push_back(ai); | ||||
return true; | return true; | ||||
} | } | ||||
bool RunGamestateInit(const shared_ptr<ScriptInterface::StructuredClone>& gameState, const Grid<NavcellData>& passabilityMap, const Grid<u8>& territoryMap, | bool RunGamestateInit(const shared_ptr<ScriptInterface::StructuredClone>& gameState, const Grid<NavcellData>& passabilityMap, const Grid<u8>& territoryMap, | ||||
const std::map<std::string, pass_class_t>& nonPathfindingPassClassMasks, const std::map<std::string, pass_class_t>& pathfindingPassClassMasks) | const std::map<std::string, pass_class_t>& nonPathfindingPassClassMasks, const std::map<std::string, pass_class_t>& pathfindingPassClassMasks) | ||||
{ | { | ||||
// this will be run last by InitGame.Js, passing the full game representation. | // this will be run last by InitGame.js, passing the full game representation. | ||||
// For now it will run for the shared Component. | // For now it will run for the shared Component. | ||||
// This is NOT run during deserialization. | // This is NOT run during deserialization. | ||||
JSContext* cx = m_ScriptInterface->GetContext(); | JSContext* cx = m_ScriptInterface->GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedValue state(cx); | JS::RootedValue state(cx); | ||||
m_ScriptInterface->ReadStructuredClone(gameState, &state); | m_ScriptInterface->ReadStructuredClone(gameState, &state); | ||||
ScriptInterface::ToJSVal(cx, &m_PassabilityMapVal, passabilityMap); | ScriptInterface::ToJSVal(cx, &m_PassabilityMapVal, passabilityMap); | ||||
▲ Show 20 Lines • Show All 180 Lines • ▼ Show 20 Lines | if (m_HasSharedComponent) | ||||
LOGERROR("AI shared script Serialize call failed"); | LOGERROR("AI shared script Serialize call failed"); | ||||
serializer.ScriptVal("sharedData", &sharedData); | serializer.ScriptVal("sharedData", &sharedData); | ||||
} | } | ||||
for (size_t i = 0; i < m_Players.size(); ++i) | for (size_t i = 0; i < m_Players.size(); ++i) | ||||
{ | { | ||||
serializer.String("name", m_Players[i]->m_AIName, 1, 256); | serializer.String("name", m_Players[i]->m_AIName, 1, 256); | ||||
serializer.NumberI32_Unbounded("player", m_Players[i]->m_Player); | serializer.NumberI32_Unbounded("player", m_Players[i]->m_Player); | ||||
serializer.NumberU8_Unbounded("difficulty", m_Players[i]->m_Difficulty); | serializer.NumberU8_Unbounded("difficulty", m_Players[i]->m_Difficulty); | ||||
serializer.String("behavior", m_Players[i]->m_Behavior, 1, 256); | |||||
serializer.NumberU32_Unbounded("num commands", (u32)m_Players[i]->m_Commands.size()); | serializer.NumberU32_Unbounded("num commands", (u32)m_Players[i]->m_Commands.size()); | ||||
for (size_t j = 0; j < m_Players[i]->m_Commands.size(); ++j) | for (size_t j = 0; j < m_Players[i]->m_Commands.size(); ++j) | ||||
{ | { | ||||
JS::RootedValue val(cx); | JS::RootedValue val(cx); | ||||
m_ScriptInterface->ReadStructuredClone(m_Players[i]->m_Commands[j], &val); | m_ScriptInterface->ReadStructuredClone(m_Players[i]->m_Commands[j], &val); | ||||
serializer.ScriptVal("command", &val); | serializer.ScriptVal("command", &val); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | if (m_HasSharedComponent) | ||||
LOGERROR("AI shared script Deserialize call failed"); | LOGERROR("AI shared script Deserialize call failed"); | ||||
} | } | ||||
for (size_t i = 0; i < numAis; ++i) | for (size_t i = 0; i < numAis; ++i) | ||||
{ | { | ||||
std::wstring name; | std::wstring name; | ||||
player_id_t player; | player_id_t player; | ||||
u8 difficulty; | u8 difficulty; | ||||
std::wstring behavior; | |||||
deserializer.String("name", name, 1, 256); | deserializer.String("name", name, 1, 256); | ||||
deserializer.NumberI32_Unbounded("player", player); | deserializer.NumberI32_Unbounded("player", player); | ||||
deserializer.NumberU8_Unbounded("difficulty",difficulty); | deserializer.NumberU8_Unbounded("difficulty",difficulty); | ||||
if (!AddPlayer(name, player, difficulty)) | deserializer.String("behavior", behavior, 1, 256); | ||||
if (!AddPlayer(name, player, difficulty, behavior)) | |||||
throw PSERROR_Deserialize_ScriptError(); | throw PSERROR_Deserialize_ScriptError(); | ||||
u32 numCommands; | u32 numCommands; | ||||
deserializer.NumberU32_Unbounded("num commands", numCommands); | deserializer.NumberU32_Unbounded("num commands", numCommands); | ||||
m_Players.back()->m_Commands.reserve(numCommands); | m_Players.back()->m_Commands.reserve(numCommands); | ||||
for (size_t j = 0; j < numCommands; ++j) | for (size_t j = 0; j < numCommands; ++j) | ||||
{ | { | ||||
JS::RootedValue val(cx); | JS::RootedValue val(cx); | ||||
▲ Show 20 Lines • Show All 216 Lines • ▼ Show 20 Lines | virtual void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize) | ||||
if (numAis > 0) | if (numAis > 0) | ||||
LoadUsedEntityTemplates(); | LoadUsedEntityTemplates(); | ||||
m_Worker.Deserialize(deserialize.GetStream(), numAis); | m_Worker.Deserialize(deserialize.GetStream(), numAis); | ||||
m_JustDeserialized = true; | m_JustDeserialized = true; | ||||
} | } | ||||
virtual void AddPlayer(const std::wstring& id, player_id_t player, u8 difficulty) | virtual void AddPlayer(const std::wstring& id, player_id_t player, u8 difficulty, const std::wstring& behavior) | ||||
{ | { | ||||
LoadUsedEntityTemplates(); | LoadUsedEntityTemplates(); | ||||
m_Worker.AddPlayer(id, player, difficulty); | m_Worker.AddPlayer(id, player, difficulty, behavior); | ||||
// AI players can cheat and see through FoW/SoD, since that greatly simplifies | // AI players can cheat and see through FoW/SoD, since that greatly simplifies | ||||
// their implementation. | // their implementation. | ||||
// (TODO: maybe cleverer AIs should be able to optionally retain FoW/SoD) | // (TODO: maybe cleverer AIs should be able to optionally retain FoW/SoD) | ||||
CmpPtr<ICmpRangeManager> cmpRangeManager(GetSystemEntity()); | CmpPtr<ICmpRangeManager> cmpRangeManager(GetSystemEntity()); | ||||
if (cmpRangeManager) | if (cmpRangeManager) | ||||
cmpRangeManager->SetLosRevealAll(player, true); | cmpRangeManager->SetLosRevealAll(player, true); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 200 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator