aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorOvalord <1Don7H4v3@m41L.com>2016-07-23 18:39:56 +0200
committerShauren <shauren.trinity@gmail.com>2016-07-23 18:39:56 +0200
commit79aafd5865f11b5ecdd2865829562b981652db75 (patch)
tree73b19b280e4b153e8ba10e4f459421d0cc9f6712 /src/server/game
parent3b8cdd434133939cec1c7aaceb24fb7dc98000f9 (diff)
Core/Players: Initial work on demon hunters
* Added starting level and required level config options as well as rbac permission to ignore the requirements * Updated max power values for both demon hunter specs * Fixed a crash during DK and DH creation * Added playercreateinfo data for demon hunters Closes #17651
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Accounts/RBAC.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp12
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp78
-rw-r--r--src/server/game/World/World.cpp27
-rw-r--r--src/server/game/World/World.h3
6 files changed, 112 insertions, 12 deletions
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 2b85d922657..28c8fc11e27 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -61,7 +61,7 @@ enum RBACPermissions
// 9 - reuse
RBAC_PERM_USE_CHARACTER_TEMPLATES = 10,
RBAC_PERM_LOG_GM_TRADE = 11,
- // 12 - reuse
+ RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEMON_HUNTER = 12,
RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES = 13,
RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_TEAMMASK = 14,
RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_CLASSMASK = 15,
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 9873f90edbb..2c238fe4e60 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -482,9 +482,11 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac
SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
// set starting level
- uint32 start_level = getClass() != CLASS_DEATH_KNIGHT
- ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)
- : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+ uint32 start_level = sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL);
+ if (getClass() == CLASS_DEATH_KNIGHT)
+ start_level = sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+ else if (getClass() == CLASS_DEMON_HUNTER)
+ start_level = sWorld->getIntConfig(CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL);
if (m_session->HasPermission(rbac::RBAC_PERM_USE_START_GM_LEVEL))
{
@@ -11933,7 +11935,8 @@ void Player::VisualizeItem(uint8 slot, Item* pItem)
if (pItem->GetTemplate()->GetBonding() == BIND_WHEN_EQUIPED || pItem->GetTemplate()->GetBonding() == BIND_WHEN_PICKED_UP || pItem->GetTemplate()->GetBonding() == BIND_QUEST_ITEM)
{
pItem->SetBinding(true);
- GetSession()->GetCollectionMgr()->AddItemAppearance(pItem);
+ if (IsInWorld())
+ GetSession()->GetCollectionMgr()->AddItemAppearance(pItem);
}
TC_LOG_DEBUG("entities.player.items", "Player::SetVisibleItemSlot: Player '%s' (%s), Slot: %u, Item: %u",
@@ -26710,6 +26713,7 @@ uint32 Player::CalculateTalentsTiers() const
break;
case CLASS_DEMON_HUNTER:
rowLevels = DHTalentRowLevels;
+ break;
default:
rowLevels = DefaultTalentRowLevels;
break;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ea36658b786..1b67b78a5f1 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -11090,12 +11090,14 @@ int32 Unit::GetCreatePowers(Powers power) const
case POWER_MANA:
return GetCreateMana();
case POWER_RAGE:
+ case POWER_PAIN:
return 1000;
case POWER_FOCUS:
if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_HUNTER)
return 100;
return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100);
case POWER_ENERGY:
+ case POWER_FURY:
return 100;
case POWER_COMBO_POINTS:
return 5;
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index abac1b283fb..044eb15dab7 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -264,10 +264,11 @@ bool LoginQueryHolder::Initialize()
void WorldSession::HandleCharEnum(PreparedQueryResult result)
{
+ uint8 demonHunterCount = 0; // We use this counter to allow multiple demon hunter creations when allowed in config
+ bool canAlwaysCreateDemonHunter = HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEMON_HUNTER);
WorldPackets::Character::EnumCharactersResult charEnum;
charEnum.Success = true;
charEnum.IsDeletedCharacters = false;
- charEnum.IsDemonHunterCreationAllowed = true;
charEnum.DisabledClassesMask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
_legitCharacters.clear();
@@ -303,8 +304,14 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result)
sWorld->AddCharacterInfo(charInfo.Guid, GetAccountId(), charInfo.Name, charInfo.Sex, charInfo.Race, charInfo.Class, charInfo.Level, false);
if (charInfo.Class == CLASS_DEMON_HUNTER)
+ demonHunterCount++;
+
+ if (demonHunterCount >= sWorld->getIntConfig(CONFIG_DEMON_HUNTERS_PER_REALM) && !canAlwaysCreateDemonHunter)
charEnum.HasDemonHunterOnRealm = true;
- if (charInfo.Level >= 70)
+ else
+ charEnum.HasDemonHunterOnRealm = false;
+
+ if (charInfo.Level >= sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_DEMON_HUNTER) || canAlwaysCreateDemonHunter)
charEnum.HasLevel70OnRealm = true;
charEnum.Characters.emplace_back(charInfo);
@@ -312,6 +319,8 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result)
while (result->NextRow());
}
+ charEnum.IsDemonHunterCreationAllowed = (!charEnum.HasDemonHunterOnRealm && charEnum.HasLevel70OnRealm);
+
SendPacket(charEnum.Write());
}
@@ -580,11 +589,11 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
_charCreateCallback.FreeResult();
- if (!allowTwoSideAccounts || skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT)
+ if (!allowTwoSideAccounts || skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT || createInfo->Class == CLASS_DEMON_HUNTER)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CREATE_INFO);
stmt->setUInt32(0, GetAccountId());
- stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
+ stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT || createInfo->Class == CLASS_DEMON_HUNTER) ? 12 : 1);
_charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
_charCreateCallback.NextStage();
return;
@@ -598,15 +607,19 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
{
bool haveSameRace = false;
uint32 heroicReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
+ uint32 demonHunterReqLevel = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_DEMON_HUNTER);
bool hasHeroicReqLevel = (heroicReqLevel == 0);
+ bool hasDemonHunterReqLevel = (demonHunterReqLevel == 0);
bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || HasPermission(rbac::RBAC_PERM_TWO_SIDE_CHARACTER_CREATION);
uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
bool checkHeroicReqs = createInfo->Class == CLASS_DEATH_KNIGHT && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_HEROIC_CHARACTER);
+ bool checkDemonHunterReqs = createInfo->Class == CLASS_DEMON_HUNTER && !HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_DEMON_HUNTER);
if (result)
{
uint32 team = Player::TeamForRace(createInfo->Race);
uint32 freeHeroicSlots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
+ uint32 freeDemonHunterSlots = sWorld->getIntConfig(CONFIG_DEMON_HUNTERS_PER_REALM);
Field* field = result->Fetch();
uint8 accRace = field[1].GetUInt8();
@@ -635,6 +648,30 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
}
}
+ if (checkDemonHunterReqs)
+ {
+ uint8 accClass = field[2].GetUInt8();
+ if (accClass == CLASS_DEMON_HUNTER)
+ {
+ if (freeDemonHunterSlots > 0)
+ --freeDemonHunterSlots;
+
+ if (freeDemonHunterSlots == 0)
+ {
+ SendCharCreate(CHAR_CREATE_FAILED);
+ _charCreateCallback.Reset();
+ return;
+ }
+ }
+
+ if (!hasDemonHunterReqLevel)
+ {
+ uint8 accLevel = field[0].GetUInt8();
+ if (accLevel >= demonHunterReqLevel)
+ hasDemonHunterReqLevel = true;
+ }
+ }
+
// need to check team only for first character
/// @todo what to if account already has characters of both races?
if (!allowTwoSideAccounts)
@@ -653,7 +690,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
// search same race for cinematic or same class if need
/// @todo check if cinematic already shown? (already logged in?; cinematic field)
- while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT)
+ while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT || createInfo->Class == CLASS_DEMON_HUNTER)
{
if (!result->NextRow())
break;
@@ -687,6 +724,30 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
hasHeroicReqLevel = true;
}
}
+
+ if (checkDemonHunterReqs)
+ {
+ uint8 accClass = field[2].GetUInt8();
+ if (accClass == CLASS_DEMON_HUNTER)
+ {
+ if (freeDemonHunterSlots > 0)
+ --freeDemonHunterSlots;
+
+ if (freeDemonHunterSlots == 0)
+ {
+ SendCharCreate(CHAR_CREATE_FAILED);
+ _charCreateCallback.Reset();
+ return;
+ }
+ }
+
+ if (!hasDemonHunterReqLevel)
+ {
+ uint8 accLevel = field[0].GetUInt8();
+ if (accLevel >= demonHunterReqLevel)
+ hasDemonHunterReqLevel = true;
+ }
+ }
}
}
@@ -697,6 +758,13 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac
return;
}
+ if (checkDemonHunterReqs && !hasDemonHunterReqLevel)
+ {
+ SendCharCreate(CHAR_CREATE_LEVEL_REQUIREMENT);
+ _charCreateCallback.Reset();
+ return;
+ }
+
Player newChar(this);
newChar.GetMotionMaster()->Initialize();
if (!newChar.Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo))
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index e2c80f16ca8..8d0030849c9 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -808,14 +808,23 @@ void World::LoadConfigSettings(bool reload)
}
m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = sConfigMgr->GetIntDefault("HeroicCharactersPerRealm", 1);
- if (int32(m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]) < 0 || m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 10)
+ if (int32(m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]) < 0 || m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 12)
{
- TC_LOG_ERROR("server.loading", "HeroicCharactersPerRealm (%i) must be in range 0..10. Set to 1.", m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]);
+ TC_LOG_ERROR("server.loading", "HeroicCharactersPerRealm (%i) must be in range 0..12. Set to 1.", m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]);
m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = 1;
}
m_int_configs[CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER] = sConfigMgr->GetIntDefault("CharacterCreating.MinLevelForHeroicCharacter", 55);
+ m_int_configs[CONFIG_DEMON_HUNTERS_PER_REALM] = sConfigMgr->GetIntDefault("DemonHuntersPerRealm", 1);
+ if (int32(m_int_configs[CONFIG_DEMON_HUNTERS_PER_REALM]) < 0 || m_int_configs[CONFIG_DEMON_HUNTERS_PER_REALM] > 12)
+ {
+ TC_LOG_ERROR("server.loading", "DemonHuntersPerRealm (%i) must be in range 0..12. Set to 1.", m_int_configs[CONFIG_DEMON_HUNTERS_PER_REALM]);
+ m_int_configs[CONFIG_DEMON_HUNTERS_PER_REALM] = 1;
+ }
+
+ m_int_configs[CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_DEMON_HUNTER] = sConfigMgr->GetIntDefault("CharacterCreating.MinLevelForDemonHunter", 70);
+
m_int_configs[CONFIG_SKIP_CINEMATICS] = sConfigMgr->GetIntDefault("SkipCinematics", 0);
if (int32(m_int_configs[CONFIG_SKIP_CINEMATICS]) < 0 || m_int_configs[CONFIG_SKIP_CINEMATICS] > 2)
{
@@ -866,6 +875,20 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = m_int_configs[CONFIG_MAX_PLAYER_LEVEL];
}
+ m_int_configs[CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL] = sConfigMgr->GetIntDefault("StartDemonHunterPlayerLevel", 98);
+ if (m_int_configs[CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL] < 98)
+ {
+ TC_LOG_ERROR("server.loading", "StartDemonHunterPlayerLevel (%i) must be in range 98..MaxPlayerLevel(%u). Set to 98.",
+ m_int_configs[CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL]);
+ m_int_configs[CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL] = 98;
+ }
+ else if (m_int_configs[CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL] > m_int_configs[CONFIG_MAX_PLAYER_LEVEL])
+ {
+ TC_LOG_ERROR("server.loading", "StartDemonHunterPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",
+ m_int_configs[CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL]);
+ m_int_configs[CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL] = m_int_configs[CONFIG_MAX_PLAYER_LEVEL];
+ }
+
m_int_configs[CONFIG_START_PLAYER_MONEY] = sConfigMgr->GetIntDefault("StartPlayerMoney", 0);
if (int32(m_int_configs[CONFIG_START_PLAYER_MONEY]) < 0)
{
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 1851ffa6079..9b1b2ade6cb 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -242,11 +242,14 @@ enum WorldIntConfigs
CONFIG_CHARACTERS_PER_REALM,
CONFIG_HEROIC_CHARACTERS_PER_REALM,
CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER,
+ CONFIG_DEMON_HUNTERS_PER_REALM,
+ CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_DEMON_HUNTER,
CONFIG_SKIP_CINEMATICS,
CONFIG_MAX_PLAYER_LEVEL,
CONFIG_MIN_DUALSPEC_LEVEL,
CONFIG_START_PLAYER_LEVEL,
CONFIG_START_HEROIC_PLAYER_LEVEL,
+ CONFIG_START_DEMON_HUNTER_PLAYER_LEVEL,
CONFIG_START_PLAYER_MONEY,
CONFIG_CURRENCY_START_APEXIS_CRYSTALS,
CONFIG_CURRENCY_MAX_APEXIS_CRYSTALS,