*Update to Mangos 7006.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-01-02 11:03:43 -06:00
parent 3deefb9f00
commit 1e4381f7b1
24 changed files with 259 additions and 81 deletions
+24
View File
@@ -614,7 +614,26 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, 1);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
{
// miscvalue1 = itemid
// miscvalue2 = diced value
if(!miscvalue1)
continue;
if(miscvalue2 != achievementCriteria->roll_greed_on_loot.rollValue)
continue;
ItemPrototype const *pProto = objmgr.GetItemPrototype( miscvalue1 );
uint32 requiredItemLevel = 0;
if (achievementCriteria->ID == 2412 || achievementCriteria->ID == 2358)
requiredItemLevel = 185;
if(!pProto || pProto->ItemLevel <requiredItemLevel)
continue;
SetCriteriaProgress(achievementCriteria, 1, true);
break;
}
}
if(IsCompletedCriteria(achievementCriteria))
CompletedCriteria(achievementCriteria);
@@ -678,6 +697,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end();
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
return progress->counter >= achievementCriteria->reach_skill_level.skillLevel;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
return progress->counter >= achievementCriteria->complete_quest_count.totalQuestCount;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
@@ -710,6 +731,9 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions;
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
return progress->counter >= 1;
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
return progress->counter >= achievementCriteria->roll_greed_on_loot.count;
// handle all statistic-only criteria here
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+4
View File
@@ -727,6 +727,8 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
if(player && player->GetSession())
{
player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT, roll->itemid, maxresul);
ItemPosCountVec dest;
LootItem *item = &(roll->getLoot()->items[roll->itemSlot]);
uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
@@ -772,6 +774,8 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
if(player && player->GetSession())
{
player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT, roll->itemid, maxresul);
ItemPosCountVec dest;
LootItem *item = &(roll->getLoot()->items[roll->itemSlot]);
uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count );
+2 -1
View File
@@ -2501,7 +2501,8 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
return false;
PSendSysMessage(LANG_TELEPORTING_TO, name.c_str(), GetTrinityString(LANG_OFFLINE), tele->name.c_str());
Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y),guid);
Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,
MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),guid);
}
else
PSendSysMessage(LANG_NO_PLAYER, name.c_str());
+22 -3
View File
@@ -1244,7 +1244,7 @@ float Map::GetHeight(float x, float y, float z, bool pUseVmaps) const
}
}
uint16 Map::GetAreaFlag(float x, float y ) const
uint16 Map::GetAreaFlag(float x, float y, float z) const
{
//local x,y coords
float lx,ly;
@@ -1262,11 +1262,30 @@ uint16 Map::GetAreaFlag(float x, float y ) const
// ensure GridMap is loaded
const_cast<Map*>(this)->EnsureGridCreated(GridPair(63-gx,63-gy));
uint16 areaflag;
if(GridMaps[gx][gy])
return GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)];
areaflag = GridMaps[gx][gy]->area_flag[(int)(lx)][(int)(ly)];
// this used while not all *.map files generated (instances)
else
return GetAreaFlagByMapId(i_id);
areaflag = GetAreaFlagByMapId(i_id);
//FIXME: some hacks for areas above or underground for ground area
// required for area specific spells/etc, until map/vmap data
// not provided correct areaflag with this hacks
switch(areaflag)
{
// Acherus: The Ebon Hold (Plaguelands: The Scarlet Enclave)
case 1984: // Plaguelands: The Scarlet Enclave
case 2076: // Death's Breach (Plaguelands: The Scarlet Enclave)
case 2745: // The Noxious Pass (Plaguelands: The Scarlet Enclave)
if(z > 350.0f) areaflag = 2048; break;
// Acherus: The Ebon Hold (Eastern Plaguelands)
case 856: // The Noxious Glade (Eastern Plaguelands)
case 2456: // Death's Breach (Eastern Plaguelands)
if(z > 350.0f) areaflag = 1950; break;
}
return areaflag;
}
uint8 Map::GetTerrainType(float x, float y ) const
+5 -5
View File
@@ -185,7 +185,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
float GetHeight(float x, float y, float z, bool pCheckVMap=true) const;
bool IsInWater(float x, float y, float z) const; // does not use z pos. This is for future use
uint16 GetAreaFlag(float x, float y ) const;
uint16 GetAreaFlag(float x, float y, float z) const;
uint8 GetTerrainType(float x, float y ) const;
float GetWaterLevel(float x, float y ) const;
bool IsUnderWater(float x, float y, float z) const;
@@ -193,14 +193,14 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
static uint32 GetAreaId(uint16 areaflag,uint32 map_id);
static uint32 GetZoneId(uint16 areaflag,uint32 map_id);
uint32 GetAreaId(float x, float y) const
uint32 GetAreaId(float x, float y, float z) const
{
return GetAreaId(GetAreaFlag(x,y),i_id);
return GetAreaId(GetAreaFlag(x,y,z),i_id);
}
uint32 GetZoneId(float x, float y) const
uint32 GetZoneId(float x, float y, float z) const
{
return GetZoneId(GetAreaFlag(x,y),i_id);
return GetZoneId(GetAreaFlag(x,y,z),i_id);
}
virtual void MoveAllCreaturesInMoveList();
+4 -4
View File
@@ -47,13 +47,13 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit
Map const* GetBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_GetBaseMap(id); }
void DeleteInstance(uint32 mapid, uint32 instanceId);
inline uint16 GetAreaFlag(uint32 mapid, float x, float y) const
inline uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const
{
Map const* m = GetBaseMap(mapid);
return m->GetAreaFlag(x, y);
return m->GetAreaFlag(x, y, z);
}
inline uint32 GetAreaId(uint32 mapid, float x, float y) { return Map::GetAreaId(GetAreaFlag(mapid, x, y),mapid); }
inline uint32 GetZoneId(uint32 mapid, float x, float y) { return Map::GetZoneId(GetAreaFlag(mapid, x, y),mapid); }
inline uint32 GetAreaId(uint32 mapid, float x, float y, float z) { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); }
inline uint32 GetZoneId(uint32 mapid, float x, float y, float z) { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); }
void Initialize(void);
void Update(time_t);
+2 -2
View File
@@ -1108,12 +1108,12 @@ void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid )
uint32 WorldObject::GetZoneId() const
{
return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY);
return MapManager::Instance().GetBaseMap(m_mapId)->GetZoneId(m_positionX,m_positionY,m_positionZ);
}
uint32 WorldObject::GetAreaId() const
{
return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY);
return MapManager::Instance().GetBaseMap(m_mapId)->GetAreaId(m_positionX,m_positionY,m_positionZ);
}
InstanceData* WorldObject::GetInstanceData()
+1 -1
View File
@@ -4970,7 +4970,7 @@ void ObjectMgr::LoadGraveyardZones()
WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team)
{
// search for zone associated closest graveyard
uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y);
uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y,z);
// Simulate std. algorithm:
// found some graveyard associated to (ghost_zone,ghost_map)
-3
View File
@@ -263,9 +263,6 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
data << uint32(spellInfo->RequiresSpellFocus);
break;
case SPELL_FAILED_REQUIRES_AREA:
data << uint32(spellInfo->AreaId);
break;
}
SendPacket(&data);
}
+27 -14
View File
@@ -1436,7 +1436,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << uint8(getLevel()); // player level
// do not use GetMap! it will spawn a new instance since the bound instances are not loaded
uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY());
uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY(),GetPositionZ());
sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId);
*p_data << uint32(zoneId);
*p_data << uint32(GetMapId());
@@ -5431,7 +5431,7 @@ void Player::CheckExploreSystem()
if (isInFlight())
return;
uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY());
uint16 areaFlag=MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY(),GetPositionZ());
if(areaFlag==0xffff)
return;
int offset = areaFlag / 32;
@@ -6316,16 +6316,17 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)
if (!zone)
{
// stored zone is zero, use generic and slow zone detection
result = CharacterDatabase.PQuery("SELECT map,position_x,position_y FROM characters WHERE guid='%u'", guidLow);
result = CharacterDatabase.PQuery("SELECT map,position_x,position_y,position_z FROM characters WHERE guid='%u'", guidLow);
if( !result )
return 0;
fields = result->Fetch();
uint32 map = fields[0].GetUInt32();
float posx = fields[1].GetFloat();
float posy = fields[2].GetFloat();
float posz = fields[3].GetFloat();
delete result;
zone = MapManager::Instance().GetZoneId(map,posx,posy);
zone = MapManager::Instance().GetZoneId(map,posx,posy,posz);
CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, guidLow);
}
@@ -19217,22 +19218,34 @@ void Player::UpdateAreaDependentAuras( uint32 newArea )
for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
{
// use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date
if(!IsSpellAllowedInLocation(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea))
if(GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea)!=0)
RemoveAura(iter);
else
++iter;
}
// Dragonmaw Illusion
if( newArea == 3759 || newArea == 3966 || newArea == 3939 )
// some auras applied at subzone enter
switch(newArea)
{
if( GetDummyAura(40214) )
{
if( !HasAura(40216,0) )
CastSpell(this,40216,true);
if( !HasAura(42016,0) )
CastSpell(this,42016,true);
}
// Dragonmaw Illusion
case 3759: // Netherwing Ledge
case 3939: // Dragonmaw Fortress
case 3966: // Dragonmaw Base Camp
if( GetDummyAura(40214) )
{
if( !HasAura(40216,0) )
CastSpell(this,40216,true);
if( !HasAura(42016,0) )
CastSpell(this,42016,true);
}
break;
// Dominion Over Acherus
case 4281: // Acherus: The Ebon Hold
case 4342: // Acherus: The Ebon Hold
if( HasSpell(51721) )
if( !HasAura(51721,0) )
CastSpell(this,51721,true);
break;
}
}
+36 -19
View File
@@ -1379,38 +1379,55 @@ void Spell::EffectDummy(uint32 i)
}
break;
case SPELLFAMILY_WARLOCK:
//Life Tap (only it have this with dummy effect)
if (m_spellInfo->SpellFamilyFlags == 0x40000)
// Life Tap
if (m_spellInfo->SpellFamilyFlags & 0x0000000000040000LL)
{
float cost = damage;
if(Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this);
int32 dmg = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE);
if(int32(m_caster->GetHealth()) > dmg)
// In 303 exist spirit depend
uint32 spirit = m_caster->GetStat(STAT_SPIRIT);
switch (m_spellInfo->Id)
{
case 1454: damage+=spirit; break;
case 1455: damage+=spirit*15/10; break;
case 1456: damage+=spirit*2; break;
case 11687: damage+=spirit*25/10; break;
case 11688:
case 11689:
case 27222:
case 57946: damage+=spirit*3; break;
default:
sLog.outError("Spell::EffectDummy: %u Life Tap need set spirit multipler", m_spellInfo->Id);
return;
}
// Think its not need (also need remove Life Tap from SpellDamageBonus or add new value)
// damage = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(damage > 0 ? damage : 0), SPELL_DIRECT_DAMAGE);
if(int32(unitTarget->GetHealth()) > damage)
{
// Shouldn't Appear in Combat Log
m_caster->ModifyHealth(-dmg);
int32 mana = dmg;
unitTarget->ModifyHealth(-damage);
int32 mana = damage;
// Improved Life Tap mod
Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr)
{
// only Imp. Life Tap have this in combination with dummy aura
if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 208)
mana = ((*itr)->GetModifier()->m_amount + 100)* mana / 100;
}
m_caster->CastCustomSpell(m_caster,31818,&mana,NULL,NULL,true,NULL);
m_caster->CastCustomSpell(unitTarget, 31818, &mana, NULL, NULL, true);
// Mana Feed
int32 manaFeedVal = m_caster->CalculateSpellDamage(m_spellInfo,1, m_spellInfo->EffectBasePoints[1],m_caster);
manaFeedVal = manaFeedVal * mana / 100;
int32 manaFeedVal = 0;
Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
for(Unit::AuraList::const_iterator itr = mod.begin(); itr != mod.end(); ++itr)
{
if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 1982)
manaFeedVal+= (*itr)->GetModifier()->m_amount;
}
if(manaFeedVal > 0)
m_caster->CastCustomSpell(m_caster,32553,&manaFeedVal,NULL,NULL,true,NULL);
{
manaFeedVal = manaFeedVal * mana / 100;
m_caster->CastCustomSpell(m_caster, 32553, &manaFeedVal, NULL, NULL, true, NULL);
}
}
else
SendCastResult(SPELL_FAILED_FIZZLE);
+30 -14
View File
@@ -2437,11 +2437,24 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
return true;
}
bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id)
uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id)
{
// normal case
if( spellInfo->AreaId > 0 && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )
return false;
if( spellInfo->AreaGroupId > 0)
{
bool found = false;
AreaGroupEntry const* groupEntry = sAreaGroupStore.LookupEntry(spellInfo->AreaGroupId);
if(groupEntry)
{
for (uint8 i=0; i<7; i++)
if( groupEntry->AreaId[i] == zone_id || groupEntry->AreaId[i] == area_id )
found = true;
}
if(!found)
return SPELL_FAILED_INCORRECT_AREA;
}
// elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup)
if(spellInfo->SpellFamilyName==SPELLFAMILY_POTION)
@@ -2451,24 +2464,24 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
if(mask & ELIXIR_BATTLE_MASK)
{
if(spellInfo->Id==45373) // Bloodberry Elixir
return zone_id==4075;
return zone_id==4075 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
if(mask & ELIXIR_UNSTABLE_MASK)
{
// in the Blade's Edge Mountains Plateaus and Gruul's Lair.
return zone_id ==3522 || map_id==565;
return zone_id ==3522 || map_id==565 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
if(mask & ELIXIR_SHATTRATH_MASK)
{
// in Tempest Keep, Serpentshrine Cavern, Caverns of Time: Mount Hyjal, Black Temple, Sunwell Plateau
if(zone_id ==3607 || map_id==534 || map_id==564 || zone_id==4075)
return true;
return 0;
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
return false;
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->multimap_id==206;
return mapEntry->multimap_id==206 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
// elixirs not have another limitations
@@ -2484,25 +2497,28 @@ bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 z
{
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
return false;
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->multimap_id==206;
return mapEntry->multimap_id==206 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 41617: // Cenarion Mana Salve
case 41619: // Cenarion Healing Salve
{
MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
if(!mapEntry)
return false;
return SPELL_FAILED_INCORRECT_AREA;
return mapEntry->multimap_id==207;
return mapEntry->multimap_id==207 ? 0 : SPELL_FAILED_REQUIRES_AREA;
}
case 40216: // Dragonmaw Illusion
case 42016: // Dragonmaw Illusion
return area_id == 3759 || area_id == 3966 || area_id == 3939;
return area_id == 3759 || area_id == 3966 || area_id == 3939 ? 0 : SPELL_FAILED_INCORRECT_AREA;
case 51721: // Dominion Over Acherus
case 54055: // Dominion Over Acherus
return area_id == 4281 || area_id == 4342 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
return true;
return 0;
}
void SpellMgr::LoadSkillLineAbilityMap()
+23 -12
View File
@@ -267,26 +267,36 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
{
HostilReference* currentRef = NULL;
bool found = false;
bool noPriorityTargetFound = false;
std::list<HostilReference*>::iterator lastRef = iThreatList.end();
lastRef--;
for(std::list<HostilReference*>::iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found; ++iter)
for(std::list<HostilReference*>::iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
{
currentRef = (*iter);
Unit* target = currentRef->getTarget();
assert(target); // if the ref has status online the target must be there !
// some units are preferred in comparison to others
if(iter != lastRef && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask(), false) ||
target->hasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_DAMAGE)
) )
// some units are prefered in comparison to others
if(!noPriorityTargetFound && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask(), false) || target->hasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_DAMAGE)) )
{
// current victim is a second choice target, so don't compare threat with it below
if(currentRef == pCurrentVictim)
pCurrentVictim = NULL;
continue;
if(iter != lastRef)
{
// current victim is a second choice target, so don't compare threat with it below
if(currentRef == pCurrentVictim)
pCurrentVictim = NULL;
++iter;
continue;
}
else
{
// if we reached to this point, everyone in the threatlist is a second choice target. In such a situation the target with the highest threat should be attacked.
noPriorityTargetFound = true;
iter = iThreatList.begin();
continue;
}
}
if(!pAttacker->IsOutOfThreatArea(target)) // skip non attackable currently targets
@@ -314,6 +324,7 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
break;
}
}
++iter;
}
if(!found)
currentRef = NULL;