Advertisement
Parranoia

Peacekeeper

Jul 15th, 2013
703
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.79 KB | None | 0 0
  1. #include "ScriptPCH.h"
  2.  
  3. typedef struct {float x, y;} Point;
  4.  
  5. // This is a list of X, Y coordinates that you want to make your "safe area"
  6. // The first and last points MUST be the same for this to work
  7. static const Point V[] = { {4513.935f, -4256.359f}, {4510.568f, -4236.598f}, {4490.970f, -4249.030f}, {4489.567f, -4194.844f}, {4513.935f, -4256.359f} };
  8. // Set n to the number of elements in V - 1
  9. // Since there are a total of 5 points, n is 4
  10. static const int n = 4;
  11.  
  12. class npc_peacekeeper : public CreatureScript
  13. {
  14. public:
  15.     npc_peacekeeper() : CreatureScript("npc_peacekeeper") {}
  16.  
  17.     CreatureAI* GetAI(Creature* c) const
  18.     {
  19.         return new npc_peacekeeperAI(c);
  20.     }
  21.  
  22.     struct npc_peacekeeperAI : public ScriptedAI
  23.     {
  24.         npc_peacekeeperAI(Creature* c) : ScriptedAI(c) {}
  25.  
  26.             int isLeft(Point P0, Point P1, Point P2)
  27.             {
  28.                 return ( (P1.x - P0.x) * (P2.y - P0.y)
  29.                         - (P2.x - P0.x) * (P1.y - P0.y) );
  30.             }
  31.      
  32.             // Checks if a Point is inside the predefined area
  33.             bool IsInArea(Point P)
  34.             {
  35.                 int wn = 0;  
  36.  
  37.                 for (int i=0; i < n; i++)
  38.             {  
  39.                         if (V[i].y <= P.y)
  40.                 {        
  41.                             if (V[i + 1].y > P.y)      
  42.                                 if (isLeft(V[i], V[i+1], P) > 0)  
  43.                                     ++wn;            
  44.                         }
  45.                         else
  46.                 {                      
  47.                             if (V[i + 1].y <= P.y)    
  48.                                 if (isLeft(V[i], V[i+1], P) < 0)  
  49.                                     --wn;            
  50.                         }
  51.                 }
  52.                 return wn != 0;
  53.             }
  54.      
  55.             void Reset()
  56.             {
  57.                 // Only run the check every 1 second rather than every update
  58.                 // Not sure how intensive this algorithm is, but it's better to be safe
  59.                 timer = 1000;
  60.             }
  61.      
  62.         void UpdateAI(uint32 diff)
  63.         {
  64.                 if (timer <= diff)
  65.                 {
  66.                         Map::PlayerList const& Players = me->GetMap()->GetPlayers();
  67.                         for (Map::PlayerList::const_iterator itr = Players.begin(); itr != Players.end(); ++itr)
  68.                         {
  69.                             if (Player* player = itr->GetSource())
  70.                             {
  71.                                 if (player->GetAreaId() != me->GetAreaId())
  72.                                         continue;
  73.                                 Point p = { player->GetPositionX(), player->GetPositionY() };
  74.                                 if (IsInArea(p))
  75.                                         player->SetPvP(false);
  76.                                 else
  77.                                         player->SetPvP(true);
  78.                             }
  79.                     }
  80.                         timer = 1000;
  81.                 } else timer -= diff;
  82.         }
  83.      
  84.             uint32 timer;
  85.     };
  86. };
  87.  
  88. void AddSC_npc_peacekeeper()
  89. {
  90.     new npc_peacekeeper();
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement