87 lines
2.3 KiB
C++
87 lines
2.3 KiB
C++
#include "gameplay/ai.h"
|
|
#include "gameplay/gameactor.h"
|
|
|
|
#include "utility/raycaster.h"
|
|
#include "utility/script.h"
|
|
|
|
AI::AI(GameActor* actor, std::unique_ptr<Raycaster> raycaster)
|
|
: state(AIState::Idle), raycaster(std::move(raycaster)), actor(actor),
|
|
lastGCTime(std::chrono::high_resolution_clock::now()), GCTimeout(3)
|
|
{}
|
|
|
|
void AI::attachBehaviourScript(std::unique_ptr<AIScript> behaviour)
|
|
{
|
|
// passing out instance of raycaster and this AI into our scripting api
|
|
// pay special attention each ai script has control of only their own instance of ai!
|
|
this->behaviour = std::move(behaviour);
|
|
this->behaviour->lua["raycaster"] = sol::make_reference(this->behaviour->lua, raycaster.get());
|
|
this->behaviour->lua["ai"] = sol::make_reference(this->behaviour->lua, this);
|
|
|
|
idleFunc = this->behaviour->lua["idle"];
|
|
patrolFunc = this->behaviour->lua["patrol"];
|
|
alertFunc = this->behaviour->lua["alert"];
|
|
}
|
|
|
|
void AI::update()
|
|
{
|
|
try {
|
|
if (actor && target) {
|
|
switch (state)
|
|
{
|
|
case AIState::Idle:
|
|
if (idleFunc.valid())
|
|
{
|
|
auto result = idleFunc(actor, target);
|
|
if (!result.valid())
|
|
{
|
|
sol::error err = result;
|
|
std::cerr << "lua error: " << err.what() << std::endl;
|
|
}
|
|
}
|
|
break;
|
|
case AIState::Patrol:
|
|
if (patrolFunc.valid())
|
|
{
|
|
auto result = patrolFunc(actor, target);
|
|
if (!result.valid())
|
|
{
|
|
sol::error err = result;
|
|
std::cerr << "lua error: " << err.what() << std::endl;
|
|
}
|
|
}
|
|
break;
|
|
case AIState::Alert:
|
|
if (alertFunc.valid())
|
|
{
|
|
auto result = alertFunc(actor, target);
|
|
if (!result.valid())
|
|
{
|
|
sol::error err = result;
|
|
std::cerr << "lua error: " << err.what() << std::endl;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
std::chrono::high_resolution_clock::time_point curTime = std::chrono::high_resolution_clock::now();
|
|
if (curTime - lastGCTime >= GCTimeout)
|
|
{
|
|
behaviour->lua.collect_gc();
|
|
lastGCTime = curTime;
|
|
}
|
|
}
|
|
catch (const std::exception& e) {
|
|
std::cerr << "Error during AI update: " << e.what() << std::endl;
|
|
state = AIState::Idle;
|
|
}
|
|
}
|
|
|
|
AI::~AI()
|
|
{
|
|
behaviour->lua["raycaster"] = sol::nil;
|
|
behaviour->lua["ai"] = sol::nil;
|
|
behaviour->lua["idle"] = sol::nil;
|
|
behaviour->lua["patrol"] = sol::nil;
|
|
behaviour->lua["alert"] = sol::nil;
|
|
behaviour->lua.collect_gc();
|
|
}
|