コード例 #1
0
ファイル: MapInstanced.cpp プロジェクト: Choices/mangos
/// returns a new or existing Instance
/// in case of battlegrounds it will only return an existing map, those maps are created by bg-system
Map* MapInstanced::CreateInstance(Player * player)
{
    Map* map;
    uint32 NewInstanceId;                                   // instanceId of the resulting map

    if(IsBattleGroundOrArena())
    {
        // find existing bg map for player
        NewInstanceId = player->GetBattleGroundId();
        MANGOS_ASSERT(NewInstanceId);
        map = _FindMap(NewInstanceId);
        MANGOS_ASSERT(map);
    }
    else if (InstanceSave* pSave = player->GetBoundInstanceSaveForSelfOrGroup(GetId()))
    {
        // solo/perm/group
        NewInstanceId = pSave->GetInstanceId();
        map = _FindMap(NewInstanceId);
        // it is possible that the save exists but the map doesn't
        if (!map)
            map = CreateInstanceMap(NewInstanceId, pSave->GetDifficulty(), pSave);
    }
    else
    {
        // if no instanceId via group members or instance saves is found
        // the instance will be created for the first time
        NewInstanceId = sObjectMgr.GenerateLowGuid(HIGHGUID_INSTANCE);

        Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid());
        map = CreateInstanceMap(NewInstanceId, diff);
    }

    return map;
}
コード例 #2
0
ファイル: MapInstanced.cpp プロジェクト: Finest/MMOCore
/*
- return the right instance for the object, based on its InstanceId
- create the instance if it's not created already
- the player is not actually added to the instance (only in InstanceMap::Add)
*/
Map* MapInstanced::CreateInstance(const uint32 mapId, Player* player)
{
    if (GetId() != mapId || !player)
        return NULL;

    Map* map = NULL;
    uint32 NewInstanceId = 0;                       // instanceId of the resulting map

    if (IsBattlegroundOrArena())
    {
        // instantiate or find existing bg map for player
        // the instance id is set in battlegroundid
        NewInstanceId = player->GetBattlegroundId();
        if (!NewInstanceId) return NULL;
        map = _FindMap(NewInstanceId);
        if (!map)
            if (Battleground* NewBattleground = player->GetBattleground())
                map = CreateBattleground(NewInstanceId, NewBattleground);
    }
    else
    {
        InstancePlayerBind* pBind = player->GetBoundInstance(GetId(), player->GetDifficulty(IsRaid()));
        InstanceSave* pSave = pBind ? pBind->save : NULL;

        // the player's permanent player bind is taken into consideration first
        // then the player's group bind and finally the solo bind.
        if (!pBind || !pBind->perm)
        {
            InstanceGroupBind* groupBind = NULL;
            Group* group = player->GetGroup();
            // use the player's difficulty setting (it may not be the same as the group's)
            if (group)
            {
                groupBind = group->GetBoundInstance(this);
                if (groupBind)
                    pSave = groupBind->save;
            }
        }
        if (pSave)
        {
            // solo/perm/group
            NewInstanceId = pSave->GetInstanceId();
            map = _FindMap(NewInstanceId);
            // it is possible that the save exists but the map doesn't
            if (!map)
                map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty());
        }
        else
        {
            // if no instanceId via group members or instance saves is found
            // the instance will be created for the first time
            NewInstanceId = sMapMgr->GenerateInstanceId();

            Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid());
            map = CreateInstance(NewInstanceId, NULL, diff);
        }
    }

    return map;
}
コード例 #3
0
ファイル: MapInstanced.cpp プロジェクト: Artea/mangos-svn
bool MapInstanced::IsValidInstance(uint32 InstanceId)
{
    // verify, if the map exists and needs to be reset
    Map* m = _FindMap(InstanceId);

    if (m && m->NeedsReset())
    {
        // check for real reset need (can only reset if no players)
        if (!m->HavePlayers())
            return false;                                   // map exists, but needs reset
        // shift reset time of the map to a bit later
        m->InitResetTime();
    }

    // verify, if the map theoretically exists but not loaded
    QueryResult* result = CharacterDatabase.PQuery("SELECT '1' FROM instance WHERE (id = '%u') AND (map = '%u') AND (resettime > " I64FMTD ")", InstanceId, GetId(), (uint64)time(NULL));
    if (result)
    {
        delete result;
        return(true);
    }

    // no map exists at all
    return(false);
}
コード例 #4
0
ファイル: MapInstanced.cpp プロジェクト: TrueWoW/TrinityCore
/*
- return the right instance for the object, based on its InstanceId
- create the instance if it's not created already
- the player is not actually added to the instance (only in InstanceMap::Add)
*/
Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player)
{
    if (GetId() != mapId || !player)
        return NULL;

    Map* map = NULL;
    uint32 newInstanceId = 0;                       // instanceId of the resulting map

    if (IsBattlegroundOrArena())
    {
        // instantiate or find existing bg map for player
        // the instance id is set in battlegroundid
        newInstanceId = player->GetBattlegroundId();
        if (!newInstanceId)
            return NULL;

        map = _FindMap(newInstanceId);
        if (!map)
            map = CreateBattleground(NewInstanceId, player->GetBattleground());
            if (Battleground* bg = player->GetBattleground())
                map = CreateBattleground(newInstanceId, bg);
            else
            {
                player->TeleportToBGEntryPoint();
                return NULL;
            }
        }
    }
コード例 #5
0
ファイル: MapInstanced.cpp プロジェクト: Artea/mangos-svn
Map* MapInstanced::GetInstance(const WorldObject* obj)
{
    uint32 InstanceId = obj->GetInstanceId();
    Map* map = NULL;

    if (InstanceId != 0) map = _FindMap(InstanceId);

                                                            // return map for non-player objects
    if (map && obj->GetTypeId() != TYPEID_PLAYER) return(map);

    if (obj->GetTypeId() != TYPEID_PLAYER)
    {
        sLog.outDebug("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) is requesting instance '%u' of map '%u', instantiating", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), InstanceId, GetId());

        if (InstanceId == 0)
        {
            sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) requested base map instance of map '%u', this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), GetId());
            return(this);
        }

        // short instantiate process for world object
        CreateInstance(InstanceId, map);
        return(map);
    }

    // here we do additionally verify, if the player is allowed in instance by leader
    // and if it has current instance bound correctly
    Player* player = (Player*)obj;

    // reset instance validation flag
    player->m_InstanceValid = true;

    BoundInstancesMap::iterator i = player->m_BoundInstances.find(GetId());
    if (i != player->m_BoundInstances.end())
    {
        // well, we have an instance bound, really, verify self or group leader
        if (!((player->GetGUIDLow() == i->second.second) ||
            (player->GetGroup() &&
            (GUID_LOPART(player->GetGroup()->GetLeaderGUID()) == i->second.second))))
        {
            // well, we are bound to instance, but are not a leader and are not in the correct group
            // we must not rebind us or the instantiator (which can surely be the same)
            // will remain bound if accepted into group or will be unbound, if we go to homebind
            InstanceId = i->second.first;                   // restore the instance bound
            player->m_InstanceValid = false;                // player instance is invalid
            if (InstanceId != 0) map = _FindMap(InstanceId);// restore the map bound
        }
    }
    else
    {
        // the player has no map bindings, we can proceed safely creating a new one
        map = NULL;
    }

    if (map) return(map);                                   // here we go, the map is found and we are correctly bound

    Player* instantiator = NULL;
    uint32 instantiator_id = 0;
    bool instantiator_online = true;
    bool instantiator_bound = false;

    // we do need to scan for the instantiator, if the instance we scan for is valid, not temporary
    if (player->m_InstanceValid)
    {
        // either we are not bound to the instance, or we have to create new instance, do it
        InstanceId = 0;

        // determine the instantiator which designates the instance id
        if (player->GetGroup())
        {
            // instantiate map for group leader (possibly got from the database)
            sLog.outDebug("MAPINSTANCED: Player '%s' is in group, instantiating map for group leader", player->GetName());
            instantiator = objmgr.GetPlayer(player->GetGroup()->GetLeaderGUID());
            if (!instantiator)
            {
                // the very special case: leader is not online, read instance map from DB
                instantiator_online = false;
            }
        }

        if (!instantiator && instantiator_online)
        {
            sLog.outDebug("MAPINSTANCED: Player '%s' is not in group, instantiating map for player", player->GetName());
            instantiator = player;
        }

        // now, get the real instance id from the instantiator
        if (instantiator_online)
        {
            // player online, normal instantianting
            sLog.outDebug("MAPINSTANCED: Instantiating map for player '%s' (group leader '%s')", player->GetName(), instantiator->GetName());
            instantiator_id = instantiator->GetGUIDLow();
            BoundInstancesMap::iterator i = instantiator->m_BoundInstances.find(GetId());
            if (i != instantiator->m_BoundInstances.end())
            {
                // the instantiator has his instance bound
                InstanceId = i->second.first;
                // this check is to avoid the case where remote instantiator has his instance
                // bound to another remote instantiator (e.g. exited from group recently)
                // if that is the case, the instance for him will be regenerated and rebound
                if ((instantiator == player) || (i->second.second == instantiator_id))
                {
                    // player is instantiator or instantiator has his instance bound to himself
                    instantiator_bound = true;
                }
            }
        }
        else
        {
            // the aforementioned "very special" case of leader being not online
            sLog.outDebug("MAPINSTANCED: Instantiating map for player '%s' (group leader is not online, querying DB)", player->GetName());
            instantiator_id = GUID_LOPART(player->GetGroup()->GetLeaderGUID());
            QueryResult* result = CharacterDatabase.PQuery("SELECT instance FROM character_instance WHERE (guid = '%u') AND (map = '%u') AND (leader = '%u')", instantiator_id, GetId(), instantiator_id);
            if (result)
            {
                // the instantiator has his instance bound
                InstanceId = result->Fetch()[0].GetUInt32();
                instantiator_bound = true;
                delete result;
            }
        }

        // check, if we have to generate new instance
        if (!instantiator_bound || (InstanceId == 0))
        {
            // yes, new instance id has to be generated
            InstanceId = MapManager::Instance().GenerateInstanceId();
        }
        else
        {
            // find map of the designated instance and verify it
            map = _FindMap(InstanceId);
        }
    }

    // now create the instance
    CreateInstance(InstanceId, map);

    // we do need to bind instance, if the instance we use is valid, not temporary
    if (player->m_InstanceValid)
    {
        // bind instance to instantiator (only if needed)
        if (!instantiator_bound)
        {
            CharacterDatabase.BeginTransaction();
            if (instantiator_online)
            {
                // player online, normal bind
                instantiator->m_BoundInstances[GetId()] = std::pair< uint32, uint32 >(InstanceId, instantiator_id);
                CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", instantiator_id, GetId());
                CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", instantiator_id, GetId(), InstanceId, instantiator_id);
            }
            else
            {
                // the aforementioned "very special" case of leader being not online
                CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", GUID_LOPART(player->GetGroup()->GetLeaderGUID()), GetId());
                CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(player->GetGroup()->GetLeaderGUID()), GetId(), InstanceId, GUID_LOPART(player->GetGroup()->GetLeaderGUID()));
            }
            CharacterDatabase.CommitTransaction();
        }

        // bind instance to player (avoid duplicate binding)
        if (instantiator != player)
        {
            CharacterDatabase.BeginTransaction();
            if (instantiator_online)
            {
                player->m_BoundInstances[GetId()] = std::pair< uint32, uint32 >(InstanceId, instantiator_id);
                CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", player->GetGUIDLow(), GetId());
                CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", player->GetGUIDLow(), GetId(), InstanceId, instantiator_id);
            }
            else
            {
                // the aforementioned "very special" case of leader being not online
                player->m_BoundInstances[GetId()] = std::pair< uint32, uint32 >(InstanceId, GUID_LOPART(player->GetGroup()->GetLeaderGUID()));
                CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", player->GetGUIDLow(), GetId());
                CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", player->GetGUIDLow(), GetId(), InstanceId, GUID_LOPART(player->GetGroup()->GetLeaderGUID()));
            }
            CharacterDatabase.CommitTransaction();
        }
    }

    // set instance id for instantiating player
    if (player->GetPet()) player->GetPet()->SetInstanceId(InstanceId);
    player->SetInstanceId(InstanceId);

    return(map);
}
コード例 #6
0
ファイル: MapInstanced.cpp プロジェクト: yunishaa/mangos-112
/*
- return the right instance for the object, based on its InstanceId
- create the instance if it's not created already
- the player is not actually added to the instance (only in InstanceMap::Add)
*/
Map* MapInstanced::GetInstance(const WorldObject* obj)
{
    uint32 CurInstanceId = obj->GetInstanceId();
    Map* map = NULL;

    if (obj->GetMapId() == GetId() && CurInstanceId != 0)
    {
        // the object wants to be put in a certain instance of this map
        map = _FindMap(CurInstanceId);
        if(!map)
        {
            // For players if the instanceId is set, it's assumed they are already in a map,
            // hence the map must be loaded. For Creatures, GameObjects etc the map must exist
            // prior to calling GetMap, they are not allowed to create maps for themselves.
            sLog.outError("GetInstance: object %s(%d), typeId %d, in world %d, should be in map %d,%d but that's not loaded yet.", obj->GetName(), obj->GetGUIDLow(), obj->GetTypeId(), obj->IsInWorld(), obj->GetMapId(), obj->GetInstanceId());
            assert(false);
        }
        return(map);
    }
    else
    {
        // instance not specified, find an existing or create a new one
        if(obj->GetTypeId() != TYPEID_PLAYER)
        {
            sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u TypeID: %u) is in map %d,%d and requested base map instance of map %d, this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), obj->GetMapId(), obj->GetInstanceId(), GetId());
            assert(false);
            return NULL;
        }
        else
        {
            uint32 NewInstanceId = 0;                       // instanceId of the resulting map
            Player* player = (Player*)obj;

            // TODO: battlegrounds and arenas

            InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty());
            InstanceSave *pSave = pBind ? pBind->save : NULL;

            // the player's permanet player bind is taken into consideration first
            // then the player's group bind and finally the solo bind.
            if(!pBind || !pBind->perm)
            {
                InstanceGroupBind *groupBind = NULL;
                Group *group = player->GetGroup();
                // use the player's difficulty setting (it may not be the same as the group's)
                if(group && (groupBind = group->GetBoundInstance(GetId(), player->GetDifficulty())))
                    pSave = groupBind->save;
            }

            if(pSave)
            {
                // solo/perm/group
                NewInstanceId = pSave->GetInstanceId();
                map = _FindMap(NewInstanceId);
                // it is possible that the save exists but the map doesn't
                if(!map)
                    map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty());
                return map;
            }
            else
            {
                // if no instanceId via group members or instance saves is found
                // the instance will be created for the first time
                NewInstanceId = MapManager::Instance().GenerateInstanceId();
                return CreateInstance(NewInstanceId, NULL, player->GetDifficulty());
            }
        }
    }
}
コード例 #7
0
ファイル: MapInstanced.cpp プロジェクト: Trizzor/uecore
/*
- return the right instance for the object, based on its InstanceId
- create the instance if it's not created already
- the player is not actually added to the instance (only in InstanceMap::Add)
*/
Map* MapInstanced::GetInstance(const WorldObject* obj)
{
    uint32 CurInstanceId = obj->GetInstanceId();
    Map* map = NULL;

    if (obj->GetMapId() == GetId() && CurInstanceId != 0)
    {
        // the object wants to be put in a certain instance of this map
        map = _FindMap(CurInstanceId);
        if(!map)
        {
            // For players if the instanceId is set, it's assumed they are already in a map,
            // hence the map must be loaded. For Creatures, GameObjects etc the map must exist
            // prior to calling GetMap, they are not allowed to create maps for themselves.
            sLog.outError("GetInstance: object %s(%d), typeId %d, in world %d, should be in map %d,%d but that's not loaded yet.", obj->GetName(), obj->GetGUIDLow(), obj->GetTypeId(), obj->IsInWorld(), obj->GetMapId(), obj->GetInstanceId());
            assert(false);
        }
        return(map);
    }
    else
    {
        // instance not specified, find an existing or create a new one
        if(obj->GetTypeId() != TYPEID_PLAYER)
        {
            sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u TypeID: %u) is in map %d,%d and requested base map instance of map %d, this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), obj->GetMapId(), obj->GetInstanceId(), GetId());
            assert(false);
            return NULL;
        }
        else
        {
            uint32 NewInstanceId = 0;                       // instanceId of the resulting map
            Player* player = (Player*)obj;

            if(IsBattleGroundOrArena())
            {
                // instantiate or find existing bg map for player
                // the instance id is set in battlegroundid
                NewInstanceId = player->GetBattleGroundId();
                if(!NewInstanceId)
                {
                    if(player->GetSession()->PlayerLoading())
                        return NULL;
                    else
                        assert(NewInstanceId);
                }
                map = _FindMap(NewInstanceId);
                if(!map)
                {
                    map = CreateBattleGround(NewInstanceId);
                    ((BattleGroundMap*)map)->SetBG(player->GetBattleGround());
                }
                if(!((BattleGroundMap*)map)->GetBG())
                {
                    sLog.outError("The bg-class couldn't be assigned (very early) to the battlegroundmap, it's possible, that some db-spawned creatures are now not handled right this is related to battleground alterac valley (av) - please post bugreport, and add information how this bg was created (if you don't have information, report it also) Player: %s (%u) in map:%u requested map:%u", player->GetName(), player->GetGUIDLow(), player->GetMapId(), GetId());
                    if(player->GetBattleGround())
                    {
                        sLog.outError("somehow the battleground was found, but please report also - i end this bg now..");
                        ((BattleGroundMap*)map)->SetBG(player->GetBattleGround());
                        player->GetBattleGround()->EndBattleGround(0); //to avoid the assert
                    }
                    //assert(false);
                }
                return map;
            }

            InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty());
            InstanceSave *pSave = pBind ? pBind->save : NULL;

            // the player's permanet player bind is taken into consideration first
            // then the player's group bind and finally the solo bind.
            if(!pBind || !pBind->perm)
            {
                InstanceGroupBind *groupBind = NULL;
                Group *group = player->GetGroup();
                // use the player's difficulty setting (it may not be the same as the group's)
                if(group && (groupBind = group->GetBoundInstance(GetId(), player->GetDifficulty())))
                    pSave = groupBind->save;
            }

            if(pSave)
            {
                // solo/perm/group
                NewInstanceId = pSave->GetInstanceId();
                map = _FindMap(NewInstanceId);
                // it is possible that the save exists but the map doesn't
                if(!map)
                    map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty());
                return map;
            }
            else
            {
                // if no instanceId via group members or instance saves is found
                // the instance will be created for the first time
                NewInstanceId = MapManager::Instance().GenerateInstanceId();
                return CreateInstance(NewInstanceId, NULL, player->GetDifficulty());
            }
        }
    }
}