Forum > Miscellaneous
[QUESTION:Wrath] New Dungeon Difficulty
<< < (2/5) > >>
schlumpf:
https://wowdev.wiki/DB/Difficulty?
Nupper:
--- Quote from: "schlumpf" ---https://wowdev.wiki/DB/Difficulty? --- End quote --- EPIC Dungeon difficulty was unused in wrath trying to figure how to add it...
Grymskvll:
--- Quote from: "schlumpf" ---https://wowdev.wiki/DB/Difficulty? --- End quote ---
On that note, I guess you'd have to add epic difficulty entries in MapDifficulty.dbc.
From what I gather, TrinityCore gets creature stats from the world.creature_template database. I'm guessing that you would put a reference to an epic difficulty version of the creature in difficulty_entry_2 of the normal mode creature entry. At least, that's how it's done for raids.
So you would need to create new epic version entries in creature_template for each creature in each dungeon that you want to have an epic difficulty setting, and then reference those new epic versions in difficulty_entry_2 of the normal version.
Of course, that's not all you'd need to do to make the difficulty work.
Grymskvll:
--- Quote from: "Grymskvll" ---You'll also need to increment the MAX_DUNGEON_DIFFICULTY constant. Not sure what else you'd need. --- End quote ---
Oops nevermind that, it's not needed at all.
I tried adding an Eluna playermethod for setting dungeon difficulty (so that the button would work), and it worked... but with a major flaw. The client's difficulty doesn't get updated until you relog. I guess you would either have to send some kind of difficulty mode update from the server to the client, or else modify Wow.exe so that it accepts 3 as a valid SetDungeonDifficulty setting.
Edit: oops, just realized that the core has Player::SendDungeonDifficulty built in. After all, it has to update group members' dungeon difficulty when the party leader sets it.
Grymskvll:
I'm stuck. I've managed to set dungeon difficulty to Epic from the interface and create an empty Epic difficulty instance, but I can't figure out how to spawn creatures. The earliest function I can find that's called when instance creatures are spawned is Creature::LoadCreatureFromDB, but none of the places that call that function are called when you create a dungeon instance... So what the hell is calling Creature::LoadCreatureFromDB???
If you want to try debugging, here's what I did to enable the Epic dungeon difficulty:
Look up the Map entry you want to have an Epic difficulty in Map.dbc, then in MapDifficulty.dbc, create a new entry for your Map ID with the difficulty field set to 2 (Epic).
This step wont work since there's something missing, but it will be required if someone figures it out. In your mysql world.creature_template, copy entries for all the heroic versions for creatures in that Map, but change the name to have a "(2)" at the end, just like how heroic versions have "(1)". Make sure the new Epic entries you make have nothing in the "difficulty_entry_#" fields. In all the normal mode entries in creature_template, add a reference to the new entry you made in difficulty_entry_2
In WorldSession.h, add this below "void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData);":
--- Code: ---void HandleSetDungeonDifficulty(Difficulty mode);
--- End code ---
In MiscHandler.cpp, add:
--- Code: ---void WorldSession::HandleSetDungeonDifficulty(Difficulty mode) { TC_LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY");
if (mode >= MAX_DUNGEON_DIFFICULTY) { TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUID().GetCounter(), mode); return; }
if (Difficulty(mode) == _player->GetDungeonDifficulty()) return;
// cannot reset while in an instance Map* map = _player->FindMap(); if (map && map->IsDungeon()) { TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player (Name: %s, GUID: %u) tried to reset the instance while player is inside!", _player->GetName().c_str(), _player->GetGUID().GetCounter()); return; }
Group* group = _player->GetGroup(); if (group) { if (group->IsLeader(_player->GetGUID())) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* groupGuy = itr->GetSource(); if (!groupGuy) continue;
if (!groupGuy->IsInMap(groupGuy)) return;
if (groupGuy->GetMap()->IsNonRaidDungeon()) { TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while group member (Name: %s, GUID: %u) is inside!", _player->GetGUID().GetCounter(), groupGuy->GetName().c_str(), groupGuy->GetGUID().GetCounter()); return; } } // the difficulty is set even if the instances can't be reset //_player->SendDungeonDifficulty(true); group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player); group->SetDungeonDifficulty(Difficulty(mode)); } } else { _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false); _player->SetDungeonDifficulty(Difficulty(mode)); } }
--- End code ---
In Eluna's PlayerMethods.h, add:
--- Code: --- /** * Sets the [Player]s dungeon difficulty to the specified value * * @param uint32 difficulty */ int SetDungeonDifficulty(Eluna* /*E*/, lua_State* L, Player* player) { Difficulty difficulty = (Difficulty)Eluna::CHECKVAL<uint32>(L, 2, 0);
WorldSession* session = player->GetSession(); session->HandleSetDungeonDifficulty(difficulty);
bool isInGroup = (player->GetGroup() != 0); player->SendDungeonDifficulty(isInGroup);
return 0; }
--- End code ---
In Eluna's LuaFunctions.cpp, in "ElunaRegister<Player> PlayerMethods[]" add:
--- Code: ---{ "SetDungeonDifficulty", &LuaPlayer::SetDungeonDifficulty },
--- End code ---
And add this AIO script to your server's lua_scripts folder:
--- Code: ---local AIO = AIO or require("AIO") AIO.AddAddon()
if AIO.IsServer() then -- TrinityCore: starting from 0=normal, 1=heroic, 2=epic local MAX_DUNGEON_DIFFICULTY = 3 function HandlePlayerSetDungeonDifficulty(player, msg) -- difficulties start at 0 in TrinityCore, 1 in client msg = tonumber(msg) - 1 if msg >= 0 and msg < MAX_DUNGEON_DIFFICULTY then player:SetDungeonDifficulty(msg) end end AIO.RegisterEvent("SetDungeonDifficulty", HandlePlayerSetDungeonDifficulty) return end
UnitPopupButtons["DUNGEON_DIFFICULTY3"] = { text = DUNGEON_DIFFICULTY3, dist = 0 }; UnitPopupMenus["DUNGEON_DIFFICULTY"] = { "DUNGEON_DIFFICULTY1", "DUNGEON_DIFFICULTY2", "DUNGEON_DIFFICULTY3" }; DUNGEON_DIFFICULTY_5PLAYER_EPIC = "5 Player (Epic)";
function SetDungeonDifficultyCustom(difficulty) AIO.Msg():Add("SetDungeonDifficulty", difficulty):Send() end
origSetDungeonDifficulty = SetDungeonDifficulty SetDungeonDifficulty = function(...) local difficulty = ... if difficulty < 3 then origSetDungeonDifficulty(difficulty) else SetDungeonDifficultyCustom(difficulty) end end
--- End code ---
Apologies if there's any errors, I made some last minute changes as I was copying the code.
Edit: forgot to mention that if you want to try to add a new difficulty, you should try to add a heroic mode to a dungeon that normally doesn't have one first. That doesn't (or at least shouldn't) require the core mods and AIO script above, it should only require mysql database and DBC edits as far as I understand, but I can't even get that to work.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
|