コード例 #1
0
ファイル: OutdoorPvP.cpp プロジェクト: BlueSellafield/ArkCORE
bool OPvPCapturePoint::DelObject(uint32 type) {
    if (!m_Objects[type])
        return false;

    GameObject *obj = HashMapHolder<GameObject>::Find(m_Objects[type]);
    if (!obj) {
        m_Objects[type] = 0;
        return false;
    }
    uint32 guid = obj->GetDBTableGUIDLow();
    obj->SetRespawnTime(0); // not save respawn time
    obj->Delete();
    sObjectMgr->DeleteGOData(guid);
    m_ObjectTypes[m_Objects[type]] = 0;
    m_Objects[type] = 0;
    return true;
}
コード例 #2
0
ファイル: OutdoorPvP.cpp プロジェクト: Trizzor/uecore
bool OutdoorPvPObjective::DelCapturePoint()
{
    if(!m_CapturePoint)
        return false;

    GameObject *obj = HashMapHolder<GameObject>::Find(m_CapturePoint);
    if(!obj)
    {
        sLog.outError("OutdoorPvPObjective: Can't find gobject guid: %u", GUID_LOPART(m_CapturePoint));
        return false;
    }
    uint32 guid = obj->GetDBTableGUIDLow();
    obj->SetRespawnTime(0);                                 // not save respawn time
    obj->Delete();
    objmgr.DeleteGOData(guid);
    m_CapturePoint = 0;
    return true;
}
コード例 #3
0
bool OPvPCapturePoint::DelObject(uint32 type)
{
    if(!m_Objects[type])
        return false;

    GameObject * obj = ObjectAccessor::GetGameObjectInWorld(m_Objects[type]);
    if(!obj)
    {
        m_Objects[type] = 0;
        return false;
    }
    uint32 guid = obj->GetDBTableGUIDLow();
    obj->SetRespawnTime(0);                                 // not save respawn time
    obj->Delete();
    sObjectMgr.DeleteGOData(guid);
    m_ObjectTypes[m_Objects[type]] = 0;
    m_Objects[type] = 0;
    return true;
}
コード例 #4
0
ファイル: OutdoorPvP.cpp プロジェクト: Trizzor/uecore
bool OutdoorPvPObjective::AddCapturePoint(uint32 entry, uint32 map, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3)
{
    sLog.outDebug("OutdoorPvPObjective: creating capture point %u and capture point creature",entry);

    // check info existence
    GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
    if (!goinfo)
        return false;

    CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(OPVP_TRIGGER_CREATURE_ENTRY);
    if(!cinfo)
        return false;

    // create capture point creature
    uint32 displayId = objmgr.ChooseDisplayId(0, cinfo, NULL);

    uint32 creature_guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);

    CreatureData& cdata = objmgr.NewOrExistCreatureData(creature_guid);

    cdata.id = OPVP_TRIGGER_CREATURE_ENTRY;
    cdata.mapid         = map;
    cdata.displayid     = displayId;
    cdata.equipmentId   = cinfo->equipmentId;
    cdata.posX          = x;
    cdata.posY          = y;
    cdata.posZ          = z;
    cdata.orientation   = o;
    cdata.spawntimesecs = 1;
    cdata.spawndist     = 0;
    cdata.currentwaypoint = 0;
    cdata.curhealth     = cinfo->maxhealth;
    cdata.curmana       = cinfo->maxmana;
    cdata.is_dead       = false;
    cdata.movementType  = cinfo->MovementType;
    cdata.spawnMask     = 1;
    cdata.phaseMask     = PHASEMASK_NORMAL;

    objmgr.AddCreatureToGrid(creature_guid, &cdata);
    m_CapturePointCreature = MAKE_NEW_GUID(creature_guid, OPVP_TRIGGER_CREATURE_ENTRY, HIGHGUID_UNIT);

    // create capture point go
    uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);

    GameObjectData& data = objmgr.NewGOData(guid);

    data.id             = entry;
    data.mapid          = map;
    data.posX           = x;
    data.posY           = y;
    data.posZ           = z;
    data.orientation    = o;
    data.rotation0      = rotation0;
    data.rotation1      = rotation1;
    data.rotation2      = rotation2;
    data.rotation3      = rotation3;
    data.spawntimesecs  = 1;
    data.animprogress   = 100;
    data.spawnMask      = 1;
    data.go_state       = GO_STATE_READY;
    data.phaseMask      = PHASEMASK_NORMAL;

    objmgr.AddGameobjectToGrid(guid, &data);

    m_CapturePoint = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT);

    // get the needed values from goinfo
    m_ShiftMaxPhase = goinfo->raw.data[17];
    m_ShiftMaxCaptureSpeed = m_ShiftMaxPhase / float(goinfo->raw.data[16]);
    m_NeutralValue = goinfo->raw.data[12];

    // add to map if map is already loaded
    Map * pMap = MapManager::Instance().FindMap(map);
    if(!pMap)
        return true;
    // add GO...
    GameObject * go = new GameObject;
    if(!go->Create(guid,entry, pMap, PHASEMASK_NORMAL, x,y,z,o,rotation0,rotation1,rotation2,rotation3,100, GO_STATE_READY))
    {
        sLog.outError("OutdoorPvPObjective: Gameobject template %u not found in database.", entry);
        delete go;
    }
    else
    {
        go->SetRespawnTime(0);
        objmgr.SaveGORespawnTime(go->GetDBTableGUIDLow(), 0, 0); //this is useless this isn't spawned through db so it doesn't has dbtableguid (it's just 0)
        pMap->Add(go);
    }
    // add creature...
    Creature* pCreature = new Creature;
    if (!pCreature->Create(creature_guid, pMap,PHASEMASK_NORMAL, OPVP_TRIGGER_CREATURE_ENTRY, 0))
    {
        sLog.outError("OutdoorPvPObjective: Can't create creature entry: %u",entry);
        delete pCreature;
    }
    else
    {
        pCreature->AIM_Initialize();

        pCreature->Relocate(x, y, z, o);

        if(!pCreature->IsPositionValid())
        {
            sLog.outError("OutdoorPvPObjective: Creature (guidlow %d, entry %d) not added to opvp. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
            return false;
        }

        pMap->Add(pCreature);
    }
    return true;
}
コード例 #5
0
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
    uint32 opcode = recv_data.GetOpcode();
    sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);

    Unit *mover = _player->m_mover;
    Player *plMover = mover->GetTypeId()==TYPEID_PLAYER ? (Player*)mover : NULL;

    // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
    if(plMover && plMover->IsBeingTeleported()){
        // movement anticheat
        plMover->m_anti_JustTeleported = 1;
        // end movement anticheat
        return;
    }

    /* extract packet */
    MovementInfo movementInfo;
    ReadMovementInfo(recv_data, &movementInfo);
    /*----------------*/

    if(recv_data.size() != recv_data.rpos())
    {
        sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos());
        KickPlayer();
        return;
    }

    if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
        return;

    /* handle special cases */
    if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
    {
        // transports size limited
        // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
        if( movementInfo.t_x > 60 || movementInfo.t_y > 60 || movementInfo.t_x < -60 ||  movementInfo.t_y < -60 )
            return;

        if( !MaNGOS::IsValidMapCoord(movementInfo.x+movementInfo.t_x, movementInfo.y + movementInfo.t_y,
            movementInfo.z + movementInfo.t_z, movementInfo.o + movementInfo.t_o) )
            return;

        if (plMover && plMover->m_anti_TransportGUID == 0 && (movementInfo.t_guid !=0))
        {
            // if we boarded a transport, add us to it
            if (plMover && !plMover->m_transport)
            {
                // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
                for (MapManager::TransportSet::const_iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
                {
                    if ((*iter)->GetGUID() == movementInfo.t_guid)
                    {
                        plMover->m_transport = (*iter);
                        (*iter)->AddPassenger(plMover);
                        break;
                    }
                }
            }
            //movement anticheat;
            //Correct finding GO guid in DB (thanks to GriffonHeart)
            GameObject *obj = HashMapHolder<GameObject>::Find(movementInfo.t_guid);
            if(obj)
                plMover->m_anti_TransportGUID = obj->GetDBTableGUIDLow();
            else
                plMover->m_anti_TransportGUID = GUID_LOPART(movementInfo.t_guid);
            // end movement anticheat
        }
    } else if (plMover && plMover->m_anti_TransportGUID != 0){
        if (plMover && plMover->m_transport)               // if we were on a transport, leave
        {
            plMover->m_transport->RemovePassenger(plMover);
            plMover->m_transport = NULL;
        }
        movementInfo.t_x = 0.0f;
        movementInfo.t_y = 0.0f;
        movementInfo.t_z = 0.0f;
        movementInfo.t_o = 0.0f;
        movementInfo.t_time = 0;
        movementInfo.t_seat = -1;
        plMover->m_anti_TransportGUID = 0;
    }

    // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
    if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight())
    {
        //movement anticheat
        plMover->m_anti_JustJumped = 0;
        plMover->m_anti_JumpBaseZ = 0;
        //end movement anticheat
        plMover->HandleFall(movementInfo);
    }


    if (plMover && (movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING) != plMover->IsInWater()))
    {
        // now client not include swimming flag in case jumping under water
        plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
    }

    /*----------------------*/
    //---- anti-cheat features -->>>
    bool check_passed = true;
    #ifdef MOVEMENT_ANTICHEAT_DEBUG
    if (plMover){
        sLog.outBasic("MA-%s > client-time:%d fall-time:%d | xyzo: %f,%f,%fo(%f) flags[%X] opcode[%s]| transport (xyzo): %f,%f,%fo(%f)",
                    plMover->GetName(),movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o,
                    movementInfo.flags, LookupOpcodeName(opcode),movementInfo.t_x,movementInfo.t_y,movementInfo.t_z,movementInfo.t_o);
        sLog.outBasic("MA-%s Transport > server GUID: %d |  client GUID: (lo)%d - (hi)%d",
                    plMover->GetName(),plMover->m_anti_TransportGUID, GUID_LOPART(movementInfo.t_guid), GUID_HIPART(movementInfo.t_guid));
    } else {
        sLog.outBasic("MA > client-time:%d fall-time:%d | xyzo: %f,%f,%fo(%f) flags[%X] opcode[%s]| transport (xyzo): %f,%f,%fo(%f)",
                    movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o,
                    movementInfo.flags, LookupOpcodeName(opcode),movementInfo.t_x,movementInfo.t_y,movementInfo.t_z,movementInfo.t_o);
        sLog.outBasic("MA Transport > server GUID:  |  client GUID: (lo)%d - (hi)%d",
                    GUID_LOPART(movementInfo.t_guid), GUID_HIPART(movementInfo.t_guid));
    }
    #endif

    if (plMover && World::GetEnableMvAnticheat())
    {
        //calc time deltas
        int32 cClientTimeDelta = 1500;
        if (plMover->m_anti_LastClientTime !=0){
            cClientTimeDelta = movementInfo.time - plMover->m_anti_LastClientTime;
            plMover->m_anti_DeltaClientTime += cClientTimeDelta;
            plMover->m_anti_LastClientTime = movementInfo.time;
        } else {
            plMover->m_anti_LastClientTime = movementInfo.time;
        }

        uint32 cServerTime=getMSTime();
        uint32 cServerTimeDelta = 1500;
        if (plMover->m_anti_LastServerTime != 0){
            cServerTimeDelta = cServerTime - plMover->m_anti_LastServerTime;
            plMover->m_anti_DeltaServerTime += cServerTimeDelta;
            plMover->m_anti_LastServerTime = cServerTime;
        } else {
            plMover->m_anti_LastServerTime = cServerTime;
        }

        //resync times on client login (first 15 sec for heavy areas)
        if (plMover->m_anti_DeltaServerTime < 15000 && plMover->m_anti_DeltaClientTime < 15000)
            plMover->m_anti_DeltaClientTime = plMover->m_anti_DeltaServerTime;

        int32 sync_time = plMover->m_anti_DeltaClientTime - plMover->m_anti_DeltaServerTime;

        #ifdef MOVEMENT_ANTICHEAT_DEBUG
        sLog.outBasic("MA-%s Time > cClientTimeDelta: %d, cServerTime: %d || deltaC: %d - deltaS: %d || SyncTime: %d",
                        plMover->GetName(),cClientTimeDelta, cServerTime,
                        plMover->m_anti_DeltaClientTime, plMover->m_anti_DeltaServerTime, sync_time);
        #endif

        //mistiming checks
        int32 gmd = World::GetMistimingDelta();
        if (sync_time > gmd || sync_time < -gmd){
            cClientTimeDelta = cServerTimeDelta;
            plMover->m_anti_MistimingCount++;

            sLog.outError("MA-%s, mistiming exception. #:%d, mistiming: %dms ",
                            plMover->GetName(), plMover->m_anti_MistimingCount, sync_time);

            if (plMover->m_anti_MistimingCount > World::GetMistimingAlarms())
            {
                plMover->GetSession()->KickPlayer();
                return;
            }
            check_passed = false;
        }
        // end mistiming checks


        uint32 curDest = plMover->m_taxi.GetTaxiDestination(); //check taxi flight
        if ((plMover->m_anti_TransportGUID == 0) && !curDest)
        {
            UnitMoveType move_type;

            // calculating section ---------------------
            //current speed
            if (movementInfo.flags & MOVEMENTFLAG_FLYING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_FLIGHT_BACK : MOVE_FLIGHT;
            else if (movementInfo.flags & MOVEMENTFLAG_SWIMMING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_SWIM;
            else if (movementInfo.flags & MOVEMENTFLAG_WALK_MODE) move_type = MOVE_WALK;
            //hmm... in first time after login player has MOVE_SWIMBACK instead MOVE_WALKBACK
            else move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_RUN;

            float current_speed = plMover->GetSpeed(move_type);
            // end current speed

            // movement distance
            float allowed_delta= 0;

            float delta_x = plMover->GetPositionX() - movementInfo.x;
            float delta_y = plMover->GetPositionY() - movementInfo.y;
            float delta_z = plMover->GetPositionZ() - movementInfo.z;
            float real_delta = delta_x * delta_x + delta_y * delta_y;
            float tg_z = -99999; //tangens
            // end movement distance

            if (cClientTimeDelta < 0) {cClientTimeDelta = 0;}
            float time_delta = (cClientTimeDelta < 1500) ? (float)cClientTimeDelta/1000 : 1.5f; //normalize time - 1.5 second allowed for heavy loaded server

            if (!(movementInfo.flags & (MOVEMENTFLAG_FLYING | MOVEMENTFLAG_SWIMMING)))
              tg_z = (real_delta !=0) ? (delta_z*delta_z / real_delta) : -99999;

            if (current_speed < plMover->m_anti_Last_HSpeed)
            {
                allowed_delta = plMover->m_anti_Last_HSpeed;
                if (plMover->m_anti_LastSpeedChangeTime == 0 )
                    plMover->m_anti_LastSpeedChangeTime = movementInfo.time + (uint32)floor(((plMover->m_anti_Last_HSpeed / current_speed) * 1500)) + 100; //100ms above for random fluctuating =)))
            } else {
                allowed_delta = current_speed;
            }
            allowed_delta = allowed_delta * time_delta;
            allowed_delta = allowed_delta * allowed_delta + 2;
            if (tg_z > 2.2)
                allowed_delta = allowed_delta + (delta_z*delta_z)/2.37; // mountain fall allowed speed

            if (movementInfo.time>plMover->m_anti_LastSpeedChangeTime)
            {
                plMover->m_anti_Last_HSpeed = current_speed; // store current speed
                plMover->m_anti_Last_VSpeed = -2.3f;
                if (plMover->m_anti_LastSpeedChangeTime != 0) plMover->m_anti_LastSpeedChangeTime = 0;
            }
            // end calculating section ---------------------

            //AntiGravitation (thanks to Meekro)
            float JumpHeight = plMover->m_anti_JumpBaseZ - movementInfo.z;
            if ((plMover->m_anti_JumpBaseZ != 0)
                    && !(movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2))
                    && (JumpHeight < plMover->m_anti_Last_VSpeed))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, GraviJump exception. JumpHeight = %f, Allowed Veritcal Speed = %f",
                                plMover->GetName(), JumpHeight, plMover->m_anti_Last_VSpeed);
                #endif
                check_passed = false;
            }

            //multi jump checks
            if (opcode == MSG_MOVE_JUMP && !plMover->IsInWater())
            {
                if (plMover->m_anti_JustJumped >= 1){
                    check_passed = false; //don't process new jump packet
                } else {
                    plMover->m_anti_JustJumped += 1;
                    plMover->m_anti_JumpBaseZ = movementInfo.z;
                }
            } else if (plMover->IsInWater()) {
                 plMover->m_anti_JustJumped = 0;
            }

            //speed hack checks
            if ((real_delta > allowed_delta)) // && (delta_z < 0))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, speed exception | cDelta=%f aDelta=%f | cSpeed=%f lSpeed=%f deltaTime=%f",
                                plMover->GetName(), real_delta, allowed_delta, current_speed, plMover->m_anti_Last_HSpeed,time_delta);
                #endif
                check_passed = false;
            }
            //teleport hack checks
            if ((real_delta>4900.0f) && !(real_delta < allowed_delta))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, is teleport exception | cDelta=%f aDelta=%f | cSpeed=%f lSpeed=%f deltaToime=%f",
                                plMover->GetName(),real_delta, allowed_delta, current_speed, plMover->m_anti_Last_HSpeed,time_delta);
                #endif
                check_passed = false;
            }

            //mountian hack checks // 1.56f (delta_z < GetPlayer()->m_anti_Last_VSpeed))
            if ((delta_z < plMover->m_anti_Last_VSpeed) && (plMover->m_anti_JustJumped == 0) && (tg_z > 2.37f))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, mountain exception | tg_z=%f", plMover->GetName(),tg_z);
                #endif
                check_passed = false;
            }
            //Fly hack checks
            if (((movementInfo.flags & (MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) != 0)
                  && !plMover->isGameMaster()
                  && !(plMover->HasAuraType(SPELL_AURA_FLY) || plMover->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, flight exception. {SPELL_AURA_FLY=[%X]} {SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED=[%X]} {SPELL_AURA_MOD_SPEED_FLIGHT=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK=[%X]}",
                   plMover->GetName(),
                   plMover->HasAuraType(SPELL_AURA_FLY), plMover->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED),
                   plMover->HasAuraType(SPELL_AURA_MOD_SPEED_FLIGHT), plMover->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS),
                   plMover->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK));
                #endif
                check_passed = false;
            }
            //Water-Walk checks
            if (((movementInfo.flags & MOVEMENTFLAG_WATERWALKING) != 0)
                  && !plMover->isGameMaster()
                  && !(plMover->HasAuraType(SPELL_AURA_WATER_WALK) | plMover->HasAuraType(SPELL_AURA_GHOST)))
            {
                #ifdef MOVEMENT_ANTICHEAT_DEBUG
                sLog.outError("MA-%s, water-walk exception. [%X]{SPELL_AURA_WATER_WALK=[%X]}",
                                plMover->GetName(), movementInfo.flags, plMover->HasAuraType(SPELL_AURA_WATER_WALK));
                #endif
                check_passed = false;
            }
            //Teleport To Plane checks
            if (movementInfo.z < 0.0001f && movementInfo.z > -0.0001f
                && ((movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) == 0)
                && !plMover->isGameMaster())
            {
                // Prevent using TeleportToPlan.
                Map *map = plMover->GetMap();
                if (map){
                    float plane_z = map->GetHeight(movementInfo.x, movementInfo.y, MAX_HEIGHT) - movementInfo.z;
                    plane_z = (plane_z < -500.0f) ? 0 : plane_z; //check holes in heigth map
                    if(plane_z > 0.1f || plane_z < -0.1f)
                    {
                        plMover->m_anti_TeleToPlane_Count++;
                        check_passed = false;
                        #ifdef MOVEMENT_ANTICHEAT_DEBUG
                        sLog.outDebug("MA-%s, teleport to plan exception. plane_z: %f ",
                                        plMover->GetName(), plane_z);
                        #endif
                        if (plMover->m_anti_TeleToPlane_Count > World::GetTeleportToPlaneAlarms())
                        {
                            sLog.outError("MA-%s, teleport to plan exception. Exception count: %d ",
                                            plMover->GetName(), plMover->m_anti_TeleToPlane_Count);
                            plMover->GetSession()->KickPlayer();
                            return;
                        }
                    }
                }
            } else {
                if (plMover->m_anti_TeleToPlane_Count != 0)
                    plMover->m_anti_TeleToPlane_Count = 0;
            }
        } else if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) {
            //antiwrap checks
            if (plMover->m_transport)
            {
                float trans_rad = movementInfo.t_x*movementInfo.t_x + movementInfo.t_y*movementInfo.t_y + movementInfo.t_z*movementInfo.t_z;
                if (trans_rad > 3600.0f){
                    check_passed = false;
                    #ifdef MOVEMENT_ANTICHEAT_DEBUG
                    sLog.outError("MA-%s, leave transport.", plMover->GetName());
                    #endif
                }
            } else {
                if (GameObjectData const* go_data = objmgr.GetGOData(plMover->m_anti_TransportGUID))
                {
                    float delta_gox = go_data->posX - movementInfo.x;
                    float delta_goy = go_data->posY - movementInfo.y;
                    float delta_goz = go_data->posZ - movementInfo.z;
                    int mapid = go_data->mapid;
                    #ifdef MOVEMENT_ANTICHEAT_DEBUG
                    sLog.outDebug("MA-%s, transport movement. GO xyzo: %f,%f,%f",
                                    plMover->GetName(), go_data->posX,go_data->posY,go_data->posZ);
                    #endif
                    if (plMover->GetMapId() != mapid){
                        check_passed = false;
                    } else if (mapid !=369) {
                        float delta_go = delta_gox*delta_gox + delta_goy*delta_goy;
                        if (delta_go > 3600.0f) {
                            check_passed = false;
                            #ifdef MOVEMENT_ANTICHEAT_DEBUG
                            sLog.outError("MA-%s, leave transport. GO xyzo: %f,%f,%f",
                                            plMover->GetName(), go_data->posX,go_data->posY,go_data->posZ);
                            #endif
                        }
                    }

                } else {
                    #ifdef MOVEMENT_ANTICHEAT_DEBUG
                    sLog.outDebug("MA-%s, undefined transport.", plMover->GetName());
                    #endif
                    check_passed = false;
                }
            }
            if (!check_passed){
                if (plMover->m_transport)
                    {
                        plMover->m_transport->RemovePassenger(plMover);
                        plMover->m_transport = NULL;
                    }
                    movementInfo.t_x = 0.0f;
                    movementInfo.t_y = 0.0f;
                    movementInfo.t_z = 0.0f;
                    movementInfo.t_o = 0.0f;
                    movementInfo.t_time = 0;
                    plMover->m_anti_TransportGUID = 0;
            }
        }
    }
    /* process position-change */
    if (check_passed)
    {
    recv_data.put<uint32>(6, getMSTime());                  // fix time, offset flags(4) + unk(2)
    WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
    data.append(mover->GetPackGUID());                      // use mover guid
    data.append(recv_data.contents(), recv_data.size());
    GetPlayer()->SendMessageToSet(&data, false);

    if(plMover)                                             // nothing is charmed, or player charmed
    {
        plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
        plMover->m_movementInfo = movementInfo;
        plMover->UpdateFallInformationIfNeed(movementInfo, recv_data.GetOpcode());

        if(plMover->isMovingOrTurning())
            plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

        if(movementInfo.z < -500.0f)
        {
            if(plMover->InBattleGround()
                && plMover->GetBattleGround()
                && plMover->GetBattleGround()->HandlePlayerUnderMap(_player))
            {
                // do nothing, the handle already did if returned true
            }
            else
            {
                // NOTE: this is actually called many times while falling
                // even after the player has been teleported away
                // TODO: discard movement packets after the player is rooted
                if(plMover->isAlive())
                {
                    plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
                    // pl can be alive if GM/etc
                    if(!plMover->isAlive())
                    {
                        // change the death state to CORPSE to prevent the death timer from
                        // starting in the next player update
                        plMover->KillPlayer();
                        plMover->BuildPlayerRepop();
                    }
                }

                // cancel the death timer here if started
                plMover->RepopAtGraveyard();
            }
        }
        //movement anticheat >>>
        if (plMover->m_anti_AlarmCount > 0){
            sLog.outError("MA-%s produce %d anticheat alarms",plMover->GetName(),plMover->m_anti_AlarmCount);
            plMover->m_anti_AlarmCount = 0;
        }
    // end movement anticheat
    }
    else                                                    // creature charmed
    {
        if(mover->IsInWorld())
            mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
    }
    
    } else if (plMover) {
        plMover->m_anti_AlarmCount++;
        WorldPacket data;
        plMover->m_movementInfo.SetMovementFlags(MovementFlags(MOVEMENTFLAG_NONE));
        plMover->BuildTeleportAckMsg(&data, plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), plMover->GetOrientation());
        plMover->GetSession()->SendPacket(&data);
        plMover->BuildHeartBeatMsg(&data);
        plMover->SendMessageToSet(&data, true);
    }
}
コード例 #6
0
ファイル: GOMove.cpp プロジェクト: Kretol/TrinityCore
    static bool GOMove_Command(ChatHandler* handler, const char* args)
    {
        if (!args)
            return false;

        char* ID_t = strtok((char*)args, " ");
        if (!ID_t)
            return false;
        uint32 ID = (uint32)atol(ID_t);

        char* GObjectID_C = strtok(NULL, " ");
        uint32 GObjectID = 0;
        bool isHex = false;
        if (GObjectID_C)
        {
            GObjectID = strtoul(GObjectID_C, NULL, 0); // can take in hex as well as dec
            isHex = (std::string(GObjectID_C).find("0x") != std::string::npos);
        }

        char* ARG_t = strtok(NULL, " ");
        uint32 ARG = 0;
        if (ARG_t)
            ARG = (uint32)atol(ARG_t);

        WorldSession* session = handler->GetSession();
        Player* player = session->GetPlayer();
        uint64 playerGUID = player->GetGUID();

        if (ID < SPAWN) // no args
        {
            if (ID >= DELET && ID <= GOTO) // has target (needs retrieve gameobject)
            {
                GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex);
                if (!target)
                    ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temp(%u)", GObjectID, isHex ? 1 : 0);
                else
                {
                    float x,y,z,o;
                    target->GetPosition(x,y,z,o);
                    uint32 p = target->GetPhaseMask();
                    switch(ID)
                    {
                    case DELET: DeleteObject(target/*, isHex ? GObjectID : 0*/); SendSelectionInfo(player, GObjectID, isHex, false); break;
                    case X: SpawnObject(player,player->GetPositionX(),y,z,o,p,true,GObjectID, isHex);      break;
                    case Y: SpawnObject(player,x,player->GetPositionY(),z,o,p,true,GObjectID, isHex);      break;
                    case Z: SpawnObject(player,x,y,player->GetPositionZ(),o,p,true,GObjectID, isHex);      break;
                    case O: SpawnObject(player,x,y,z,player->GetOrientation(),p,true,GObjectID, isHex);    break;
                    case GOTO: player->TeleportTo(target->GetMapId(), x,y,z,o);                     break;
                    case RESPAWN: SpawnObject(player,x,y,z,o,p,false,target->GetEntry(), isHex);           break;
                    case GROUND:
                        {
                            float ground = target->GetMap()->GetHeight(target->GetPhaseMask(), x, y, MAX_HEIGHT);
                            if(ground != INVALID_HEIGHT)
                                SpawnObject(player,x,y,ground,o,p,true,GObjectID, isHex);
                        } break;
                    }
                }
            }
            else
            {
                switch(ID)
                {
                case TEST: session->SendAreaTriggerMessage(player->GetName().c_str());      break;
                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;
                case SAVE: SaveObject(player, GObjectID, isHex);                                   break;
                case SELECTNEAR:
                    {
                        GameObject* object = handler->GetNearbyGameObject();
                        object = GetClosestGObjectID(player, object);
                        if (!object)
                            ChatHandler(player->GetSession()).PSendSysMessage("No objects found");
                        else
                        {
                            bool isHex = (object->GetGUIDHigh() != HIGHGUID_GAMEOBJECT);
                            SendSelectionInfo(player, isHex ? object->GetGUIDHigh() : object->GetDBTableGUIDLow() ? object->GetDBTableGUIDLow() : object->GetGUIDLow(), isHex, true);
                            session->SendAreaTriggerMessage("Selected %s", object->GetName().c_str());
                        }
                    } break;
                }
            }
        }
        else if (ARG && ID >= SPAWN)
        {
            if (ID >= NORTH && ID <= PHASE)
            {
                GameObject* target = GetObjectByGObjectID(player, GObjectID, isHex);
                if (!target)
                    ChatHandler(player->GetSession()).PSendSysMessage("Object GUID: %u not found. Temporary: %s", GObjectID, isHex ? "true" : "false");
                else
                {
                    float x,y,z,o;
                    target->GetPosition(x,y,z,o);
                    uint32 p = target->GetPhaseMask();
                    switch(ID)
                    {
                    case NORTH: SpawnObject(player,x+((float)ARG/100),y,z,o,p,true,GObjectID, isHex);                        break;
                    case EAST: SpawnObject(player,x,y-((float)ARG/100),z,o,p,true,GObjectID, isHex);                         break;
                    case SOUTH: SpawnObject(player,x-((float)ARG/100),y,z,o,p,true,GObjectID, isHex);                        break;
                    case WEST: SpawnObject(player,x,y+((float)ARG/100),z,o,p,true,GObjectID, isHex);                         break;
                    case NORTHEAST: SpawnObject(player,x+((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case SOUTHEAST: SpawnObject(player,x-((float)ARG/100),y-((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case SOUTHWEST: SpawnObject(player,x-((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case NORTHWEST: SpawnObject(player,x+((float)ARG/100),y+((float)ARG/100),z,o,p,true,GObjectID, isHex);   break;
                    case UP: SpawnObject(player,x,y,z+((float)ARG/100),o,p,true,GObjectID, isHex);                           break;
                    case DOWN: SpawnObject(player,x,y,z-((float)ARG/100),o,p,true,GObjectID, isHex);                         break;
                    case RIGHT: SpawnObject(player,x,y,z,o-((float)ARG/100),p,true,GObjectID, isHex);                        break;
                    case LEFT: SpawnObject(player,x,y,z,o+((float)ARG/100),p,true,GObjectID, isHex);                         break;
                    case PHASE: SpawnObject(player,x,y,z,o,ARG,true,GObjectID, isHex);                                       break;
                    }
                }
            }
            else
            {
                switch(ID)
                {
                case SPAWN:
                    {
                        if (SpawnObject(player, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),  player->GetOrientation(), player->GetPhaseMaskForSpawn(), false, ARG, false, true))
                            SpawnQue[player->GetGUID()] = ARG;
                    } break;
                case SPAWNSPELL:
                    {
                        SpawnQue[player->GetGUID()] = ARG;
                    } break;
                case SELECTALLNEAR:
                    { 
                        if (ARG > 5000)
                            ARG = 5000;

                        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",
                            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);

                        if (result)
                        {
                            do
                            {
                                Field* fields   = result->Fetch();
                                uint32 guidLow  = fields[0].GetUInt32();

                                if (GameObject* object = GetObjectByGObjectID(player, guidLow, false))
                                    SendSelectionInfo(player, guidLow, false, true);
                            }
                            while (result->NextRow());
                        }
                        for(std::set<uint32>::const_iterator it = GObjects.begin(); it != GObjects.end();)
                        {
                            GameObject* temp = player->GetGameObject(*it);
                            if(!temp)
                            {
                                GObjects.erase(*it++);
                                continue;
                            }
                            if(temp->IsWithinDistInMap(player, ARG))
                                SendSelectionInfo(player, (*it), true, true);
                            ++it;
                        }
                    } break;
                }
            }
        }
        else
            return false;
        return true;
    }
コード例 #7
0
ファイル: SpellHandler.cpp プロジェクト: Artea/mangos-svn
void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
{
    CHECK_PACKET_SIZE(recv_data,8);

    uint64 guid;
    uint32 spellId = OPEN_CHEST;
    const GameObjectInfo *info;

    recv_data >> guid;

    sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", guid);
    GameObject *obj = ObjectAccessor::GetGameObject(*_player, guid);

    if(!obj) return;
    //obj->SetUInt32Value(GAMEOBJECT_FLAGS,2);
    //obj->SetUInt32Value(GAMEOBJECT_FLAGS,2);

    // default spell caster is player that use GO
    Unit* spellCaster = GetPlayer();
    // default spell target is player that use GO
    Unit* spellTarget = GetPlayer();

    if (Script->GOHello(_player, obj))
        return;

    switch(obj->GetGoType())
    {
        case GAMEOBJECT_TYPE_DOOR:                          //0
            obj->SetUInt32Value(GAMEOBJECT_FLAGS,33);
            obj->SetUInt32Value(GAMEOBJECT_STATE,0);        //open
            //obj->SetUInt32Value(GAMEOBJECT_TIMESTAMP,0x465EE6D2); //load timestamp

            obj->SetLootState(GO_CLOSED);
            obj->SetRespawnTime(5);                         //close door in 5 seconds
            return;

        case GAMEOBJECT_TYPE_BUTTON:                        //1
            obj->SetUInt32Value(GAMEOBJECT_FLAGS,33);
            obj->SetUInt32Value(GAMEOBJECT_STATE,0);        //open
            obj->SetLootState(GO_CLOSED);
            obj->SetRespawnTime(2);                         //close in 1 seconds

            // activate script
            sWorld.ScriptsStart(sButtonScripts, obj->GetDBTableGUIDLow(), spellCaster, obj);
            return;

        case GAMEOBJECT_TYPE_QUESTGIVER:                    //2
            _player->PrepareQuestMenu( guid );
            _player->SendPreparedQuest( guid );
            return;

        //Sitting: Wooden bench, chairs enzz
        case GAMEOBJECT_TYPE_CHAIR:                         //7

            info = obj->GetGOInfo();
            if(info)
            {
                //spellId = info->data0;                   // this is not a spell or offset
                _player->TeleportTo(obj->GetMapId(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),false,false);
                _player->SetFlag(UNIT_FIELD_BYTES_1,PLAYER_STATE_SIT_LOW_CHAIR); // Using (3 + spellId) was wrong, this is a number of slot for chair/bench, not offset
                _player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR);
                return;
            }
            break;

        //big gun, its a spell/aura
        case GAMEOBJECT_TYPE_GOOBER:                        //10
            info = obj->GetGOInfo();
            spellId = info ? info->data10 : 0;
            break;

        case GAMEOBJECT_TYPE_SPELLCASTER:                   //22

            obj->SetUInt32Value(GAMEOBJECT_FLAGS,2);

            info = obj->GetGOInfo();
            if(info)
            {
                spellId = info->data0;
                if (spellId == 0)
                    spellId = info->data3;

                //guid=_player->GetGUID();
            }

            break;
        case GAMEOBJECT_TYPE_CAMERA:                        //13
            info = obj->GetGOInfo();
            if(info)
            {
                uint32 cinematic_id = info->data1;
                if(cinematic_id)
                {
                    WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4);
                    data << cinematic_id;
                    _player->GetSession()->SendPacket(&data);
                }
                return;
            }
            break;

        //fishing bobber
        case GAMEOBJECT_TYPE_FISHINGNODE:                   //17
        {
            if(_player->GetGUID() != obj->GetOwnerGUID())
                return;

            switch(obj->getLootState())
            {
                case GO_CLOSED:                             // ready for loot
                {
                    // 1) skill must be >= base_zone_skill
                    // 2) if skill == base_zone_skill => 5% chance
                    // 3) chance is linear dependence from (base_zone_skill-skill)

                    int32 skill = _player->GetSkillValue(SKILL_FISHING);
                    int32 zone_skill = _player->FishingMinSkillForCurrentZone();
                    int32 chance = skill - zone_skill + 5;
                    int32 roll = irand(1,100);

                    DEBUG_LOG("Fishing check (skill: %i zone min skill: %i chance %i roll: %i",skill,zone_skill,chance,roll);

                    if(skill >= zone_skill && chance >= roll)
                    {
                        // prevent removing GO at spell cancel
                        _player->RemoveGameObject(obj,false);
                        obj->SetOwnerGUID(_player->GetGUID());

                        //fish catched
                        _player->UpdateFishingSkill();
                        _player->SendLoot(obj->GetGUID(),LOOT_FISHING);
                    }
                    else
                    {
                        // fish escaped
                        obj->SetLootState(GO_LOOTED);       // can be deleted now

                        WorldPacket data(SMSG_FISH_ESCAPED, 0);
                        SendPacket(&data);
                    }
                    break;
                }
                case GO_LOOTED:                             // nothing to do, will be deleted at next update
                    break;
                default:
                {
                    obj->SetLootState(GO_LOOTED);

                    WorldPacket data(SMSG_FISH_NOT_HOOKED, 0);
                    SendPacket(&data);
                    break;
                }
            }

            if(_player->m_currentSpells[CURRENT_CHANNELED_SPELL])
            {
                _player->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0);
                _player->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish();
            }
            return;
        }

        case GAMEOBJECT_TYPE_SUMMONING_RITUAL:
        {
            Unit* caster = obj->GetOwner();

            info = obj->GetGOInfo();

            if( !caster || caster->GetTypeId()!=TYPEID_PLAYER )
                return;

            // accept only use by player from same group for caster except caster itself
            if(((Player*)caster)==GetPlayer() || !((Player*)caster)->IsInSameGroupWith(GetPlayer()))
                return;

            obj->AddUse(GetPlayer());

            // must 2 group members use GO, or only 1 when it is meeting stone summon
            if(obj->GetUniqueUseCount() < (info->data0 == 2 ? 1 : 2))
                return;

            // in case summoning ritual caster is GO creator
            spellCaster = caster;

            if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL])
                return;

            spellId = info->data1;

            // finish spell
            caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0);
            caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish();

            // can be deleted now
            obj->SetLootState(GO_LOOTED);

            // go to end function to spell casting
            break;
        }
        case GAMEOBJECT_TYPE_MEETINGSTONE:                  //23
        {
            info = obj->GetGOInfo();

            Player* targetPlayer = ObjectAccessor::FindPlayer(((Player*)spellCaster)->GetSelection());

            // accept only use by player from same group for caster except caster itself
            if(!targetPlayer || targetPlayer == GetPlayer() || !targetPlayer->IsInSameGroupWith(GetPlayer()))
                return;

            //required lvl checks!
            uint8 level = _player->getLevel();
            if (level < info->data0 || level > info->data1)
                return;
            level = targetPlayer->getLevel();
            if (level < info->data0 || level > info->data1)
                return;

            spellId = 23598;

            break;
        }

        case GAMEOBJECT_TYPE_FLAGSTAND:                     // 24
            if(_player->InBattleGround() &&                 // in battleground
                !_player->IsMounted() &&                    // not mounted
                !_player->HasStealthAura() &&               // not stealthed
                !_player->HasInvisibilityAura() &&          // not invisible
                _player->isAlive())                         // live player
            {
                BattleGround *bg = _player->GetBattleGround();
                if(!bg)
                    return;
                // BG flag click
                // AB:
                // 15001
                // 15002
                // 15003
                // 15004
                // 15005
                // WS:
                // 179830 - Silverwing Flag
                // 179831 - Warsong Flag
                // EotS:
                // 184141 - Netherstorm Flag
                info = obj->GetGOInfo();
                if(info)
                {
                    switch(info->id)
                    {
                        case 179830:
                            // check if it's correct bg
                            if(bg->GetTypeID() != BATTLEGROUND_WS)
                                return;
                            // check if flag dropped
                            if(((BattleGroundWS*)bg)->GetFlagState(ALLIANCE) != BG_WS_FLAG_STATE_ON_BASE)
                                return;
                            // check if it's correct flag
                            if(((BattleGroundWS*)bg)->m_bgobjects[BG_WS_OBJECT_A_FLAG] != obj->GetGUID())
                                return;
                            // check player team
                            if(_player->GetTeam() == ALLIANCE)
                                return;
                            spellId = 23335;                // Silverwing Flag
                            break;
                        case 179831:
                            // check if it's correct bg
                            if(bg->GetTypeID() != BATTLEGROUND_WS)
                                return;
                            // check if flag dropped
                            if(((BattleGroundWS*)bg)->GetFlagState(HORDE) != BG_WS_FLAG_STATE_ON_BASE)
                                return;
                            // check if it's correct flag
                            if(((BattleGroundWS*)bg)->m_bgobjects[BG_WS_OBJECT_H_FLAG] != obj->GetGUID())
                                return;
                            // check player team
                            if(_player->GetTeam() == HORDE)
                                return;
                            spellId = 23333;                // Warsong Flag
                            break;
                        case 184141:
                            // check if it's correct bg
                            if(bg->GetTypeID() != BATTLEGROUND_EY)
                                return;
                            spellId = 34976;                // Netherstorm Flag
                            break;
                    }
                }
            }
            break;
        case GAMEOBJECT_TYPE_FLAGDROP:                      // 26
            if(_player->InBattleGround() &&                 // in battleground
                !_player->IsMounted() &&                    // not mounted
                !_player->HasStealthAura() &&               // not stealthed
                !_player->HasInvisibilityAura() &&          // not invisible
                _player->isAlive())                         // live player
            {
                BattleGround *bg = _player->GetBattleGround();
                if(!bg)
                    return;
                // BG flag dropped
                // WS:
                // 179785 - Silverwing Flag
                // 179786 - Warsong Flag
                // EotS:
                // 184142 - Netherstorm Flag
                info = obj->GetGOInfo();
                if(info)
                {
                    switch(info->id)
                    {
                        case 179785:                        // Silverwing Flag
                            // check if it's correct bg
                            if(bg->GetTypeID() != BATTLEGROUND_WS)
                                return;
                            // check if flag dropped
                            if(((BattleGroundWS*)bg)->GetFlagState(ALLIANCE) != BG_WS_FLAG_STATE_ON_GROUND)
                                return;
                            obj->Delete();
                            if(_player->GetTeam() == ALLIANCE)
                            {
                                ((BattleGroundWS*)bg)->EventPlayerReturnedFlag(_player);
                                return;
                            }
                            else
                            {
                                _player->CastSpell(_player, 23335, true);
                                return;
                            }
                            break;
                        case 179786:                        // Warsong Flag
                            // check if it's correct bg
                            if(bg->GetTypeID() != BATTLEGROUND_WS)
                                return;
                            // check if flag dropped
                            if(((BattleGroundWS*)bg)->GetFlagState(HORDE) != BG_WS_FLAG_STATE_ON_GROUND)
                                return;
                            obj->Delete();
                            if(_player->GetTeam() == HORDE)
                            {
                                ((BattleGroundWS*)bg)->EventPlayerReturnedFlag(_player);
                                return;
                            }
                            else
                            {
                                _player->CastSpell(_player, 23333, true);
                                return;
                            }
                            break;
                    }
                }
                obj->Delete();
            }
            break;
        default:
            sLog.outDebug("Unknown Object Type %u\n", obj->GetGoType());
            break;
    }

    if (!spellId) return;

    SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId );
    if(!spellInfo)
    {
        sLog.outError("WORLD: unknown spell id %u\n", spellId);
        return;
    }

    Spell *spell = new Spell(spellCaster, spellInfo, false, 0);

    SpellCastTargets targets;
    targets.setUnitTarget( spellTarget );

    if(obj)
        targets.setGOTarget( obj );

    spell->prepare(&targets);
}