Advertisement
Guest User

Untitled

a guest
Feb 21st, 2010
864
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.11 KB | None | 0 0
  1. void NPC::Act()
  2. {
  3.     // Needed for the server startup spawn to work properly
  4.     if (this->Data()->child && !this->parent)
  5.     {
  6.         UTIL_PTR_VECTOR_FOREACH(this->map->npcs, NPC, npc)
  7.         {
  8.             if (npc->Data()->boss)
  9.             {
  10.                 this->parent = *npc;
  11.                 break;
  12.             }
  13.         }
  14.     }
  15.  
  16.     this->last_act += double(util::rand(int(this->act_speed * 750.0), int(this->act_speed * 1250.0))) / 1000.0;
  17.  
  18.     if (this->spawn_type == 7)
  19.     {
  20.         return;
  21.     }
  22.     Character *attacker = 0;
  23.     if(this->pet) { attacker = this->owner; } // set pet owner as default target
  24.  
  25.     unsigned char attacker_distance = static_cast<int>(this->map->world->config["NPCChaseDistance"]);
  26.     unsigned short attacker_damage = 0;
  27.  
  28.     UTIL_PTR_LIST_FOREACH(this->damagelist, NPC_Opponent, opponent)
  29.     {
  30.         if (opponent->attacker->map != this->map || opponent->attacker->nowhere || opponent->last_hit < Timer::GetTime() - static_cast<double>(this->map->world->config["NPCBoredTimer"]))
  31.         {
  32.             continue;
  33.         }
  34.  
  35.         int distance = util::path_length(opponent->attacker->x, opponent->attacker->y, this->x, this->y);
  36.  
  37.         if ((distance < attacker_distance) || (distance == attacker_distance && opponent->damage > attacker_damage))
  38.         {
  39.             attacker = opponent->attacker;
  40.             attacker_damage = opponent->damage;
  41.             attacker_distance = distance;
  42.         }
  43.     }
  44.  
  45.     if (this->parent)
  46.     {
  47.         UTIL_PTR_LIST_FOREACH(this->parent->damagelist, NPC_Opponent, opponent)
  48.         {
  49.             if (opponent->attacker->map != this->map || opponent->attacker->nowhere || opponent->last_hit < Timer::GetTime() - static_cast<double>(this->map->world->config["NPCBoredTimer"]))
  50.             {
  51.                 continue;
  52.             }
  53.             int distance = util::path_length(opponent->attacker->x, opponent->attacker->y, this->x, this->y);
  54.  
  55.             if ((distance < attacker_distance) || (distance == attacker_distance && opponent->damage > attacker_damage))
  56.             {
  57.                 attacker = opponent->attacker;
  58.                 attacker_damage = opponent->damage;
  59.                 attacker_distance = distance;
  60.             }
  61.         }
  62.     }
  63.  
  64.     if (this->Data()->type == ENF::Aggressive && !attacker)
  65.     {
  66.         Character *closest = 0;
  67.         unsigned char closest_distance = static_cast<int>(this->map->world->config["NPCChaseDistance"]);
  68.  
  69.         UTIL_PTR_LIST_FOREACH(this->map->characters, Character, character)
  70.         {
  71.             int distance = util::path_length(character->x, character->y, this->x, this->y);
  72.  
  73.             if (distance < closest_distance)
  74.             {
  75.                 if(this->pet)
  76.                 {
  77.                     if(this->attack_command) // get closest target and attack him if #attack command was used
  78.                     {
  79.                         if(this->owner != *character)
  80.                         closest = *character;
  81.                     }
  82.                     else closest = this->owner; // set pet owner as default target to follow
  83.                 }
  84.                 else
  85.                 {
  86.                     closest = *character;
  87.                 }
  88.                 closest_distance = distance;
  89.             }
  90.         }
  91.  
  92.         if (closest)
  93.         {
  94.             attacker = closest;
  95.         }
  96.     }
  97.  
  98.     if (attacker)
  99.     {
  100.         int xdiff = this->x - attacker->x;
  101.         int ydiff = this->y - attacker->y;
  102.         int absxdiff = std::abs(xdiff);
  103.         int absydiff = std::abs(ydiff);
  104.  
  105.         if ((absxdiff == 1 && absydiff == 0) || (absxdiff == 0 && absydiff == 1) || (absxdiff == 0 && absydiff == 0))
  106.         {
  107.             if(attacker != this->owner) // don't attack character if it's pet owner
  108.             this->Attack(attacker);
  109.             return;
  110.         }
  111.         else if (absxdiff > absydiff)
  112.         {
  113.             if (xdiff < 0)
  114.             {
  115.                 this->direction = DIRECTION_RIGHT;
  116.             }
  117.             else
  118.             {
  119.                 this->direction = DIRECTION_LEFT;
  120.             }
  121.         }
  122.         else
  123.         {
  124.             if (ydiff < 0)
  125.             {
  126.                 this->direction = DIRECTION_DOWN;
  127.             }
  128.             else
  129.             {
  130.                 this->direction = DIRECTION_UP;
  131.             }
  132.         }
  133.  
  134.         if (!this->Walk(this->direction))
  135.         {
  136.             this->Walk(static_cast<Direction>(util::rand(0,3)));
  137.         }
  138.     }
  139.     else
  140.     {
  141.         // Random walking
  142.  
  143.         int act;
  144.         if (this->walk_idle_for == 0)
  145.         {
  146.             act = util::rand(1,10);
  147.         }
  148.         else
  149.         {
  150.             --this->walk_idle_for;
  151.             act = 11;
  152.         }
  153.  
  154.         if (act >= 1 && act <= 6) // 60% chance walk foward
  155.         {
  156.             this->Walk(this->direction);
  157.         }
  158.  
  159.         if (act >= 7 && act <= 9) // 30% change direction
  160.         {
  161.             this->Walk(static_cast<Direction>(util::rand(0,3)));
  162.         }
  163.  
  164.         if (act == 10) // 10% take a break
  165.         {
  166.             this->walk_idle_for = util::rand(1,4);
  167.         }
  168.     }
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement