Advertisement
Rochet2

Intersect && snap

Oct 11th, 2013
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.74 KB | None | 0 0
  1. #include "ScriptPCH.h"
  2. #include "MapManager.h"
  3. #include "Language.h"
  4.  
  5. #define SIZE(objectId)  sObjectMgr->GetGameObjectTemplate(objectId)->size // lazy macro to get size for testing
  6.  
  7. struct PlayerData
  8. {
  9.     bool Snap;
  10.     bool Intersect;
  11. };
  12.  
  13. static UNORDERED_MAP<uint32, PlayerData> DataMap;
  14.  
  15. class GOSnap_commandscript : public CommandScript
  16. {
  17. public:
  18.     GOSnap_commandscript() : CommandScript("GOSnap_commandscript")
  19.     {
  20.     }
  21.  
  22.     ChatCommand* GetCommands() const
  23.     {
  24.         static ChatCommand GOSnapCommandTable[] =
  25.         {
  26.             // Fix RBAC crap :|
  27.             { "gosnap",             SEC_GAMEMASTER,         false,      &GOSnap_Command,                               "", NULL },
  28.             { "gointersect",        SEC_GAMEMASTER,         false,      &GOintersect_command,                               "", NULL },
  29.             { NULL,                 0,                      false,      NULL,                                                   "", NULL }
  30.         };
  31.         return GOSnapCommandTable;
  32.     }
  33.  
  34.     static bool GOSnap_Command(ChatHandler* handler, const char* args)
  35.     {
  36.         DataMap[handler->GetSession()->GetGuidLow()].Snap = !DataMap[handler->GetSession()->GetGuidLow()].Snap;
  37.         if(DataMap[handler->GetSession()->GetGuidLow()].Snap)
  38.             handler->GetSession()->SendNotification("On");
  39.         return true;
  40.     }
  41.  
  42.     static bool GOintersect_command(ChatHandler* handler, const char* args)
  43.     {
  44.         DataMap[handler->GetSession()->GetGuidLow()].Intersect = !DataMap[handler->GetSession()->GetGuidLow()].Intersect;
  45.         if(DataMap[handler->GetSession()->GetGuidLow()].Intersect)
  46.             handler->GetSession()->SendNotification("On");
  47.         return true;
  48.     }
  49. };
  50.  
  51. // possible spells:
  52. // 27651, 897
  53.  
  54. class AOE_Placer_Script : public SpellScriptLoader
  55. {
  56. public:
  57.     AOE_Placer_Script() : SpellScriptLoader("AOE_Placer_Script")
  58.     {
  59.     }
  60.  
  61.     class spell_AOE_Placer_Script : public SpellScript
  62.     {
  63.         PrepareSpellScript(spell_AOE_Placer_Script);
  64.  
  65.         uint32 objectId;
  66.         WorldLocation summonPos;
  67.         typedef std::list<GameObject*> BlockList;
  68.  
  69.         uint32 GetObjectEntry()
  70.         {
  71.             return 178442;
  72.                 Item* item = GetCastItem();
  73.             if (!item)
  74.                 return 0;
  75.  
  76.             switch (item->GetEntry())
  77.             {
  78.                 // item entry is 123, spawn object entry 345
  79.             case 123: return 345;
  80.             case 435: return 567;
  81.             }
  82.             return 0;
  83.         }
  84.  
  85.         void HandleAfterCast()
  86.         {
  87.             if (!GetCaster() || !GetCaster()->ToPlayer())
  88.                 return;
  89.             if (!GetExplTargetDest())
  90.                 return;
  91.             summonPos.WorldRelocate(*GetExplTargetDest());
  92.             summonPos.SetOrientation(GetCaster()->GetOrientation());
  93.             objectId = GetObjectEntry();
  94.             if (!objectId)
  95.                 return;
  96.             const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId);
  97.             if (!objectInfo)
  98.                 return;
  99.             if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId))
  100.                 return;
  101.  
  102.             FixSnap();
  103.             if (DoesIntersect3D())
  104.                 ;//return;
  105.             SpawnObject();
  106.         }
  107.  
  108.         // made it so the orientations can be anything and width and height can be anything
  109.         // this assumes the spawn point is the center of the object
  110.         // This does not check ground intersecting, so checking from center doesnt matter, but the width and height need to be according to center.
  111.         bool DoesIntersect3D()
  112.         {
  113.             BlockList list = GetNearGameobjects();
  114.             if (list.empty())
  115.                 return false;
  116.             Position* spawn = GetCorners(GetExplTargetDest(), SIZE(objectId), SIZE(objectId)); // actually an array[5] | !memory management!
  117.             for (BlockList::const_iterator it = list.begin(); it != list.end(); ++it)
  118.             {
  119.                 if (!(*it) || !(*it)->IsInWorld())
  120.                     continue;   // no need to check
  121.                 if (fabs((*it)->GetPositionZ() - summonPos.GetPositionZ()) > (*it)->GetObjectSize() + SIZE(objectId))
  122.                     continue;   // doesnt interserct, too high apart (Z) | Fix the object heights above! Atm uses object size (size = height from center, so ObjectHeight = 2xSize)
  123.  
  124.                 Position* target = GetCorners((*it), SIZE((*it)->GetEntry()), SIZE((*it)->GetEntry())); // funny thing about gameobjects etc .. they ARE Position objects :3
  125.                 for (uint8 i = 0; i < 4; ++i)
  126.                     for (uint8 j = 0; j < 4; ++j)
  127.                         if (DoesCross(spawn[i], spawn[i+1], target[j], target[j+1]))
  128.                         {
  129.                             delete spawn; // !memory management!
  130.                             return true;
  131.                         }
  132.  
  133.             }
  134.             delete spawn; // !memory management!
  135.             return false;
  136.         }
  137.  
  138.         // a and b are lines, 1 and 2 are start and end points
  139.         bool DoesCross(Position a1, Position a2, Position b1, Position b2)
  140.         {
  141.             float a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y;
  142.             a1.GetPosition(a1x, a1y);
  143.             a2.GetPosition(a2x, a2y);
  144.             b1.GetPosition(b1x, b1y);
  145.             b2.GetPosition(b2x, b2y);
  146.             float a = (a1x - a2x)*(b1y - a1y) - (a1y - a2y)*(b1x - a1x);
  147.             float b = (a1x - a2x)*(b2y - a1y) - (a1y - a2y)*(b2x - a1x);
  148.             return a < 0 != b < 0; // a and b have different sign -> crosses
  149.         }
  150.  
  151.         // returns array[5]
  152.         static Position* GetCorners(const Position* pos, float width, float height)
  153.         {
  154.             Position * ret = new Position[5]; // 4 corners and one twice | !memory management!
  155.             for (uint8 i = 0; i < 5; ++i)
  156.             {
  157.                 float o = Position::NormalizeOrientation(pos->GetOrientation()+i*M_PI/2);
  158.                 float x = std::cos(o)*height; // wow uses Y,X coordinates?
  159.                 float y = -std::sin(o)*width;
  160.                 ret[i].Relocate(x,y,o);
  161.             }
  162.             return ret;
  163.         }
  164.  
  165.         BlockList GetNearGameobjects()
  166.         {
  167.             // SIZE_OF_GRIDS || 2*sqrt(2*pow(MAX_RADIUS, 2)) // max radius for any object x2 (more efficency)
  168.             float x,y,z;
  169.             summonPos.GetPosition(x,y,z);
  170.             BlockList objects;
  171.             Trinity::GameObjectInRangeCheck checker(x,y,z, SIZE_OF_GRIDS);
  172.             Trinity::GameObjectListSearcher<Trinity::GameObjectInRangeCheck> searcher(GetCaster(), objects, checker);
  173.             GetCaster()->VisitNearbyGridObject(SIZE_OF_GRIDS, searcher);
  174.             return objects;
  175.         }
  176.  
  177.         // tries to snap to a predefined grid (2D grid, not 3D atm)
  178.         void FixSnap()
  179.         {
  180.             static const float gridsize = 4.0f;
  181.             float x,y,z;
  182.             summonPos.GetPosition(x,y,z);
  183.             float fract, whole;
  184.             fract = modf(x / gridsize, &whole);
  185.             x = (fract < 0.5f ? whole : whole+1)*gridsize+gridsize/2;
  186.             fract = modf(y / gridsize, &whole);
  187.             y = (fract < 0.5f ? whole : whole+1)*gridsize+gridsize/2;
  188.             float newZ = GetCaster()->GetMap()->GetHeight(GetCaster()->ToPlayer()->GetPhaseMaskForSpawn(), x, y, MAX_HEIGHT);
  189.             if (newZ != INVALID_HEIGHT)
  190.                 z = newZ;
  191.             summonPos.Relocate(x, y, z);
  192.         }
  193.  
  194.         void SpawnObject()
  195.         {
  196.             Player* player = GetCaster()->ToPlayer();
  197.             float x, y, z, o;
  198.             summonPos.GetPosition(x,y,z,o);
  199.             Map* map = player->GetMap();
  200.             GameObject* object = new GameObject;
  201.             uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT);
  202.             if (!object->Create(guidLow, objectId, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
  203.             {
  204.                 delete object;
  205.                 return;
  206.             }
  207.             object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn());
  208.             if (!object->LoadGameObjectFromDB(guidLow, map))
  209.             {
  210.                 delete object;
  211.                 return;
  212.             }
  213.             sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow));
  214.             return;
  215.         }
  216.  
  217.         void Register()
  218.         {
  219.             AfterCast += SpellCastFn(spell_AOE_Placer_Script::HandleAfterCast);
  220.         }
  221.     };
  222.  
  223.     SpellScript* GetSpellScript() const
  224.     {
  225.         return new spell_AOE_Placer_Script();
  226.     }
  227. };
  228.  
  229. void AddSC_AOE_Placer_Script()
  230. {
  231.     new AOE_Placer_Script();
  232. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement