diff --git a/source/simulation2/Simulation2.cpp b/source/simulation2/Simulation2.cpp
index fef97bf..a29902d 100644
a
|
b
|
void CSimulation2::InitGame(JS::HandleValue data)
|
718 | 718 | JSAutoRequest rq(cx); |
719 | 719 | JS::RootedValue global(cx, GetScriptInterface().GetGlobalObject()); |
720 | 720 | GetScriptInterface().CallFunctionVoid(global, "InitGame", data); |
| 721 | |
| 722 | CmpPtr<ICmpAIManager> cmpAIManager(m->m_SimContext, SYSTEM_ENTITY); |
| 723 | if (!cmpAIManager->HasActiveAIs()) |
| 724 | m->m_ComponentManager.SkipAiProxy(); |
721 | 725 | } |
722 | 726 | |
723 | 727 | void CSimulation2::Update(int turnLength) |
diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp
index dd210c6..4981595 100644
a
|
b
|
public:
|
1159 | 1159 | } |
1160 | 1160 | } |
1161 | 1161 | |
| 1162 | virtual bool HasActiveAIs() |
| 1163 | { |
| 1164 | return m_Worker.getPlayerSize() > 0; |
| 1165 | } |
| 1166 | |
1162 | 1167 | private: |
1163 | 1168 | std::vector<std::string> m_TemplateNames; |
1164 | 1169 | size_t m_TemplateLoadedIdx; |
diff --git a/source/simulation2/components/ICmpAIManager.h b/source/simulation2/components/ICmpAIManager.h
index 97d46f7..5f97912 100644
a
|
b
|
public:
|
48 | 48 | virtual void PushCommands() = 0; |
49 | 49 | |
50 | 50 | /** |
| 51 | * Returns true if there are currently any AI registered with the AiManager |
| 52 | */ |
| 53 | virtual bool HasActiveAIs() = 0; |
| 54 | |
| 55 | /** |
51 | 56 | * Returns a vector of {"id":"value-for-AddPlayer", "name":"Human readable name"} |
52 | 57 | * objects, based on all the available AI scripts. |
53 | 58 | */ |
diff --git a/source/simulation2/system/ComponentManager.cpp b/source/simulation2/system/ComponentManager.cpp
index 005b82b..2c48ff1 100644
a
|
b
|
|
26 | 26 | |
27 | 27 | #include "simulation2/MessageTypes.h" |
28 | 28 | #include "simulation2/components/ICmpTemplateManager.h" |
| 29 | #include "simulation2/components/ICmpAiManager.h" |
29 | 30 | |
30 | 31 | #include "lib/utf8.h" |
31 | 32 | #include "ps/CLogger.h" |
… |
… |
void CComponentManager::SetRNGSeed(u32 seed)
|
543 | 544 | m_RNG.seed(seed); |
544 | 545 | } |
545 | 546 | |
| 547 | void CComponentManager::SkipAiProxy() |
| 548 | { |
| 549 | // don't actually delete the components, just make AIProxy not subscribe to anything |
| 550 | for (auto& messageType : m_LocalMessageSubscriptions) |
| 551 | { |
| 552 | // 49 is AIProxy CID |
| 553 | std::vector<ComponentTypeId>::iterator aiproxy = std::find(messageType.second.begin(),messageType.second.end(), 49); |
| 554 | if (aiproxy != messageType.second.end()) |
| 555 | { |
| 556 | // pop and swap, I do not believe we actually care about the order here. |
| 557 | std::swap(*aiproxy, messageType.second.back()); |
| 558 | messageType.second.pop_back(); |
| 559 | } |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | |
546 | 564 | void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc, |
547 | 565 | const char* name, const std::string& schema) |
548 | 566 | { |
… |
… |
entity_id_t CComponentManager::AddEntity(const std::wstring& templateName, entit
|
874 | 892 | continue; |
875 | 893 | |
876 | 894 | CComponentManager::ComponentTypeId cid = LookupCID(it->first); |
| 895 | |
877 | 896 | if (cid == CID__Invalid) |
878 | 897 | { |
879 | 898 | LOGERROR("Unrecognised component type name '%s' in entity template '%s'", it->first, utf8_from_wstring(templateName)); |
diff --git a/source/simulation2/system/ComponentManager.h b/source/simulation2/system/ComponentManager.h
index 8176dc5..bce3dcb 100644
a
|
b
|
public:
|
301 | 301 | */ |
302 | 302 | void SetRNGSeed(u32 seed); |
303 | 303 | |
| 304 | /** |
| 305 | * Tells the Component Manager to remove subscriptions of AIProxy, effectively acting like it didn't exist |
| 306 | * This is called by the simulation after game initialisation if there are no AI players present |
| 307 | * Since AIProxy can end up taking several ms (>3/4) per turn doing nothing useful otherwise |
| 308 | * Intended to make MP games faster. |
| 309 | */ |
| 310 | void SkipAiProxy(); |
| 311 | |
304 | 312 | // Various state serialization functions: |
305 | 313 | bool ComputeStateHash(std::string& outHash, bool quick); |
306 | 314 | bool DumpDebugState(std::ostream& stream, bool includeDebugInfo); |
… |
… |
private:
|
385 | 393 | |
386 | 394 | boost::rand48 m_RNG; |
387 | 395 | |
| 396 | bool m_SkipAiProxy = false; |
| 397 | |
388 | 398 | friend class TestComponentManager; |
389 | 399 | }; |
390 | 400 | |