Weather system changed to that of the previous cores.

Weather system changed to that of the previous cores.

This is part of the current build errors fixes.
This commit is contained in:
Charles A Edwards 2016-02-07 10:45:43 +00:00 committed by Antz
parent 9e94234bdf
commit 165cfba9c4
28 changed files with 1650 additions and 859 deletions

View file

@ -558,6 +558,33 @@ ArenaType ArenaTeam::GetTypeBySlot(uint8 slot)
return ArenaType(0xFF);
}
uint32 ArenaTeam::GetPoints(uint32 MemberRating)
{
// returns how many points would be awarded with this team type with this rating
float points;
uint32 rating = MemberRating + 150 < m_stats.rating ? MemberRating : m_stats.rating;
if (rating <= 1500)
{
// As of Season 6 and later, all teams below 1500 rating will earn points as if they were a 1500 rated team
if (sWorld.getConfig(CONFIG_UINT32_ARENA_SEASON_ID) >= 6)
rating = 1500;
points = (float)rating * 0.22f + 14.0f;
}
else
points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
// type penalties for <5v5 teams
if (m_Type == ARENA_TYPE_2v2)
points *= 0.76f;
else if (m_Type == ARENA_TYPE_3v3)
points *= 0.88f;
return (uint32)points;
}
bool ArenaTeam::HaveMember(ObjectGuid guid) const
{
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@ -703,6 +730,35 @@ void ArenaTeam::MemberWon(Player* plr, uint32 againstRating)
}
}
void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
{
// called after a match has ended and the stats are already modified
// helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
// 10 played games per week is a minimum
if (m_stats.games_week < 10)
return;
// to get points, a player has to participate in at least 30% of the matches
uint32 min_plays = (uint32)ceil(m_stats.games_week * 0.3);
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
// the player participated in enough games, update his points
uint32 points_to_add = 0;
if (itr->games_week >= min_plays)
points_to_add = GetPoints(itr->personal_rating);
// OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, m_TeamId, itr->guid);
std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(itr->guid.GetCounter());
if (plr_itr != PlayerPoints.end())
{
// check if there is already more points
if (plr_itr->second < points_to_add)
PlayerPoints[itr->guid.GetCounter()] = points_to_add;
}
else
PlayerPoints[itr->guid.GetCounter()] = points_to_add;
}
}
void ArenaTeam::SaveToDB()
{
// save team and member stats to db

View file

@ -200,6 +200,7 @@ class ArenaTeam
void Stats(WorldSession* session);
void InspectStats(WorldSession* session, ObjectGuid guid);
uint32 GetPoints(uint32 MemberRating);
float GetChanceAgainst(uint32 own_rating, uint32 enemy_rating);
int32 WonAgainst(uint32 againstRating);
void MemberWon(Player* plr, uint32 againstRating);
@ -207,6 +208,8 @@ class ArenaTeam
void MemberLost(Player* plr, uint32 againstRating);
void OfflineMemberLost(ObjectGuid guid, uint32 againstRating);
void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
void NotifyStatsChanged();
void FinishWeek();

View file

@ -238,6 +238,17 @@ struct CreatureDataAddon
uint32 const* auras; // loaded as char* "spell1 spell2 ... "
};
// Bases values for given Level and UnitClass
struct CreatureClassLvlStats
{
uint32 BaseHealth;
uint32 BaseMana;
float BaseDamage;
float BaseMeleeAttackPower;
float BaseRangedAttackPower;
uint32 BaseArmor;
};
struct CreatureModelInfo
{
uint32 modelid;

View file

@ -868,6 +868,82 @@ void ObjectMgr::LoadCreatureAddons()
sLog.outErrorDb("Creature (GUID: %u) does not exist but has a record in `creature_addon`", addon->guidOrEntry);
}
void ObjectMgr::LoadCreatureClassLvlStats()
{
// initialize data array
memset(&m_creatureClassLvlStats, 0, sizeof(m_creatureClassLvlStats));
std::string queryStr = "SELECT Class, Level, BaseMana, BaseMeleeAttackPower, BaseRangedAttackPower, BaseArmor";
for (int i = 0; i <= MAX_EXPANSION; i++)
{
std::ostringstream str;
str << ", `BaseHealthExp" << i << "`, `BaseDamageExp" << i << "`";
queryStr.append(str.str().c_str());
}
queryStr.append(" FROM `creature_template_classlevelstats` ORDER BY `Class`, `Level`");
QueryResult* result = WorldDatabase.Query(queryStr.c_str());
if (!result)
{
BarGoLink bar(1);
bar.step();
sLog.outString();
sLog.outErrorDb("DB table `creature_template_classlevelstats` is empty.");
return;
}
BarGoLink bar(result->GetRowCount());
uint32 DataCount = 0;
do
{
Field* fields = result->Fetch();
bar.step();
uint32 creatureClass = fields[0].GetUInt32();
uint32 creatureLevel = fields[1].GetUInt32();
if (creatureLevel == 0 || creatureLevel > DEFAULT_MAX_CREATURE_LEVEL)
{
sLog.outErrorDb("Found stats for creature level [%u] with incorrect level. Skipping!", creatureLevel);
continue;
}
if (((1 << (creatureClass - 1)) & CLASSMASK_ALL_CREATURES) == 0)
{
sLog.outErrorDb("Found stats for creature class [%u] with incorrect class. Skipping!", creatureClass);
continue;
}
uint32 baseMana = fields[2].GetUInt32();
float baseMeleeAttackPower = fields[3].GetFloat();
float baseRangedAttackPower = fields[4].GetFloat();
uint32 baseArmor = fields[5].GetUInt32();
for (uint8 i = 0; i <= MAX_EXPANSION; ++i)
{
CreatureClassLvlStats &cCLS = m_creatureClassLvlStats[creatureLevel][classToIndex[creatureClass]][i - 1]; // values should start from 0
cCLS.BaseMana = baseMana;
cCLS.BaseMeleeAttackPower = baseMeleeAttackPower;
cCLS.BaseRangedAttackPower = baseRangedAttackPower;
cCLS.BaseArmor = baseArmor;
cCLS.BaseHealth = fields[6 + (i * 2)].GetUInt32();
cCLS.BaseDamage = fields[7 + (i * 2)].GetFloat();
}
++DataCount;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString(">> Loaded %u creature class level stats definitions.", DataCount);
}
void ObjectMgr::LoadEquipmentTemplates()
{
sEquipmentStorage.Load();
@ -6993,6 +7069,112 @@ void ObjectMgr::LoadQuestPOI()
sLog.outString(">> Loaded %u quest POI definitions", count);
}
void ObjectMgr::LoadDungeonFinderRequirements()
{
uint32 count = 0;
mDungeonFinderRequirementsMap.clear(); // in case of a reload
// 0 1 2 3 4 5 6 7 8
QueryResult* result = WorldDatabase.Query("SELECT mapId, difficulty, min_item_level, item, item_2, alliance_quest, horde_quest, achievement, quest_incomplete_text FROM dungeonfinder_requirements");
if (!result)
{
BarGoLink bar(1);
bar.step();
sLog.outString();
sLog.outErrorDb(">> Loaded 0 dungeon finder requirements. DB table `dungeonfinder_requirements`, is empty!");
return;
}
BarGoLink bar(result->GetRowCount());
do
{
Field* fields = result->Fetch();
bar.step();
uint32 mapId = fields[0].GetUInt32();
uint32 difficulty = fields[1].GetUInt32();
uint32 dungeonKey = MAKE_PAIR32(mapId, difficulty); // for unique key
uint32 minItemLevel = fields[2].GetUInt32();
uint32 item = fields[3].GetUInt32();
uint32 item2 = fields[4].GetUInt32();
uint32 allianceQuest = fields[5].GetUInt32();
uint32 hordeQuest = fields[6].GetUInt32();
uint32 achievement = fields[7].GetUInt32();
const char* questText = fields[8].GetString();
// check that items, quests, & achievements are real
if (item)
{
ItemEntry const* dbcitem = sItemStore.LookupEntry(item);
if (!dbcitem)
{
sLog.outString();
sLog.outErrorDb("Table `dungeonfinder_requirements` has invalid item entry %u for map %u ! Removing requirement.", item, mapId);
item = 0;
}
}
if (item2)
{
ItemEntry const* dbcitem = sItemStore.LookupEntry(item2);
if (!dbcitem)
{
sLog.outString();
sLog.outErrorDb("Table `dungeonfinder_requirements` has invalid item entry %u for map %u ! Removing requirement.", item2, mapId);
item2 = 0;
}
}
if (allianceQuest)
{
QuestMap::iterator qReqItr = mQuestTemplates.find(allianceQuest);
if (qReqItr == mQuestTemplates.end())
{
sLog.outString();
sLog.outErrorDb("Table `dungeonfinder_requirements` has invalid quest requirement %u for map %u ! Removing requirement.", allianceQuest, mapId);
allianceQuest = 0;
}
}
if (hordeQuest)
{
QuestMap::iterator qReqItr = mQuestTemplates.find(hordeQuest);
if (qReqItr == mQuestTemplates.end())
{
sLog.outString();
sLog.outErrorDb("Table `dungeonfinder_requirements` has invalid quest requirement %u for map %u ! Removing requirement.", hordeQuest, mapId);
hordeQuest = 0;
}
}
if (achievement)
{
if (!sAchievementStore.LookupEntry(achievement))
{
sLog.outString();
sLog.outErrorDb("Table `dungeonfinder_requirements` has invalid achievement %u for map %u ! Removing requirement.", achievement, mapId);
achievement = 0;
}
}
// add to map after checks
DungeonFinderRequirements requirement(minItemLevel, item, item2, allianceQuest, hordeQuest, achievement, questText);
mDungeonFinderRequirementsMap[dungeonKey] = requirement;
++count;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString(">> Loaded %u Dungeon Finder Requirements", count);
}
void ObjectMgr::LoadNPCSpellClickSpells()
{
uint32 count = 0;
@ -7100,68 +7282,57 @@ void ObjectMgr::GetConditions(uint32 conditionId, std::vector<PlayerCondition co
out.push_back(condition);
}
void ObjectMgr::LoadWeatherZoneChances()
static char SERVER_SIDE_SPELL[] = "MaNGOS server-side spell";
struct SQLSpellLoader : public SQLStorageLoaderBase<SQLSpellLoader, SQLHashStorage>
{
uint32 count = 0;
// 0 1 2 3 4 5 6 7 8 9 10 11 12
QueryResult* result = WorldDatabase.Query("SELECT zone, spring_rain_chance, spring_snow_chance, spring_storm_chance, summer_rain_chance, summer_snow_chance, summer_storm_chance, fall_rain_chance, fall_snow_chance, fall_storm_chance, winter_rain_chance, winter_snow_chance, winter_storm_chance FROM game_weather");
if (!result)
template<class S, class D>
void default_fill(uint32 field_pos, S src, D& dst)
{
BarGoLink bar(1);
bar.step();
sLog.outString();
sLog.outErrorDb(">> Loaded 0 weather definitions. DB table `game_weather` is empty.");
return;
if (field_pos == LOADED_SPELLDBC_FIELD_POS_EQUIPPED_ITEM_CLASS)
dst = D(-1);
else
dst = D(src);
}
BarGoLink bar(result->GetRowCount());
do
void default_fill_to_str(uint32 field_pos, char const* /*src*/, char * & dst)
{
Field* fields = result->Fetch();
bar.step();
uint32 zone_id = fields[0].GetUInt32();
WeatherZoneChances& wzc = mWeatherZoneMap[zone_id];
for (int season = 0; season < WEATHER_SEASONS; ++season)
if (field_pos == LOADED_SPELLDBC_FIELD_POS_SPELLNAME_0)
{
wzc.data[season].rainChance = fields[season * (MAX_WEATHER_TYPE - 1) + 1].GetUInt32();
wzc.data[season].snowChance = fields[season * (MAX_WEATHER_TYPE - 1) + 2].GetUInt32();
wzc.data[season].stormChance = fields[season * (MAX_WEATHER_TYPE - 1) + 3].GetUInt32();
if (wzc.data[season].rainChance > 100)
{
wzc.data[season].rainChance = 25;
sLog.outErrorDb("Weather for zone %u season %u has wrong rain chance > 100%%", zone_id, season);
}
if (wzc.data[season].snowChance > 100)
{
wzc.data[season].snowChance = 25;
sLog.outErrorDb("Weather for zone %u season %u has wrong snow chance > 100%%", zone_id, season);
}
if (wzc.data[season].stormChance > 100)
{
wzc.data[season].stormChance = 25;
sLog.outErrorDb("Weather for zone %u season %u has wrong storm chance > 100%%", zone_id, season);
}
dst = SERVER_SIDE_SPELL;
}
else
{
dst = new char[1];
*dst = 0;
}
++count;
}
while (result->NextRow());
};
delete result;
void ObjectMgr::LoadSpellTemplate()
{
SQLSpellLoader loader;
loader.Load(sSpellTemplate);
sLog.outString(">> Loaded %u spell definitions", sSpellTemplate.GetRecordCount());
sLog.outString();
sLog.outString(">> Loaded %u weather definitions", count);
for (uint32 i = 1; i < sSpellTemplate.GetMaxEntry(); ++i)
{
// check data correctness
SpellEntry const* spellEntry = sSpellTemplate.LookupEntry<SpellEntry>(i);
if (!spellEntry)
continue;
// insert serverside spell data
if (sSpellStore.GetNumRows() <= i)
{
sLog.outErrorDb("Loading Spell Template for spell %u, index out of bounds (max = %u)", i, sSpellStore.GetNumRows());
continue;
}
else
sSpellStore.InsertEntry(const_cast<SpellEntry*>(spellEntry), i);
}
}
void ObjectMgr::DeleteCreatureData(uint32 guid)
@ -7737,7 +7908,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
{
data.SoundId = fields[10].GetUInt32();
data.Type = fields[11].GetUInt32();
data.Language = fields[12].GetUInt32();
data.LanguageId = (Language)fields[12].GetUInt32();
data.Emote = fields[13].GetUInt32();
if (data.SoundId && !sSoundEntriesStore.LookupEntry(data.SoundId))
@ -7746,10 +7917,10 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
data.SoundId = 0;
}
if (!GetLanguageDescByID(data.Language))
if (!GetLanguageDescByID(data.LanguageId))
{
_DoStringError(entry, "Entry %i in table `%s` using Language %u but Language does not exist.", entry, table, data.Language);
data.Language = LANG_UNIVERSAL;
_DoStringError(entry, "Entry %i in table `%s` using Language %u but Language does not exist.", entry, table, data.LanguageId);
data.LanguageId = LANG_UNIVERSAL;
}
if (data.Type > CHAT_TYPE_ZONE_YELL)
@ -10107,10 +10278,10 @@ bool DoDisplayText(WorldObject* source, int32 entry, Unit const* target /*=NULL*
switch (data->Type)
{
case CHAT_TYPE_SAY:
source->MonsterSay(entry, data->Language, target);
source->MonsterSay(entry, data->LanguageId, target);
break;
case CHAT_TYPE_YELL:
source->MonsterYell(entry, data->Language, target);
source->MonsterYell(entry, data->LanguageId, target);
break;
case CHAT_TYPE_TEXT_EMOTE:
source->MonsterTextEmote(entry, target);
@ -10141,7 +10312,7 @@ bool DoDisplayText(WorldObject* source, int32 entry, Unit const* target /*=NULL*
break;
}
case CHAT_TYPE_ZONE_YELL:
source->MonsterYellToZone(entry, data->Language, target);
source->MonsterYellToZone(entry, data->LanguageId, target);
break;
}

View file

@ -141,12 +141,12 @@ static_assert(MAX_DB_SCRIPT_STRING_ID < ACE_INT32_MAX, "Must scope with int32 ra
struct MangosStringLocale
{
MangosStringLocale() : SoundId(0), Type(0), Language(0), Emote(0) { }
MangosStringLocale() : SoundId(0), Type(0), LanguageId(LANG_UNIVERSAL), Emote(0) { }
std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index
uint32 SoundId;
uint8 Type;
uint32 Language;
Language LanguageId;
uint32 Emote; // 0 -> default, i -> i-1 locale index
};
@ -333,19 +333,6 @@ struct QuestPOI
typedef std::vector<QuestPOI> QuestPOIVector;
typedef UNORDERED_MAP<uint32, QuestPOIVector> QuestPOIMap;
#define WEATHER_SEASONS 4
struct WeatherSeasonChances
{
uint32 rainChance;
uint32 snowChance;
uint32 stormChance;
};
struct WeatherZoneChances
{
WeatherSeasonChances data[WEATHER_SEASONS];
};
struct DungeonEncounter
{
DungeonEncounter(DungeonEncounterEntry const* _dbcEntry, EncounterCreditType _creditType, uint32 _creditEntry, uint32 _lastEncounterDungeon)
@ -359,6 +346,51 @@ struct DungeonEncounter
typedef std::multimap<uint32, DungeonEncounter const*> DungeonEncounterMap;
typedef std::pair<DungeonEncounterMap::const_iterator, DungeonEncounterMap::const_iterator> DungeonEncounterMapBounds;
struct DungeonFinderRequirements
{
uint32 minItemLevel;
uint32 item;
uint32 item2;
uint32 allianceQuestId;
uint32 hordeQuestId;
uint32 achievement;
const char* questIncompleteText;
DungeonFinderRequirements()
: minItemLevel(0), item(0), item2(0), allianceQuestId(0), hordeQuestId(0), achievement(0) {}
DungeonFinderRequirements(uint32 MinItemLevel, uint32 Item, uint32 Item2, uint32 AllianceQuestId,
uint32 HordeQuestId, uint32 Achievement, const char* QuestIncompleteText)
: minItemLevel(MinItemLevel), item(Item), item2(Item2), allianceQuestId(AllianceQuestId),
hordeQuestId(HordeQuestId), achievement(Achievement), questIncompleteText(QuestIncompleteText) {}
};
struct DungeonFinderRewards
{
uint32 baseXPReward;
int32 baseMonetaryReward;
DungeonFinderRewards() : baseXPReward(0), baseMonetaryReward(0) {}
DungeonFinderRewards(uint32 BaseXPReward, int32 BaseMonetaryReward) : baseXPReward(BaseXPReward), baseMonetaryReward(BaseMonetaryReward) {}
};
struct DungeonFinderItems
{
// sorted by auto-incrementing id
uint32 minLevel;
uint32 maxLevel;
uint32 itemReward;
uint32 itemAmount;
uint32 dungeonType;
DungeonFinderItems() : minLevel(0), maxLevel(0), itemReward(0), itemAmount(0), dungeonType(0) {}
DungeonFinderItems(uint32 MinLevel, uint32 MaxLevel, uint32 ItemReward, uint32 ItemAmount, uint32 DungeonType)
: minLevel(MinLevel), maxLevel(MaxLevel), itemReward(ItemReward), itemAmount(ItemAmount), dungeonType(DungeonType) {}
};
typedef UNORDERED_MAP<uint32, DungeonFinderRequirements> DungeonFinderRequirementsMap;
typedef UNORDERED_MAP<uint32, DungeonFinderRewards> DungeonFinderRewardsMap;
typedef UNORDERED_MAP<uint32, DungeonFinderItems> DungeonFinderItemsMap;
struct GraveYardData
{
uint32 safeLocId;
@ -548,8 +580,6 @@ class ObjectMgr
typedef UNORDERED_MAP<uint32, PointOfInterest> PointOfInterestMap;
typedef UNORDERED_MAP<uint32, WeatherZoneChances> WeatherZoneMap;
void LoadGameobjectInfo();
void AddGameobjectInfo(GameObjectInfo* goinfo);
@ -713,6 +743,7 @@ class ObjectMgr
void LoadCreatureTemplates();
void LoadCreatures();
void LoadCreatureAddons();
void LoadCreatureClassLvlStats();
void LoadCreatureModelInfo();
void LoadCreatureModelRace();
void LoadEquipmentTemplates();
@ -759,10 +790,14 @@ class ObjectMgr
void LoadPointsOfInterest();
void LoadQuestPOI();
void LoadDungeonFinderRequirements();
void LoadDungeonFinderRewards();
void LoadDungeonFinderItems();
void LoadNPCSpellClickSpells();
void LoadSpellTemplate();
void LoadCreatureTemplateSpells();
void LoadWeatherZoneChances();
void LoadGameTele();
void LoadNpcGossips();
@ -826,15 +861,6 @@ class ObjectMgr
return NULL;
}
WeatherZoneChances const* GetWeatherChances(uint32 zone_id) const
{
WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id);
if (itr != mWeatherZoneMap.end())
return &itr->second;
else
return NULL;
}
CreatureDataPair const* GetCreatureDataPair(uint32 guid) const
{
CreatureDataMap::const_iterator itr = mCreatureDataMap.find(guid);
@ -1217,7 +1243,9 @@ class ObjectMgr
QuestPOIMap mQuestPOIMap;
WeatherZoneMap mWeatherZoneMap;
DungeonFinderRequirementsMap mDungeonFinderRequirementsMap;
DungeonFinderRewardsMap mDungeonFinderRewardsMap;
DungeonFinderItemsMap mDungeonFinderItemsMap;
// character reserved names
typedef std::set<std::wstring> ReservedNamesMap;
@ -1277,6 +1305,9 @@ class ObjectMgr
HalfNameMap PetHalfName0;
HalfNameMap PetHalfName1;
// Array to store creature stats, Max creature level + 1 (for data alignement with in game level)
CreatureClassLvlStats m_creatureClassLvlStats[DEFAULT_MAX_CREATURE_LEVEL + 1][MAX_CREATURE_CLASS][MAX_EXPANSION + 1];
MapObjectGuids mMapObjectGuids;
CreatureDataMap mCreatureDataMap;
CreatureLocaleMap mCreatureLocaleMap;

View file

@ -74,6 +74,9 @@
#include "Vehicle.h"
#include "Calendar.h"
#include "PhaseMgr.h"
#ifdef ENABLE_ELUNA
#include "LuaEngine.h"
#endif /*ENABLE_ELUNA*/
#include <cmath>
@ -1944,6 +1947,13 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
return true;
}
void Player::SetRandomWinner(bool isWinner)
{
m_IsBGRandomWinner = isWinner;
if (m_IsBGRandomWinner)
CharacterDatabase.PExecute("INSERT INTO character_battleground_random (guid) VALUES ('%u')", GetGUIDLow());
}
bool Player::TeleportToBGEntryPoint()
{
ScheduleDelayedOperation(DELAYED_BG_MOUNT_RESTORE);
@ -6898,8 +6908,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
if (!zone)
return;
phaseMgr->AddUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE);
if (m_zoneUpdateId != newZone)
{
// handle outdoor pvp zones
@ -6910,17 +6918,16 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
if (sWorld.getConfig(CONFIG_BOOL_WEATHER))
{
if (Weather* wth = sWorld.FindWeather(zone->ID))
wth->SendWeatherUpdateToPlayer(this);
else if (!sWorld.AddWeather(zone->ID))
{
// send fine weather packet to remove old zone's weather
Weather::SendFineWeatherUpdateToPlayer(this);
}
Weather* wth = GetMap()->GetWeatherSystem()->FindOrCreateWeather(newZone);
wth->SendWeatherUpdateToPlayer(this);
}
}
m_zoneUpdateId = newZone;
#ifdef ENABLE_ELUNA
sEluna->OnUpdateZone(this, newZone, newArea);
#endif
m_zoneUpdateId = newZone;
m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
// zone changed, so area changed as well, update it
@ -6930,19 +6937,19 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
// in PvE, only opposition team capital
switch (zone->team)
{
case AREATEAM_ALLY:
pvpInfo.inHostileArea = GetTeam() != ALLIANCE && (sWorld.IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_HORDE:
pvpInfo.inHostileArea = GetTeam() != HORDE && (sWorld.IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_NONE:
// overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this
pvpInfo.inHostileArea = sWorld.IsPvPRealm() || InBattleGround();
break;
default: // 6 in fact
pvpInfo.inHostileArea = false;
break;
case AREATEAM_ALLY:
pvpInfo.inHostileArea = GetTeam() != ALLIANCE && (sWorld.IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_HORDE:
pvpInfo.inHostileArea = GetTeam() != HORDE && (sWorld.IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_NONE:
// overwrite for battlegrounds, maybe batter some zone flags but current known not 100% fit to this
pvpInfo.inHostileArea = sWorld.IsPvPRealm() || InBattleGround();
break;
default: // 6 in fact
pvpInfo.inHostileArea = false;
break;
}
if (pvpInfo.inHostileArea) // in hostile area
@ -6990,8 +6997,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
UpdateZoneDependentAuras();
UpdateZoneDependentPets();
phaseMgr->RemoveUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE);
}
// If players are too far way of duel flag... then player loose the duel
@ -14056,18 +14061,6 @@ void Player::CompleteQuest(uint32 quest_id)
}
}
void Player::IncompleteQuest(uint32 quest_id)
{
if (quest_id)
{
SetQuestStatus(quest_id, QUEST_STATUS_INCOMPLETE);
uint16 log_slot = FindQuestSlot(quest_id);
if (log_slot < MAX_QUEST_LOG_SIZE)
RemoveQuestSlotState(log_slot, QUEST_STATE_COMPLETE);
}
}
void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver, bool announce)
{
uint32 quest_id = pQuest->GetQuestId();
@ -14075,7 +14068,9 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
if (pQuest->ReqItemId[i])
{
DestroyItemCount(pQuest->ReqItemId[i], pQuest->ReqItemCount[i], true);
}
}
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
@ -14088,18 +14083,13 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
}
}
// take currency
for (uint32 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
{
if (pQuest->ReqCurrencyId[i])
ModifyCurrencyCount(pQuest->ReqCurrencyId[i], -int32(pQuest->ReqCurrencyCount[i] * GetCurrencyPrecision(pQuest->ReqCurrencyId[i])));
}
RemoveTimedQuest(quest_id);
if (BattleGround* bg = GetBattleGround())
if (bg->GetTypeID() == BATTLEGROUND_AV)
if (bg->GetTypeID(true) == BATTLEGROUND_AV)
{
((BattleGroundAV*)bg)->HandleQuestComplete(pQuest->GetQuestId(), this);
}
if (pQuest->GetRewChoiceItemsCount() > 0)
{
@ -14134,7 +14124,9 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
uint16 log_slot = FindQuestSlot(quest_id);
if (log_slot < MAX_QUEST_LOG_SIZE)
{
SetQuestSlot(log_slot, 0);
}
QuestStatusData& q_status = mQuestStatus[quest_id];
@ -14143,7 +14135,7 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
if (getLevel() < sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL))
{
GiveXP(xp , NULL);
GiveXP(xp, NULL);
// Give player extra money (for max level already included in pQuest->GetRewMoneyMaxLevel())
if (pQuest->GetRewOrReqMoney() > 0)
@ -14155,10 +14147,10 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
else
{
// reward money for max level already included in pQuest->GetRewMoneyMaxLevel()
uint64 money = uint32(pQuest->GetRewMoneyMaxLevel() * sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_MONEY));
uint32 money = uint32(pQuest->GetRewMoneyMaxLevel() * sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_MONEY));
// reward money used if > xp replacement money
if (pQuest->GetRewOrReqMoney() > int64(money))
if (pQuest->GetRewOrReqMoney() > int32(money))
money = pQuest->GetRewOrReqMoney();
ModifyMoney(money);
@ -14169,16 +14161,9 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
if (pQuest->GetRewOrReqMoney() < 0)
ModifyMoney(pQuest->GetRewOrReqMoney());
// reward currency
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
if (pQuest->RewCurrencyId[i])
ModifyCurrencyCount(pQuest->RewCurrencyId[i], int32(pQuest->RewCurrencyCount[i] * GetCurrencyPrecision(pQuest->RewCurrencyId[i])));
}
// reward skill
if (uint32 skill = pQuest->GetRewSkill())
UpdateSkill(skill, pQuest->GetRewSkillValue());
// honor reward
if (uint32 honor = pQuest->CalculateRewardHonor(getLevel()))
RewardHonor(NULL, 0, honor);
// title reward
if (pQuest->GetCharTitleId())
@ -14219,18 +14204,18 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
q_status.uState = QUEST_CHANGED;
if (announce)
SendQuestReward(pQuest, xp, questGiver);
SendQuestReward(pQuest, xp);
bool handled = false;
switch (questGiver->GetTypeId())
{
case TYPEID_UNIT:
handled = sScriptMgr.OnQuestRewarded(this, (Creature*)questGiver, pQuest);
break;
case TYPEID_GAMEOBJECT:
handled = sScriptMgr.OnQuestRewarded(this, (GameObject*)questGiver, pQuest);
break;
case TYPEID_UNIT:
handled = sScriptMgr.OnQuestRewarded(this, reinterpret_cast<Creature*>(questGiver), pQuest, reward);
break;
case TYPEID_GAMEOBJECT:
handled = sScriptMgr.OnQuestRewarded(this, reinterpret_cast<GameObject*>(questGiver), pQuest, reward);
break;
}
if (!handled && pQuest->GetQuestCompleteScript() != 0)
@ -14248,8 +14233,6 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT);
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, pQuest->GetQuestId());
UpdateForQuestWorldObjects();
// remove auras from spells with quest reward state limitations
// Some spells applied at quest reward
uint32 zone, area;
@ -14266,11 +14249,18 @@ void Player::RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver,
saBounds = sSpellMgr.GetSpellAreaForAreaMapBounds(0);
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
itr->second->ApplyOrRemoveSpellIfCan(this, zone, area, false);
}
PhaseUpdateData phaseUdateData;
phaseUdateData.AddQuestUpdate(quest_id);
void Player::IncompleteQuest(uint32 quest_id)
{
if (quest_id)
{
SetQuestStatus(quest_id, QUEST_STATUS_INCOMPLETE);
phaseMgr->NotifyConditionChanged(phaseUdateData);
uint16 log_slot = FindQuestSlot(quest_id);
if (log_slot < MAX_QUEST_LOG_SIZE)
RemoveQuestSlotState(log_slot, QUEST_STATE_COMPLETE);
}
}
void Player::FailQuest(uint32 questId)
@ -15418,7 +15408,34 @@ void Player::SendQuestCompleteEvent(uint32 quest_id)
}
}
void Player::SendQuestReward(Quest const* pQuest, uint32 XP, Object* /*questGiver*/)
void Player::SendQuestReward(Quest const* pQuest, uint32 XP)
{
uint32 questid = pQuest->GetQuestId();
DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid);
WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4 + 4 + 4 + 4 + 4));
data << uint32(questid);
if (getLevel() < sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL))
{
data << uint32(XP);
data << uint32(pQuest->GetRewOrReqMoney());
}
else
{
data << uint32(0);
data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_MONEY)));
}
data << uint32(10 * MaNGOS::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorAddition()));
data << uint32(pQuest->GetBonusTalents()); // bonus talents
data << uint32(0); // arena points
GetSession()->SendPacket(&data);
}
// Delete this if the above works
// the above was added for deve21 (chucky)
//void Player::SendQuestReward(Quest const* pQuest, uint32 XP, Object* /*questGiver*/)
/*
{
uint32 questid = pQuest->GetQuestId();
DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid);
@ -15436,7 +15453,6 @@ void Player::SendQuestReward(Quest const* pQuest, uint32 XP, Object* /*questGive
data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getConfig(CONFIG_FLOAT_RATE_DROP_MONEY)));
data << uint32(0);
}
data << uint32(questid);
data << uint32(pQuest->GetRewSkill());
@ -15445,6 +15461,7 @@ void Player::SendQuestReward(Quest const* pQuest, uint32 XP, Object* /*questGive
GetSession()->SendPacket(&data);
}
*/
void Player::SendQuestFailed(uint32 quest_id, InventoryResult reason)
{

View file

@ -1047,6 +1047,8 @@ class Player : public Unit
bool TeleportToBGEntryPoint();
void SetRandomWinner(bool isWinner);
void SetSummonPoint(uint32 mapid, float x, float y, float z)
{
m_summon_expire = time(NULL) + MAX_PLAYER_SUMMON_DELAY;
@ -1364,7 +1366,7 @@ class Player : public Unit
void AddQuest(Quest const* pQuest, Object* questGiver);
void CompleteQuest(uint32 quest_id);
void IncompleteQuest(uint32 quest_id);
void RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver, bool announce = true);
void RewardQuest(Quest const* pQuest, uint32 reward, Object* questGiver, bool announce);
void FailQuest(uint32 quest_id);
bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;
@ -1449,7 +1451,8 @@ class Player : public Unit
bool CanShareQuest(uint32 quest_id) const;
void SendQuestCompleteEvent(uint32 quest_id);
void SendQuestReward(Quest const* pQuest, uint32 XP, Object* questGiver);
void SendQuestReward(Quest const* pQuest, uint32 XP);
// void SendQuestReward(Quest const* pQuest, uint32 XP, Object* questGiver); // delete this if the above works (chucky)
void SendQuestFailed(uint32 quest_id, InventoryResult reason = EQUIP_ERR_OK);
void SendQuestTimerFailed(uint32 quest_id);
void SendCanTakeQuestResponse(uint32 msg) const;
@ -2192,6 +2195,8 @@ class Player : public Unit
// returns true if the player is in active state for capture point capturing
bool CanUseCapturePoint();
bool m_IsBGRandomWinner;
/*********************************************************/
/*** REST SYSTEM ***/
/*********************************************************/

View file

@ -129,7 +129,7 @@ enum EUnitFields
UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x87,
UNIT_FIELD_MAXITEMLEVEL = OBJECT_END + 0x88,
UNIT_FIELD_PADDING = OBJECT_END + 0x89,
UNIT_END = OBJECT_END + 0x8A
UNIT_END = OBJECT_END + 0x008E,
};
enum EItemFields