Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/components/CCmpAIManager.cpp
Show All 26 Lines | |||||
#include "lib/tex/tex.h" | #include "lib/tex/tex.h" | ||||
#include "lib/allocators/shared_ptr.h" | #include "lib/allocators/shared_ptr.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#include "ps/Filesystem.h" | #include "ps/Filesystem.h" | ||||
#include "ps/Profile.h" | #include "ps/Profile.h" | ||||
#include "ps/scripting/JSInterface_VFS.h" | #include "ps/scripting/JSInterface_VFS.h" | ||||
#include "ps/TemplateLoader.h" | #include "ps/TemplateLoader.h" | ||||
#include "ps/Util.h" | #include "ps/Util.h" | ||||
#include "scriptinterface/FunctionWrapper.h" | |||||
#include "simulation2/components/ICmpAIInterface.h" | #include "simulation2/components/ICmpAIInterface.h" | ||||
#include "simulation2/components/ICmpCommandQueue.h" | #include "simulation2/components/ICmpCommandQueue.h" | ||||
#include "simulation2/components/ICmpObstructionManager.h" | #include "simulation2/components/ICmpObstructionManager.h" | ||||
#include "simulation2/components/ICmpRangeManager.h" | #include "simulation2/components/ICmpRangeManager.h" | ||||
#include "simulation2/components/ICmpTemplateManager.h" | #include "simulation2/components/ICmpTemplateManager.h" | ||||
#include "simulation2/components/ICmpTerritoryManager.h" | #include "simulation2/components/ICmpTerritoryManager.h" | ||||
#include "simulation2/helpers/HierarchicalPathfinder.h" | #include "simulation2/helpers/HierarchicalPathfinder.h" | ||||
#include "simulation2/helpers/LongPathfinder.h" | #include "simulation2/helpers/LongPathfinder.h" | ||||
▲ Show 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | CAIWorker() : | ||||
m_ScriptInterface->ReplaceNondeterministicRNG(m_RNG); | m_ScriptInterface->ReplaceNondeterministicRNG(m_RNG); | ||||
m_ScriptInterface->SetCallbackData(static_cast<void*> (this)); | m_ScriptInterface->SetCallbackData(static_cast<void*> (this)); | ||||
m_SerializablePrototypes->init(); | m_SerializablePrototypes->init(); | ||||
JS_AddExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), Trace, this); | JS_AddExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), Trace, this); | ||||
m_ScriptInterface->RegisterFunction<void, int, JS::HandleValue, CAIWorker::PostCommand>("PostCommand"); | ScriptWrapper::WrapAndRegister<decltype(&QuitEngine), &QuitEngine>(*m_ScriptInterface, "Exit"); | ||||
m_ScriptInterface->RegisterFunction<void, std::wstring, CAIWorker::IncludeModule>("IncludeModule"); | |||||
m_ScriptInterface->RegisterFunction<void, CAIWorker::ExitProgram>("Exit"); | |||||
m_ScriptInterface->RegisterFunction<JS::Value, JS::HandleValue, JS::HandleValue, pass_class_t, CAIWorker::ComputePath>("ComputePath"); | #define Register(func, name) \ | ||||
ScriptWrapper::WrapAndRegister<decltype(&func), &func, CAIWorker, &CAIWorker::GetCAIWorkerFromCxPrivateData>(*m_ScriptInterface, name); | |||||
m_ScriptInterface->RegisterFunction<void, std::wstring, std::vector<u32>, u32, u32, u32, CAIWorker::DumpImage>("DumpImage"); | Register(CAIWorker::PostCommand, "PostCommand"); | ||||
m_ScriptInterface->RegisterFunction<CParamNode, std::string, CAIWorker::GetTemplate>("GetTemplate"); | Register(CAIWorker::LoadScripts, "IncludeModule"); | ||||
Register(CAIWorker::ComputePath, "ComputePath"); | |||||
Register(CAIWorker::DumpImage, "DumpImage"); | |||||
Register(CAIWorker::GetTemplate, "GetTemplate"); | |||||
#undef Register | |||||
JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get())); | JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get())); | ||||
// Globalscripts may use VFS script functions | // Globalscripts may use VFS script functions | ||||
m_ScriptInterface->LoadGlobalScripts(); | m_ScriptInterface->LoadGlobalScripts(); | ||||
} | } | ||||
~CAIWorker() | ~CAIWorker() | ||||
{ | { | ||||
JS_RemoveExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), Trace, this); | JS_RemoveExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), Trace, this); | ||||
} | } | ||||
static CAIWorker* GetCAIWorkerFromCxPrivateData(JSContext* cx, JS::CallArgs&) | |||||
{ | |||||
ScriptInterface::CxPrivate* pCxPrivate = ScriptInterface::GetScriptInterfaceAndCBData(cx); | |||||
ENSURE(pCxPrivate->pCBData); | |||||
return static_cast<CAIWorker*> (pCxPrivate->pCBData); | |||||
} | |||||
bool HasLoadedEntityTemplates() const { return m_HasLoadedEntityTemplates; } | bool HasLoadedEntityTemplates() const { return m_HasLoadedEntityTemplates; } | ||||
bool LoadScripts(const std::wstring& moduleName) | bool LoadScripts(const std::wstring& moduleName) | ||||
{ | { | ||||
// Ignore modules that are already loaded | // Ignore modules that are already loaded | ||||
if (m_LoadedModules.find(moduleName) != m_LoadedModules.end()) | if (m_LoadedModules.find(moduleName) != m_LoadedModules.end()) | ||||
return true; | return true; | ||||
Show All 15 Lines | for (const VfsPath& path : pathnames) | ||||
LOGERROR("Failed to load script %s", path.string8()); | LOGERROR("Failed to load script %s", path.string8()); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static void IncludeModule(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& name) | |||||
{ | |||||
ENSURE(pCxPrivate->pCBData); | |||||
CAIWorker* self = static_cast<CAIWorker*> (pCxPrivate->pCBData); | |||||
self->LoadScripts(name); | |||||
} | |||||
static void PostCommand(ScriptInterface::CxPrivate* pCxPrivate, int playerid, JS::HandleValue cmd) | |||||
{ | |||||
ENSURE(pCxPrivate->pCBData); | |||||
CAIWorker* self = static_cast<CAIWorker*> (pCxPrivate->pCBData); | |||||
self->PostCommand(playerid, cmd); | |||||
} | |||||
void PostCommand(int playerid, JS::HandleValue cmd) | void PostCommand(int playerid, JS::HandleValue cmd) | ||||
{ | { | ||||
for (size_t i=0; i<m_Players.size(); i++) | for (size_t i=0; i<m_Players.size(); i++) | ||||
{ | { | ||||
if (m_Players[i]->m_Player == playerid) | if (m_Players[i]->m_Player == playerid) | ||||
{ | { | ||||
m_Players[i]->m_Commands.push_back(m_ScriptInterface->WriteStructuredClone(cmd)); | m_Players[i]->m_Commands.push_back(m_ScriptInterface->WriteStructuredClone(cmd)); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
LOGERROR("Invalid playerid in PostCommand!"); | LOGERROR("Invalid playerid in PostCommand!"); | ||||
} | } | ||||
static JS::Value ComputePath(ScriptInterface::CxPrivate* pCxPrivate, | std::vector<CFixedVector2D> ComputePath(const CFixedVector2D& pos, const CFixedVector2D& goal, pass_class_t passClass) | ||||
JS::HandleValue position, JS::HandleValue goal, pass_class_t passClass) | |||||
{ | |||||
ENSURE(pCxPrivate->pCBData); | |||||
CAIWorker* self = static_cast<CAIWorker*> (pCxPrivate->pCBData); | |||||
JSContext* cx(self->m_ScriptInterface->GetContext()); | |||||
JSAutoRequest rq(cx); | |||||
CFixedVector2D pos, goalPos; | |||||
std::vector<CFixedVector2D> waypoints; | |||||
JS::RootedValue retVal(cx); | |||||
self->m_ScriptInterface->FromJSVal<CFixedVector2D>(cx, position, pos); | |||||
self->m_ScriptInterface->FromJSVal<CFixedVector2D>(cx, goal, goalPos); | |||||
self->ComputePath(pos, goalPos, passClass, waypoints); | |||||
self->m_ScriptInterface->ToJSVal<std::vector<CFixedVector2D> >(cx, &retVal, waypoints); | |||||
return retVal; | |||||
} | |||||
void ComputePath(const CFixedVector2D& pos, const CFixedVector2D& goal, pass_class_t passClass, std::vector<CFixedVector2D>& waypoints) | |||||
{ | { | ||||
WaypointPath ret; | WaypointPath ret; | ||||
PathGoal pathGoal = { PathGoal::POINT, goal.X, goal.Y }; | PathGoal pathGoal = { PathGoal::POINT, goal.X, goal.Y }; | ||||
m_LongPathfinder.ComputePath(m_HierarchicalPathfinder, pos.X, pos.Y, pathGoal, passClass, ret); | m_LongPathfinder.ComputePath(m_HierarchicalPathfinder, pos.X, pos.Y, pathGoal, passClass, ret); | ||||
std::vector<CFixedVector2D> waypoints; | |||||
for (Waypoint& wp : ret.m_Waypoints) | for (Waypoint& wp : ret.m_Waypoints) | ||||
waypoints.emplace_back(wp.x, wp.z); | waypoints.emplace_back(wp.x, wp.z); | ||||
} | return waypoints; | ||||
static CParamNode GetTemplate(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name) | |||||
{ | |||||
ENSURE(pCxPrivate->pCBData); | |||||
CAIWorker* self = static_cast<CAIWorker*> (pCxPrivate->pCBData); | |||||
return self->GetTemplate(name); | |||||
} | } | ||||
CParamNode GetTemplate(const std::string& name) | CParamNode GetTemplate(const std::string& name) | ||||
{ | { | ||||
if (!m_TemplateLoader.TemplateExists(name)) | if (!m_TemplateLoader.TemplateExists(name)) | ||||
return CParamNode(false); | return CParamNode(false); | ||||
return m_TemplateLoader.GetTemplateFileData(name).GetChild("Entity"); | return m_TemplateLoader.GetTemplateFileData(name).GetChild("Entity"); | ||||
} | } | ||||
static void ExitProgram(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) | |||||
{ | |||||
QuitEngine(); | |||||
} | |||||
/** | /** | ||||
* Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights). | * Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights). | ||||
*/ | */ | ||||
static void DumpImage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& name, const std::vector<u32>& data, u32 w, u32 h, u32 max) | void DumpImage(const std::wstring& name, const std::vector<u32>& data, u32 w, u32 h, u32 max) | ||||
{ | { | ||||
// TODO: this is totally not threadsafe. | // TODO: this is totally not threadsafe. | ||||
VfsPath filename = L"screenshots/aidump/" + name; | VfsPath filename = L"screenshots/aidump/" + name; | ||||
if (data.size() != w*h) | if (data.size() != w*h) | ||||
{ | { | ||||
debug_warn(L"DumpImage: data size doesn't match w*h"); | debug_warn(L"DumpImage: data size doesn't match w*h"); | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 832 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator