Advertisement
Guest User

Untitled

a guest
Nov 2nd, 2013
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.27 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",   SEC_GAMEMASTER,     false,   &GOMove_Command,   "", NULL },
  53.            { NULL,   0,  false, NULL,    "", 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