diff options
-rw-r--r-- | sql/updates/6970_01_mangos_playercreateinfo.sql | 7 | ||||
-rw-r--r-- | sql/updates/6976_01_realmd_realmd_db_version.sql | 1 | ||||
-rw-r--r-- | sql/updates/6976_02_characters_character_db_version.sql | 1 | ||||
-rw-r--r-- | sql/updates/7002_01_mangos_spell_chain.sql.obs | 9 | ||||
-rw-r--r-- | src/game/AchievementMgr.cpp | 26 | ||||
-rw-r--r-- | src/game/Group.cpp | 4 | ||||
-rw-r--r-- | src/game/Level1.cpp | 3 | ||||
-rw-r--r-- | src/game/Map.cpp | 25 | ||||
-rw-r--r-- | src/game/Map.h | 10 | ||||
-rw-r--r-- | src/game/MapManager.h | 8 | ||||
-rw-r--r-- | src/game/Object.cpp | 4 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/PetHandler.cpp | 3 | ||||
-rw-r--r-- | src/game/Player.cpp | 41 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 55 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 44 | ||||
-rw-r--r-- | src/game/ThreatManager.cpp | 35 | ||||
-rw-r--r-- | src/mangosd/CliRunnable.cpp | 20 | ||||
-rw-r--r-- | src/mangosd/mangosd.conf.dist.in | 24 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.cpp | 2 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.h | 1 | ||||
-rw-r--r-- | src/shared/Database/DBCStructure.h | 14 | ||||
-rw-r--r-- | src/shared/Database/DBCfmt.cpp | 1 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 |
24 files changed, 260 insertions, 82 deletions
diff --git a/sql/updates/6970_01_mangos_playercreateinfo.sql b/sql/updates/6970_01_mangos_playercreateinfo.sql new file mode 100644 index 00000000000..a6d7747383d --- /dev/null +++ b/sql/updates/6970_01_mangos_playercreateinfo.sql @@ -0,0 +1,7 @@ +ALTER TABLE db_version CHANGE COLUMN required_6961_01_mangos_command required_6970_01_mangos_playercreateinfo bit; + +DELETE FROM `playercreateinfo` WHERE `race`=7 AND `class` IN (4,8,9); +INSERT INTO `playercreateinfo` VALUES +(7,4,0,1,-6240,331,383), +(7,8,0,1,-6240,331,383), +(7,9,0,1,-6240,331,383); diff --git a/sql/updates/6976_01_realmd_realmd_db_version.sql b/sql/updates/6976_01_realmd_realmd_db_version.sql new file mode 100644 index 00000000000..0ebbb2c82ab --- /dev/null +++ b/sql/updates/6976_01_realmd_realmd_db_version.sql @@ -0,0 +1 @@ +ALTER TABLE realmd_db_version CHANGE COLUMN required_2008_11_07_04_realmd_account required_6976_01_realmd_realmd_db_version bit;
\ No newline at end of file diff --git a/sql/updates/6976_02_characters_character_db_version.sql b/sql/updates/6976_02_characters_character_db_version.sql new file mode 100644 index 00000000000..5fc19205843 --- /dev/null +++ b/sql/updates/6976_02_characters_character_db_version.sql @@ -0,0 +1 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_2008_12_22_19_characters_item_instance required_6976_02_characters_character_db_version bit;
\ No newline at end of file diff --git a/sql/updates/7002_01_mangos_spell_chain.sql.obs b/sql/updates/7002_01_mangos_spell_chain.sql.obs new file mode 100644 index 00000000000..1ec5c5c0333 --- /dev/null +++ b/sql/updates/7002_01_mangos_spell_chain.sql.obs @@ -0,0 +1,9 @@ +ALTER TABLE db_version CHANGE COLUMN required_6970_01_mangos_playercreateinfo required_7002_01_mangos_spell_chain bit; + +DELETE FROM `spell_chain` WHERE `spell_id` IN (51490,59156,59158,59159); + +INSERT INTO `spell_chain` VALUES +(51490,0,51490,1,0), +(59156,51490,51490,2,0), +(59158,59156,51490,3,0), +(59159,59158,51490,4,0); diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index ec1085d8a02..90ae2dde0a4 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -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: diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 3e9dcff7d1b..8afac50da13 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -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 ); diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 4d30987836e..4489cbf1579 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -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()); diff --git a/src/game/Map.cpp b/src/game/Map.cpp index b973a8cb11e..89427a02082 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -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 diff --git a/src/game/Map.h b/src/game/Map.h index 074c859c408..b11aea4582c 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -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(); diff --git a/src/game/MapManager.h b/src/game/MapManager.h index cba0a86d1a5..e7ff17b0aa1 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -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); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index a33cd1a7bd4..84440eec34b 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -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() diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 5ae6b5b63e0..65ccbf583de 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -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) diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index f059662987c..c9c9bfde6df 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -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); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index ed8c38297b6..d928ef4a4ce 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -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; } } diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e10bd98c3c8..f1f85825b99 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -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); diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 5ff242537d0..0ec0de4903d 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -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() diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp index e824223eb2d..9586f1d4722 100644 --- a/src/game/ThreatManager.cpp +++ b/src/game/ThreatManager.cpp @@ -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; diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index 7fe2ab784a6..78c6e0dbb85 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -272,6 +272,26 @@ bool ChatHandler::HandleServerSetLogLevelCommand(const char *args) return true; } +/// set diff time record interval +bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args) +{ + if(!*args) + return false; + + char *NewTimeStr = strtok((char*)args, " "); + if(!NewTimeStr) + return false; + + int32 NewTime =atoi(NewTimeStr); + if(NewTime < 0) + return false; + + sWorld.SetRecordDiffInterval(NewTime); + printf( "Record diff every %u ms\n", NewTime); + return true; +} + + /// @} #ifdef linux diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 7175e95d745..13ac9d694db 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -1289,6 +1289,26 @@ Ra.Secure = 1 # example: "538,90" # Note that it's HIGHLY DISCOURAGED to forbid starting maps (0, 1, 530)! # +# ShowKickInWorld +# determines wether a message is broadcasted to the entire server when a player gets kicked +# Default: 0 +# 1 = Enable +# 0 = Disable +# +# RecordUpdateTimeDiffInterval +# record update time diff to the log file +# update diff can be used as a criterion of performance +# diff < 300: good performance +# diff > 600: bad performance, may be caused by high cpu usage +# Default: 60000 (diff is written into log every 60000 ms or 1 minute. +# >0 = Interval +# 0 = Disable +# +# PlayerStart.String +# If set to anything else than "", this string will be displayed to players when they login +# to a newly created character. +# Default: "" - send no text +# ################################################################################################################### PlayerStart.AllReputation = 0 @@ -1302,4 +1322,6 @@ PvPToken.MapAllowType = 4 PvPToken.ItemID = 29434 PvPToken.ItemCount = 1 NoResetTalentsCost = 0 - +ShowKickInWorld = 0 +RecordUpdateTimeDiffInterval = 60000 +PlayerStart.String = "" diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index c183f8356b4..cd02ed42252 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -32,6 +32,7 @@ typedef std::map<uint16,uint32> AreaFlagByAreaID; typedef std::map<uint32,uint32> AreaFlagByMapID; DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt); +DBCStorage <AreaGroupEntry> sAreaGroupStore(AreaGroupEntryfmt); static AreaFlagByAreaID sAreaFlagByAreaID; static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files @@ -217,6 +218,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaGroupStore, dbcPath,"AreaGroup.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h index 8f53fef84ef..66c55942975 100644 --- a/src/shared/Database/DBCStores.h +++ b/src/shared/Database/DBCStores.h @@ -135,6 +135,7 @@ class DBCStorage extern DBCStorage <AchievementEntry> sAchievementStore; extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore; extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions +extern DBCStorage <AreaGroupEntry> sAreaGroupStore; extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore; extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore; extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore; diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index c01b2f440fc..e26e9d2baad 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -327,6 +327,12 @@ struct AchievementCriteriaEntry uint32 rollValue; // 3 uint32 count; // 4 } roll_need_on_loot; + // ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51 + struct + { + uint32 rollValue; // 3 + uint32 count; // 4 + } roll_greed_on_loot; // ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52 struct @@ -487,6 +493,12 @@ struct AreaTableEntry uint32 team; // 28 }; +struct AreaGroupEntry +{ + uint32 AreaGroupId; // 0 + uint32 AreaId[7]; // 1-7 +}; + struct AreaTriggerEntry { uint32 id; // 0 m_ID @@ -1158,7 +1170,7 @@ struct SpellEntry //uint32 MinReputation; // 223 m_minReputation not used //uint32 RequiredAuraVision; // 224 m_requiredAuraVision not used uint32 TotemCategory[2]; // 225-226 m_requiredTotemCategoryID - int32 AreaId; // 227 m_requiredAreasID + int32 AreaGroupId; // 227 m_requiredAreaGroupId uint32 SchoolMask; // 228 m_schoolMask uint32 runeCostID; // 229 m_runeCostID //uint32 spellMissileID; // 230 m_spellMissileID not used diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index edcf7e2b2be..6cf475c4938 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -21,6 +21,7 @@ const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxxi"; const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix"; const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx"; +const char AreaGroupEntryfmt[]="niiiiiii"; const char AreaTriggerEntryfmt[]="niffffffff"; const char BankBagSlotPricesEntryfmt[]="ni"; const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 49149eb004a..3e3459cfe8d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "6995" + #define REVISION_NR "7006" #endif // __REVISION_NR_H__ |