void World::massiveDamage(const Vec2 &pos, int range, int damage) { // Пробегаем по всем объектам. for ( std::list< WorldObject* >::iterator it = items.begin(); it != items.end(); ++it ) { // Нас интересуют пони. if ( ( *it )->isTargetable() ) { WorldObject* unit = *it; // Интересуют только живые пони. if ( !unit->isDead() ) { // Находим расстояние до этого пони. double distance = unit->getPos().distance(pos); // Если зацепили пони. if ( distance < range ) { unit->hit( static_cast< int > ( damage ) ); } } } } }
WorldObject *World::getNearestTarget(const Vec2 &pos, int range) { double minRange = 100000000; WorldObject *target = nullptr; for (std::list<WorldObject *>::iterator it = items.begin(); it != items.end(); ++it) { WorldObject *unit = *it; if (!unit->isTargetable()) continue; if (unit->isDead()) continue; double distance = pos.distance(unit->getPos()); if (distance < range) { if (distance < minRange) { minRange = distance; target = unit; } } } return target; }
int ActionCover::scoreEvaluator(Actor* actor,Action* action) { ActionCover* self = static_cast<ActionCover*>(action); Anchor* resAnchor = NULL; WorldObject* enemy = actor->getEnemy(); if (!enemy) return 0; if (self->m_attackInfo && !self->m_attackInfo->coverState.empty()) { //check if there is anchor hereabout Anchors& anchors = Anchor::getAnchors(); for (size_t i=0; i<anchors.size(); i++) { Anchor* anchor = anchors[i]; float distToEnemySq = (anchor->getPos() - enemy->getPos()).lengthSq(); if (distToEnemySq < MIN_DIST_TO_ENEMY*MIN_DIST_TO_ENEMY) continue; //.todo: check conditions(i.e. reasonable distance, availability, etc) if (anchor->isVacant(actor)) { resAnchor = anchor; break; } } } if (resAnchor) return 5; else return 0; }
float ActionCover::anchorRankEvaluator(Anchor* anchor) { float rank = -1.f; if (anchor->isVacant(m_owner)) { float dist = anchor->getDistSq(m_owner->getPos()); WorldObject* enemy = m_owner->getEnemy(); if (!enemy) return rank; float distToEnemySq = (anchor->getPos() - enemy->getPos()).lengthSq(); if (distToEnemySq < MIN_DIST_TO_ENEMY*MIN_DIST_TO_ENEMY) return rank; if (dist < MAX_DIST_TO_ANCHOR*MAX_DIST_TO_ANCHOR) { rank = 1.f/dist; AnchorStatMap::iterator it = m_anchorStat.find(anchor); unsigned int occupancyTime = it!=m_anchorStat.end() ? it->second : 0; float occupancyTimeSec = (float) occupancyTime / 1000.f; if (m_anchor == anchor && occupancyTimeSec < 10.f) { rank += 5.f; //persistence } else if(m_anchor != anchor && occupancyTimeSec < 5.f) { rank += 5.f - occupancyTimeSec; } } } return rank; };
void World::updatePathFinderMap() { for (int col = 0; col < Config::World::WIDTH_CELL; ++col) for (int row = 0; row < Config::World::WIDTH_CELL; ++row) pathFinder.cells[col][row] = WorldObjectId::Empty; for (std::list<WorldObject *>::iterator it = items.begin(); it != items.end(); ++it) { WorldObject *worldObject = *it; Vec2 size = worldObject->getDim(); if (!size.isZero()) { Vec2 p = worldObject->getPos() / Config::World::CELL_SIZE; WorldObjectId id = worldObject->getId(); for (int col = 0; col < size.x; ++col) for (int row = 0; row < size.y; ++row) pathFinder.cells[col + p.x][row + p.y] = id; } } }