Added Scaling to boss and figured out event race conditions

This commit is contained in:
2024-09-20 01:17:39 -04:00
parent 7a73671b0f
commit e7d1b85074
5 changed files with 145 additions and 21 deletions

View File

@@ -1,5 +1,6 @@
#include "MapMgr.h"
#include "MpDataStore.h"
#include "ObjectMgr.h"
#include "MpLogger.h"
#include "MythicPlus.h"
#include "ScriptMgr.h"
@@ -12,9 +13,6 @@ public:
{
}
void Creature_SelectLevel(const CreatureTemplate* /*template*/, Creature* creature) override {
// LOG_INFO("module.MythicPlus", "Creature_SelectLevel({}, {}) for instance {}", creature->GetName(), creature->GetLevel(), creature->GetMap()->GetMapName());
}
void OnBeforeCreatureSelectLevel(const CreatureTemplate* /*creatureTemplate*/, Creature* creature, uint8& level) override {
@@ -23,6 +21,21 @@ public:
return;
}
if (!sMythicPlus->IsCreatureEligible(creature)) {
return;
}
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(!instanceData) {
return;
}
MpLogger::debug("OnBeforeCreatureSelectLevel({}, {}) for instance {}",
creature->GetName(),
level,
map->GetMapName()
);
// // bail if the creature is not eligible to be scaled
// if (!sMythicPlus->IsCreatureEligible(creature)) {
// return;
@@ -73,17 +86,21 @@ public:
if (creature->IsDungeonBoss()) {
level = instanceData->boss.avgLevel;
} else {
uint8 level = instanceData->creature.avgLevel;
level = uint8(irand(level-1, level+1));
level = uint8(urand(instanceData->creature.avgLevel-1, instanceData->creature.avgLevel+1));
}
MpLogger::debug("Setting creature level from {} to {} because {} mode is set", creature->GetLevel(), level, instanceData->difficulty);
uint32 diff = getMSTime();
creature->SelectLevel(level);
creature->UpdateAllStats();
creature->UpdateAllResistances();
creature->UpdateArmor();
creature->Update(diff);
// Scale the creature to its new level
sMythicPlus->ScaleCreature(level, creature);
MpLogger::debug("SetLevel and Updateded Creature {} Entry {} Id {} level from {} to {}",
creature->GetName(),
creature->GetEntry(),
creature->GetGUID().GetCounter(),
creature->GetLevel(),
level
);
// creature->SetLevel(level, false);
// MpLogger

View File

@@ -16,11 +16,36 @@ public:
void OnCreateMap(Map* map)
{
MpLogger::debug("AllMapScript::OnCreateMap(): {}", map->GetMapName());
if (!sMythicPlus->IsMapEligible(map)) {
return;
}
// Attempt to cast map to InstanceMap, making sure it is not null
InstanceMap* instance = dynamic_cast<InstanceMap*>(sMapMgr->FindMap(map->GetId(), map->GetInstanceId()));
if (!instance)
{
MpLogger::error("Failed to find InstanceMap for map ID {} and instance ID {}.", map->GetId(), map->GetInstanceId());
return;
}
Map::PlayerList playerList = instance->GetPlayers();
if (!playerList.IsEmpty()) {
for (auto i = playerList.begin(); i != playerList.end(); ++i) {
if (Player* iPlayer = i->GetSource()) {
Group* group = iPlayer->GetGroup();
if (group) {
MpLogger::debug("Player {} entered map {} in groupLeader {}", iPlayer->GetName(), map->GetMapName(), group->GetLeaderName());
} else {
return;
}
}
}
} else {
MpLogger::debug("No players found in map {}", map->GetMapName());
}
}
/**
@@ -80,7 +105,14 @@ public:
}
instanceData.difficulty = groupData->difficulty;
instanceData.instance = (InstanceMap*)sMapMgr->FindMap(map->GetId(), map->GetInstanceId());
// Attempt to cast map to InstanceMap, making sure it is not null
instanceData.instance = dynamic_cast<InstanceMap*>(sMapMgr->FindMap(map->GetId(), map->GetInstanceId()));
if (!instanceData.instance)
{
MpLogger::error("Failed to find InstanceMap for map ID {} and instance ID {}.", map->GetId(), map->GetInstanceId());
return;
}
MpLogger::debug("Setting up instance data for group {} for map {} instance {} data {}",
group->GetGUID().GetCounter(),

View File

@@ -1,4 +1,5 @@
#include "MythicPlus.h"
#include "ObjectMgr.h"
#include "MapMgr.h"
bool MythicPlus::IsMapEligible(Map* map)
@@ -60,5 +61,76 @@ bool MythicPlus::IsCreatureEligible(Creature* creature)
}
return true;
}
void MythicPlus::ScaleCreature(uint8 level, Creature* creature)
{
creature->SetLevel(level);
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(
level,
creature->GetCreatureTemplate()->unit_class
);
uint32 rank = 0;
CreatureTemplate const* cInfo = creature->GetCreatureTemplate();
if(cInfo && cInfo->rank > 0) {
rank = cInfo->rank;
}
// Scales the creatures hitpoints
float healthmod = GetHealthModifier(rank);
uint32 basehp = std::max<uint32>(1, stats->GenerateHealth(cInfo));
uint32 health = uint32(basehp * healthmod);
creature->SetCreateHealth(health);
creature->SetMaxHealth(health);
creature->SetHealth(health);
creature->ResetPlayerDamageReq();
// Scales the creatures mana
uint32 mana = stats->GenerateMana(cInfo);
creature->SetCreateMana(mana);
creature->SetMaxPower(POWER_MANA, mana);
creature->SetPower(POWER_MANA, mana);
creature->SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
creature->SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana);
// Scales the damage
float basedamage = stats->GenerateBaseDamage(cInfo);
float weaponBaseMinDamage = basedamage;
float weaponBaseMaxDamage = basedamage * 1.5;
creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, weaponBaseMinDamage);
creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
creature->SetBaseWeaponDamage(OFF_ATTACK, MINDAMAGE, weaponBaseMinDamage);
creature->SetBaseWeaponDamage(OFF_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
creature->SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, weaponBaseMinDamage);
creature->SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
creature->SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower);
creature->SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower);
}
/**
* Function is copied because was not accessible in core creature class
*/
float GetHealthModifier(int32 Rank)
{
switch (Rank) // define rates for each elite rank
{
case CREATURE_ELITE_NORMAL:
return sWorld->getRate(RATE_CREATURE_NORMAL_HP);
case CREATURE_ELITE_ELITE:
return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_HP);
case CREATURE_ELITE_RAREELITE:
return sWorld->getRate(RATE_CREATURE_ELITE_RAREELITE_HP);
case CREATURE_ELITE_WORLDBOSS:
return sWorld->getRate(RATE_CREATURE_ELITE_WORLDBOSS_HP);
case CREATURE_ELITE_RARE:
return sWorld->getRate(RATE_CREATURE_ELITE_RARE_HP);
default:
return sWorld->getRate(RATE_CREATURE_ELITE_ELITE_HP);
}
}

View File

@@ -61,6 +61,9 @@ public:
// The creature should be given Mythic+ scaling and powers check for pets, npcs, etc
bool IsCreatureEligible(Creature* creature);
// Scales the creature based on the level and the creature base stats
void ScaleCreature(uint8 level, Creature* creature);
private:
MythicPlus() { }
~MythicPlus() { }

View File

@@ -27,7 +27,7 @@ public:
.melee = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonMelee", 1.25f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonSpell", 1.15f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonArmor", 1.25f),
.avgLevel = sConfigMgr->GetOption<uint32>("MythicPlus.Mythic.DungeonAvgLevel", 83)
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Mythic.DungeonAvgLevel", 83)
};
sMythicPlus->mythicBossModifiers = {
@@ -35,7 +35,7 @@ public:
.melee = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossMelee", 1.35f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossSpell", 1.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Mythic.DungeonBossArmor", 1.35f),
.avgLevel = sConfigMgr->GetOption<uint32>("MythicPlus.Mythic.DungeonBossLevel", 85)
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Mythic.DungeonBossLevel", 85)
};
// Legendary Difficulty Modifiers
@@ -44,7 +44,7 @@ public:
.melee = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonMelee", 2.25f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonSpell", 2.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonArmor", 2.25f),
.avgLevel = sConfigMgr->GetOption<uint32>("MythicPlus.Legendary.DungeonAvgLevel", 85)
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Legendary.DungeonAvgLevel", 85)
};
sMythicPlus->legendaryBossModifiers = {
@@ -52,7 +52,7 @@ public:
.melee = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossMelee", 2.25f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossSpell", 2.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Legendary.DungeonBossArmor", 3.25f),
.avgLevel = sConfigMgr->GetOption<uint32>("MythicPlus.Legendary.DungeonBossLevel", 87)
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Legendary.DungeonBossLevel", 87)
};
sMythicPlus->ascendantDungeonModifiers = {
@@ -60,7 +60,7 @@ public:
.melee = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonMelee", 3.25f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonSpell", 3.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonArmor", 3.25f),
.avgLevel = sConfigMgr->GetOption<uint32>("MythicPlus.Ascendant.DungeonAvgLevel", 87)
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Ascendant.DungeonAvgLevel", 87)
};
sMythicPlus->ascendantBossModifiers = {
@@ -68,7 +68,7 @@ public:
.melee = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossMelee", 3.25f),
.spell = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossSpell", 3.25f),
.armor = sConfigMgr->GetOption<float>("MythicPlus.Ascendant.DungeonBossArmor", 3.25f),
.avgLevel = sConfigMgr->GetOption<uint32>("MythicPlus.Ascendant.DungeonBossLevel", 90)
.avgLevel = sConfigMgr->GetOption<uint8>("MythicPlus.Ascendant.DungeonBossLevel", 90)
};
// Death Allowances