Advertisement
Guest User

Untitled

a guest
Nov 2nd, 2013
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.71 KB | None | 0 0
  1. #include "ScriptPCH.h"
  2. #include "MapManager.h"
  3. #include "Language.h"
  4.  
  5. enum commandIDs
  6. {
  7.     TEST,
  8.     SELECTNEAR,
  9.     DELET,
  10.     X,
  11.     Y,
  12.     Z,
  13.     O,
  14.     GROUND,
  15.     RESPAWN,
  16.     GOTO,
  17.     FACE,
  18.     SAVE,
  19.  
  20.     SPAWN,
  21.     NORTH,
  22.     EAST,
  23.     SOUTH,
  24.     WEST,
  25.     NORTHEAST,
  26.     NORTHWEST,
  27.     SOUTHEAST,
  28.     SOUTHWEST,
  29.     UP,
  30.     DOWN,
  31.     LEFT,
  32.     RIGHT,
  33.     PHASE,
  34.     SELECTALLNEAR,
  35.     SPAWNSPELL,
  36. };
  37.  
  38. class GOMove_commandscript : public CommandScript
  39. {
  40. public:
  41.     GOMove_commandscript() : CommandScript("GOMove_commandscript")
  42.     {
  43.     }
  44.  
  45.     static UNORDERED_MAP<uint32, GameObject*> GObjects; // GObjects[GObjectID] = pointer // GObjectID comes from highguid. lowguid is 0 for temps.
  46.     static UNORDERED_MAP<uint64, uint32> SpawnQue;
  47.  
  48.     ChatCommand* GetCommands() const
  49.     {
  50.         static ChatCommand GOMoveCommandTable[] =
  51.         {
  52.             { "gomove",         rbac::RBAC_PERM_COMMAND_GOMOVE,     false,  &GOMove_Command,                "", NULL },
  53.             { NULL,             0,                                  falseNULL,                           "", NULL }
  54.         };
  55.         return GOMoveCommandTable;
  56.     }
  57.  
  58.     static bool GOMove_Command(ChatHandler* handler, const char* args)
  59.     {
  60.         if (!args)
  61.             return false;
  62.  
  63.         char* ID_t = strtok((char*)args, " ");
  64.         if (!ID_t)
  65.             return false;
  66.         uint32 ID = (uint32)atol(ID_t);
  67.  
  68.         char* GObjectID_C = strtok(NULL, " ");
  69.         uint32 GObjectID = 0;
  70.         bool isHex = false;
  71.         if (GObjectID_C)
  72.         {
  73.             GObjectID = strtoul(GObjectID_C, NULL, 0); // can take in hex as well as dec
  74.             isHex = (std::string(GObjectID_C).find("0x") != std::string::npos);
  75.         }
  76.  
  77.         char* ARG_t = strtok(NULL, " ");
  78.         uint32 ARG = 0;
  79.         if (ARG_t)
  80.             ARG = (uint32)atol(ARG_t);
  81.  
  82.         WorldSession* session = handler->GetSession();
  83.         Player* player = session->GetPlayer();
  84.         uint64 playerGUID = player->GetGUID();
  85.  
  86.         if (ID < SPAWN) // no args
  87.         {
  88.             if (ID >= DELET && ID <= GOTO) // has target (needs retrieve gameobject)
  89.             {
  90.                 GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex);
  91.                 if (!target)
  92.                     ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temp(%u)", GObjectID, isHex ? 1 : 0);
  93.                 else
  94.                 {
  95.                     float x,y,z,o;
  96.                     target->GetPosition(x,y,z,o);
  97.                     uint32 p = target->GetPhaseMask();
  98.                     switch(ID)
  99.                     {
  100.                     case DELET: DeleteObject(target, isHex ? GObjectID : 0); SendSelectionInfo(player, GObjectID, isHex, false); break;
  101.                     case X: SpawnObject(player,player->GetPositionX(),y,z,o,p,true,GObjectID, isHex);      break;
  102.                     case Y: SpawnObject(player,x,player->GetPositionY(),z,o,p,true,GObjectID, isHex);      break;
  103.                     case Z: SpawnObject(player,x,y,player->GetPositionZ(),o,p,true,GObjectID, isHex);      break;
  104.                     case O: SpawnObject(player,x,y,z,player->GetOrientation(),p,true,GObjectID, isHex);    break;
  105.                     case GOTO: player->TeleportTo(target->GetMapId(), x,y,z,o);                     break;
  106.                     case RESPAWN: SpawnObject(player,x,y,z,o,p,false,target->GetEntry(), isHex);           break;
  107.                     case GROUND:
  108.                         {
  109.                             float ground = target->GetMap()->GetHeight(target->GetPhaseMask(), x, y, MAX_HEIGHT);
  110.                             if(ground != INVALID_HEIGHT)
  111.                                 SpawnObject(player,x,y,ground,o,p,true,GObjectID, isHex);
  112.                         } break;
  113.                     }
  114.                 }
  115.             }
  116.             else
  117.             {
  118.                 switch(ID)
  119.                 {
  120.                 case TEST: session->SendAreaTriggerMessage(player->GetName().c_str());      break;
  121.                 case FACE: { float piper2 = M_PI/2; float multi = player->GetOrientation()/piper2; float multi_int = floor(multi); float new_ori = (multi-multi_int > 0.5f) ? (multi_int+1)*piper2 : multi_int*piper2; player->SetFacingTo(new_ori); } break;
  122.                 case SAVE: SaveObject(player, GObjectID, isHex);                                   break;
  123.                 case SELECTNEAR:
  124.                     {
  125.                         GameObject* object = handler->GetNearbyGameObject();
  126.                         uint32 closestID = GetClosestGObjectID(player, object);
  127.                         if (!closestID && !object)
  128.                             ChatHandler(player->GetSession()).PSendSysMessage("No objects found");
  129.                         else
  130.                         {
  131.                             bool isHex = (closestID != 0);
  132.                             if(closestID)
  133.                                 object = GObjects[closestID]; // MUST be valid
  134.                             else
  135.                                 closestID = object->GetGUIDLow();
  136.                             SendSelectionInfo(player, closestID, isHex, true);
  137.                             session->SendAreaTriggerMessage("Selected %s", object->GetName().c_str());
  138.                         }
  139.                     } break;
  140.                 }
  141.             }
  142.         }
  143.         else if (ARG && ID >= SPAWN)
  144.         {
  145.             if (ID >= NORTH && ID <= PHASE)
  146.             {
  147.                 GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex);
  148.                 if (!target)
  149.                     ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temporary: %s", GObjectID, isHex ? "true" : "false");
  150.                 else
  151.                 {
  152.                     float x,y,z,o;
  153.                     target->GetPosition(x,y,z,o);
  154.                     uint32 p = target->GetPhaseMask();
  155.                     switch(ID)
  156.                     {
  157.                     case NORTH: SpawnObject(player,x+((float)ARG/100),y,z,o,p,true,GObjectID, isHex);                        break;
  158.                     case EAST: SpawnObject(player,x,y-((float)ARG/100),z,o,p,true,GObjectID, isHex);                         break;
  159.                     case SOUTH: SpawnObject(player,x-((float)ARG/100),y,z,o,p,true,GObjectID, isHex);                        break;
  160.                     case WEST: SpawnObject(player,x,y+((float)ARG/100),z,o,p,true,GObjectID, isHex);                         break;
  161.                     case NORTHEAST: SpawnObject(player,x+((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
  162.                     case SOUTHEAST: SpawnObject(player,x-((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
  163.                     case SOUTHWEST: SpawnObject(player,x-((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
  164.                     case NORTHWEST: SpawnObject(player,x+((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
  165.                     case UP: SpawnObject(player,x,y,z+((float)ARG/100),o,p,true,GObjectID, isHex);                           break;
  166.                     case DOWN: SpawnObject(player,x,y,z-((float)ARG/100),o,p,true,GObjectID, isHex);                         break;
  167.                     case RIGHT: SpawnObject(player,x,y,z,o-((float)ARG/100),p,true,GObjectID, isHex);                        break;
  168.                     case LEFT: SpawnObject(player,x,y,z,o+((float)ARG/100),p,true,GObjectID, isHex);                         break;
  169.                     case PHASE: SpawnObject(player,x,y,z,o,ARG,true,GObjectID, isHex);                                       break;
  170.                     }
  171.                 }
  172.             }
  173.             else
  174.             {
  175.                 switch(ID)
  176.                 {
  177.                 case SPAWN:
  178.                     {
  179.                         if (SpawnObject(player, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),  player->GetOrientation(), player->GetPhaseMaskForSpawn(), false, ARG, false, true))
  180.                             SpawnQue[player->GetGUID()] = ARG;
  181.                     } break;
  182.                 case SPAWNSPELL:
  183.                     {
  184.                         SpawnQue[player->GetGUID()] = ARG;
  185.                     } break;
  186.                 case SELECTALLNEAR:
  187.                     {
  188.                         if (ARG > 5000)
  189.                             ARG = 5000;
  190.  
  191.                         QueryResult result = WorldDatabase.PQuery("SELECT guid, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%u' AND position_x BETWEEN '%f'-'%u' AND '%f'+'%u' AND position_y BETWEEN '%f'-'%u' AND '%f'+'%u' AND position_z BETWEEN '%f'-'%u' AND '%f'+'%u' ORDER BY order_ ASC LIMIT 100",
  192.                             player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetPositionX(), ARG, player->GetPositionX(), ARG, player->GetPositionY(), ARG, player->GetPositionY(), ARG, player->GetPositionZ(), ARG, player->GetPositionZ(), ARG);
  193.  
  194.                         if (result)
  195.                         {
  196.                             do
  197.                             {
  198.                                 Field* fields   = result->Fetch();
  199.                                 uint32 guidLow  = fields[0].GetUInt32();
  200.  
  201.                                 if (GameObject* object = GetObjectByGObjectID(player, guidLow, false))
  202.                                     SendSelectionInfo(player, guidLow, false, true);
  203.                             }
  204.                             while (result->NextRow());
  205.                         }
  206.                         for(UNORDERED_MAP<uint32, GameObject*>::const_iterator it = GObjects.begin(); it != GObjects.end();)
  207.                         {
  208.                             if(!it->second)
  209.                             {
  210.                                 GObjects.erase(it++);
  211.                                 continue;
  212.                             }
  213.                             if(it->second->IsWithinDistInMap(player, ARG))
  214.                                 SendSelectionInfo(player, it->first, true, true);
  215.                             ++it;
  216.                         }
  217.                     } break;
  218.                 }
  219.             }
  220.         }
  221.         else
  222.             return false;
  223.         return true;
  224.     }
  225.  
  226.     static uint32 GetClosestGObjectID(Player* player, GameObject* obj = NULL)
  227.     {
  228.         if(!player)
  229.             return 0;
  230.         uint32 closestID = 0;
  231.         for(UNORDERED_MAP<uint32, GameObject*>::const_iterator it = GObjects.begin(); it != GObjects.end();)
  232.         {
  233.             if(!it->second)
  234.             {
  235.                 GObjects.erase(it++);
  236.                 continue;
  237.             }
  238.             if(!it->second->IsInMap(player))
  239.             {
  240.                 ++it;
  241.                 continue;
  242.             }
  243.             if(obj && obj != it->second && it->second->GetDistance(player) > obj->GetDistance(player))
  244.             {
  245.                 ++it;
  246.                 continue;
  247.             }
  248.             closestID = it->first;
  249.             obj = it->second;
  250.             ++it;
  251.         }
  252.         if (obj && !closestID && obj->GetGUIDLow() && !obj->GetDBTableGUIDLow()) // obj is .gob add temp, respawn and return
  253.         {
  254.             float x,y,z,o;
  255.             obj->GetPosition(x,y,z,o);
  256.             GameObject* obj2 = SpawnObject(player,x,y,z,o,obj->GetPhaseMask(),false,obj->GetEntry(),false);
  257.             if(obj2)
  258.                 closestID = obj2->GetGUIDHigh();
  259.             DeleteObject(obj);
  260.         }
  261.         return closestID;
  262.     }
  263.  
  264.     static GameObject* GetObjectByGObjectID(Player* player, uint32 GObjectID, bool isHex)
  265.     {
  266.         GameObject* object = NULL;
  267.         if (isHex)
  268.         {
  269.             UNORDERED_MAP<uint32, GameObject*>::const_iterator it = GObjects.find(GObjectID);
  270.             if(it == GObjects.end())
  271.                 return NULL;
  272.             else if(!it->second)
  273.             {
  274.                 GObjects.erase(it);
  275.                 return NULL;
  276.             }
  277.             object = it->second;
  278.         }
  279.         else
  280.         {
  281.             if (GameObjectData const* gameObjectData = sObjectMgr->GetGOData(GObjectID))
  282.                 object = ChatHandler(player->GetSession()).GetObjectGlobalyWithGuidOrNearWithDbGuid(GObjectID, gameObjectData->id);
  283.         }
  284.  
  285.         if(!object || !object->IsInMap(player)) // cant move objects on different maps
  286.             return NULL;
  287.         return object;
  288.     }
  289.  
  290.     static void SendAddonMessage(Player* player, const char* msg)
  291.     {
  292.         WorldPacket* data =  new WorldPacket(); // Needs a custom built packet since TC doesnt send guid
  293.         uint32 messageLength = (uint32)strlen(msg) + 1;
  294.         data->Initialize(SMSG_MESSAGECHAT, 100);
  295.         *data << (uint8)CHAT_MSG_SYSTEM;
  296.         *data << LANG_ADDON;
  297.         *data << player->GetGUID();
  298.         *data << uint32(0);
  299.         *data << player->GetGUID();
  300.         *data << messageLength;
  301.         *data << msg;
  302.         *data << uint8(0);
  303.         player->GetSession()->SendPacket(data);
  304.     }
  305.  
  306.     static void SendSelectionInfo(Player* player, uint32 GObjectID, bool isHex, bool add) // Sends an addon message for selected objects list
  307.     {
  308.         if (!player || !GObjectID)
  309.             return;
  310.  
  311.         std::ostringstream ss;
  312.         if (!add)
  313.             if(!isHex)
  314.                 ss << "GOMOVE|REMOVE|" << std::dec << (uint32)GObjectID <<"||0";
  315.             else
  316.                 ss << "GOMOVE|REMOVE|" << "0x" << std::hex << GObjectID <<"||0";
  317.         else
  318.         {
  319.             GameObject* object = GetObjectByGObjectID(player, GObjectID, isHex);
  320.             if(!object)
  321.                 return;
  322.             if(!isHex)
  323.                 ss <<"GOMOVE|ADD|" << std::dec << (uint32)GObjectID << std::dec <<"|"<< object->GetName() <<"|"<< object->GetEntry();
  324.             else
  325.                 ss <<"GOMOVE|ADD|" << "0x" << std::hex << GObjectID << std::dec <<"|"<< object->GetName() <<"|"<< object->GetEntry();
  326.         }
  327.  
  328.         SendAddonMessage(player, ss.str().c_str());
  329.     }
  330.  
  331.     static GameObject* SummonGameObject(Player* obj, uint32 entry, float x, float y, float z, float o, uint32 p, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
  332.     {
  333.         if (!obj->IsInWorld())
  334.             return NULL;
  335.  
  336.         GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry);
  337.         if (!goinfo)
  338.             return NULL;
  339.  
  340.         Map* map = obj->GetMap();
  341.         GameObject* go = new GameObject();
  342.         if (!go->Create(0, entry, map, p, x, y, z, o, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY))
  343.         {
  344.             delete go;
  345.             return NULL;
  346.         }
  347.  
  348.         go->SetRespawnTime(respawnTime);
  349.         obj->AddGameObject(go);
  350.         map->AddToMap(go);
  351.  
  352.         GObjects[go->GetGUIDHigh()] = go;
  353.         return go;
  354.     }
  355.  
  356.     static void DeleteObject(GameObject* object, uint32 GObjectID = 0)
  357.     {
  358.         if(GObjectID)
  359.             GObjects.erase(GObjectID);
  360.         if (object)
  361.         {
  362.             uint64 ownerGuid = object->GetOwnerGUID();
  363.             if (ownerGuid)
  364.             {
  365.                 Unit* owner = ObjectAccessor::GetUnit(*object, ownerGuid);
  366.                 if (owner && IS_PLAYER_GUID(ownerGuid))
  367.                     owner->RemoveGameObject(object, false);
  368.             }
  369.             object->SetRespawnTime(0);
  370.             object->Delete();
  371.             object->DeleteFromDB();
  372.         }
  373.     }
  374.  
  375.     static GameObject* SpawnObject(Player* player,float x,float y,float z,float o,uint32 p, bool move, uint32 eorg, bool isHex, bool message = false)
  376.     {
  377.         // eorg = !move && entry or move && GObjectID (entry or ID)
  378.         if (!player || !eorg)
  379.             return NULL;
  380.  
  381.         float rot2 = std::sin(o/2);
  382.         float rot3 = std::cos(o/2);
  383.  
  384.         GameObject* object = NULL;
  385.         if (move)
  386.         {
  387.             object = GetObjectByGObjectID(player, eorg, isHex);
  388.             if (!object)
  389.                 return NULL;
  390.             GameObject* spawned = SummonGameObject(player, object->GetEntry(), x, y, z, o, p, 0, 0, rot2, rot3, 0);
  391.             DeleteObject(object, isHex ? eorg : 0);
  392.             if(!spawned)
  393.                 return NULL;
  394.             // object->SetPhaseMask(p, true);
  395.             std::ostringstream ss;
  396.             if (!isHex)
  397.                 ss << "GOMOVE|SWAP|" << eorg << "||" << "0x" << std::hex << spawned->GetGUIDHigh();
  398.             else
  399.                 ss << "GOMOVE|SWAP|" << "0x" << std::hex << eorg << "||" << "0x" << std::hex << spawned->GetGUIDHigh();
  400.             SendAddonMessage(player, ss.str().c_str());
  401.         }
  402.         else
  403.         {
  404.             object = SummonGameObject(player, eorg, x, y, z, o, p, 0, 0, rot2, rot3, 0);
  405.             if(!object)
  406.                 return NULL;
  407.             SendSelectionInfo(player, object->GetGUIDHigh(), true, true); // MUST be handled here. There are no good ways to get the GObjectID later.
  408.         }
  409.  
  410.         return object;
  411.     }
  412.  
  413.     static void SaveObject(Player* player, uint32 GObjectID, bool isHex, bool message = false)
  414.     {
  415.         GameObject* object = GetObjectByGObjectID(player, GObjectID, isHex);
  416.         if (!object)
  417.             return;
  418.  
  419.         Map* map = player->GetMap();
  420.         GameObject* saved = new GameObject;
  421.         uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT);
  422.         float x, y, z, o;
  423.         object->GetPosition(x, y, z, o);
  424.         if (!saved->Create(guidLow, object->GetEntry(), map, object->GetPhaseMask(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
  425.         {
  426.             delete saved;
  427.             return;
  428.         }
  429.         saved->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), object->GetPhaseMask());
  430.         if (!saved->LoadGameObjectFromDB(guidLow, map))
  431.         {
  432.             delete saved;
  433.             return;
  434.         }
  435.         sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow));
  436.  
  437.         DeleteObject(object, isHex ? GObjectID : 0); // delete old
  438.         std::ostringstream ss;
  439.         if(!isHex)
  440.             ss << "GOMOVE|SWAP|" << std::dec << GObjectID << std::dec << "||" << guidLow;
  441.         else
  442.             ss << "GOMOVE|SWAP|" << "0x" << std::hex << GObjectID << std::dec << "||" << guidLow;
  443.         SendAddonMessage(player, ss.str().c_str());
  444.     }
  445. };
  446. UNORDERED_MAP<uint32, GameObject*> GOMove_commandscript::GObjects;
  447. UNORDERED_MAP<uint64, uint32> GOMove_commandscript::SpawnQue;
  448.  
  449. // possible spells:
  450. // 27651, 897
  451.  
  452. class spell_place_GOMove : public SpellScriptLoader
  453. {
  454. public:
  455.     spell_place_GOMove() : SpellScriptLoader("spell_place_GOMove") { }
  456.  
  457.     class spell_place_GOMoveSpellScript : public SpellScript
  458.     {
  459.         PrepareSpellScript(spell_place_GOMoveSpellScript);
  460.  
  461.         void HandleAfterCast()
  462.         {
  463.             if(!GetCaster())
  464.                 return;
  465.             Player* player = GetCaster()->ToPlayer();
  466.             if(!player)
  467.                 return;
  468.             const WorldLocation* summonPos = GetExplTargetDest();
  469.             if(summonPos && GOMove_commandscript::SpawnQue.find(player->GetGUID()) != GOMove_commandscript::SpawnQue.end())
  470.                 GOMove_commandscript::SpawnObject(player, summonPos->GetPositionX(), summonPos->GetPositionY(), summonPos->GetPositionZ(), player->GetOrientation(), player->GetPhaseMaskForSpawn(), false, GOMove_commandscript::SpawnQue[player->GetGUID()], false, true);
  471.         }
  472.  
  473.         void Register()
  474.         {
  475.             AfterCast += SpellCastFn(spell_place_GOMoveSpellScript::HandleAfterCast);
  476.         }
  477.     };
  478.  
  479.     SpellScript* GetSpellScript() const
  480.     {
  481.         return new spell_place_GOMoveSpellScript();
  482.     }
  483. };
  484.  
  485. void AddSC_GOMove_commandscript()
  486. {
  487.     new GOMove_commandscript();
  488.     new spell_place_GOMove();
  489. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement