Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void NPC::Act()
- {
- // Needed for the server startup spawn to work properly
- if (this->Data()->child && !this->parent)
- {
- UTIL_PTR_VECTOR_FOREACH(this->map->npcs, NPC, npc)
- {
- if (npc->Data()->boss)
- {
- this->parent = *npc;
- break;
- }
- }
- }
- this->last_act += double(util::rand(int(this->act_speed * 750.0), int(this->act_speed * 1250.0))) / 1000.0;
- if (this->spawn_type == 7)
- {
- return;
- }
- Character *attacker = 0;
- if(this->pet) { attacker = this->owner; } // set pet owner as default target
- unsigned char attacker_distance = static_cast<int>(this->map->world->config["NPCChaseDistance"]);
- unsigned short attacker_damage = 0;
- UTIL_PTR_LIST_FOREACH(this->damagelist, NPC_Opponent, opponent)
- {
- if (opponent->attacker->map != this->map || opponent->attacker->nowhere || opponent->last_hit < Timer::GetTime() - static_cast<double>(this->map->world->config["NPCBoredTimer"]))
- {
- continue;
- }
- int distance = util::path_length(opponent->attacker->x, opponent->attacker->y, this->x, this->y);
- if ((distance < attacker_distance) || (distance == attacker_distance && opponent->damage > attacker_damage))
- {
- attacker = opponent->attacker;
- attacker_damage = opponent->damage;
- attacker_distance = distance;
- }
- }
- if (this->parent)
- {
- UTIL_PTR_LIST_FOREACH(this->parent->damagelist, NPC_Opponent, opponent)
- {
- if (opponent->attacker->map != this->map || opponent->attacker->nowhere || opponent->last_hit < Timer::GetTime() - static_cast<double>(this->map->world->config["NPCBoredTimer"]))
- {
- continue;
- }
- int distance = util::path_length(opponent->attacker->x, opponent->attacker->y, this->x, this->y);
- if ((distance < attacker_distance) || (distance == attacker_distance && opponent->damage > attacker_damage))
- {
- attacker = opponent->attacker;
- attacker_damage = opponent->damage;
- attacker_distance = distance;
- }
- }
- }
- if (this->Data()->type == ENF::Aggressive && !attacker)
- {
- Character *closest = 0;
- unsigned char closest_distance = static_cast<int>(this->map->world->config["NPCChaseDistance"]);
- UTIL_PTR_LIST_FOREACH(this->map->characters, Character, character)
- {
- int distance = util::path_length(character->x, character->y, this->x, this->y);
- if (distance < closest_distance)
- {
- if(this->pet)
- {
- if(this->attack_command) // get closest target and attack him if #attack command was used
- {
- if(this->owner != *character)
- closest = *character;
- }
- else closest = this->owner; // set pet owner as default target to follow
- }
- else
- {
- closest = *character;
- }
- closest_distance = distance;
- }
- }
- if (closest)
- {
- attacker = closest;
- }
- }
- if (attacker)
- {
- int xdiff = this->x - attacker->x;
- int ydiff = this->y - attacker->y;
- int absxdiff = std::abs(xdiff);
- int absydiff = std::abs(ydiff);
- if ((absxdiff == 1 && absydiff == 0) || (absxdiff == 0 && absydiff == 1) || (absxdiff == 0 && absydiff == 0))
- {
- if(attacker != this->owner) // don't attack character if it's pet owner
- this->Attack(attacker);
- return;
- }
- else if (absxdiff > absydiff)
- {
- if (xdiff < 0)
- {
- this->direction = DIRECTION_RIGHT;
- }
- else
- {
- this->direction = DIRECTION_LEFT;
- }
- }
- else
- {
- if (ydiff < 0)
- {
- this->direction = DIRECTION_DOWN;
- }
- else
- {
- this->direction = DIRECTION_UP;
- }
- }
- if (!this->Walk(this->direction))
- {
- this->Walk(static_cast<Direction>(util::rand(0,3)));
- }
- }
- else
- {
- // Random walking
- int act;
- if (this->walk_idle_for == 0)
- {
- act = util::rand(1,10);
- }
- else
- {
- --this->walk_idle_for;
- act = 11;
- }
- if (act >= 1 && act <= 6) // 60% chance walk foward
- {
- this->Walk(this->direction);
- }
- if (act >= 7 && act <= 9) // 30% change direction
- {
- this->Walk(static_cast<Direction>(util::rand(0,3)));
- }
- if (act == 10) // 10% take a break
- {
- this->walk_idle_for = util::rand(1,4);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement