Implement perception criteria when searching for nth nearest creature
This commit is contained in:
parent
ff9d939c32
commit
9e436508bd
6 changed files with 56 additions and 14 deletions
|
@ -34,13 +34,13 @@ CreatureFinder::CreatureFinder(Area *area) : _area(area) {
|
|||
}
|
||||
}
|
||||
|
||||
shared_ptr<Creature> CreatureFinder::getNearestCreature(const SpatialObject &target, const CreatureFinder::CriteriaList &criterias, int nth) {
|
||||
shared_ptr<Creature> CreatureFinder::getNearestCreature(const std::shared_ptr<SpatialObject> &target, const CreatureFinder::CriteriaList &criterias, int nth) {
|
||||
vector<pair<shared_ptr<Creature>, float>> candidates;
|
||||
|
||||
for (auto &object : _area->getObjectsByType(ObjectType::Creature)) {
|
||||
auto creature = static_pointer_cast<Creature>(object);
|
||||
if (matchesCriterias(*creature, criterias)) {
|
||||
float distance2 = creature->getDistanceTo2(target);
|
||||
if (matchesCriterias(*creature, criterias, target)) {
|
||||
float distance2 = creature->getDistanceTo2(*target);
|
||||
candidates.push_back(make_pair(move(creature), distance2));
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ shared_ptr<Creature> CreatureFinder::getNearestCreature(const SpatialObject &tar
|
|||
return nth < candidates.size() ? candidates[nth].first : nullptr;
|
||||
}
|
||||
|
||||
bool CreatureFinder::matchesCriterias(const Creature &creature, const CriteriaList &criterias, shared_ptr<SpatialObject> target) const {
|
||||
bool CreatureFinder::matchesCriterias(const Creature &creature, const CriteriaList &criterias, std::shared_ptr<SpatialObject> target) const {
|
||||
for (auto &criteria : criterias) {
|
||||
switch (criteria.first) {
|
||||
case CreatureType::Reputation: {
|
||||
|
@ -72,6 +72,44 @@ bool CreatureFinder::matchesCriterias(const Creature &creature, const CriteriaLi
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CreatureType::Perception: {
|
||||
if (!target) return false;
|
||||
|
||||
bool seen = creature.perception().seen.count(target) > 0;
|
||||
bool heard = creature.perception().heard.count(target) > 0;
|
||||
bool matches = false;
|
||||
auto perception = static_cast<PerceptionType>(criteria.second);
|
||||
switch (perception) {
|
||||
case PerceptionType::SeenAndHeard:
|
||||
matches = seen && heard;
|
||||
break;
|
||||
case PerceptionType::NotSeenAndNotHeard:
|
||||
matches = !seen && !heard;
|
||||
break;
|
||||
case PerceptionType::HeardAndNotSeen:
|
||||
matches = heard && !seen;
|
||||
break;
|
||||
case PerceptionType::SeenAndNotHeard:
|
||||
matches = seen && !heard;
|
||||
break;
|
||||
case PerceptionType::NotHeard:
|
||||
matches = !heard;
|
||||
break;
|
||||
case PerceptionType::Heard:
|
||||
matches = heard;
|
||||
break;
|
||||
case PerceptionType::NotSeen:
|
||||
matches = !seen;
|
||||
break;
|
||||
case PerceptionType::Seen:
|
||||
matches = seen;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!matches) return false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// TODO: implement other criterias
|
||||
break;
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
* @param nth 0-based index of the creature
|
||||
* @return nth nearest creature to the target object, that matches the specified criterias
|
||||
*/
|
||||
std::shared_ptr<Creature> getNearestCreature(const SpatialObject &target, const CriteriaList &criterias, int nth = 0);
|
||||
std::shared_ptr<Creature> getNearestCreature(const std::shared_ptr<SpatialObject> &target, const CriteriaList &criterias, int nth = 0);
|
||||
|
||||
/**
|
||||
* @param nth 0-based index of the creature
|
||||
|
|
|
@ -578,7 +578,7 @@ void Creature::runOnNoticeScript() {
|
|||
|
||||
void Creature::onObjectVanished(const shared_ptr<SpatialObject> &object) {
|
||||
_perception.seen.erase(object);
|
||||
_perception.lastPerception = PerceptionType::Vanished;
|
||||
_perception.lastPerception = PerceptionType::NotSeen;
|
||||
_perception.lastPerceived = object;
|
||||
runOnNoticeScript();
|
||||
}
|
||||
|
@ -592,7 +592,7 @@ void Creature::onObjectHeard(const shared_ptr<SpatialObject> &object) {
|
|||
|
||||
void Creature::onObjectInaudible(const shared_ptr<SpatialObject> &object) {
|
||||
_perception.heard.erase(object);
|
||||
_perception.lastPerception = PerceptionType::Inaudible;
|
||||
_perception.lastPerception = PerceptionType::NotHeard;
|
||||
_perception.lastPerceived = object;
|
||||
runOnNoticeScript();
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ Variable Routines::getNearestCreature(const VariablesList &args, ExecutionContex
|
|||
criterias.push_back(make_pair(static_cast<CreatureType>(thirdCriteriaType), thirdCriteriaValue));
|
||||
}
|
||||
|
||||
shared_ptr<Creature> creature(_game->module()->area()->creatureFinder().getNearestCreature(*target, criterias, nth - 1));
|
||||
shared_ptr<Creature> creature(_game->module()->area()->creatureFinder().getNearestCreature(target, criterias, nth - 1));
|
||||
|
||||
return static_pointer_cast<ScriptObject>(creature);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ Variable Routines::getLastPerceptionVanished(const VariablesList &args, Executio
|
|||
|
||||
auto caller = getCallerAsCreature(ctx);
|
||||
if (caller) {
|
||||
result.intValue = caller->perception().lastPerception == PerceptionType::Vanished;
|
||||
result.intValue = caller->perception().lastPerception == PerceptionType::NotSeen;
|
||||
} else {
|
||||
warn("Script: getLastPerceptionVanished: invalid caller");
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ Variable Routines::getLastPerceptionInaudible(const VariablesList &args, Executi
|
|||
|
||||
auto caller = getCallerAsCreature(ctx);
|
||||
if (caller) {
|
||||
result.intValue = caller->perception().lastPerception == PerceptionType::Inaudible;
|
||||
result.intValue = caller->perception().lastPerception == PerceptionType::NotHeard;
|
||||
} else {
|
||||
warn("Script: getLastPerceptionInaudible: invalid caller");
|
||||
}
|
||||
|
|
|
@ -834,10 +834,14 @@ enum class ReputationType {
|
|||
};
|
||||
|
||||
enum class PerceptionType {
|
||||
Seen,
|
||||
Vanished,
|
||||
Heard,
|
||||
Inaudible
|
||||
SeenAndHeard = 0,
|
||||
NotSeenAndNotHeard = 1,
|
||||
HeardAndNotSeen = 2,
|
||||
SeenAndNotHeard = 3,
|
||||
NotHeard = 4,
|
||||
Heard = 5,
|
||||
NotSeen = 6,
|
||||
Seen = 7
|
||||
};
|
||||
|
||||
struct InventorySlot {
|
||||
|
|
Loading…
Reference in a new issue