From 35596b0b01d590c640151ede12ab8b6e12ade3a9 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Wed, 27 Apr 2022 15:12:33 +0200 Subject: [PATCH 01/21] fix(Core/Battlegrounds): Remove all DoTs when exiting battleground. (#11517) Fixes #11332 --- src/server/game/Entities/Player/Player.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3544fb2d1..603b3d508 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11033,6 +11033,11 @@ void Player::LeaveBattleground(Battleground* bg) // xinef: reset corpse reclaim time m_deathExpireTime = GameTime::GetGameTime().count(); + // Remove all dots + RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); + RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); + // pussywizard: clear movement, because after porting player will move to arena cords GetMotionMaster()->MovementExpired(); StopMoving(); From b7be09e96c285aa2d961fff6cbd6175139d8c6a8 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Wed, 27 Apr 2022 15:12:45 +0200 Subject: [PATCH 02/21] fix(Core/Players): Updates visibility of nearby entities around player's viewpoint in case of immediate changing farsight object. (#11520) Fixes #11322 --- src/server/game/Spells/SpellEffects.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 1fc7443c1..c911d506d 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2728,6 +2728,8 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex) dynObj->SetDuration(duration); dynObj->SetCasterViewpoint(); + + m_caster->ToPlayer()->UpdateVisibilityForPlayer(); } void Spell::EffectUntrainTalents(SpellEffIndex /*effIndex*/) From ad8f8ee5a5e8d3078406772d25aeedd4d109c2e4 Mon Sep 17 00:00:00 2001 From: IntelligentQuantum Date: Thu, 28 Apr 2022 00:27:21 +0430 Subject: [PATCH 03/21] feat(Tools): Automatically create directories for tools (#11540) * . * . --- src/common/Collision/Maps/TileAssembler.cpp | 3 ++- src/tools/mmaps_generator/PathGenerator.cpp | 3 +-- src/tools/vmap4_assembler/VMapAssembler.cpp | 15 +++++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp index 6f4760c68..806f4e202 100644 --- a/src/common/Collision/Maps/TileAssembler.cpp +++ b/src/common/Collision/Maps/TileAssembler.cpp @@ -23,6 +23,7 @@ #include #include #include +#include using G3D::Vector3; using G3D::AABox; @@ -54,7 +55,7 @@ namespace VMAP TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName) : iDestDir(pDestDirName), iSrcDir(pSrcDirName) { - //mkdir(iDestDir); + boost::filesystem::create_directory(iDestDir); //init(); } diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 1e59a3d20..18e070ae4 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -56,8 +56,7 @@ bool checkDirectories(bool debugOutput) dirFiles.clear(); if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) { - printf("'mmaps' directory does not exist\n"); - return false; + return boost::filesystem::create_directory("mmaps"); } dirFiles.clear(); diff --git a/src/tools/vmap4_assembler/VMapAssembler.cpp b/src/tools/vmap4_assembler/VMapAssembler.cpp index 8b37339e0..fbe5fadb5 100644 --- a/src/tools/vmap4_assembler/VMapAssembler.cpp +++ b/src/tools/vmap4_assembler/VMapAssembler.cpp @@ -22,14 +22,21 @@ int main(int argc, char* argv[]) { - if (argc != 3) + std::string src = "Buildings"; + std::string dest = "vmaps"; + + if (argc > 3) { std::cout << "usage: " << argv[0] << " " << std::endl; return 1; } - - std::string src = argv[1]; - std::string dest = argv[2]; + else + { + if (argc > 1) + src = argv[1]; + if (argc > 2) + dest = argv[2]; + } std::cout << "using " << src << " as source directory and writing output to " << dest << std::endl; From 59e45c251eb53abb0ed4b37a57254cbdf415e69a Mon Sep 17 00:00:00 2001 From: IntelligentQuantum Date: Thu, 28 Apr 2022 03:48:44 +0430 Subject: [PATCH 04/21] fix(Core/Spell): Improvements to path generation for Charge mechanic (#11534) It has its flaws but it can be improved and it's actually a lot better than what we currently have. --- src/server/game/Movement/MotionMaster.cpp | 13 +++++ src/server/game/Movement/MotionMaster.h | 1 + .../PointMovementGenerator.cpp | 2 +- src/server/game/Spells/Spell.cpp | 48 +++++++------------ src/server/game/Spells/Spell.h | 3 +- src/server/game/Spells/SpellEffects.cpp | 13 +++-- src/server/shared/SharedDefines.h | 5 ++ 7 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 4137758cc..6dd0d8f8a 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -608,6 +608,19 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, } } +void MotionMaster::MoveCharge(PathGenerator const& path, float speed /*= SPEED_CHARGE*/) +{ + G3D::Vector3 dest = path.GetActualEndPosition(); + + MoveCharge(dest.x, dest.y, dest.z, speed, EVENT_CHARGE_PREPATH); + + // Charge movement is not started when using EVENT_CHARGE_PREPATH + Movement::MoveSplineInit init(_owner); + init.MovebyPath(path.GetPath()); + init.SetVelocity(speed); + init.Launch(); +} + void MotionMaster::MoveSeekAssistance(float x, float y, float z) { // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index a23f7ce31..718177828 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -219,6 +219,7 @@ public: void MoveTakeoff(uint32 id, float x, float y, float z, float speed = 0.0f); // pussywizard: added for easy calling by passing 3 floats x, y, z void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, const Movement::PointsArray* path = nullptr, bool generatePath = false, float orientation = 0.0f, ObjectGuid targetGUID = ObjectGuid::Empty); + void MoveCharge(PathGenerator const& path, float speed = SPEED_CHARGE); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = 0) diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 501558066..6e8f80065 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -117,7 +117,7 @@ bool PointMovementGenerator::DoUpdate(T* unit, uint32 /*diff*/) unit->AddUnitState(UNIT_STATE_ROAMING_MOVE); - if (i_recalculateSpeed && !unit->movespline->Finalized()) + if (id != EVENT_CHARGE_PREPATH && i_recalculateSpeed && !unit->movespline->Finalized()) { i_recalculateSpeed = false; Movement::MoveSplineInit init(unit); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index ebedfbb0d..93c8f5ed6 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -646,7 +646,6 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, m_glyphIndex = 0; m_preCastSpell = 0; m_spellAura = nullptr; - m_pathFinder = nullptr; // pussywizard _scriptsLoaded = false; //Auto Shot & Shoot (wand) @@ -701,7 +700,6 @@ Spell::~Spell() } delete m_spellValue; - delete m_pathFinder; // pussywizard CheckEffectExecuteData(); } @@ -6001,40 +5999,28 @@ SpellCastResult Spell::CheckCast(bool strict) { Unit* target = m_targets.GetUnitTarget(); if (!target) - return SPELL_FAILED_BAD_TARGETS; + return SPELL_FAILED_DONT_REPORT; - Position pos; - target->GetChargeContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); + // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells + if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2 + return SPELL_FAILED_LINE_OF_SIGHT; - if (m_caster->GetMapId() == 618) // pussywizard: 618 Ring of Valor - pos.m_positionZ = std::max(pos.m_positionZ, 28.28f); + float objSize = target->GetCombatReach(); + float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict - float maxdist = m_caster->GetMeleeRange(target); - if (!target->IsInDist(&pos, maxdist)) + m_preGeneratedPath = std::make_unique(m_caster); + m_preGeneratedPath->SetPathLengthLimit(range); + + // first try with raycast, if it fails fall back to normal path + bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false); + if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT) + return SPELL_FAILED_NOPATH; + else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE)) + return SPELL_FAILED_NOPATH; + else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line return SPELL_FAILED_NOPATH; - if (m_caster->GetMapId() == 618) // pussywizard: 618 Ring of Valor - { - if (!((target->GetPositionZ() > 32.0f) ^ (m_caster->GetPositionZ() > 32.0f))) - break; - return SPELL_FAILED_NOPATH; - } - else if (m_caster->GetMapId() == 572) // pussywizard: 572 Ruins of Lordaeron - { - if (pos.GetPositionX() < 1275.0f || m_caster->GetPositionX() < 1275.0f) // special case (acid) - break; // can't force path because the way is around and the path is too long - } - - if (m_caster->GetTransport() != target->GetTransport()) - return SPELL_FAILED_NOPATH; - if (m_caster->GetTransport()) - break; - - m_pathFinder = new PathGenerator(m_caster); - m_pathFinder->CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.15f, false); - G3D::Vector3 endPos = m_pathFinder->GetEndPosition(); // also check distance between target and the point calculated by mmaps - if (m_pathFinder->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE) || target->GetExactDistSq(endPos.x, endPos.y, endPos.z) > maxdist * maxdist || m_pathFinder->getPathLength() > (40.0f + (m_caster->HasAura(58097) ? 5.0f : 0.0f))) - return SPELL_FAILED_NOPATH; + m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back } if (Player* player = m_caster->ToPlayer()) player->SetCanTeleport(true); diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index febc675ed..75cecae7b 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -544,8 +544,6 @@ public: UsedSpellMods m_appliedMods; - PathGenerator* m_pathFinder; // pussywizard: for precomputing path for charge - int32 GetCastTime() const { return m_casttime; } bool IsAutoRepeat() const { return m_autoRepeat; } void SetAutoRepeat(bool rep) { m_autoRepeat = rep; } @@ -770,6 +768,7 @@ public: bool m_skipCheck; uint8 m_auraScaleMask; + std::unique_ptr m_preGeneratedPath; // xinef: bool _spellTargetsSelected; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index c911d506d..9465bb82f 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4870,10 +4870,12 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) targetGUID = unitTarget->GetGUID(); } - if (m_pathFinder) + float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE; + // Spell is not using explicit target - no generated path + if (!m_preGeneratedPath) { - m_caster->GetMotionMaster()->MoveCharge(m_pathFinder->GetEndPosition().x, m_pathFinder->GetEndPosition().y, m_pathFinder->GetEndPosition().z, - 42.0f, EVENT_CHARGE, &m_pathFinder->GetPath(), false, 0.f, targetGUID); + Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetCombatReach(), unitTarget->GetRelativeAngle(m_caster)); + m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed); if (m_caster->GetTypeId() == TYPEID_PLAYER) { @@ -4882,10 +4884,7 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) } else { - Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetObjectSize(), unitTarget->GetRelativeAngle(m_caster)); - - m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + Z_OFFSET_FIND_HEIGHT, SPEED_CHARGE, EVENT_CHARGE, - nullptr, false, 0.f, targetGUID); + m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed); if (m_caster->GetTypeId() == TYPEID_PLAYER) { diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 5d24d3fb6..36a0c9242 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -3282,6 +3282,11 @@ enum SummonType enum EventId { EVENT_CHARGE = 1003, + + /// Special charge event which is used for charge spells that have explicit targets + /// and had a path already generated - using it in PointMovementGenerator will not + /// create a new spline and launch it + EVENT_CHARGE_PREPATH = 1005, }; enum ResponseCodes From 026941c39e2535dbf64455da72f8aed04194b7b1 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 28 Apr 2022 19:37:37 +0200 Subject: [PATCH 05/21] refactor(DB): Handle SQL files in a new way (#11494) * refactor(DB): Handle SQL files in a new way * remove proof that it works files * Update rev_1650721405699287200.sql * Update rev_1650721339143444200.sql * Update rev_1650721386624384400.sql * fix build * fix --- apps/ci/ci-pending-sql.sh | 42 ------------------- .../sql/updates/pending_db_auth/create_sql.sh | 2 +- .../rev_1650721405699287200.sql | 3 ++ .../pending_db_characters/create_sql.sh | 2 +- .../rev_1650721386624384400.sql | 3 ++ .../updates/pending_db_world/create_sql.sh | 2 +- .../rev_1650721339143444200.sql | 3 ++ src/server/game/World/IWorld.h | 4 -- src/server/game/World/World.cpp | 39 ----------------- src/server/game/World/World.h | 7 ---- src/server/scripts/Commands/cs_server.cpp | 3 -- src/server/worldserver/Main.cpp | 1 - src/test/mocks/WorldMock.h | 4 -- 13 files changed, 12 insertions(+), 103 deletions(-) create mode 100644 data/sql/updates/pending_db_auth/rev_1650721405699287200.sql create mode 100644 data/sql/updates/pending_db_characters/rev_1650721386624384400.sql create mode 100644 data/sql/updates/pending_db_world/rev_1650721339143444200.sql diff --git a/apps/ci/ci-pending-sql.sh b/apps/ci/ci-pending-sql.sh index b2f9751be..dcfb74df3 100644 --- a/apps/ci/ci-pending-sql.sh +++ b/apps/ci/ci-pending-sql.sh @@ -43,10 +43,6 @@ function import() { newVer=$dateToday"_"$cnt - startTransaction="START TRANSACTION;"; - updHeader="ALTER TABLE version_db_"$db" CHANGE COLUMN "$oldVer" "$newVer" bit;"; - endTransaction="COMMIT;"; - newFile="$updPath/"$dateToday"_"$cnt".sql" oldFile=$(basename "$entry") @@ -61,46 +57,8 @@ function import() { echo "-- DB update $oldVer -> $newVer" > "$newFile"; - if [[ $isRev -eq 1 ]]; then - echo "DROP PROCEDURE IF EXISTS \`updateDb\`;" >> "$newFile"; - echo "DELIMITER //" >> "$newFile"; - echo "CREATE PROCEDURE updateDb ()" >> "$newFile"; - echo "proc:BEGIN DECLARE OK VARCHAR(100) DEFAULT 'FALSE';" >> "$newFile"; - echo "SELECT COUNT(*) INTO @COLEXISTS" >> "$newFile"; - echo "FROM information_schema.COLUMNS" >> "$newFile"; - echo "WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'version_db_"$db"' AND COLUMN_NAME = '"$oldVer"';" >> "$newFile"; - echo "IF @COLEXISTS = 0 THEN LEAVE proc; END IF;" >> "$newFile"; - fi - - echo "$startTransaction" >> "$newFile"; - echo "$updHeader" >> "$newFile"; - - if [[ $isRev -eq 1 ]]; then - echo "SELECT sql_rev INTO OK FROM version_db_"$db" WHERE sql_rev = '$rev'; IF OK <> 'FALSE' THEN LEAVE proc; END IF;" >> "$newFile"; - fi; - - echo "--" >> "$newFile"; - echo "-- START UPDATING QUERIES" >> "$newFile"; - echo "--" >> "$newFile"; - echo "" >> "$newFile"; - cat $entry >> "$newFile"; - echo "" >> "$newFile"; - echo "--" >> "$newFile"; - echo "-- END UPDATING QUERIES" >> "$newFile"; - echo "--" >> "$newFile"; - echo "UPDATE version_db_"$db" SET date = '"$newVer"' WHERE sql_rev = '"$rev"';" >> "$newFile"; - - echo "$endTransaction" >> "$newFile"; - - if [[ $isRev -eq 1 ]]; then - echo "END //" >> "$newFile"; - echo "DELIMITER ;" >> "$newFile"; - echo "CALL updateDb();" >> "$newFile"; - echo "DROP PROCEDURE IF EXISTS \`updateDb\`;" >> "$newFile"; - fi; - currentHash="$(git log --diff-filter=A "$entry" | grep "^commit " | sed -e 's/commit //')" if [[ "$COMMIT_HASH" != *"$currentHash"* ]] diff --git a/data/sql/updates/pending_db_auth/create_sql.sh b/data/sql/updates/pending_db_auth/create_sql.sh index 2f4081235..21f356bd2 100755 --- a/data/sql/updates/pending_db_auth/create_sql.sh +++ b/data/sql/updates/pending_db_auth/create_sql.sh @@ -12,4 +12,4 @@ CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )/" && pwd )"; rev=$( $date +%s%N ); filename=rev_"$rev".sql -echo "INSERT INTO \`version_db_auth\` (\`sql_rev\`) VALUES ('"$rev"');" > "$CUR_PATH/$filename" && echo "File created: $filename"; +echo "--" > "$CUR_PATH/$filename" && echo "File created: $filename"; diff --git a/data/sql/updates/pending_db_auth/rev_1650721405699287200.sql b/data/sql/updates/pending_db_auth/rev_1650721405699287200.sql new file mode 100644 index 000000000..3abec0f23 --- /dev/null +++ b/data/sql/updates/pending_db_auth/rev_1650721405699287200.sql @@ -0,0 +1,3 @@ +-- + +DROP TABLE IF EXISTS `version_db_auth`; diff --git a/data/sql/updates/pending_db_characters/create_sql.sh b/data/sql/updates/pending_db_characters/create_sql.sh index 782fc2167..21f356bd2 100755 --- a/data/sql/updates/pending_db_characters/create_sql.sh +++ b/data/sql/updates/pending_db_characters/create_sql.sh @@ -12,4 +12,4 @@ CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )/" && pwd )"; rev=$( $date +%s%N ); filename=rev_"$rev".sql -echo "INSERT INTO \`version_db_characters\` (\`sql_rev\`) VALUES ('"$rev"');" > "$CUR_PATH/$filename" && echo "File created: $filename"; +echo "--" > "$CUR_PATH/$filename" && echo "File created: $filename"; diff --git a/data/sql/updates/pending_db_characters/rev_1650721386624384400.sql b/data/sql/updates/pending_db_characters/rev_1650721386624384400.sql new file mode 100644 index 000000000..914162936 --- /dev/null +++ b/data/sql/updates/pending_db_characters/rev_1650721386624384400.sql @@ -0,0 +1,3 @@ +-- + +DROP TABLE IF EXISTS `version_db_characters`; diff --git a/data/sql/updates/pending_db_world/create_sql.sh b/data/sql/updates/pending_db_world/create_sql.sh index a89149e63..21f356bd2 100755 --- a/data/sql/updates/pending_db_world/create_sql.sh +++ b/data/sql/updates/pending_db_world/create_sql.sh @@ -12,4 +12,4 @@ CUR_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )/" && pwd )"; rev=$( $date +%s%N ); filename=rev_"$rev".sql -echo "INSERT INTO \`version_db_world\` (\`sql_rev\`) VALUES ('"$rev"');" > "$CUR_PATH/$filename" && echo "File created: $filename"; +echo "--" > "$CUR_PATH/$filename" && echo "File created: $filename"; diff --git a/data/sql/updates/pending_db_world/rev_1650721339143444200.sql b/data/sql/updates/pending_db_world/rev_1650721339143444200.sql new file mode 100644 index 000000000..12442e909 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1650721339143444200.sql @@ -0,0 +1,3 @@ +-- + +DROP TABLE IF EXISTS `version_db_world`; diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index da1d2bcdd..cd1dbe220 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -583,11 +583,7 @@ public: virtual void UpdateRealmCharCount(uint32 accid) = 0; [[nodiscard]] virtual LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const = 0; virtual void LoadDBVersion() = 0; - virtual void LoadDBRevision() = 0; [[nodiscard]] virtual char const* GetDBVersion() const = 0; - [[nodiscard]] virtual char const* GetWorldDBRevision() const = 0; - [[nodiscard]] virtual char const* GetCharacterDBRevision() const = 0; - [[nodiscard]] virtual char const* GetAuthDBRevision() const = 0; virtual void LoadAutobroadcasts() = 0; virtual void UpdateAreaDependentAuras() = 0; [[nodiscard]] virtual uint32 GetCleaningFlags() const = 0; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 0d1363cfa..366f4412d 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -3268,45 +3268,6 @@ void World::LoadDBVersion() m_DBVersion = "Unknown world database."; } -void World::LoadDBRevision() -{ - QueryResult resultWorld = WorldDatabase.Query("SELECT date FROM version_db_world ORDER BY date DESC LIMIT 1"); - QueryResult resultCharacter = CharacterDatabase.Query("SELECT date FROM version_db_characters ORDER BY date DESC LIMIT 1"); - QueryResult resultAuth = LoginDatabase.Query("SELECT date FROM version_db_auth ORDER BY date DESC LIMIT 1"); - - if (resultWorld) - { - Field* fields = resultWorld->Fetch(); - - m_WorldDBRevision = fields[0].Get(); - } - if (resultCharacter) - { - Field* fields = resultCharacter->Fetch(); - - m_CharacterDBRevision = fields[0].Get(); - } - if (resultAuth) - { - Field* fields = resultAuth->Fetch(); - - m_AuthDBRevision = fields[0].Get(); - } - - if (m_WorldDBRevision.empty()) - { - m_WorldDBRevision = "Unkown World Database Revision"; - } - if (m_CharacterDBRevision.empty()) - { - m_CharacterDBRevision = "Unkown Character Database Revision"; - } - if (m_AuthDBRevision.empty()) - { - m_AuthDBRevision = "Unkown Auth Database Revision"; - } -} - void World::UpdateAreaDependentAuras() { SessionMap::const_iterator itr; diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 423bba669..7e7380d56 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -339,11 +339,7 @@ public: // used World DB version void LoadDBVersion() override; - void LoadDBRevision() override; [[nodiscard]] char const* GetDBVersion() const override { return m_DBVersion.c_str(); } - [[nodiscard]] char const* GetWorldDBRevision() const override { return m_WorldDBRevision.c_str(); } - [[nodiscard]] char const* GetCharacterDBRevision() const override { return m_CharacterDBRevision.c_str(); } - [[nodiscard]] char const* GetAuthDBRevision() const override { return m_AuthDBRevision.c_str(); } void LoadAutobroadcasts() override; @@ -440,9 +436,6 @@ private: // used versions std::string m_DBVersion; - std::string m_WorldDBRevision; - std::string m_CharacterDBRevision; - std::string m_AuthDBRevision; typedef std::map AutobroadcastsMap; AutobroadcastsMap m_Autobroadcasts; diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp index 5b93fa518..2e0c47200 100644 --- a/src/server/scripts/Commands/cs_server.cpp +++ b/src/server/scripts/Commands/cs_server.cpp @@ -213,9 +213,6 @@ public: handler->PSendSysMessage("Using %s DBC Locale as default. All available DBC locales: %s", localeNames[defaultLocale], availableLocales.c_str()); handler->PSendSysMessage("Using World DB: %s", sWorld->GetDBVersion()); - handler->PSendSysMessage("Using World DB Revision: %s", sWorld->GetWorldDBRevision()); - handler->PSendSysMessage("Using Character DB Revision: %s", sWorld->GetCharacterDBRevision()); - handler->PSendSysMessage("Using Auth DB Revision: %s", sWorld->GetAuthDBRevision()); handler->PSendSysMessage("LoginDatabase queue size: %zu", LoginDatabase.QueueSize()); handler->PSendSysMessage("CharacterDatabase queue size: %zu", CharacterDatabase.QueueSize()); diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 9822d52bc..4d2279633 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -478,7 +478,6 @@ bool StartDB() WorldDatabase.Execute("UPDATE version SET core_version = '{}', core_revision = '{}'", GitRevision::GetFullVersion(), GitRevision::GetHash()); // One-time query sWorld->LoadDBVersion(); - sWorld->LoadDBRevision(); LOG_INFO("server.loading", "> Version DB world: {}", sWorld->GetDBVersion()); diff --git a/src/test/mocks/WorldMock.h b/src/test/mocks/WorldMock.h index 832d4917a..73742627a 100644 --- a/src/test/mocks/WorldMock.h +++ b/src/test/mocks/WorldMock.h @@ -111,11 +111,7 @@ public: MOCK_METHOD(void, UpdateRealmCharCount, (uint32 accid), ()); MOCK_METHOD(LocaleConstant, GetAvailableDbcLocale, (LocaleConstant locale), (const)); MOCK_METHOD(void, LoadDBVersion, ()); - MOCK_METHOD(void, LoadDBRevision, ()); MOCK_METHOD(char const *, GetDBVersion, (), (const)); - MOCK_METHOD(char const *, GetWorldDBRevision, (), (const)); - MOCK_METHOD(char const *, GetCharacterDBRevision, (), (const)); - MOCK_METHOD(char const *, GetAuthDBRevision, (), (const)); MOCK_METHOD(void, LoadAutobroadcasts, ()); MOCK_METHOD(void, UpdateAreaDependentAuras, ()); MOCK_METHOD(uint32, GetCleaningFlags, (), (const)); From 9a34d981dabee4ec64c7b335b17276718c58ba48 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Thu, 28 Apr 2022 17:39:45 +0000 Subject: [PATCH 06/21] chore(DB): import pending files Referenced commit(s): 026941c39e2535dbf64455da72f8aed04194b7b1 --- .../rev_1650721405699287200.sql => db_auth/2022_04_28_00.sql} | 1 + .../2022_04_28_00.sql} | 1 + .../rev_1650721339143444200.sql => db_world/2022_04_28_00.sql} | 1 + 3 files changed, 3 insertions(+) rename data/sql/updates/{pending_db_auth/rev_1650721405699287200.sql => db_auth/2022_04_28_00.sql} (50%) rename data/sql/updates/{pending_db_characters/rev_1650721386624384400.sql => db_characters/2022_04_28_00.sql} (53%) rename data/sql/updates/{pending_db_world/rev_1650721339143444200.sql => db_world/2022_04_28_00.sql} (50%) diff --git a/data/sql/updates/pending_db_auth/rev_1650721405699287200.sql b/data/sql/updates/db_auth/2022_04_28_00.sql similarity index 50% rename from data/sql/updates/pending_db_auth/rev_1650721405699287200.sql rename to data/sql/updates/db_auth/2022_04_28_00.sql index 3abec0f23..f4fa48bf0 100644 --- a/data/sql/updates/pending_db_auth/rev_1650721405699287200.sql +++ b/data/sql/updates/db_auth/2022_04_28_00.sql @@ -1,3 +1,4 @@ +-- DB update 2022_04_24_00 -> 2022_04_28_00 -- DROP TABLE IF EXISTS `version_db_auth`; diff --git a/data/sql/updates/pending_db_characters/rev_1650721386624384400.sql b/data/sql/updates/db_characters/2022_04_28_00.sql similarity index 53% rename from data/sql/updates/pending_db_characters/rev_1650721386624384400.sql rename to data/sql/updates/db_characters/2022_04_28_00.sql index 914162936..4ed7f2ccc 100644 --- a/data/sql/updates/pending_db_characters/rev_1650721386624384400.sql +++ b/data/sql/updates/db_characters/2022_04_28_00.sql @@ -1,3 +1,4 @@ +-- DB update 2022_04_24_00 -> 2022_04_28_00 -- DROP TABLE IF EXISTS `version_db_characters`; diff --git a/data/sql/updates/pending_db_world/rev_1650721339143444200.sql b/data/sql/updates/db_world/2022_04_28_00.sql similarity index 50% rename from data/sql/updates/pending_db_world/rev_1650721339143444200.sql rename to data/sql/updates/db_world/2022_04_28_00.sql index 12442e909..8f72a07cc 100644 --- a/data/sql/updates/pending_db_world/rev_1650721339143444200.sql +++ b/data/sql/updates/db_world/2022_04_28_00.sql @@ -1,3 +1,4 @@ +-- DB update 2022_04_25_03 -> 2022_04_28_00 -- DROP TABLE IF EXISTS `version_db_world`; From 2bef6b497d2463bd2e013b2a367b438b8c34a94f Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Thu, 28 Apr 2022 20:49:56 +0200 Subject: [PATCH 07/21] fix(Scripts/Spells): Validate some spells in spell_generic (#11549) * fix(Scripts/Spells): Validate some spells in spell_generic * Update src/server/scripts/Spells/spell_generic.cpp --- src/server/scripts/Spells/spell_generic.cpp | 157 +++++++++++++++++--- 1 file changed, 135 insertions(+), 22 deletions(-) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index ef947aaf3..bf0847fd9 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -218,12 +218,23 @@ class spell_gen_have_item_auras : public AuraScript } }; +enum MineSweeper +{ + SPELL_LAND_MINE_KNOCKBACK = 54402, + SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT = 57064, +}; + /* 54355 - Detonation 57099 - Landmine Knockback Achievement Aura */ class spell_gen_mine_sweeper : public SpellScript { PrepareSpellScript(spell_gen_mine_sweeper); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LAND_MINE_KNOCKBACK, SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT}); + } + void HandleSchoolDMG(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); @@ -232,7 +243,7 @@ class spell_gen_mine_sweeper : public SpellScript return; target->RemoveAurasByType(SPELL_AURA_MOUNTED); - caster->CastSpell(target, 54402, true); + caster->CastSpell(target, SPELL_LAND_MINE_KNOCKBACK, true); } void HandleScriptEffect(SpellEffIndex /*effIndex*/) @@ -240,7 +251,7 @@ class spell_gen_mine_sweeper : public SpellScript if (Unit* target = GetHitPlayer()) if (Aura* aur = target->GetAura(GetSpellInfo()->Id)) if (aur->GetStackAmount() >= 10) - target->CastSpell(target, 57064, true); + target->CastSpell(target, SPELL_LANDMINE_KNOCKBACK_ACHIEVEMENT, true); } void Register() override @@ -1714,6 +1725,11 @@ class spell_gen_remove_flight_auras : public SpellScript { PrepareSpellScript(spell_gen_remove_flight_auras); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_AURA_FLY, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED }); + } + void HandleScript(SpellEffIndex /*effIndex*/) { if (Unit* target = GetHitUnit()) @@ -1840,6 +1856,11 @@ class spell_gen_teleporting : public SpellScript { PrepareSpellScript(spell_gen_teleporting); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TELEPORT_SPIRE_UP, SPELL_TELEPORT_SPIRE_DOWN }); + } + void HandleScript(SpellEffIndex /* effIndex */) { Unit* target = GetHitUnit(); @@ -2268,6 +2289,11 @@ class spell_gen_turkey_marker : public AuraScript { PrepareAuraScript(spell_gen_turkey_marker); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TURKEY_VENGEANCE }); + } + bool Load() override { _applyTimes.clear(); @@ -2470,7 +2496,14 @@ class spell_gen_damage_reduction_aura : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_DAMAGE_REDUCTION_AURA }); + return ValidateSpellInfo( + { + SPELL_DAMAGE_REDUCTION_AURA, + SPELL_BLESSING_OF_SANCTUARY, + SPELL_GREATER_BLESSING_OF_SANCTUARY, + SPELL_RENEWED_HOPE, + SPELL_VIGILANCE + }); } void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) @@ -2665,26 +2698,17 @@ class spell_gen_dalaran_disguise : public SpellScript { PrepareSpellScript(spell_gen_dalaran_disguise); - bool Validate(SpellInfo const* spellInfo) override + bool Validate(SpellInfo const* /*spellInfo*/) override { - switch (spellInfo->Id) - { - case SPELL_SUNREAVER_DISGUISE_TRIGGER: - return ValidateSpellInfo( - { - SPELL_SUNREAVER_DISGUISE_FEMALE, - SPELL_SUNREAVER_DISGUISE_MALE - }); - case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER: - return ValidateSpellInfo( - { - SPELL_SILVER_COVENANT_DISGUISE_FEMALE, - SPELL_SILVER_COVENANT_DISGUISE_MALE - }); - default: - break; - } - return false; + return ValidateSpellInfo( + { + SPELL_SUNREAVER_DISGUISE_TRIGGER, + SPELL_SUNREAVER_DISGUISE_FEMALE, + SPELL_SUNREAVER_DISGUISE_MALE, + SPELL_SILVER_COVENANT_DISGUISE_TRIGGER, + SPELL_SILVER_COVENANT_DISGUISE_FEMALE, + SPELL_SILVER_COVENANT_DISGUISE_MALE + }); } void HandleScript(SpellEffIndex /*effIndex*/) @@ -2759,6 +2783,19 @@ class spell_gen_break_shield : public SpellScript { PrepareSpellScript(spell_gen_break_shield) + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_BREAK_SHIELD_DAMAGE_2K, + SPELL_BREAK_SHIELD_DAMAGE_10K, + SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS, + SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE, + SPELL_BREAK_SHIELD_TRIGGER_UNK, + SPELL_BREAK_SHIELD_TRIGGER_SUNDERING_THURST + }); + } + void HandleScriptEffect(SpellEffIndex effIndex) { Unit* target = GetHitUnit(); @@ -2876,6 +2913,24 @@ class spell_gen_mounted_charge : public SpellScript { PrepareSpellScript(spell_gen_mounted_charge) + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_CHARGE_DAMAGE_8K5, + SPELL_CHARGE_DAMAGE_20K, + SPELL_CHARGE_DAMAGE_45K, + SPELL_CHARGE_CHARGING_EFFECT_8K5, + SPELL_CHARGE_CHARGING_EFFECT_20K_1, + SPELL_CHARGE_CHARGING_EFFECT_20K_2, + SPELL_CHARGE_CHARGING_EFFECT_45K_1, + SPELL_CHARGE_CHARGING_EFFECT_45K_2, + SPELL_CHARGE_TRIGGER_FACTION_MOUNTS, + SPELL_CHARGE_TRIGGER_TRIAL_CHAMPION, + SPELL_CHARGE_MISS_EFFECT + }); + } + void HandleScriptEffect(SpellEffIndex effIndex) { Unit* target = GetHitUnit(); @@ -3250,6 +3305,49 @@ class spell_gen_on_tournament_mount : public AuraScript { PrepareAuraScript(spell_gen_on_tournament_mount); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PENNANT_STORMWIND_ASPIRANT, + SPELL_PENNANT_STORMWIND_VALIANT, + SPELL_PENNANT_STORMWIND_CHAMPION, + SPELL_PENNANT_GNOMEREGAN_ASPIRANT, + SPELL_PENNANT_GNOMEREGAN_VALIANT, + SPELL_PENNANT_GNOMEREGAN_CHAMPION, + SPELL_PENNANT_SEN_JIN_ASPIRANT, + SPELL_PENNANT_SEN_JIN_VALIANT, + SPELL_PENNANT_SEN_JIN_CHAMPION, + SPELL_PENNANT_SILVERMOON_ASPIRANT, + SPELL_PENNANT_SILVERMOON_VALIANT, + SPELL_PENNANT_SILVERMOON_CHAMPION, + SPELL_PENNANT_DARNASSUS_ASPIRANT, + SPELL_PENNANT_DARNASSUS_VALIANT, + SPELL_PENNANT_DARNASSUS_CHAMPION, + SPELL_PENNANT_EXODAR_ASPIRANT, + SPELL_PENNANT_EXODAR_VALIANT, + SPELL_PENNANT_EXODAR_CHAMPION, + SPELL_PENNANT_IRONFORGE_ASPIRANT, + SPELL_PENNANT_IRONFORGE_VALIANT, + SPELL_PENNANT_IRONFORGE_CHAMPION, + SPELL_PENNANT_UNDERCITY_ASPIRANT, + SPELL_PENNANT_UNDERCITY_VALIANT, + SPELL_PENNANT_UNDERCITY_CHAMPION, + SPELL_PENNANT_ORGRIMMAR_ASPIRANT, + SPELL_PENNANT_ORGRIMMAR_VALIANT, + SPELL_PENNANT_ORGRIMMAR_CHAMPION, + SPELL_PENNANT_THUNDER_BLUFF_ASPIRANT, + SPELL_PENNANT_THUNDER_BLUFF_VALIANT, + SPELL_PENNANT_THUNDER_BLUFF_CHAMPION, + SPELL_PENNANT_ARGENT_CRUSADE_ASPIRANT, + SPELL_PENNANT_ARGENT_CRUSADE_VALIANT, + SPELL_PENNANT_ARGENT_CRUSADE_CHAMPION, + SPELL_PENNANT_EBON_BLADE_ASPIRANT, + SPELL_PENNANT_EBON_BLADE_VALIANT, + SPELL_PENNANT_EBON_BLADE_CHAMPION + }); + } + uint32 _pennantSpellId; bool Load() override @@ -3968,6 +4066,11 @@ class spell_gen_bonked : public SpellScript { PrepareSpellScript(spell_gen_bonked); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_BONKED, SPELL_FOAM_SWORD_DEFEAT, SPELL_ON_GUARD }); + } + void HandleScript(SpellEffIndex /*effIndex*/) { if (Player* target = GetHitPlayer()) @@ -4051,6 +4154,11 @@ class spell_gen_replenishment : public SpellScript { PrepareSpellScript(spell_gen_replenishment); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_REPLENISHMENT, SPELL_INFINITE_REPLENISHMENT }); + } + void RemoveInvalidTargets(std::list& targets) { // In arenas Replenishment may only affect the caster @@ -4352,6 +4460,11 @@ class spell_gen_holiday_buff_food : public AuraScript { PrepareAuraScript(spell_gen_holiday_buff_food); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WELL_FED }); + } + void TriggerFoodBuff(AuraEffect* aurEff) { if (aurEff->GetTickNumber() == 10 && GetUnitOwner()) From b62005a02f50d63cc8a1615c17a999fab90958a5 Mon Sep 17 00:00:00 2001 From: IntelligentQuantum Date: Fri, 29 Apr 2022 10:53:17 +0430 Subject: [PATCH 08/21] refactor(Tools/MeshExtractor): remove meshextractor (#11569) --- conf/dist/config.cmake | 1 - src/tools/CMakeLists.txt | 4 - src/tools/mesh_extractor/ADT.cpp | 70 --- src/tools/mesh_extractor/ADT.h | 49 -- src/tools/mesh_extractor/CMakeLists.txt | 49 -- src/tools/mesh_extractor/Cache.h | 80 --- src/tools/mesh_extractor/Chunk.cpp | 48 -- src/tools/mesh_extractor/Chunk.h | 37 -- src/tools/mesh_extractor/ChunkedData.cpp | 91 --- src/tools/mesh_extractor/ChunkedData.h | 38 -- src/tools/mesh_extractor/Constants.h | 75 --- src/tools/mesh_extractor/ContinentBuilder.cpp | 213 ------- src/tools/mesh_extractor/ContinentBuilder.h | 47 -- src/tools/mesh_extractor/DBC.cpp | 87 --- src/tools/mesh_extractor/DBC.h | 70 --- src/tools/mesh_extractor/DoodadHandler.cpp | 126 ---- src/tools/mesh_extractor/DoodadHandler.h | 78 --- src/tools/mesh_extractor/Geometry.cpp | 144 ----- src/tools/mesh_extractor/Geometry.h | 40 -- src/tools/mesh_extractor/LiquidHandler.cpp | 119 ---- src/tools/mesh_extractor/LiquidHandler.h | 38 -- src/tools/mesh_extractor/MPQ.cpp | 140 ----- src/tools/mesh_extractor/MPQ.h | 108 ---- src/tools/mesh_extractor/MPQMgr.cpp | 132 ---- src/tools/mesh_extractor/MPQMgr.h | 54 -- src/tools/mesh_extractor/MapChunk.cpp | 93 --- src/tools/mesh_extractor/MapChunk.h | 41 -- src/tools/mesh_extractor/MeshExtractor.cpp | 485 --------------- src/tools/mesh_extractor/Model.cpp | 83 --- src/tools/mesh_extractor/Model.h | 40 -- .../mesh_extractor/ObjectDataHandler.cpp | 24 - src/tools/mesh_extractor/ObjectDataHandler.h | 32 - src/tools/mesh_extractor/TileBuilder.cpp | 412 ------------- src/tools/mesh_extractor/TileBuilder.h | 51 -- src/tools/mesh_extractor/Utils.cpp | 563 ------------------ src/tools/mesh_extractor/Utils.h | 403 ------------- src/tools/mesh_extractor/WDT.cpp | 77 --- src/tools/mesh_extractor/WDT.h | 46 -- src/tools/mesh_extractor/WorldModelGroup.cpp | 160 ----- src/tools/mesh_extractor/WorldModelGroup.h | 55 -- .../mesh_extractor/WorldModelHandler.cpp | 234 -------- src/tools/mesh_extractor/WorldModelHandler.h | 64 -- src/tools/mesh_extractor/WorldModelRoot.cpp | 96 --- src/tools/mesh_extractor/WorldModelRoot.h | 44 -- src/tools/mesh_extractor/readme | 6 - 45 files changed, 4947 deletions(-) delete mode 100644 src/tools/mesh_extractor/ADT.cpp delete mode 100644 src/tools/mesh_extractor/ADT.h delete mode 100644 src/tools/mesh_extractor/CMakeLists.txt delete mode 100644 src/tools/mesh_extractor/Cache.h delete mode 100644 src/tools/mesh_extractor/Chunk.cpp delete mode 100644 src/tools/mesh_extractor/Chunk.h delete mode 100644 src/tools/mesh_extractor/ChunkedData.cpp delete mode 100644 src/tools/mesh_extractor/ChunkedData.h delete mode 100644 src/tools/mesh_extractor/Constants.h delete mode 100644 src/tools/mesh_extractor/ContinentBuilder.cpp delete mode 100644 src/tools/mesh_extractor/ContinentBuilder.h delete mode 100644 src/tools/mesh_extractor/DBC.cpp delete mode 100644 src/tools/mesh_extractor/DBC.h delete mode 100644 src/tools/mesh_extractor/DoodadHandler.cpp delete mode 100644 src/tools/mesh_extractor/DoodadHandler.h delete mode 100644 src/tools/mesh_extractor/Geometry.cpp delete mode 100644 src/tools/mesh_extractor/Geometry.h delete mode 100644 src/tools/mesh_extractor/LiquidHandler.cpp delete mode 100644 src/tools/mesh_extractor/LiquidHandler.h delete mode 100644 src/tools/mesh_extractor/MPQ.cpp delete mode 100644 src/tools/mesh_extractor/MPQ.h delete mode 100644 src/tools/mesh_extractor/MPQMgr.cpp delete mode 100644 src/tools/mesh_extractor/MPQMgr.h delete mode 100644 src/tools/mesh_extractor/MapChunk.cpp delete mode 100644 src/tools/mesh_extractor/MapChunk.h delete mode 100644 src/tools/mesh_extractor/MeshExtractor.cpp delete mode 100644 src/tools/mesh_extractor/Model.cpp delete mode 100644 src/tools/mesh_extractor/Model.h delete mode 100644 src/tools/mesh_extractor/ObjectDataHandler.cpp delete mode 100644 src/tools/mesh_extractor/ObjectDataHandler.h delete mode 100644 src/tools/mesh_extractor/TileBuilder.cpp delete mode 100644 src/tools/mesh_extractor/TileBuilder.h delete mode 100644 src/tools/mesh_extractor/Utils.cpp delete mode 100644 src/tools/mesh_extractor/Utils.h delete mode 100644 src/tools/mesh_extractor/WDT.cpp delete mode 100644 src/tools/mesh_extractor/WDT.h delete mode 100644 src/tools/mesh_extractor/WorldModelGroup.cpp delete mode 100644 src/tools/mesh_extractor/WorldModelGroup.h delete mode 100644 src/tools/mesh_extractor/WorldModelHandler.cpp delete mode 100644 src/tools/mesh_extractor/WorldModelHandler.h delete mode 100644 src/tools/mesh_extractor/WorldModelRoot.cpp delete mode 100644 src/tools/mesh_extractor/WorldModelRoot.h delete mode 100644 src/tools/mesh_extractor/readme diff --git a/conf/dist/config.cmake b/conf/dist/config.cmake index 43bc3dd5e..52d41a754 100644 --- a/conf/dist/config.cmake +++ b/conf/dist/config.cmake @@ -62,7 +62,6 @@ option(USE_COREPCH "Use precompiled headers when compiling servers" option(WITH_WARNINGS "Show all warnings during compile" 0) option(WITH_COREDEBUG "Include additional debug-code in core" 0) option(WITH_PERFTOOLS "Enable compilation with gperftools libraries included" 0) -option(WITH_MESHEXTRACTOR "Build meshextractor (alpha)" 0) option(WITHOUT_GIT "Disable the GIT testing routines" 0) option(ENABLE_VMAP_CHECKS "Enable Checks relative to DisableMgr system on vmap" 1) option(WITH_DYNAMIC_LINKING "Enable dynamic library linking." 0) diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 1eed02cf0..046265c77 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -14,7 +14,3 @@ add_subdirectory(map_extractor) add_subdirectory(vmap4_assembler) add_subdirectory(vmap4_extractor) add_subdirectory(mmaps_generator) - -if (WITH_MESHEXTRACTOR) - add_subdirectory(mesh_extractor) -endif() diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp deleted file mode 100644 index 0777387f2..000000000 --- a/src/tools/mesh_extractor/ADT.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ADT.h" -#include "DoodadHandler.h" -#include "LiquidHandler.h" -#include "WorldModelHandler.h" - -ADT::ADT( std::string file, int x, int y ) : ObjectData(nullptr), Data(nullptr), HasObjectData(false), - _DoodadHandler(nullptr), _WorldModelHandler(nullptr), _LiquidHandler(nullptr), X(x), Y(y) -{ - Data = new ChunkedData(file); - ObjectData = new ChunkedData(file); - if (ObjectData->Stream) - HasObjectData = true; - else - ObjectData = nullptr; -} - -ADT::~ADT() -{ - delete ObjectData; - delete Data; - - for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) - delete *itr; - - MapChunks.clear(); - delete _DoodadHandler; - delete _WorldModelHandler; - delete _LiquidHandler; -} - -void ADT::Read() -{ - Header.Read(Data->GetChunkByName("MHDR")->GetStream()); - MapChunks.reserve(16 * 16); - - for (std::vector::iterator itr = Data->Chunks.begin(); itr != Data->Chunks.end(); ++itr) - if ((*itr)->Name == "MCNK") - MapChunks.push_back(new MapChunk(this, *itr)); - - _LiquidHandler = new LiquidHandler(this); - - // do this separate from map chunk initialization to access liquid data - for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) - (*itr)->GenerateTriangles(); - - _DoodadHandler = new DoodadHandler(this); - for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) - _DoodadHandler->ProcessMapChunk(*itr); - - _WorldModelHandler = new WorldModelHandler(this); - for (std::vector::iterator itr = MapChunks.begin(); itr != MapChunks.end(); ++itr) - _WorldModelHandler->ProcessMapChunk(*itr); -} diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h deleted file mode 100644 index 372a1f005..000000000 --- a/src/tools/mesh_extractor/ADT.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ADT_H -#define ADT_H -#include "ChunkedData.h" -#include "MapChunk.h" - -class DoodadHandler; -class WorldModelHandler; -class LiquidHandler; - -class ADT -{ -public: - ADT(std::string file, int x, int y); - ~ADT(); - - void Read(); - - ChunkedData* ObjectData; - ChunkedData* Data; - std::vector MapChunks; - MHDR Header; - // Can we dispose of this? - bool HasObjectData; - - DoodadHandler* _DoodadHandler; - WorldModelHandler* _WorldModelHandler; - LiquidHandler* _LiquidHandler; - - int X; - int Y; -}; -#endif diff --git a/src/tools/mesh_extractor/CMakeLists.txt b/src/tools/mesh_extractor/CMakeLists.txt deleted file mode 100644 index 9a0dd2cef..000000000 --- a/src/tools/mesh_extractor/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# -# This file is part of the AzerothCore Project. See AUTHORS file for Copyright information -# -# This file is free software; as a special exception the author gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# - -CollectSourceFiles( - ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE_SOURCES) - -add_executable(MeshExtractor ${PRIVATE_SOURCES}) - -target_link_libraries(MeshExtractor - PRIVATE - acore-core-interface - PUBLIC - common - Recast - mpq) - -# Group sources -GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) - -CollectIncludeDirectories( - ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC_INCLUDES) - -target_include_directories(MeshExtractor - PUBLIC - ${PUBLIC_INCLUDES} - PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}) - -set_target_properties(MeshExtractor - PROPERTIES - FOLDER - "tools") - -if( UNIX ) - install(TARGETS MeshExtractor DESTINATION bin) -elseif( WIN32 ) - install(TARGETS MeshExtractor DESTINATION "${CMAKE_INSTALL_PREFIX}") -endif() diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h deleted file mode 100644 index 88d5cd231..000000000 --- a/src/tools/mesh_extractor/Cache.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef CACHE_H -#define CACHE_H -#include "Define.h" -#include "Model.h" -#include "PolicyLock.h" -#include "WorldModelRoot.h" -#include -#include -#include - -template -class GenericCache -{ -public: - GenericCache() {} - - static const uint32 FlushLimit = 300; // We can't get too close to filling up all the memory, and we have to be wary of the maximum number of open streams. - - void Insert(K key, T* val) - { - std::lock_guard guard(mutex); - - if (_items.size() > FlushLimit) - Clear(); - _items[key] = val; - } - - T* Get(K key) - { - GUARD_RETURN(mutex, nullptr); - typename std::map::iterator itr = _items.find(key); - if (itr != _items.end()) - return itr->second; - return nullptr; - } - - void Clear() - { - for (typename std::map::iterator itr = _items.begin(); itr != _items.end(); ++itr) - delete itr->second; - _items.clear(); - } -private: - std::map _items; - std::mutex mutex; -}; - -class CacheClass -{ -public: - CacheClass() {} - GenericCache ModelCache; - GenericCache WorldModelCache; - - void Clear() - { - ModelCache.Clear(); - WorldModelCache.Clear(); - } -}; - -extern CacheClass* Cache; -#endif diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp deleted file mode 100644 index c16d7cf84..000000000 --- a/src/tools/mesh_extractor/Chunk.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Chunk.h" -#include "Utils.h" - -int32 Chunk::FindSubChunkOffset(std::string name) -{ - // Reverse the name - name = std::string(name.rbegin(), name.rend()); - if (name.size() != 4) - return -1; - - FILE* stream = GetStream(); - uint32 matched = 0; - while (uint32(ftell(stream)) < Utils::Size(stream)) - { - char b = 0; - if (fread(&b, sizeof(char), 1, stream) != 1 || b != name[matched]) - matched = 0; - else - ++matched; - - if (matched == 4) - return ftell(stream) - 4; - } - return -1; -} - -FILE* Chunk::GetStream() -{ - fseek(Stream, Offset, SEEK_SET); - return Stream; -} diff --git a/src/tools/mesh_extractor/Chunk.h b/src/tools/mesh_extractor/Chunk.h deleted file mode 100644 index 056c8925f..000000000 --- a/src/tools/mesh_extractor/Chunk.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef CHUNK_H -#define CHUNK_H -#include "Define.h" -#include -class ChunkedData; - -class Chunk -{ -public: - Chunk(const char* name, uint32 length, uint32 offset, FILE* stream) : Name(name), Length(length), Offset(offset), Stream(stream) {} - - int32 FindSubChunkOffset(std::string name); - FILE* GetStream(); - std::string Name; - uint32 Length; - uint32 Offset; - FILE* Stream; -}; - -#endif diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp deleted file mode 100644 index c0c1df88c..000000000 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ChunkedData.h" -#include "MPQMgr.h" -#include "Utils.h" - -#include - -ChunkedData::ChunkedData( FILE* stream, uint32 maxLength, uint32 chunksHint /*= 300*/ ) : - Stream(stream) -{ - if (!Stream) - return; - Load(maxLength, chunksHint); -} - -ChunkedData::ChunkedData( const std::string& file, uint32 chunksHint /*= 300*/ ) -{ - Stream = MPQHandler->GetFile(file); - if (!Stream) - return; - Load(0, chunksHint); -} - -void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) -{ - if (!maxLength) - maxLength = Utils::Size(Stream); - Chunks.reserve(chunksHint); - uint32 baseOffset = ftell(Stream); - uint32 calcOffset = 0; - while ((calcOffset + baseOffset) < Utils::Size(Stream) && (calcOffset < maxLength)) - { - char nameBytes[5]; - uint32 read = fread(&nameBytes, sizeof(char), 4, Stream); - nameBytes[read] = '\0'; - std::string name = std::string(nameBytes); - // Utils::Reverse(nameBytes); - name = std::string(name.rbegin(), name.rend()); - uint32 length; - if (fread(&length, sizeof(uint32), 1, Stream) != 1) - continue; - calcOffset += 8; - Chunks.push_back(new Chunk(name.c_str(), length, calcOffset + baseOffset, Stream)); - calcOffset += length; - // save an extra seek at the end - if ((calcOffset + baseOffset) < Utils::Size(Stream) && calcOffset < maxLength) - fseek(Stream, length, SEEK_CUR); - } -} - -int ChunkedData::GetFirstIndex( const std::string& name ) -{ - for (uint32 i = 0; i < Chunks.size(); ++i) - if (Chunks[i]->Name == name) - return i; - return -1; -} - -Chunk* ChunkedData::GetChunkByName( const std::string& name ) -{ - for (uint32 i = 0; i < Chunks.size(); ++i) - if (Chunks[i]->Name == name) - return Chunks[i]; - return nullptr; -} - -ChunkedData::~ChunkedData() -{ - for (std::vector::iterator itr = Chunks.begin(); itr != Chunks.end(); ++itr) - delete *itr; - - Chunks.clear(); - if (Stream) - fclose(Stream); -} diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h deleted file mode 100644 index 6af885d67..000000000 --- a/src/tools/mesh_extractor/ChunkedData.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef CHNK_H -#define CHNK_H - -#include "Chunk.h" -#include - -class ChunkedData -{ -public: - ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); - ChunkedData(const std::string& file, uint32 chunksHint = 300); - ~ChunkedData(); - - int GetFirstIndex(const std::string& name); - Chunk* GetChunkByName(const std::string& name); - - void Load(uint32 maxLength, uint32 chunksHint); - std::vector Chunks; - FILE* Stream; -}; -#endif diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h deleted file mode 100644 index e5a3221c4..000000000 --- a/src/tools/mesh_extractor/Constants.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef CONSTANTS_H -#define CONSTANTS_H - -class Constants -{ -public: - enum TriangleType - { - TRIANGLE_TYPE_UNKNOWN, - TRIANGLE_TYPE_TERRAIN, - TRIANGLE_TYPE_WATER, - TRIANGLE_TYPE_DOODAD, - TRIANGLE_TYPE_WMO - }; - - enum PolyArea - { - POLY_AREA_TERRAIN = 1, - POLY_AREA_WATER = 2, - POLY_AREA_ROAD = 3, - POLY_AREA_DANGER = 4, - }; - - enum PolyFlag - { - POLY_FLAG_WALK = 1, - POLY_FLAG_SWIM = 2, - POLY_FLAG_FLIGHTMASTER = 4 - }; - - enum ExtractFlags - { - EXTRACT_FLAG_DBC = 0x01, - EXTRACT_FLAG_MAPS = 0x02, - EXTRACT_FLAG_VMAPS = 0x04, - EXTRACT_FLAG_GOB_MODELS = 0x08, - EXTRACT_FLAG_MMAPS = 0x10, - EXTRACT_FLAG_TEST = 0x20, - EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS | EXTRACT_FLAG_TEST - }; - - static const float TileSize; - static const float MaxXY; - static const float ChunkSize; - static const float UnitSize; - static const float Origin[]; - static const float PI; - static const float MaxStandableHeight; - static bool ToWoWCoords; - static bool Debug; - static const char* VMAPMagic; - static const float BaseUnitDim; - static const int VertexPerMap; - static const int VertexPerTile; - static const int TilesPerMap; -}; - -#endif diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp deleted file mode 100644 index 06ac2dc9e..000000000 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ContinentBuilder.h" -#include "Cache.h" -#include "DetourCommon.h" -#include "DetourNavMesh.h" -#include "Recast.h" -#include "TileBuilder.h" -#include "Utils.h" -#include "WDT.h" -#include - -class BuilderThread -{ -private: - int X, Y, MapId; - std::string Continent; - dtNavMeshParams Params; - ContinentBuilder* cBuilder; -public: - BuilderThread(ContinentBuilder* _cBuilder, dtNavMeshParams& params) : Params(params), cBuilder(_cBuilder), Free(true) {} - - void SetData(int x, int y, int map, const std::string& cont) - { - X = x; - Y = y; - MapId = map; - Continent = cont; - } - - int svc() - { - Free = false; - printf("[%02i,%02i] Building tile\n", X, Y); - TileBuilder builder(cBuilder, Continent, X, Y, MapId); - char buff[100]; - sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); - FILE* f = fopen(buff, "r"); - if (f) // Check if file already exists. - { - printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); - fclose(f); - Free = true; - return 0; - } - uint8* nav = builder.BuildTiled(Params); - if (nav) - { - f = fopen(buff, "wb"); - if (!f) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return 0; - } - MmapTileHeader header; - header.size = builder.DataSize; - fwrite(&header, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(unsigned char), builder.DataSize, f); - fclose(f); - } - dtFree(nav); - printf("[%02i,%02i] Tile Built!\n", X, Y); - Free = true; - return 0; - } - - bool Free; -}; - -void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) -{ - // this is for elevation - if (verts && vertCount) - rcCalcBounds(verts, vertCount, bmin, bmax); - else - { - bmin[1] = FLT_MIN; - bmax[1] = FLT_MAX; - } - - // this is for width and depth - bmax[0] = (32 - int(tileX)) * Constants::TileSize; - bmax[2] = (32 - int(tileY)) * Constants::TileSize; - bmin[0] = bmax[0] - Constants::TileSize; - bmin[2] = bmax[2] - Constants::TileSize; -} - -void ContinentBuilder::CalculateTileBounds() -{ - for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) - { - tileXMax = std::max(itr->X, tileXMax); - tileXMin = std::min(itr->X, tileXMin); - - tileYMax = std::max(itr->Y, tileYMax); - tileYMin = std::min(itr->Y, tileYMin); - } - getTileBounds(tileXMax, tileYMax, nullptr, 0, bmin, bmax); -} - -void ContinentBuilder::Build() -{ - char buff[50]; - sprintf(buff, "mmaps/%03u.mmap", MapId); - FILE* mmap = fopen(buff, "wb"); - if (!mmap) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return; - } - - CalculateTileBounds(); - - dtNavMeshParams params; - - std::vector Threads; - - if (TileMap->IsGlobalModel) - { - printf("Map %s ( %u ) is a WMO. Building with 1 thread.\n", Continent.c_str(), MapId); - - TileBuilder* builder = new TileBuilder(this, Continent, 0, 0, MapId); - builder->AddGeometry(TileMap->Model, TileMap->ModelDefinition); - uint8* nav = builder->BuildInstance(params); - if (nav) - { - // Set some params for the navmesh - dtMeshHeader* header = (dtMeshHeader*)nav; - dtVcopy(params.orig, header->bmin); - params.tileWidth = header->bmax[0] - header->bmin[0]; - params.tileHeight = header->bmax[2] - header->bmin[2]; - params.maxTiles = 1; - params.maxPolys = header->polyCount; - fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); - fclose(mmap); - - char buff[100]; - sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, 0, 0); - FILE* f = fopen(buff, "wb"); - if (!f) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return; - } - - MmapTileHeader mheader; - mheader.size = builder->DataSize; - fwrite(&mheader, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(unsigned char), builder->DataSize, f); - fclose(f); - } - - dtFree(nav); - delete builder; - } - else - { - params.maxPolys = 32768; - params.maxTiles = 4096; - rcVcopy(params.orig, Constants::Origin); - params.tileHeight = Constants::TileSize; - params.tileWidth = Constants::TileSize; - fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); - fclose(mmap); - - for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(this, params)); - printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); - for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) - { - bool next = false; - while (!next) - { - for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) - { - if ((*_th)->Free) - { - (*_th)->SetData(itr->X, itr->Y, MapId, Continent); - (*_th)->activate(); - next = true; - break; - } - } - // Wait for 20 seconds - std::this_thread::sleep_for(std::chrono::seconds(20)); - } - } - } - - Cache->Clear(); - - // Free memory - for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) - { - (*_th)->wait(); - delete *_th; - } -} diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h deleted file mode 100644 index b414b4c86..000000000 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef CONT_BUILDER_H -#define CONT_BUILDER_H -#include "Define.h" -#include "WDT.h" -#include - -class ContinentBuilder -{ -public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : - Continent(continent), TileMap(wdt), MapId(mapId), - NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) - {} - - void Build(); - void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); - void CalculateTileBounds(); - float bmin[3]; - float bmax[3]; -private: - std::string Continent; - WDT* TileMap; - uint32 MapId; - uint32 NumberOfThreads; - int tileXMin; - int tileYMin; - int tileXMax; - int tileYMax; -}; -#endif diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp deleted file mode 100644 index 8f7d9164d..000000000 --- a/src/tools/mesh_extractor/DBC.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "DBC.h" -#include "Define.h" -#include - -DBC::DBC( FILE* stream ) : StringBlock(nullptr), StringBlockSize(0), IsFaulty(true) -{ - char magic[5]; - uint32 count = 0; - count += fread(&magic, sizeof(char), 4, stream); - magic[4] = '\0'; - count += fread(&RecordCount, sizeof(uint32), 1, stream); - Records.reserve(RecordCount); - count += fread(&Fields, sizeof(uint32), 1, stream); - count += fread(&RecordSize, sizeof(uint32), 1, stream); - count += fread(&StringBlockSize, sizeof(uint32), 1, stream); - if (count != 8) - printf("DBC::DBC: Failed to read some data expected 8, read %u\n", count); - - for (int i = 0; i < RecordCount; i++) - { - Record* rec = new Record(this); - Records.push_back(rec); - int size = 0; - for (int f = 0; f < Fields; f++) - { - if (size + 4 > RecordSize) - { - IsFaulty = true; - break; - } - uint32 tmp; - if (fread(&tmp, sizeof(uint32), 1, stream) != 1) - printf("DBC::DBC: Failed to read some data expected 1, read 0\n"); - rec->Values.push_back(tmp); - size += 4; - } - } - StringBlock = new uint8[StringBlockSize]; - count = fread(StringBlock, sizeof(uint8), StringBlockSize, stream); - if (count != StringBlockSize) - printf("DBC::DBC: Failed to read some data expected %u, read %u\n", StringBlockSize, count); -} - -std::string DBC::GetStringByOffset( int offset ) -{ - int len = 0; - for (uint32 i = offset; i < StringBlockSize; i++) - { - if (!StringBlock[i]) - { - len = (i - offset); - break; - } - } - char* d = new char[len + 1]; - strcpy(d, (const char*)(StringBlock + offset)); - d[len] = '\0'; - std::string val = std::string(d); - delete [] d; - return val; -} - -Record* DBC::GetRecordById( int id ) -{ - // we assume Id is index 0 - for (std::vector::iterator itr = Records.begin(); itr != Records.end(); ++itr) - if ((*itr)->Values[0] == id) - return *itr; - return nullptr; -} diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h deleted file mode 100644 index 6c5126556..000000000 --- a/src/tools/mesh_extractor/DBC.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef DBC_H -#define DBC_H -#include "Define.h" -#include -#include - -class Record; - -class DBC -{ -public: - DBC(FILE* stream); - - std::string GetStringByOffset(int offset); - - Record* GetRecordById(int id); - - std::string Name; - std::vector Records; - int RecordCount; - int Fields; - int RecordSize; - uint8* StringBlock; - uint32 StringBlockSize; - bool IsFaulty; -}; - -class Record -{ -public: - Record(DBC* dbc) : Source(dbc) {} - - DBC* Source; - std::vector Values; - - int operator[](int index) - { - return Values[index]; - } - - template - T GetValue(int index) - { - return *(T*)(&Values[index]); - } - - std::string Get(int index) - { - return Source->GetStringByOffset(Values[index]); - } -}; - -#endif diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp deleted file mode 100644 index 00fda514b..000000000 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "DoodadHandler.h" -#include "Cache.h" -#include "Chunk.h" -#include "G3D/Matrix4.h" -#include "Model.h" - -DoodadHandler::DoodadHandler( ADT* adt ) : - ObjectDataHandler(adt), _definitions(nullptr), _paths(nullptr) -{ - Chunk* mddf = adt->ObjectData->GetChunkByName("MDDF"); - if (mddf) - ReadDoodadDefinitions(mddf); - - Chunk* mmid = adt->ObjectData->GetChunkByName("MMID"); - Chunk* mmdx = adt->ObjectData->GetChunkByName("MMDX"); - if (mmid && mmdx) - ReadDoodadPaths(mmid, mmdx); -} - -void DoodadHandler::ProcessInternal( MapChunk* mcnk ) -{ - if (!IsSane()) - return; - - uint32 refCount = mcnk->Header.DoodadRefs; - FILE* stream = mcnk->Source->GetStream(); - fseek(stream, mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); - for (uint32 i = 0; i < refCount; i++) - { - int32 index; - int32 count; - if ((count = fread(&index, sizeof(int32), 1, stream)) != 1) - printf("DoodadHandler::ProcessInternal: Failed to read some data expected 1, read %d\n", count); - if (index < 0 || uint32(index) >= _definitions->size()) - continue; - DoodadDefinition doodad = (*_definitions)[index]; - if (_drawn.find(doodad.UniqueId) != _drawn.end()) - continue; - _drawn.insert(doodad.UniqueId); - if (doodad.MmidIndex >= _paths->size()) - continue; - - std::string path = (*_paths)[doodad.MmidIndex]; - Model* model = Cache->ModelCache.Get(path); - if (!model) - { - model = new Model(path); - Cache->ModelCache.Insert(path, model); - } - if (!model->IsCollidable) - continue; - - Vertices.reserve(refCount * model->Vertices.size() * 0.2); - Triangles.reserve(refCount * model->Triangles.size() * 0.2); - - InsertModelGeometry(doodad, model); - } - // Restore the stream position - fseek(stream, mcnk->Source->Offset, SEEK_SET); -} - -void DoodadHandler::ReadDoodadDefinitions( Chunk* chunk ) -{ - int32 count = chunk->Length / 36; - _definitions = new std::vector; - _definitions->reserve(count); - FILE* stream = chunk->GetStream(); - for (int i = 0; i < count; i++) - { - DoodadDefinition def; - def.Read(stream); - _definitions->push_back(def); - } -} - -void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) -{ - int paths = id->Length / 4; - _paths = new std::vector(); - _paths->reserve(paths); - for (int i = 0; i < paths; i++) - { - FILE* idStream = id->GetStream(); - fseek(idStream, i * 4, SEEK_CUR); - uint32 offset; - if (fread(&offset, sizeof(uint32), 1, idStream) != 1) - printf("DoodadHandler::ReadDoodadPaths: Failed to read some data expected 1, read 0\n"); - FILE* dataStream = data->GetStream(); - fseek(dataStream, offset + data->Offset, SEEK_SET); - _paths->push_back(Utils::ReadString(dataStream)); - } -} - -void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* model) -{ - uint32 vertOffset = Vertices.size(); - - for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) - Vertices.push_back(Utils::TransformDoodadVertex(def, *itr)); // Vertices have to be converted based on the information from the DoodadDefinition struct - - for (std::vector>::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); -} - -DoodadHandler::~DoodadHandler() -{ - delete _definitions; - delete _paths; -} diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h deleted file mode 100644 index 321b62371..000000000 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef DOOADHNDL_H -#define DOOADHNDL_H -#include "Chunk.h" -#include "Model.h" -#include "ObjectDataHandler.h" -#include "Utils.h" -#include -#include - -class DoodadDefinition : public IDefinition -{ -public: - uint32 MmidIndex; - uint32 UniqueId; - uint16 DecimalScale; - uint16 Flags; - - virtual float Scale() const { return DecimalScale / 1024.0f; } - - Vector3 FixCoords(Vector3& vec) - { - return Vector3(vec.z, vec.x, vec.y); - } - - void Read(FILE* stream) - { - int count = 0; - - count += fread(&MmidIndex, sizeof(uint32), 1, stream); - count += fread(&UniqueId, sizeof(uint32), 1, stream); - Position = (Vector3::Read(stream)); - Rotation = Vector3::Read(stream); - count += fread(&DecimalScale, sizeof(uint16), 1, stream); - count += fread(&Flags, sizeof(uint16), 1, stream); - if (count != 4) - printf("DoodadDefinition::Read: Failed to read some data expected 4, read %d\n", count); - } -}; - -class DoodadHandler : public ObjectDataHandler -{ -public: - DoodadHandler(ADT* adt); - ~DoodadHandler(); - - std::vector Vertices; - std::vector> Triangles; - bool IsSane() { return _definitions && _paths; } - -protected: - void ProcessInternal(MapChunk* chunk); - -private: - void ReadDoodadDefinitions(Chunk* chunk); - void ReadDoodadPaths(Chunk* id, Chunk* data); - void InsertModelGeometry(const DoodadDefinition& def, Model* model); - std::set _drawn; - std::vector* _definitions; - std::vector* _paths; -}; -#endif diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp deleted file mode 100644 index dc5c573d0..000000000 --- a/src/tools/mesh_extractor/Geometry.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Geometry.h" -#include "ADT.h" -#include "Constants.h" -#include "DoodadHandler.h" -#include "WorldModelHandler.h" - -Geometry::Geometry() : Transform(false) -{ - Vertices.reserve(10000); - Triangles.reserve(10000); -} - -void Geometry::CalculateBoundingBox( float*& min, float*& max ) -{ - min = new float[3]; - max = new float[3]; - for (int i = 0; i < 3; ++i) - { - max[i] = std::numeric_limits::min(); - min[i] = std::numeric_limits::max(); - } - - for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) - { - if (itr->x > max[0]) - max[0] = itr->x; - if (itr->x < min[0]) - min[0] = itr->x; - - if (itr->y > max[1]) - max[1] = itr->y; - if (itr->y < min[1]) - min[1] = itr->y; - - if (itr->z > max[2]) - max[2] = itr->z; - if (itr->z < min[2]) - min[2] = itr->z; - } -} - -void Geometry::CalculateMinMaxHeight( float& min, float& max ) -{ - min = std::numeric_limits::max(); - max = std::numeric_limits::min(); - - for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) - { - if (Transform) - { - if (itr->y < min) - min = itr->y; - if (itr->y > max) - max = itr->y; - } - else - { - if (itr->z < min) - min = itr->z; - if (itr->z > max) - max = itr->z; - } - } -} - -void Geometry::AddData( std::vector& verts, std::vector>& tris ) -{ - uint32 vertOffset = Vertices.size(); - for (std::vector::iterator itr = verts.begin(); itr != verts.end(); ++itr) - Vertices.push_back(Transform ? Utils::ToRecast(*itr) : *itr); - - for (std::vector>::iterator itr = tris.begin(); itr != tris.end(); ++itr) - Triangles.push_back(Triangle(itr->Type, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); -} - -void Geometry::GetRawData( float*& verts, int*& tris, uint8*& areas ) -{ - verts = new float[Vertices.size() * 3]; - for (uint32 i = 0; i < Vertices.size(); ++i) - { - Vector3& vert = Vertices[i]; - verts[(i * 3) + 0] = vert.x; - verts[(i * 3) + 1] = vert.y; - verts[(i * 3) + 2] = vert.z; - } - - tris = new int[Triangles.size() * 3]; - for (uint32 i = 0; i < Triangles.size(); ++i) - { - Triangle& tri = Triangles[i]; - tris[(i * 3) + 0] = (int)tri.V0; - tris[(i * 3) + 1] = (int)tri.V1; - tris[(i * 3) + 2] = (int)tri.V2; - } - - areas = new uint8[Triangles.size()]; - for (uint32 i = 0; i < Triangles.size(); i++) - { - switch (Triangles[i].Type) - { - case Constants::TRIANGLE_TYPE_WATER: - areas[i] = Constants::POLY_AREA_WATER; - break; - default: - areas[i] = Constants::POLY_AREA_TERRAIN; - break; - } - } -} - -void Geometry::AddAdt( ADT* adt ) -{ - for (std::vector::iterator itr = adt->MapChunks.begin(); itr != adt->MapChunks.end(); ++itr) - { - std::vector> tmp; - tmp.reserve((*itr)->Triangles.size()); - for (std::vector>::iterator itr2 = (*itr)->Triangles.begin(); itr2 != (*itr)->Triangles.end(); ++itr2) - tmp.push_back(Triangle(itr2->Type, itr2->V0, itr2->V1, itr2->V2)); - AddData((*itr)->Vertices, tmp); - } - - if (!adt->_DoodadHandler->Triangles.empty()) - AddData(adt->_DoodadHandler->Vertices, adt->_DoodadHandler->Triangles); - - if (!adt->_WorldModelHandler->Triangles.empty()) - AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); -} diff --git a/src/tools/mesh_extractor/Geometry.h b/src/tools/mesh_extractor/Geometry.h deleted file mode 100644 index 9705a6085..000000000 --- a/src/tools/mesh_extractor/Geometry.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef GEOMETRY_H -#define GEOMETRY_H -#include - -#include "Utils.h" - -class ADT; -class Geometry -{ -public: - Geometry(); - - void CalculateBoundingBox(float*& min, float*& max); - void CalculateMinMaxHeight(float& min, float& max); - void AddData(std::vector& verts, std::vector>& tris); - void AddAdt(ADT* adt); - void GetRawData(float*& verts, int*& tris, uint8*& areas); - - std::vector Vertices; - std::vector> Triangles; - bool Transform; -}; -#endif diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp deleted file mode 100644 index cddbf58b8..000000000 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "LiquidHandler.h" -#include "Utils.h" - -LiquidHandler::LiquidHandler( ADT* adt ) : Source(adt) -{ - HandleNewLiquid(); -} - -void LiquidHandler::HandleNewLiquid() -{ - Chunk* chunk = Source->Data->GetChunkByName("MH2O"); - if (!chunk) - return; - - Vertices.reserve(1000); - Triangles.reserve(1000); - - FILE* stream = chunk->GetStream(); - H2OHeader header[256]; - MCNKData.reserve(256); - for (int i = 0; i < 256; i++) - header[i] = H2OHeader::Read(stream); - - for (int i = 0; i < 256; i++) - { - H2OHeader h = header[i]; - if (h.LayerCount == 0) - { - // Need to fill in missing data with dummies. - MCNKData.push_back(MCNKLiquidData(nullptr, H2ORenderMask())); - continue; - } - fseek(stream, chunk->Offset + h.OffsetInformation, SEEK_SET); - H2OInformation information = H2OInformation::Read(stream); - - float** heights = new float*[9]; - for (int j = 0; j < 9; ++j) - { - heights[j] = new float[9]; - memset(heights[j], 0, sizeof(float) * 9); - } - - H2ORenderMask renderMask; - if (information.LiquidType != 2) - { - fseek(stream, chunk->Offset + h.OffsetRender, SEEK_SET); - renderMask = H2ORenderMask::Read(stream); - if ((Utils::IsAllZero(renderMask.Mask, 8) || (information.Width == 8 && information.Height == 8)) && information.OffsetMask2) - { - fseek(stream, chunk->Offset + information.OffsetMask2, SEEK_SET); - uint32 size = std::ceil(information.Width * information.Height / 8.0f); - uint8* altMask = new uint8[size]; - if (fread(altMask, sizeof(uint8), size, stream) == size) - for (uint32 mi = 0; mi < size; mi++) - renderMask.Mask[mi + information.OffsetY] |= altMask[mi]; - delete[] altMask; - } - fseek(stream, chunk->Offset + information.OffsetHeightmap, SEEK_SET); - - for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) - for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) - if (fread(&heights[x][y], sizeof(float), 1, stream) != 1) - return; - } - else - { - // Fill with ocean data - for (uint32 i = 0; i < 8; ++i) - renderMask.Mask[i] = 0xFF; - - for (uint32 y = 0; y < 9; ++y) - for (uint32 x = 0; x < 9; ++x) - heights[x][y] = information.HeightLevel1; - } - - MCNKData.push_back(MCNKLiquidData(heights, renderMask)); - - for (int y = information.OffsetY; y < (information.OffsetY + information.Height); y++) - { - for (int x = information.OffsetX; x < (information.OffsetX + information.Width); x++) - { - if (!renderMask.ShouldRender(x, y)) - continue; - - MapChunk* mapChunk = Source->MapChunks[i]; - Vector3 location = mapChunk->Header.Position; - location.y = location.y - (x * Constants::UnitSize); - location.x = location.x - (y * Constants::UnitSize); - location.z = heights[x][y]; - - uint32 vertOffset = Vertices.size(); - Vertices.push_back(location); - Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y, location.z)); - Vertices.push_back(Vector3(location.x, location.y - Constants::UnitSize, location.z)); - Vertices.push_back(Vector3(location.x - Constants::UnitSize, location.y - Constants::UnitSize, location.z)); - - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); - } - } - } -} diff --git a/src/tools/mesh_extractor/LiquidHandler.h b/src/tools/mesh_extractor/LiquidHandler.h deleted file mode 100644 index 3003749cf..000000000 --- a/src/tools/mesh_extractor/LiquidHandler.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef LIQUID_H -#define LIQUID_H -#include "ADT.h" -#include "Define.h" -#include "Utils.h" - -#include - -class LiquidHandler -{ -public: - LiquidHandler(ADT* adt); - - ADT* Source; - std::vector Vertices; - std::vector> Triangles; - std::vector MCNKData; -private: - void HandleNewLiquid(); -}; -#endif diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp deleted file mode 100644 index 7073181b8..000000000 --- a/src/tools/mesh_extractor/MPQ.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "MPQ.h" -#include "MPQMgr.h" -#include -#include - -MPQArchive::MPQArchive(const char* filename) -{ - int result = libmpq__archive_open(&mpq_a, filename, -1); - printf("Opening %s\n", filename); - if (result) - { - switch (result) - { - case LIBMPQ_ERROR_OPEN : - printf("Error opening archive '%s': Does file really exist?\n", filename); - break; - case LIBMPQ_ERROR_FORMAT : /* bad file format */ - printf("Error opening archive '%s': Bad file format\n", filename); - break; - case LIBMPQ_ERROR_SEEK : /* seeking in file failed */ - printf("Error opening archive '%s': Seeking in file failed\n", filename); - break; - case LIBMPQ_ERROR_READ : /* Read error in archive */ - printf("Error opening archive '%s': Read error in archive\n", filename); - break; - case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */ - printf("Error opening archive '%s': Maybe not enough memory\n", filename); - break; - default: - printf("Error opening archive '%s': Unknown error\n", filename); - break; - } - } - GetFileListTo(Files); -} - -void MPQArchive::close() -{ - libmpq__archive_close(mpq_a); -} - -MPQFile::MPQFile(const char* filename): - eof(false), buffer(0), pointer(0), size(0) -{ - for (std::deque::iterator i = MPQHandler->Archives.begin(); i != MPQHandler->Archives.end(); ++i) - { - mpq_archive* mpq_a = (*i)->mpq_a; - - uint32_t filenum; - if (libmpq__file_number(mpq_a, filename, &filenum)) - continue; - libmpq__off_t transferred; - libmpq__file_unpacked_size(mpq_a, filenum, &size); - - // HACK: in patch.mpq some files don't want to open and give 1 for filesize - if (size <= 1) - { - // printf("warning: file %s has size %d; cannot Read.\n", filename, size); - eof = true; - buffer = 0; - return; - } - buffer = new char[size]; - - //libmpq_file_getdata - libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/ - return; - } - eof = true; - buffer = 0; -} - -size_t MPQFile::Read(void* dest, size_t bytes) -{ - if (eof) - return 0; - - size_t rpos = pointer + bytes; - if (rpos > size_t(size)) - { - bytes = size - pointer; - eof = true; - } - - memcpy(dest, &(buffer[pointer]), bytes); - - pointer = rpos; - - return bytes; -} - -void MPQFile::seek(int offset) -{ - pointer = offset; - eof = (pointer >= size); -} - -void MPQFile::seekRelative(int offset) -{ - pointer += offset; - eof = (pointer >= size); -} - -void MPQFile::close() -{ - delete[] buffer; - buffer = 0; - eof = true; -} - -FILE* MPQFile::GetFileStream() -{ - FILE* file = tmpfile(); - if (!file) - { - printf("Could not create temporary file. Please run as Administrator or root\n"); - exit(1); - } - fwrite(buffer, sizeof(char), size, file); - fseek(file, 0, SEEK_SET); - return file; -} diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h deleted file mode 100644 index 5d57165cb..000000000 --- a/src/tools/mesh_extractor/MPQ.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef MPQ_H -#define MPQ_H - -#include "Define.h" -#include "Errors.h" -#include "libmpq/mpq.h" -#include -#include -#include -#include -#include - -class MPQArchive -{ -public: - mpq_archive_s* mpq_a; - - std::vector Files; - - MPQArchive(const char* filename); - void close(); - - void GetFileListTo(std::vector& filelist) - { - uint32_t filenum; - if (libmpq__file_number(mpq_a, "(listfile)", &filenum)) return; - libmpq__off_t size, transferred; - libmpq__file_unpacked_size(mpq_a, filenum, &size); - - char* buffer = new char[size + 1]; - buffer[size] = '\0'; - - libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - - char seps[] = "\n"; - char* token; - - token = strtok( buffer, seps ); - uint32 counter = 0; - while ((token != nullptr) && (counter < size)) - { - //cout << token << endl; - token[strlen(token) - 1] = 0; - std::string s = token; - filelist.push_back(s); - counter += strlen(token) + 2; - token = strtok(nullptr, seps); - } - - delete[] buffer; - } -}; - -class MPQFile -{ - //MPQHANDLE handle; - bool eof; - char* buffer; - libmpq__off_t pointer, size; - - // disable copying - MPQFile(const MPQFile& /*f*/) {} - void operator=(const MPQFile& /*f*/) {} - -public: - MPQFile(const char* filename); // filenames are not case sensitive - ~MPQFile() { close(); } - size_t Read(void* dest, size_t bytes); - FILE* GetFileStream(); - size_t getSize() { return size; } - size_t getPos() { return pointer; } - char* getBuffer() { return buffer; } - char* getPointer() { return buffer + pointer; } - bool isEof() { return eof; } - void seek(int offset); - void seekRelative(int offset); - void close(); -}; - -inline void flipcc(char* fcc) -{ - char t; - t = fcc[0]; - fcc[0] = fcc[3]; - fcc[3] = t; - t = fcc[1]; - fcc[1] = fcc[2]; - fcc[2] = t; -} - -#endif diff --git a/src/tools/mesh_extractor/MPQMgr.cpp b/src/tools/mesh_extractor/MPQMgr.cpp deleted file mode 100644 index 864258fb5..000000000 --- a/src/tools/mesh_extractor/MPQMgr.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "MPQMgr.h" -#include "DBC.h" -#include "MPQ.h" -#include "Utils.h" - -char const* MPQMgr::Files[] = -{ - "common.MPQ", - "common-2.MPQ", - "expansion.MPQ", - "lichking.MPQ", - "patch.MPQ", - "patch-2.MPQ", - "patch-3.MPQ" -}; - -char const* MPQMgr::Languages[] = { "enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" }; - -void MPQMgr::Initialize() -{ - InitializeDBC(); - uint32 size = sizeof(Files) / sizeof(char*); - for (uint32 i = 0; i < size; ++i) - { - MPQArchive* arc = new MPQArchive(std::string("Data/" + std::string(Files[i])).c_str()); - Archives.push_front(arc); // MPQ files have to be transversed in reverse order to properly account for patched files - printf("Opened %s\n", Files[i]); - } -} - -void MPQMgr::InitializeDBC() -{ - BaseLocale = -1; - std::string fileName; - uint32 size = sizeof(Languages) / sizeof(char*); - MPQArchive* _baseLocale = nullptr; - for (uint32 i = 0; i < size; ++i) - { - std::string _fileName = "Data/" + std::string(Languages[i]) + "/locale-" + std::string(Languages[i]) + ".MPQ"; - FILE* file = fopen(_fileName.c_str(), "rb"); - if (file) - { - if (BaseLocale == -1) - { - BaseLocale = i; - _baseLocale = new MPQArchive(_fileName.c_str()); - fileName = _fileName; - LocaleFiles[i] = _baseLocale; - } - else - LocaleFiles[i] = new MPQArchive(_fileName.c_str()); - - AvailableLocales.insert(i); - printf("Detected locale: %s\n", Languages[i]); - } - } - Archives.push_front(_baseLocale); - if (BaseLocale == -1) - { - printf("No locale data detected. Please make sure that the executable is in the same folder as your WoW installation.\n"); - ABORT(); - } - else - printf("Using default locale: %s\n", Languages[BaseLocale]); -} - -FILE* MPQMgr::GetFile(const std::string& path ) -{ - GUARD_RETURN(mutex, nullptr); - MPQFile file(path.c_str()); - if (file.isEof()) - return nullptr; - return file.GetFileStream(); -} - -DBC* MPQMgr::GetDBC(const std::string& name ) -{ - std::string path = "DBFilesClient\\" + name + ".dbc"; - return new DBC(GetFile(path)); -} - -FILE* MPQMgr::GetFileFrom(const std::string& path, MPQArchive* file ) -{ - GUARD_RETURN(mutex, nullptr); - mpq_archive* mpq_a = file->mpq_a; - - uint32_t filenum; - if (libmpq__file_number(mpq_a, path.c_str(), &filenum)) - return nullptr; - - libmpq__off_t transferred; - libmpq__off_t size = 0; - libmpq__file_unpacked_size(mpq_a, filenum, &size); - - // HACK: in patch.mpq some files don't want to open and give 1 for filesize - if (size <= 1) - return nullptr; - - uint8* buffer = new uint8[size]; - - //libmpq_file_getdata - libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); - - // Pack the return into a FILE stream - FILE* ret = tmpfile(); - if (!ret) - { - printf("Could not create temporary file. Please run as Administrator or root\n"); - exit(1); - } - fwrite(buffer, sizeof(uint8), size, ret); - fseek(ret, 0, SEEK_SET); - delete[] buffer; - return ret; -} diff --git a/src/tools/mesh_extractor/MPQMgr.h b/src/tools/mesh_extractor/MPQMgr.h deleted file mode 100644 index 5b1718327..000000000 --- a/src/tools/mesh_extractor/MPQMgr.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef MPQ_MANAGER_H -#define MPQ_MANAGER_H - -#include "MPQ.h" -#include "PolicyLock.h" -#include -#include -#include - -class DBC; -class MPQMgr -{ -public: - MPQMgr() {} - ~MPQMgr() {} - - void Initialize(); - FILE* GetFile(const std::string& path); - FILE* GetFileFrom(const std::string& path, MPQArchive* file); - DBC* GetDBC(const std::string& name); - std::vector GetAllFiles(std::string extension); - - std::deque Archives; - int32 BaseLocale; - std::set AvailableLocales; - std::map LocaleFiles; - - static char const* Files[]; - static char const* Languages[]; -protected: - void InitializeDBC(); -private: - std::mutex mutex; -}; - -extern MPQMgr* MPQHandler; -#endif diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp deleted file mode 100644 index b74a938c9..000000000 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "MapChunk.h" -#include "ADT.h" -#include "LiquidHandler.h" - -MapChunk::MapChunk( ADT* _adt, Chunk* chunk ) : Adt(_adt), Source(chunk) -{ - FILE* stream = chunk->GetStream(); - Header.Read(stream); - fseek(stream, chunk->Offset, SEEK_SET); - Index = Header.IndexX + Header.IndexY * 16; - GenerateVertices(stream); -} - -void MapChunk::GenerateTriangles() -{ - Triangles.reserve(256); - for (int y = 0; y < 8; y++) - { - for (int x = 0; x < 8; x++) - { - if (HasHole(Header.Holes, x / 2, y / 2)) - continue; - - uint32 topLeft = (17 * y) + x; - uint32 topRight = (17 * y) + x + 1; - uint32 bottomLeft = (17 * (y + 1)) + x; - uint32 bottomRight = (17 * (y + 1)) + x + 1; - uint32 center = (17 * y) + 9 + x; - - Constants::TriangleType triangleType = Constants::TRIANGLE_TYPE_TERRAIN; - if (Adt->_LiquidHandler && !Adt->_LiquidHandler->MCNKData.empty()) - { - MCNKLiquidData& data = Adt->_LiquidHandler->MCNKData[Index]; - float maxHeight = std::max( - std::max( - std::max(std::max(Vertices[topLeft].z, Vertices[topRight].z), Vertices[bottomLeft].z), - Vertices[bottomRight].z), Vertices[center].z); - if (data.IsWater(x, y, maxHeight)) - triangleType = Constants::TRIANGLE_TYPE_WATER; - } - - Triangles.push_back(Triangle(triangleType, topRight, topLeft, center)); - Triangles.push_back(Triangle(triangleType, topLeft, bottomLeft, center)); - Triangles.push_back(Triangle(triangleType, bottomLeft, bottomRight, center)); - Triangles.push_back(Triangle(triangleType, bottomRight, topRight, center)); - } - } -} - -void MapChunk::GenerateVertices( FILE* stream ) -{ - fseek(stream, Header.OffsetMCVT, SEEK_CUR); - Vertices.reserve(125); - - for (int j = 0; j < 17; j++) - { - int values = j % 2 ? 8 : 9; - for (int i = 0; i < values; i++) - { - float tmp; - if (fread(&tmp, sizeof(float), 1, stream) != 1) - printf("MapChunk::GenerateVertices: Failed to read some data expected 1, read 0\n"); - Vector3 vert(Header.Position.x - (j * (Constants::UnitSize * 0.5f)), Header.Position.y - (i * Constants::UnitSize), Header.Position.z + tmp); - if (values == 8) - vert.y -= Constants::UnitSize * 0.5f; - Vertices.push_back(vert); - } - } - // Restore stream position. - fseek(stream, Source->Offset, SEEK_SET); -} - -bool MapChunk::HasHole( uint32 map, int x, int y ) -{ - return (map & 0x0000FFFF) & ((1 << x) << (y << 2)); -} diff --git a/src/tools/mesh_extractor/MapChunk.h b/src/tools/mesh_extractor/MapChunk.h deleted file mode 100644 index 83b0a43d4..000000000 --- a/src/tools/mesh_extractor/MapChunk.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef MAPCHUNK_H -#define MAPCHUNK_H -#include "Chunk.h" -#include "Constants.h" -#include "Utils.h" -#include -class ADT; - -class MapChunk -{ -public: - MapChunk(ADT* _adt, Chunk* chunk); - - void GenerateTriangles(); - void GenerateVertices(FILE* stream); - static bool HasHole(uint32 map, int x, int y); - ADT* Adt; - Chunk* Source; - MapChunkHeader Header; - std::vector Vertices; - std::vector> Triangles; - int32 Index; -}; -#endif diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp deleted file mode 100644 index 8ef89e31b..000000000 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Cache.h" -#include "Constants.h" -#include "ContinentBuilder.h" -#include "DBC.h" -#include "MPQMgr.h" -#include "Model.h" -#include "WDT.h" - -#include "DetourNavMesh.h" -#include "DetourNavMeshQuery.h" -#include "Recast.h" - -#include - -#include - -MPQMgr* MPQHandler; -CacheClass* Cache; - -void ExtractMMaps(std::set& mapIds, uint32 threads) -{ - DBC* dbc = MPQHandler->GetDBC("Map"); - printf("Map.dbc contains %u rows.\n", dbc->Records.size()); - for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) - { - uint32 mapId = (*itr)->Values[0]; - - // Skip this map if a list of specific maps was provided and this one is not contained in it. - if (!mapIds.empty() && mapIds.find(mapId) == mapIds.end()) - { - if (Constants::Debug) - printf("Map %u will not be built.\n", mapId); - continue; - } - - std::string name = (*itr)->Get(1); - WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); - if (!wdt.IsValid) - { - printf("Could not find WDT data for map %u (%s)\n", mapId, name.c_str()); - continue; - } - printf("Building %s MapId %u\n", name.c_str(), mapId); - ContinentBuilder builder(name, mapId, &wdt, threads); - builder.Build(); - } -} - -void ExtractDBCs() -{ - printf("Extracting DBCs\n"); - // Create the file system structure - std::string baseDBCPath = "dbc/"; - Utils::CreateDir(baseDBCPath); - - std::set DBCFiles; - const size_t extLen = strlen(".dbc"); - // Populate list of DBC files - // We get the DBC names by going over the (guaranteed to exist) default locale files - // Then we look in other locale files in case that they are available. - for (std::vector::iterator itr = MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.begin(); itr != MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.end(); ++itr) - if (itr->rfind(".dbc") == itr->length() - extLen) // Check if the extension is ".dbc" - DBCFiles.insert(*itr); - - const size_t folderLen = strlen("DBFilesClient\\"); - // Iterate over all available locales - for (std::set::iterator itr = MPQHandler->AvailableLocales.begin(); itr != MPQHandler->AvailableLocales.end(); ++itr) - { - printf("Extracting DBCs for locale %s\n", MPQMgr::Languages[*itr]); - std::string path = baseDBCPath; - if (*itr != uint32(MPQHandler->BaseLocale)) - { - path += std::string(MPQMgr::Languages[*itr]) + "/"; - Utils::CreateDir(path); - } - - std::string component = "component.wow-" + std::string(MPQMgr::Languages[*itr]) + ".txt"; - // Extract the component file - Utils::SaveToDisk(MPQHandler->GetFileFrom(component, MPQHandler->LocaleFiles[*itr]), path + component); - // Extract the DBC files for the given locale - for (std::set::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2) - Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + folderLen)); - } - printf("DBC extraction finished!\n"); -} - -void ExtractGameobjectModels() -{ - Constants::ToWoWCoords = true; - printf("Extracting GameObject models\n"); - - std::string baseBuildingsPath = "Buildings/"; - std::string baseVmapsPath = "vmaps/"; - Utils::CreateDir(baseVmapsPath); - Utils::CreateDir(baseBuildingsPath); - - FILE* modelList = fopen((baseVmapsPath + "GameObjectModels.list").c_str(), "wb"); - if (!modelList) - { - printf("Could not create file vmaps/GameObjectModels.list, please make sure that you have the write permissions in the folder\n"); - return; - } - - DBC* dbc = MPQHandler->GetDBC("GameObjectDisplayInfo"); - for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) - { - std::string path = (*itr)->Get(1); - std::string fileName = Utils::GetPlainName(path.c_str()); - std::string extension = Utils::GetExtension(fileName); - // Convert the extension to lowercase - std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); - if (extension == "mdx" || extension == "m2") - { - fileName = Utils::FixModelPath(fileName); - Model model(path); - - if (model.IsBad) - continue; - - FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb"); - if (!output) - { - printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str()); - continue; - } - // Placeholder for 0 values - int Nop[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - fwrite(Constants::VMAPMagic, 8, 1, output); - uint32 numVerts = model.Header.CountBoundingVertices; - fwrite(&numVerts, sizeof(uint32), 1, output); - uint32 numGroups = 1; - fwrite(&numGroups, sizeof(uint32), 1, output); - fwrite(Nop, 4 * 3, 1, output); // rootwmoid, flags, groupid - fwrite(Nop, sizeof(float), 3 * 2, output);//bbox, only needed for WMO currently - fwrite(Nop, 4, 1, output);// liquidflags - fwrite("GRP ", 4, 1, output); - - uint32 branches = 1; - uint32 wsize = sizeof(branches) + sizeof(uint32) * branches; - fwrite(&wsize, sizeof(uint32), 1, output); - fwrite(&branches, sizeof(branches), 1, output); - uint32 numTris = model.Header.CountBoundingTriangles; - fwrite(&numTris, sizeof(uint32), 1, output); - fwrite("INDX", 4, 1, output); - wsize = sizeof(uint32) + sizeof(unsigned short) * numTris; - fwrite(&wsize, sizeof(int), 1, output); - fwrite(&numTris, sizeof(uint32), 1, output); - uint16* indices = new uint16[numTris]; - - if (numTris > 0) - { - uint32 i = 0; - for (std::vector>::iterator itr2 = model.Triangles.begin(); itr2 != model.Triangles.end(); ++itr2, ++i) - { - indices[i * 3 + 0] = itr2->V0; - indices[i * 3 + 1] = itr2->V1; - indices[i * 3 + 2] = itr2->V2; - } - fwrite(indices, sizeof(uint16), numTris, output); - } - - fwrite("VERT", 4, 1, output); - wsize = sizeof(int) + sizeof(float) * 3 * numVerts; - fwrite(&wsize, sizeof(int), 1, output); - fwrite(&numVerts, sizeof(int), 1, output); - float* vertices = new float[numVerts * 3]; - - if (numVerts > 0) - { - uint32 i = 0; - for (std::vector::iterator itr2 = model.Vertices.begin(); itr2 != model.Vertices.end(); ++itr2, ++i) - { - vertices[i * 3 + 0] = itr2->x; - vertices[i * 3 + 1] = itr2->y; - vertices[i * 3 + 2] = itr2->z; - } - - fwrite(vertices, sizeof(float), numVerts * 3, output); - } - - fclose(output); - delete[] indices; - delete[] vertices; - - uint32 displayId = (*itr)->Values[0]; - uint32 pathLength = fileName.size(); - fwrite(&displayId, sizeof(uint32), 1, modelList); - fwrite(&pathLength, sizeof(uint32), 1, modelList); - fwrite(fileName.c_str(), sizeof(char), pathLength, modelList); - } - else if (extension == "wmo") - { - WorldModelRoot model(path); - - FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb"); - if (!output) - { - printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str()); - continue; - } - - fwrite(Constants::VMAPMagic, 1, 8, output); - uint32 numVertices = 0; - fwrite(&numVertices, sizeof(uint32), 1, output); // will be filled later - fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output); - fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); - - const char grp[] = { 'G', 'R', 'P', ' ' }; - for (std::vector::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2) - { - const WMOGroupHeader& header = itr2->Header; - fwrite(&header.Flags, sizeof(uint32), 1, output); - fwrite(&header.WmoId, sizeof(uint32), 1, output); - fwrite(&header.BoundingBox[0], sizeof(uint32), 1, output); - fwrite(&header.BoundingBox[1], sizeof(uint32), 1, output); - uint32 LiquidFlags = itr2->HasLiquidData ? 1 : 0; - fwrite(&LiquidFlags, sizeof(uint32), 1, output); - - fwrite(grp, sizeof(char), sizeof(grp), output); - uint32 k = 0; - uint32 mobaBatch = itr2->MOBALength / 12; - uint32* MobaEx = new uint32[mobaBatch * 4]; - - for (uint32 i = 8; i < itr2->MOBALength; i += 12) - MobaEx[k++] = itr2->MOBA[i]; - - int mobaSizeGrp = mobaBatch * 4 + 4; - fwrite(&mobaSizeGrp, 4, 1, output); - fwrite(&mobaBatch, 4, 1, output); - fwrite(MobaEx, 4, k, output); - delete[] MobaEx; - - //@TODO: Finish this. - } - - fclose(output); - } - } - - fclose(modelList); - printf("GameObject models extraction finished!"); - Constants::ToWoWCoords = false; -} - -bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapList, bool& debugOutput, uint32& extractFlags) -{ - char* param = nullptr; - extractFlags = 0; - - for (int i = 1; i < argc; ++i) - { - if (strcmp(argv[i], "--threads") == 0) - { - param = argv[++i]; - if (!param) - return false; - - threads = atoi(param); - printf("Using %u threads\n", threads); - } - else if (strcmp(argv[i], "--maps") == 0) - { - param = argv[++i]; - if (!param) - return false; - - char* copy = strdup(param); - char* token = strtok(copy, ","); - while (token) - { - mapList.insert(atoi(token)); - token = strtok(nullptr, ","); - } - - free(copy); - - printf("Extracting only provided list of maps (%u).\n", uint32(mapList.size())); - } - else if (strcmp(argv[i], "--debug") == 0) - { - param = argv[++i]; - if (!param) - return false; - debugOutput = atoi(param); - if (debugOutput) - printf("Output will contain debug information (.obj files)\n"); - } - else if (strcmp(argv[i], "--extract") == 0) - { - param = argv[++i]; - if (!param) - return false; - - extractFlags = atoi(param); - - if (!(extractFlags & Constants::EXTRACT_FLAG_ALLOWED)) // Tried to use an invalid flag - return false; - - printf("Detected flags: \n"); - printf("* Extract DBCs: %s\n", (extractFlags & Constants::EXTRACT_FLAG_DBC) ? "Yes" : "No"); - printf("* Extract Maps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MAPS) ? "Yes" : "No"); - printf("* Extract VMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_VMAPS) ? "Yes" : "No"); - printf("* Extract GameObject Models: %s\n", (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ? "Yes" : "No"); - printf("* Extract MMaps: %s\n", (extractFlags & Constants::EXTRACT_FLAG_MMAPS) ? "Yes" : "No"); - } - } - return true; -} - -void PrintUsage() -{ - printf("MeshExtractor help.\n"); - printf("* Use \"--threads \" to specify threads, default to 4 (Only available when extracting MMaps)\n"); - printf("* Use \"--maps a,b,c,d,e\" to extract only the maps specified (Do not use spaces)\n"); - printf("* Use \"--debug 1\" to generate debug information of the tiles (Only available when extracting MMaps)\n"); - printf("* Use \"--extract X\" to extract the data specified by the flag X (Note: You can combine the flags with the bitwise OR operator |). Available flags are: \n"); - { - printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); - printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); - printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); - printf("- %u to extract GameObject models (Not yet finished, you need to run VMapAssembler on the extracted files)\n", Constants::EXTRACT_FLAG_GOB_MODELS); - printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); - } -} - -void LoadTile(dtNavMesh*& navMesh, const char* tile) -{ - FILE* f = fopen(tile, "rb"); - if (!f) - return; - MmapTileHeader header; - - if (fread(&header, sizeof(MmapTileHeader), 1, f) != 1) - return; - - uint8* nav = new uint8[header.size]; - if (fread(nav, header.size, 1, f) != 1) - return; - - navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, nullptr); - - fclose(f); -} - -int main(int argc, char* argv[]) -{ - _setmaxstdio(2048); - uint32 threads = 4, extractFlags = 0; - std::set mapIds; - - if (!HandleArgs(argc, argv, threads, mapIds, Constants::Debug, extractFlags)) - { - PrintUsage(); - return -1; - } - - if (extractFlags == 0) - { - printf("You must provide valid extract flags.\n"); - PrintUsage(); - return -1; - } - - Cache = new CacheClass(); - MPQHandler = new MPQMgr(); - MPQHandler->Initialize(); - - if (extractFlags & Constants::EXTRACT_FLAG_DBC) - ExtractDBCs(); - - if (extractFlags & Constants::EXTRACT_FLAG_MMAPS) - ExtractMMaps(mapIds, threads); - - if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) - ExtractGameobjectModels(); - - if (extractFlags & Constants::EXTRACT_FLAG_TEST) - { - float start[] = { 16226.200195f, 16257.000000f, 13.202200f }; - float end[] = { 16245.725586f, 16382.465820f, 47.384956f }; - - // - float m_spos[3]; - m_spos[0] = -start[1]; - m_spos[1] = start[2]; - m_spos[2] = -start[0]; - - // - float m_epos[3]; - m_epos[0] = -end[1]; - m_epos[1] = end[2]; - m_epos[2] = -end[0]; - - // - dtQueryFilterExt m_filter; - m_filter.setIncludeFlags(Constants::POLY_AREA_ROAD | Constants::POLY_AREA_TERRAIN); - m_filter.setExcludeFlags(Constants::POLY_AREA_WATER); - - // - float m_polyPickExt[3]; - m_polyPickExt[0] = 2.5f; - m_polyPickExt[1] = 2.5f; - m_polyPickExt[2] = 2.5f; - - // - dtPolyRef m_startRef; - dtPolyRef m_endRef; - - FILE* mmap = fopen("mmaps/001.mmap", "rb"); - dtNavMeshParams params; - int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); - fclose(mmap); - if (count != 1) - { - printf("main: Error reading from .mmap\n"); - return 0; - } - - dtNavMesh* navMesh = new dtNavMesh(); - dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery(); - - navMesh->init(¶ms); - for (int i = 0; i <= 32; ++i) - { - for (int j = 0; j <= 32; ++j) - { - char buff[100]; - sprintf(buff, "mmaps/001%02i%02i.mmtile", i, j); - LoadTile(navMesh, buff); - } - } - - navMeshQuery->init(navMesh, 2048); - - float nearestPt[3]; - - navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); - navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); - - if ( !m_startRef || !m_endRef ) - { - std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl; - return 0; - } - - int hops; - dtPolyRef* hopBuffer = new dtPolyRef[8192]; - dtStatus status = navMeshQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, hopBuffer, &hops, 8192); - - int resultHopCount; - float* straightPath = new float[2048 * 3]; - unsigned char* pathFlags = new unsigned char[2048]; - dtPolyRef* pathRefs = new dtPolyRef[2048]; - - status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048); - std::vector FinalPath; - FinalPath.reserve(resultHopCount); - for (int32 i = 0; i < resultHopCount; ++i) - { - Vector3 finalV = Utils::ToWoWCoords(Vector3(straightPath[i * 3 + 0], straightPath[i * 3 + 1], straightPath[i * 3 + 2])); - FinalPath.push_back(finalV); - printf("Point %f %f %f\n", finalV.x, finalV.y, finalV.z); - } - } - - return 0; -} diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp deleted file mode 100644 index 8856b4934..000000000 --- a/src/tools/mesh_extractor/Model.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Model.h" -#include "MPQMgr.h" -#include "Utils.h" - -Model::Model( std::string path ) : IsCollidable(false), IsBad(false) -{ - Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); - if (!Stream) - { - IsBad = true; - return; - } - Header.Read(Stream); - if (Header.OffsetBoundingNormals > 0 && Header.OffsetBoundingVertices > 0 && - Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) - { - IsCollidable = true; - ReadVertices(); - ReadBoundingNormals(); - ReadBoundingTriangles(); - } -} - -Model::~Model() -{ - if (Stream) - fclose(Stream); -} - -void Model::ReadVertices() -{ - fseek(Stream, Header.OffsetBoundingVertices, SEEK_SET); - Vertices.reserve(Header.CountBoundingVertices); - for (uint32 i = 0; i < Header.CountBoundingVertices; ++i) - { - Vertices.push_back(Vector3::Read(Stream)); - if (Constants::ToWoWCoords) - Vertices[i] = Utils::ToWoWCoords(Vertices[i]); - } -} - -void Model::ReadBoundingTriangles() -{ - fseek(Stream, Header.OffsetBoundingTriangles, SEEK_SET); - Triangles.reserve(Header.CountBoundingTriangles / 3); - for (uint32 i = 0; i < Header.CountBoundingTriangles / 3; i++) - { - Triangle tri; - tri.Type = Constants::TRIANGLE_TYPE_DOODAD; - int count = 0; - count += fread(&tri.V0, sizeof(uint16), 1, Stream); - count += fread(&tri.V1, sizeof(uint16), 1, Stream); - count += fread(&tri.V2, sizeof(uint16), 1, Stream); - if (count != 3) - printf("Model::ReadBoundingTriangles: Error reading data, expected 3, read %d\n", count); - Triangles.push_back(tri); - } -} - -void Model::ReadBoundingNormals() -{ - fseek(Stream, Header.OffsetBoundingNormals, SEEK_SET); - Normals.reserve(Header.CountBoundingNormals); - for (uint32 i = 0; i < Header.CountBoundingNormals; i++) - Normals.push_back(Vector3::Read(Stream)); -} diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h deleted file mode 100644 index 0aa625e6f..000000000 --- a/src/tools/mesh_extractor/Model.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef MODEL_H -#define MODEL_H -#include "Utils.h" -#include - -class Model -{ -public: - Model(std::string path); - ~Model(); - - void ReadVertices(); - void ReadBoundingTriangles(); - void ReadBoundingNormals(); - ModelHeader Header; - std::vector Vertices; - std::vector Normals; - std::vector> Triangles; - bool IsCollidable; - FILE* Stream; - bool IsBad; -}; -#endif diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp deleted file mode 100644 index ef63b4921..000000000 --- a/src/tools/mesh_extractor/ObjectDataHandler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "ObjectDataHandler.h" -#include "ADT.h" - -void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) -{ - ProcessInternal(chunk); -} diff --git a/src/tools/mesh_extractor/ObjectDataHandler.h b/src/tools/mesh_extractor/ObjectDataHandler.h deleted file mode 100644 index 0a557eb9c..000000000 --- a/src/tools/mesh_extractor/ObjectDataHandler.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ODATA_HNDL_H -#define ODATA_HNDL_H -#include "ADT.h" -#include "MapChunk.h" - -class ObjectDataHandler -{ -public: - ObjectDataHandler(ADT* _adt) : Source(_adt) {} - - void ProcessMapChunk(MapChunk* chunk); - virtual void ProcessInternal(MapChunk* data) = 0; - ADT* Source; -}; -#endif diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp deleted file mode 100644 index d7cef07d7..000000000 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "TileBuilder.h" -#include "ADT.h" -#include "Cache.h" -#include "Constants.h" -#include "ContinentBuilder.h" -#include "DetourNavMeshBuilder.h" -#include "Geometry.h" -#include "Recast.h" -#include "RecastAlloc.h" -#include "Utils.h" -#include "WDT.h" -#include "WorldModelRoot.h" - -TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : - World(world), X(x), Y(y), MapId(mapId), _Geometry(nullptr), DataSize(0), cBuilder(_cBuilder) -{ - // Config for normal maps - memset(&Config, 0, sizeof(rcConfig)); - Config.cs = Constants::TileSize / 1800.0f; // TileSize / voxelSize - Config.ch = 0.3f; - Config.minRegionArea = 36; - Config.mergeRegionArea = 144; - Config.walkableSlopeAngle = 50.0f; - Config.detailSampleDist = 3.0f; - Config.detailSampleMaxError = 1.25f; - Config.walkableClimb = 1.0f / Config.ch; - Config.walkableHeight = 2.1 / Config.ch; - Config.walkableRadius = 0.6f / Config.cs; - Config.maxEdgeLen = Config.walkableRadius * 8; - Config.borderSize = Config.walkableRadius + 8; - Config.tileSize = 1800; - Config.maxSimplificationError = 1.3f; - Config.maxVertsPerPoly = 6; - - // Config for instances - memset(&InstanceConfig, 0, sizeof(rcConfig)); - InstanceConfig.cs = 0.2f; - InstanceConfig.ch = 0.3f; - InstanceConfig.minRegionArea = 25; - InstanceConfig.mergeRegionArea = 100; - InstanceConfig.walkableSlopeAngle = 50.0f; - InstanceConfig.detailSampleDist = 3.0f; - InstanceConfig.detailSampleMaxError = 1.5f; - InstanceConfig.walkableClimb = 1.0f / InstanceConfig.ch; - InstanceConfig.walkableHeight = 2.1f / InstanceConfig.ch; - InstanceConfig.walkableRadius = 0.6f / InstanceConfig.cs; - InstanceConfig.maxEdgeLen = 8 * InstanceConfig.walkableRadius; - InstanceConfig.maxVertsPerPoly = 6; - InstanceConfig.maxSimplificationError = 1.25f; - InstanceConfig.borderSize = 0; - - Context = new rcContext; -} - -void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshParams& /*navMeshParams*/ ) -{ - bmin = new float[3]; - bmax = new float[3]; - bmin[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * X); - bmin[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * Y); - bmax[0] = Constants::Origin[0] /*navMeshParams.orig[0]*/ + (Constants::TileSize * (X + 1)); - bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1)); -} - -void TileBuilder::AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def) -{ - _Geometry = new Geometry(); - _Geometry->Transform = true; - - WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root, false); - - OutputDebugVertices(); -} - -uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) -{ - float* bmin = nullptr, *bmax = nullptr; - - _Geometry->CalculateBoundingBox(bmin, bmax); - - rcVcopy(InstanceConfig.bmax, bmax); - rcVcopy(InstanceConfig.bmin, bmin); - - uint32 numVerts = _Geometry->Vertices.size(); - uint32 numTris = _Geometry->Triangles.size(); - float* vertices; - int* triangles; - uint8* areas; - _Geometry->GetRawData(vertices, triangles, areas); - - // this sets the dimensions of the heightfield - rcCalcGridSize(InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, &InstanceConfig.width, &InstanceConfig.height); - - rcHeightfield* hf = rcAllocHeightfield(); - rcCreateHeightfield(Context, *hf, InstanceConfig.width, InstanceConfig.height, InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, InstanceConfig.ch); - - rcClearUnwalkableTriangles(Context, InstanceConfig.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); - rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, InstanceConfig.walkableClimb); - - rcFilterLowHangingWalkableObstacles(Context, InstanceConfig.walkableClimb, *hf); - rcFilterLedgeSpans(Context, InstanceConfig.walkableHeight, InstanceConfig.walkableClimb, *hf); - rcFilterWalkableLowHeightSpans(Context, InstanceConfig.walkableHeight, *hf); - - rcCompactHeightfield* chf = rcAllocCompactHeightfield(); - rcBuildCompactHeightfield(Context, InstanceConfig.walkableHeight, InstanceConfig.walkableClimb, *hf, *chf); - - rcErodeWalkableArea(Context, InstanceConfig.walkableRadius, *chf); - rcBuildDistanceField(Context, *chf); - rcBuildRegions(Context, *chf, InstanceConfig.borderSize, InstanceConfig.minRegionArea, InstanceConfig.minRegionArea); - - rcContourSet* contours = rcAllocContourSet(); - rcBuildContours(Context, *chf, InstanceConfig.maxSimplificationError, InstanceConfig.maxEdgeLen, *contours); - - rcPolyMesh* pmesh = rcAllocPolyMesh(); - rcBuildPolyMesh(Context, *contours, InstanceConfig.maxVertsPerPoly, *pmesh); - - rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); - rcBuildPolyMeshDetail(Context, *pmesh, *chf, InstanceConfig.detailSampleDist, InstanceConfig.detailSampleMaxError, *dmesh); - - // Set flags according to area types (e.g. Swim for Water) - for (int i = 0; i < pmesh->npolys; i++) - { - if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) - pmesh->flags[i] = Constants::POLY_FLAG_WALK; - else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) - pmesh->flags[i] = Constants::POLY_FLAG_SWIM; - } - - dtNavMeshCreateParams params; - memset(¶ms, 0, sizeof(params)); - // PolyMesh data - params.verts = pmesh->verts; - params.vertCount = pmesh->nverts; - params.polys = pmesh->polys; - params.polyAreas = pmesh->areas; - params.polyFlags = pmesh->flags; - params.polyCount = pmesh->npolys; - params.nvp = pmesh->nvp; - // PolyMeshDetail data - params.detailMeshes = dmesh->meshes; - params.detailVerts = dmesh->verts; - params.detailVertsCount = dmesh->nverts; - params.detailTris = dmesh->tris; - params.detailTriCount = dmesh->ntris; - rcVcopy(params.bmin, pmesh->bmin); - rcVcopy(params.bmax, pmesh->bmax); - // General settings - params.ch = InstanceConfig.ch; - params.cs = InstanceConfig.cs; - params.walkableClimb = InstanceConfig.walkableClimb * InstanceConfig.ch; - params.walkableHeight = InstanceConfig.walkableHeight * InstanceConfig.ch; - params.walkableRadius = InstanceConfig.walkableRadius * InstanceConfig.cs; - params.tileX = X; - params.tileY = Y; - params.tileLayer = 0; - params.buildBvTree = true; - - rcVcopy(params.bmax, bmax); - rcVcopy(params.bmin, bmin); - - // Offmesh-connection settings - params.offMeshConCount = 0; // none for now - - rcFreeHeightField(hf); - rcFreeCompactHeightfield(chf); - rcFreeContourSet(contours); - delete vertices; - delete triangles; - delete areas; - delete bmin; - delete bmax; - - if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) - { - // we have flat tiles with no actual geometry - don't build those, its useless - // keep in mind that we do output those into debug info - // drop tiles with only exact count - some tiles may have geometry while having less tiles - printf("No polygons to build on tile, skipping.\n"); - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - return nullptr; - } - - int navDataSize; - uint8* navData; - printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", params.vertCount, params.polyCount, params.detailTriCount); - bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - - if (result) - { - printf("NavMesh created, size %i!\n", navDataSize); - DataSize = navDataSize; - return navData; - } - - return nullptr; -} - -uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) -{ - _Geometry = new Geometry(); - _Geometry->Transform = true; - ADT* adt = new ADT(Utils::GetAdtPath(World, X, Y), X, Y); - adt->Read(); - _Geometry->AddAdt(adt); - delete adt; - - if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) - return nullptr; - - float* bmin = nullptr, *bmax = nullptr; - CalculateTileBounds(bmin, bmax, navMeshParams); - _Geometry->CalculateMinMaxHeight(bmin[1], bmax[1]); - - // again, we load everything - wasteful but who cares - for (int ty = Y - 1; ty <= Y + 1; ty++) - { - for (int tx = X - 1; tx <= X + 1; tx++) - { - // don't load main tile again - if (tx == X && ty == Y) - continue; - - ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty), tx, ty); - // If this condition is met, it means that this WDT does not contain the ADT - if (!_adt->Data->Stream) - { - delete _adt; - continue; - } - _adt->Read(); - _Geometry->AddAdt(_adt); - delete _adt; - } - } - - OutputDebugVertices(); - - uint32 numVerts = _Geometry->Vertices.size(); - uint32 numTris = _Geometry->Triangles.size(); - float* vertices; - int* triangles; - uint8* areas; - _Geometry->GetRawData(vertices, triangles, areas); - _Geometry->Vertices.clear(); - _Geometry->Triangles.clear(); - - // add border - bmin[0] -= Config.borderSize * Config.cs; - bmin[2] -= Config.borderSize * Config.cs; - bmax[0] += Config.borderSize * Config.cs; - bmax[2] += Config.borderSize * Config.cs; - - rcHeightfield* hf = rcAllocHeightfield(); - int width = Config.tileSize + (Config.borderSize * 2); - rcCreateHeightfield(Context, *hf, width, width, bmin, bmax, Config.cs, Config.ch); - - rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); - rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - - rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); - rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); - rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - - rcCompactHeightfield* chf = rcAllocCompactHeightfield(); - rcBuildCompactHeightfield(Context, Config.walkableHeight, Config.walkableClimb, *hf, *chf); - - rcErodeWalkableArea(Context, Config.walkableRadius, *chf); - rcBuildDistanceField(Context, *chf); - rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); - - rcContourSet* contours = rcAllocContourSet(); - rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *contours); - - rcPolyMesh* pmesh = rcAllocPolyMesh(); - rcBuildPolyMesh(Context, *contours, Config.maxVertsPerPoly, *pmesh); - - rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); - rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); - - // Set flags according to area types (e.g. Swim for Water) - for (int i = 0; i < pmesh->npolys; i++) - { - if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) - pmesh->flags[i] = Constants::POLY_FLAG_WALK; - else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) - pmesh->flags[i] = Constants::POLY_FLAG_SWIM; - } - - dtNavMeshCreateParams params; - memset(¶ms, 0, sizeof(params)); - // PolyMesh data - params.verts = pmesh->verts; - params.vertCount = pmesh->nverts; - params.polys = pmesh->polys; - params.polyAreas = pmesh->areas; - params.polyFlags = pmesh->flags; - params.polyCount = pmesh->npolys; - params.nvp = pmesh->nvp; - // PolyMeshDetail data - params.detailMeshes = dmesh->meshes; - params.detailVerts = dmesh->verts; - params.detailVertsCount = dmesh->nverts; - params.detailTris = dmesh->tris; - params.detailTriCount = dmesh->ntris; - // General settings - params.ch = Config.ch; - params.cs = Config.cs; - params.walkableClimb = Config.walkableClimb * Config.ch; - params.walkableHeight = Config.walkableHeight * Config.ch; - params.walkableRadius = Config.walkableRadius * Config.cs; - params.tileX = X; - params.tileY = Y; - params.tileLayer = 0; - params.buildBvTree = true; - - // Recalculate the bounds with the added geometry - float* bmin2 = nullptr, *bmax2 = nullptr; - CalculateTileBounds(bmin2, bmax2, navMeshParams); - bmin2[1] = bmin[1]; - bmax2[1] = bmax[1]; - - rcVcopy(params.bmax, bmax2); - rcVcopy(params.bmin, bmin2); - - // Offmesh-connection settings - params.offMeshConCount = 0; // none for now - - rcFreeHeightField(hf); - rcFreeCompactHeightfield(chf); - rcFreeContourSet(contours); - delete vertices; - delete triangles; - delete areas; - delete bmin; - delete bmax; - - if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) - { - // we have flat tiles with no actual geometry - don't build those, its useless - // keep in mind that we do output those into debug info - // drop tiles with only exact count - some tiles may have geometry while having less tiles - printf("[%02i, %02i] No polygons to build on tile, skipping.\n", X, Y); - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - return nullptr; - } - - int navDataSize; - uint8* navData; - printf("[%02i, %02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, params.vertCount, params.polyCount, params.detailTriCount); - bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - - if (result) - { - printf("[%02i, %02i] NavMesh created, size %i!\n", X, Y, navDataSize); - DataSize = navDataSize; - return navData; - } - - return nullptr; -} - -void TileBuilder::OutputDebugVertices() -{ - if (Constants::Debug) - { - char buff[100]; - sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); - FILE* debug = fopen(buff, "wb"); - for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i) - { - const Vector3& vector = _Geometry->Vertices[i]; - fprintf(debug, "v %f %f %f\n", vector.x, vector.y, vector.z); - } - for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i) - { - const Triangle& triangle = _Geometry->Triangles[i]; - fprintf(debug, "f %u %u %u\n", triangle.V0 + 1, triangle.V1 + 1, triangle.V2 + 1); - } - fclose(debug); - } -} - -TileBuilder::~TileBuilder() -{ - delete Context; - delete _Geometry; -} diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h deleted file mode 100644 index 03df0f0dc..000000000 --- a/src/tools/mesh_extractor/TileBuilder.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef TILE_BUILD_H -#define TILE_BUILD_H -#include "Recast.h" -#include - -#include "Geometry.h" -#include "WorldModelRoot.h" - -class ContinentBuilder; -class WDT; - -class TileBuilder -{ -public: - TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId); - ~TileBuilder(); - - void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); - uint8* BuildTiled(dtNavMeshParams& navMeshParams); - uint8* BuildInstance(dtNavMeshParams& navMeshParams); - void AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def); - void OutputDebugVertices(); - std::string World; - int X; - int Y; - int MapId; - rcConfig Config; - rcConfig InstanceConfig; - rcContext* Context; - Geometry* _Geometry; - uint32 DataSize; - ContinentBuilder* cBuilder; -}; -#endif diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp deleted file mode 100644 index 3c8717345..000000000 --- a/src/tools/mesh_extractor/Utils.cpp +++ /dev/null @@ -1,563 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Utils.h" -#include "Constants.h" -#include "G3D/Matrix4.h" -#include "G3D/Quat.h" -#include "WorldModelHandler.h" -#include - -#ifdef _WIN32 -#include "direct.h" -#else -#include -#include -#endif - -const float Constants::TileSize = 533.0f + (1 / 3.0f); -const float Constants::MaxXY = 32.0f * Constants::TileSize; -const float Constants::ChunkSize = Constants::TileSize / 16.0f; -const float Constants::UnitSize = Constants::ChunkSize / 8.0f; -const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; -const float Constants::PI = 3.1415926f; -const float Constants::MaxStandableHeight = 1.5f; -const char* Constants::VMAPMagic = "VMAP044"; -bool Constants::ToWoWCoords = false; -bool Constants::Debug = false; -const float Constants::BaseUnitDim = 0.533333f; -const int Constants::VertexPerMap = (Constants::TileSize / Constants::BaseUnitDim) + 0.5f; -const int Constants::VertexPerTile = 40; -const int Constants::TilesPerMap = Constants::VertexPerMap / Constants::VertexPerTile; - -void Utils::CreateDir( const std::string& Path ) -{ -#ifdef _WIN32 - _mkdir( Path.c_str()); -#else - mkdir( Path.c_str(), 0777 ); -#endif -} - -void Utils::Reverse(char word[]) -{ - int len = strlen(word); - for (int i = 0; i < len / 2; i++) - { - word[i] ^= word[len - i - 1]; - word[len - i - 1] ^= word[i]; - word[i] ^= word[len - i - 1]; - } -} - -std::string Utils::ReadString( FILE* file ) -{ - std::string ret; - while (true) - { - char b; - if (fread(&b, sizeof(char), 1, file) != 1 || b == 0) - break; - ret.push_back(b); - } - return ret; -} - -uint32 Utils::Size( FILE* file ) -{ - // store the old position - uint32 offset = ftell(file); - // Get file size - fseek(file, 0, SEEK_END); - uint32 size = ftell(file); - // reset back to the old position - fseek(file, offset, SEEK_SET); - return size; -} - -Vector3 Utils::ToRecast(const Vector3& val ) -{ - return Vector3(-val.y, val.z, -val.x); -} - -std::string Utils::GetAdtPath(const std::string& world, int x, int y ) -{ - return "World\\Maps\\" + world + "\\" + world + "_" + Utils::ToString(x) + "_" + Utils::ToString(y) + ".adt"; -} - -std::string Utils::FixModelPath(const std::string& path ) -{ - return Utils::GetPathBase(path) + ".M2"; -} - -Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate) -{ - // Sources of information: - /// http://www.pxr.dk/wowdev/wiki/index.php?title=ADT/v18&oldid=3715 - - // This function applies to both external doodads and WMOs - - // Rotate our Doodad vertex - G3D::Matrix4 rot = G3D::Matrix3::fromEulerAnglesXYZ(Utils::ToRadians(def.Rotation.z), Utils::ToRadians(-def.Rotation.x), Utils::ToRadians(def.Rotation.y + 180)); - Vector3 ret = Utils::VectorTransform(vec, rot); - - // And finally scale and translate it to our origin - ret = ret * def.Scale(); - if (translate) - ret = ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); - return ret; -} - -Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate ) -{ - G3D::Quat quat = G3D::Quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); - - Vector3 ret = Utils::VectorTransform(vec, G3D::Matrix4(quat.toRotationMatrix())); - ret = ret * (inst.Scale / 1024.0f); - if (translate) - ret = ret + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y); - return ret; -} - -float Utils::ToRadians( float degrees ) -{ - return Constants::PI * degrees / 180.0f; -} - -Vector3 Utils::VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal ) -{ - G3D::Vector3 ret(vec.x, vec.y, vec.z); - ret = matrix.homoMul(ret, normal ? 0 : 1); - return Vector3(ret.x, ret.y, ret.z); -} - -std::string Utils::GetPathBase(const std::string& path ) -{ - size_t lastIndex = path.find_last_of("."); - if (lastIndex != std::string::npos) - return path.substr(0, lastIndex); - return path; -} - -Vector3 Vector3::Read( FILE* file ) -{ - Vector3 ret; - if (fread(&ret, sizeof(Vector3), 1, file) != 1) - printf("Vector3::Read: Failed to read some data expected 1, read 0\n"); - return ret; -} - -Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int x, int y, bool translate) -{ - if (Utils::Distance(height, 0.0f) > 0.5f) - basePosition.z = 0.0f; - return Utils::TransformDoodadVertex(def, basePosition + Vector3(x * Constants::UnitSize, y * Constants::UnitSize, height), translate); -} - -float Utils::Distance( float x, float y ) -{ - return std::sqrt(x * x + y * y); -} - -std::string Utils::Replace( std::string str, const std::string& oldStr, const std::string& newStr ) -{ - size_t pos = 0; - while ((pos = str.find(oldStr, pos)) != std::string::npos) - { - str.replace(pos, oldStr.length(), newStr); - pos += newStr.length(); - } - return str; -} - -void Utils::SaveToDisk( FILE* stream, const std::string& path ) -{ - FILE* disk = fopen(path.c_str(), "wb"); - if (!disk) - { - printf("SaveToDisk: Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); - fclose(stream); - return; - } - - uint32 size = Utils::Size(stream); - uint8* data = new uint8[size]; - // Read the data to an array - size_t read = fread(data, size, 1, stream); - if (read != 1) - { - printf("SaveToDisk: Error reading from Stream while trying to save file %s to disk.\n", path.c_str()); - fclose(disk); - fclose(stream); - return; - } - - // And write it in the file - size_t wrote = fwrite(data, size, 1, disk); - if (wrote != 1) - { - printf("SaveToDisk: Error writing to the file while trying to save %s to disk.\n", path.c_str()); - fclose(stream); - fclose(disk); - return; - } - - // Close the filestream - fclose(disk); - fclose(stream); - - // Free the used memory - delete[] data; -} - -Vector3 Utils::ToWoWCoords(const Vector3& vec ) -{ - return Vector3(-vec.z, -vec.x, vec.y); -} - -std::string Utils::GetExtension( std::string path ) -{ - std::string::size_type idx = path.rfind('.'); - std::string extension = ""; - - if (idx != std::string::npos) - extension = path.substr(idx + 1); - return extension; -} - -void MapChunkHeader::Read(FILE* stream) -{ - int count = 0; - - count += fread(&Flags, sizeof(uint32), 1, stream); - count += fread(&IndexX, sizeof(uint32), 1, stream); - count += fread(&IndexY, sizeof(uint32), 1, stream); - count += fread(&Layers, sizeof(uint32), 1, stream); - count += fread(&DoodadRefs, sizeof(uint32), 1, stream); - count += fread(&OffsetMCVT, sizeof(uint32), 1, stream); - count += fread(&OffsetMCNR, sizeof(uint32), 1, stream); - count += fread(&OffsetMCLY, sizeof(uint32), 1, stream); - count += fread(&OffsetMCRF, sizeof(uint32), 1, stream); - count += fread(&OffsetMCAL, sizeof(uint32), 1, stream); - count += fread(&SizeMCAL, sizeof(uint32), 1, stream); - count += fread(&OffsetMCSH, sizeof(uint32), 1, stream); - count += fread(&SizeMCSH, sizeof(uint32), 1, stream); - count += fread(&AreaId, sizeof(uint32), 1, stream); - count += fread(&MapObjectRefs, sizeof(uint32), 1, stream); - count += fread(&Holes, sizeof(uint32), 1, stream); - LowQualityTextureMap = new uint32[4]; - count += fread(LowQualityTextureMap, sizeof(uint32), 4, stream); - count += fread(&PredTex, sizeof(uint32), 1, stream); - count += fread(&NumberEffectDoodad, sizeof(uint32), 1, stream); - count += fread(&OffsetMCSE, sizeof(uint32), 1, stream); - count += fread(&SoundEmitters, sizeof(uint32), 1, stream); - count += fread(&OffsetMCLQ, sizeof(uint32), 1, stream); - count += fread(&SizeMCLQ, sizeof(uint32), 1, stream); - Position = Vector3::Read(stream); - count += fread(&OffsetMCCV, sizeof(uint32), 1, stream); - - if (count != 27) - printf("MapChunkHeader::Read: Failed to read some data expected 27, read %d\n", count); -} - -void MHDR::Read(FILE* stream) -{ - int count = 0; - - count += fread(&Flags, sizeof(uint32), 1, stream); - count += fread(&OffsetMCIN, sizeof(uint32), 1, stream); - count += fread(&OffsetMTEX, sizeof(uint32), 1, stream); - count += fread(&OffsetMMDX, sizeof(uint32), 1, stream); - count += fread(&OffsetMMID, sizeof(uint32), 1, stream); - count += fread(&OffsetMWMO, sizeof(uint32), 1, stream); - count += fread(&OffsetMWID, sizeof(uint32), 1, stream); - count += fread(&OffsetMDDF, sizeof(uint32), 1, stream); - count += fread(&OffsetMODF, sizeof(uint32), 1, stream); - count += fread(&OffsetMFBO, sizeof(uint32), 1, stream); - count += fread(&OffsetMH2O, sizeof(uint32), 1, stream); - count += fread(&OffsetMTFX, sizeof(uint32), 1, stream); - - if (count != 12) - printf("MHDR::Read: Failed to read some data expected 12, read %d\n", count); -} - -void ModelHeader::Read(FILE* stream) -{ - int count = 0; - - count += fread(&Magic, sizeof(char), 4, stream); - Magic[4] = '\0'; // null-terminate it. - count += fread(&Version, sizeof(uint32), 1, stream); - count += fread(&LengthModelName, sizeof(uint32), 1, stream); - count += fread(&OffsetName, sizeof(uint32), 1, stream); - count += fread(&ModelFlags, sizeof(uint32), 1, stream); - count += fread(&CountGlobalSequences, sizeof(uint32), 1, stream); - count += fread(&OffsetGlobalSequences, sizeof(uint32), 1, stream); - count += fread(&CountAnimations, sizeof(uint32), 1, stream); - count += fread(&OffsetAnimations, sizeof(uint32), 1, stream); - count += fread(&CountAnimationLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetAnimationLookup, sizeof(uint32), 1, stream); - count += fread(&CountBones, sizeof(uint32), 1, stream); - count += fread(&OffsetBones, sizeof(uint32), 1, stream); - count += fread(&CountKeyBoneLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetKeyBoneLookup, sizeof(uint32), 1, stream); - count += fread(&CountVertices, sizeof(uint32), 1, stream); - count += fread(&OffsetVertices, sizeof(uint32), 1, stream); - count += fread(&CountViews, sizeof(uint32), 1, stream); - count += fread(&CountColors, sizeof(uint32), 1, stream); - count += fread(&OffsetColors, sizeof(uint32), 1, stream); - count += fread(&CountTextures, sizeof(uint32), 1, stream); - count += fread(&OffsetTextures, sizeof(uint32), 1, stream); - count += fread(&CountTransparency, sizeof(uint32), 1, stream); - count += fread(&OffsetTransparency, sizeof(uint32), 1, stream); - count += fread(&CountUvAnimation, sizeof(uint32), 1, stream); - count += fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - count += fread(&CountTexReplace, sizeof(uint32), 1, stream); - count += fread(&OffsetTexReplace, sizeof(uint32), 1, stream); - count += fread(&CountRenderFlags, sizeof(uint32), 1, stream); - count += fread(&OffsetRenderFlags, sizeof(uint32), 1, stream); - count += fread(&CountBoneLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetBoneLookup, sizeof(uint32), 1, stream); - count += fread(&CountTexLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetTexLookup, sizeof(uint32), 1, stream); - count += fread(&CountTexUnits, sizeof(uint32), 1, stream); - count += fread(&OffsetTexUnits, sizeof(uint32), 1, stream); - count += fread(&CountTransLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetTransLookup, sizeof(uint32), 1, stream); - count += fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); - count += fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); - VertexBox[0] = Vector3::Read(stream); - VertexBox[1] = Vector3::Read(stream); - count += fread(&VertexRadius, sizeof(float), 1, stream); - BoundingBox[0] = Vector3::Read(stream); - BoundingBox[1] = Vector3::Read(stream); - count += fread(&BoundingRadius, sizeof(float), 1, stream); - count += fread(&CountBoundingTriangles, sizeof(uint32), 1, stream); - count += fread(&OffsetBoundingTriangles, sizeof(uint32), 1, stream); - count += fread(&CountBoundingVertices, sizeof(uint32), 1, stream); - count += fread(&OffsetBoundingVertices, sizeof(uint32), 1, stream); - count += fread(&CountBoundingNormals, sizeof(uint32), 1, stream); - count += fread(&OffsetBoundingNormals, sizeof(uint32), 1, stream); - - if (count != 51) - printf("ModelHeader::Read: Failed to read some data expected 51, read %d\n", count); -} - -WorldModelHeader WorldModelHeader::Read(FILE* stream) -{ - WorldModelHeader ret; - int count = 0; - - count += fread(&ret.CountMaterials, sizeof(uint32), 1, stream); - count += fread(&ret.CountGroups, sizeof(uint32), 1, stream); - count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); - count += fread(&ret.CountLights, sizeof(uint32), 1, stream); - count += fread(&ret.CountModels, sizeof(uint32), 1, stream); - count += fread(&ret.CountDoodads, sizeof(uint32), 1, stream); - count += fread(&ret.CountSets, sizeof(uint32), 1, stream); - count += fread(&ret.AmbientColorUnk, sizeof(uint32), 1, stream); - count += fread(&ret.WmoId, sizeof(uint32), 1, stream); - ret.BoundingBox[0] = Vector3::Read(stream); - ret.BoundingBox[1] = Vector3::Read(stream); - count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - - if (count != 10) - printf("WorldModelHeader::Read: Failed to read some data expected 10, read %d\n", count); - - return ret; -} - -DoodadInstance DoodadInstance::Read(FILE* stream) -{ - DoodadInstance ret; - int count = 0; - - count += fread(&ret.FileOffset, sizeof(uint32), 1, stream); - ret.Position = Vector3::Read(stream); - count += fread(&ret.QuatW, sizeof(float), 1, stream); - count += fread(&ret.QuatX, sizeof(float), 1, stream); - count += fread(&ret.QuatY, sizeof(float), 1, stream); - count += fread(&ret.QuatZ, sizeof(float), 1, stream); - count += fread(&ret.Scale, sizeof(float), 1, stream); - count += fread(&ret.LightColor, sizeof(uint32), 1, stream); - - if (count != 7) - printf("DoodadInstance::Read: Failed to read some data expected 7, read %d\n", count); - - return ret; -} - -DoodadSet DoodadSet::Read(FILE* stream) -{ - DoodadSet ret; - char name[21]; - int count = 0; - - count += fread(&name, sizeof(char), 20, stream); - name[20] = '\0'; - ret.Name = name; - count += fread(&ret.FirstInstanceIndex, sizeof(uint32), 1, stream); - count += fread(&ret.CountInstances, sizeof(uint32), 1, stream); - count += fread(&ret.UnknownZero, sizeof(uint32), 1, stream); - - if (count != 23) - printf("DoodadSet::Read: Failed to read some data expected 23, read %d\n", count); - - return ret; -} - -LiquidHeader LiquidHeader::Read(FILE* stream) -{ - LiquidHeader ret; - int count = 0; - count += fread(&ret.CountXVertices, sizeof(uint32), 1, stream); - count += fread(&ret.CountYVertices, sizeof(uint32), 1, stream); - count += fread(&ret.Width, sizeof(uint32), 1, stream); - count += fread(&ret.Height, sizeof(uint32), 1, stream); - ret.BaseLocation = Vector3::Read(stream); - count += fread(&ret.MaterialId, sizeof(uint16), 1, stream); - - if (count != 5) - printf("LiquidHeader::Read: Failed to read some data expected 5, read %d\n", count); - - return ret; -} - -LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) -{ - LiquidData ret; - ret.HeightMap = new float*[header.CountXVertices]; - for (uint32 i = 0; i < header.CountXVertices; ++i) - ret.HeightMap[i] = new float[header.CountYVertices]; - - ret.RenderFlags = new uint8*[header.Width]; - for (uint32 i = 0; i < header.Width; ++i) - ret.RenderFlags[i] = new uint8[header.Height]; - - for (uint32 y = 0; y < header.CountYVertices; y++) - { - for (uint32 x = 0; x < header.CountXVertices; x++) - { - uint32 discard; - float tmp; - if (fread(&discard, sizeof(uint32), 1, stream) == 1 && - fread(&tmp, sizeof(float), 1, stream) == 1) - { - ret.HeightMap[x][y] = tmp; - } - } - } - - for (uint32 y = 0; y < header.Height; y++) - { - for (uint32 x = 0; x < header.Width; x++) - { - uint8 tmp = 0; - if (fread(&tmp, sizeof(uint8), 1, stream) == 1) - ret.RenderFlags[x][y] = tmp; - } - } - - return ret; -} - -H2ORenderMask H2ORenderMask::Read(FILE* stream) -{ - H2ORenderMask ret; - int32 count; - if ((count = fread(&ret.Mask, sizeof(uint8), 8, stream)) != 8) - printf("H2OHeader::Read: Failed to read some data expected 8, read %d\n", count); - return ret; -} - -bool MCNKLiquidData::IsWater(int x, int y, float height) -{ - if (!Heights) - return false; - if (!Mask.ShouldRender(x, y)) - return false; - float diff = Heights[x][y] - height; - if (diff > Constants::MaxStandableHeight) - return true; - return false; -} - -H2OHeader H2OHeader::Read(FILE* stream) -{ - H2OHeader ret; - int count = 0; - count += fread(&ret.OffsetInformation, sizeof(uint32), 1, stream); - count += fread(&ret.LayerCount, sizeof(uint32), 1, stream); - count += fread(&ret.OffsetRender, sizeof(uint32), 1, stream); - - if (count != 3) - printf("H2OHeader::Read: Failed to read some data expected 3, read %d\n", count); - - return ret; -} - -H2OInformation H2OInformation::Read(FILE* stream) -{ - H2OInformation ret; - int count = 0; - count += fread(&ret.LiquidType, sizeof(uint16), 1, stream); - count += fread(&ret.Flags, sizeof(uint16), 1, stream); - count += fread(&ret.HeightLevel1, sizeof(float), 1, stream); - count += fread(&ret.HeightLevel2, sizeof(float), 1, stream); - count += fread(&ret.OffsetX, sizeof(uint8), 1, stream); - count += fread(&ret.OffsetY, sizeof(uint8), 1, stream); - count += fread(&ret.Width, sizeof(uint8), 1, stream); - count += fread(&ret.Height, sizeof(uint8), 1, stream); - count += fread(&ret.OffsetMask2, sizeof(uint32), 1, stream); - count += fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); - - if (count != 10) - printf("H2OInformation::Read: Failed to read some data expected 10, read %d\n", count); - - return ret; -} - -char* Utils::GetPlainName(const char* FileName) -{ - char* temp; - - if ((temp = (char*)strrchr(FileName, '\\')) != nullptr) - FileName = temp + 1; - return (char*)FileName; -} - -WMOGroupHeader WMOGroupHeader::Read( FILE* stream ) -{ - WMOGroupHeader ret; - int count = 0; - count += fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); - count += fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); - count += fread(&ret.Flags, sizeof(uint32), 1, stream); - ret.BoundingBox[0] = Vector3::Read(stream); - ret.BoundingBox[1] = Vector3::Read(stream); - count += fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); - count += fread(&ret.CountPortals, sizeof(uint32), 1, stream); - count += fread(&ret.CountBatches, sizeof(uint16), 4, stream); - count += fread(&ret.Fogs, sizeof(uint8), 4, stream); - count += fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); - count += fread(&ret.WmoId, sizeof(uint32), 1, stream); - - if (count != 15) - printf("WMOGroupHeader::Read: Failed to read some data expected 15, read %d\n", count); - - return ret; -} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h deleted file mode 100644 index df5b13d1d..000000000 --- a/src/tools/mesh_extractor/Utils.h +++ /dev/null @@ -1,403 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef UTILS_H -#define UTILS_H - -#include -#include -#include - -#include "DetourNavMesh.h" -#include "G3D/Matrix4.h" - -#include "Constants.h" -#include "Define.h" - -struct WorldModelDefinition; -class DoodadDefinition; -class DoodadInstance; - -#define ASSERT(assertion) { if (!(assertion)) {fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)nullptr) = 0; } } - -struct Vector3 -{ - Vector3() {} - Vector3(float X, float Y, float Z) : x(X), y(Y), z(Z) {} - float x; - float y; - float z; - - Vector3 operator +(Vector3 const& other) const - { - return Vector3(x + other.x, y + other.y, z + other.z); - } - - Vector3 operator -(Vector3 const& other) const - { - return Vector3(x - other.x, y - other.y, z - other.z); - } - - template - Vector3 operator *(T s) const - { - return Vector3(x * s, y * s, z * s); - } - - static Vector3 Read(FILE* file); -}; - -struct TilePos -{ - TilePos(int x, int y) : X(x), Y(y) {} - int X; - int Y; -}; - -template -struct Triangle -{ - Triangle() {} - Triangle(Constants::TriangleType type, T v0, T v1, T v2) : V0(v0), V1(v1), V2(v2), Type(type) {} - T V0; - T V1; - T V2; - Constants::TriangleType Type; -}; - -class MapChunkHeader -{ -public: - MapChunkHeader() {} - uint32 Flags; - uint32 IndexX; - uint32 IndexY; - uint32 Layers; - uint32 DoodadRefs; - uint32 OffsetMCVT; - uint32 OffsetMCNR; - uint32 OffsetMCLY; - uint32 OffsetMCRF; - uint32 OffsetMCAL; - uint32 SizeMCAL; - uint32 OffsetMCSH; - uint32 SizeMCSH; - uint32 AreaId; - uint32 MapObjectRefs; - uint32 Holes; - uint32* LowQualityTextureMap; - uint32 PredTex; - uint32 NumberEffectDoodad; - uint32 OffsetMCSE; - uint32 SoundEmitters; - uint32 OffsetMCLQ; - uint32 SizeMCLQ; - Vector3 Position; - uint32 OffsetMCCV; - - void Read(FILE* stream); -}; - -class MHDR -{ -public: - MHDR() {} - uint32 Flags; - uint32 OffsetMCIN; - uint32 OffsetMTEX; - uint32 OffsetMMDX; - uint32 OffsetMMID; - uint32 OffsetMWMO; - uint32 OffsetMWID; - uint32 OffsetMDDF; - uint32 OffsetMODF; - uint32 OffsetMFBO; - uint32 OffsetMH2O; - uint32 OffsetMTFX; - - void Read(FILE* stream); -}; - -class ModelHeader -{ -public: - char Magic[5]; - uint32 Version; - uint32 LengthModelName; - uint32 OffsetName; - uint32 ModelFlags; - uint32 CountGlobalSequences; - uint32 OffsetGlobalSequences; - uint32 CountAnimations; - uint32 OffsetAnimations; - uint32 CountAnimationLookup; - uint32 OffsetAnimationLookup; - uint32 CountBones; - uint32 OffsetBones; - uint32 CountKeyBoneLookup; - uint32 OffsetKeyBoneLookup; - uint32 CountVertices; - uint32 OffsetVertices; - uint32 CountViews; - uint32 CountColors; - uint32 OffsetColors; - uint32 CountTextures; - uint32 OffsetTextures; - uint32 CountTransparency; - uint32 OffsetTransparency; - uint32 CountUvAnimation; - uint32 OffsetUvAnimation; - uint32 CountTexReplace; - uint32 OffsetTexReplace; - uint32 CountRenderFlags; - uint32 OffsetRenderFlags; - uint32 CountBoneLookup; - uint32 OffsetBoneLookup; - uint32 CountTexLookup; - uint32 OffsetTexLookup; - uint32 CountTexUnits; - uint32 OffsetTexUnits; - uint32 CountTransLookup; - uint32 OffsetTransLookup; - uint32 CountUvAnimLookup; - uint32 OffsetUvAnimLookup; - Vector3 VertexBox[2]; - float VertexRadius; - Vector3 BoundingBox[2]; - float BoundingRadius; - uint32 CountBoundingTriangles; - uint32 OffsetBoundingTriangles; - uint32 CountBoundingVertices; - uint32 OffsetBoundingVertices; - uint32 CountBoundingNormals; - uint32 OffsetBoundingNormals; - - void Read(FILE* stream); -}; - -class WorldModelHeader -{ -public: - WorldModelHeader() {} - uint32 CountMaterials; - uint32 CountGroups; - uint32 CountPortals; - uint32 CountLights; - uint32 CountModels; - uint32 CountDoodads; - uint32 CountSets; - uint32 AmbientColorUnk; - uint32 WmoId; - Vector3 BoundingBox[2]; - uint32 LiquidTypeRelated; - - static WorldModelHeader Read(FILE* stream); -}; - -class DoodadInstance -{ -public: - DoodadInstance() {} - uint32 FileOffset; - std::string File; - Vector3 Position; - float QuatW; - float QuatX; - float QuatY; - float QuatZ; - float Scale; - uint32 LightColor; - - static DoodadInstance Read(FILE* stream); -}; - -class DoodadSet -{ -public: - DoodadSet() {} - std::string Name; - uint32 FirstInstanceIndex; - uint32 CountInstances; - uint32 UnknownZero; - - static DoodadSet Read(FILE* stream); -}; - -class LiquidHeader -{ -public: - LiquidHeader() {} - uint32 CountXVertices; - uint32 CountYVertices; - uint32 Width; - uint32 Height; - Vector3 BaseLocation; - uint16 MaterialId; - - static LiquidHeader Read(FILE* stream); -}; - -class LiquidData -{ -public: - LiquidData() {} - float** HeightMap; - uint8** RenderFlags; - - bool ShouldRender(int x, int y) - { - return RenderFlags[x][y] != 0x0F; - } - - static LiquidData Read(FILE* stream, LiquidHeader& header); -}; - -class H2ORenderMask -{ -public: - H2ORenderMask() {} - uint8 Mask[8]; - - bool ShouldRender(int x, int y) - { - return (Mask[y] >> x & 1) != 0; - } - - static H2ORenderMask Read(FILE* stream); -}; - -class MCNKLiquidData -{ -public: - MCNKLiquidData() {} - MCNKLiquidData(float** heights, H2ORenderMask mask) : Heights(heights), Mask(mask) {} - - float** Heights; - H2ORenderMask Mask; - - bool IsWater(int x, int y, float height); -}; - -class H2OHeader -{ -public: - H2OHeader() {} - uint32 OffsetInformation; - uint32 LayerCount; - uint32 OffsetRender; - - static H2OHeader Read(FILE* stream); -}; - -class H2OInformation -{ -public: - H2OInformation() {} - uint16 LiquidType; - uint16 Flags; - float HeightLevel1; - float HeightLevel2; - uint8 OffsetX; - uint8 OffsetY; - uint8 Width; - uint8 Height; - uint32 OffsetMask2; - uint32 OffsetHeightmap; - - static H2OInformation Read(FILE* stream); -}; - -class WMOGroupHeader -{ -public: - WMOGroupHeader() {} - - uint32 OffsetGroupName; - uint32 OffsetDescriptiveName; - uint32 Flags; - Vector3 BoundingBox[2]; - uint32 OffsetPortals; - uint32 CountPortals; - uint16 CountBatches[4]; - uint8 Fogs[4]; - uint32 LiquidTypeRelated; - uint32 WmoId; - - static WMOGroupHeader Read(FILE* stream); -}; - -// Dummy class to act as an interface. -class IDefinition -{ -public: - Vector3 Position; - Vector3 Rotation; - virtual float Scale() const { return 1.0f; }; -}; - -struct MmapTileHeader -{ - uint32 mmapMagic; - uint32 dtVersion; - uint32 mmapVersion; - uint32 size; - bool usesLiquids; - - MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION), - mmapVersion(MMAP_VERSION), size(0), usesLiquids(true) {} -}; - -class Utils -{ -public: - static void Reverse(char word[]); - static std::string ReadString(FILE* file); - static uint32 Size(FILE* file); - static Vector3 ToRecast(const Vector3& val ); - static std::string GetAdtPath(const std::string& world, int x, int y); - static std::string FixModelPath(const std::string& path); - /// They say its better to declare template functions in the header files. - template - static std::string ToString(T val) - { - std::stringstream ss; - ss << val; - return ss.str(); - } - static float ToRadians(float degrees); - static std::string GetPathBase(const std::string& path); - static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/, bool translate = true); - static float Distance(float x, float y); - template - static bool IsAllZero(T* arr, uint32 size) - { - for (uint32 i = 0; i < size; ++i) - if (arr[i]) - return false; - return true; - } - static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); - static void CreateDir( const std::string& Path ); - static void SaveToDisk(FILE* stream, const std::string& path); - static Vector3 ToWoWCoords(const Vector3& vec ); - static std::string GetExtension( std::string path ); - static char* GetPlainName(const char* FileName); - static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate = true); - static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false ); - static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true ); -}; -#endif diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp deleted file mode 100644 index fd7526fa5..000000000 --- a/src/tools/mesh_extractor/WDT.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "WDT.h" -#include "Chunk.h" -#include "ChunkedData.h" -#include "Utils.h" -#include "WorldModelHandler.h" - -WDT::WDT(std::string file) : IsGlobalModel(false), IsValid(false), Model(nullptr) -{ - Data = new ChunkedData(file, 2); - ReadTileTable(); - ReadGlobalModel(); -} - -void WDT::ReadGlobalModel() -{ - Chunk* fileChunk = Data->GetChunkByName("MWMO"); - Chunk* defChunk = Data->GetChunkByName("MODF"); - if (!fileChunk || !defChunk) - return; - - IsGlobalModel = true; - ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); - ModelFile = Utils::ReadString(fileChunk->GetStream()); - Model = new WorldModelRoot(ModelFile); -} - -void WDT::ReadTileTable() -{ - Chunk* chunk = Data->GetChunkByName("MAIN"); - if (!chunk) - return; - IsValid = true; - FILE* stream = chunk->GetStream(); - for (int y = 0; y < 64; ++y) - { - for (int x = 0; x < 64; ++x) - { - const uint32 hasTileFlag = 0x1; - uint32 flags; - uint32 discard; - int count = 0; - count += fread(&flags, sizeof(uint32), 1, stream); - count += fread(&discard, sizeof(uint32), 1, stream); - - if (count != 2) - printf("WDT::ReadTileTable: Failed to read some data expected 2, read %d\n", count); - - if (flags & hasTileFlag) - TileTable.push_back(TilePos(x, y)); - } - } -} - -bool WDT::HasTile( int x, int y ) -{ - for (std::vector::iterator itr = TileTable.begin(); itr != TileTable.end(); ++itr) - if (itr->X == x && itr->Y == y) - return true; - return false; -} diff --git a/src/tools/mesh_extractor/WDT.h b/src/tools/mesh_extractor/WDT.h deleted file mode 100644 index 76bf2744b..000000000 --- a/src/tools/mesh_extractor/WDT.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef WDT_H -#define WDT_H -#include -#include - -#include "ChunkedData.h" -#include "WorldModelHandler.h" -#include "WorldModelRoot.h" -#include "Utils.h" - -class WDT -{ -public: - WDT(std::string file); - - ChunkedData* Data; - std::vector TileTable; - bool IsGlobalModel; - bool IsValid; - std::string ModelFile; - WorldModelDefinition ModelDefinition; - WorldModelRoot* Model; - bool HasTile(int x, int y); -private: - void ReadGlobalModel(); - void ReadTileTable(); -}; - -#endif diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp deleted file mode 100644 index 4b3085e68..000000000 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "WorldModelGroup.h" -#include "Chunk.h" -#include "ChunkedData.h" -#include "Utils.h" - -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), MOBA(nullptr), IsBad(false), HasLiquidData(false) -{ - Data = new ChunkedData(path); - if (!Data->Stream) - { - IsBad = true; - return; - } - Chunk* mainChunk = Data->GetChunkByName("MOGP"); - int32 firstSub = mainChunk->FindSubChunkOffset("MOPY"); - if (firstSub == -1) - return; - - Name = Utils::GetPlainName(path.c_str()); - - FILE* stream = mainChunk->GetStream(); - fseek(stream, firstSub, SEEK_SET); - SubData = new ChunkedData(stream, mainChunk->Length - firstSub); - - ReadHeader(); - ReadMaterials(); - ReadTriangles(); - ReadVertices(); - ReadNormals(); - ReadLiquid(); - ReadBatches(); -} - -void WorldModelGroup::ReadNormals() -{ - Chunk* chunk = SubData->GetChunkByName("MONR"); - if (!chunk) - return; - - uint32 normalCount = chunk->Length / 12; - ASSERT(normalCount == Vertices.size() && "normalCount is different than the Vertices count"); - Normals.reserve(normalCount); - FILE* stream = chunk->GetStream(); - for (uint32 i = 0; i < normalCount; i++) - Normals.push_back(Vector3::Read(stream)); -} - -void WorldModelGroup::ReadLiquid() -{ - Chunk* chunk = SubData->GetChunkByName("MLIQ"); - if (!chunk) - return; - - HasLiquidData = true; - FILE* stream = chunk->GetStream(); - LiquidDataHeader = LiquidHeader::Read(stream); - LiquidDataGeometry = LiquidData::Read(stream, LiquidDataHeader); -} - -void WorldModelGroup::ReadVertices() -{ - Chunk* chunk = SubData->GetChunkByName("MOVT"); - if (!chunk) - return; - - uint32 verticeCount = chunk->Length / 12; - Vertices.reserve(verticeCount); - FILE* stream = chunk->GetStream(); - for (uint32 i = 0; i < verticeCount; i++) - Vertices.push_back(Vector3::Read(stream)); -} - -void WorldModelGroup::ReadTriangles() -{ - Chunk* chunk = SubData->GetChunkByName("MOVI"); - if (!chunk) - return; - - uint32 triangleCount = chunk->Length / 6; - ASSERT(triangleCount == TriangleFlags.size() && "triangleCount != TriangleFlags.size()"); - FILE* stream = chunk->GetStream(); - Triangles.reserve(triangleCount); - for (uint32 i = 0; i < triangleCount; i++) - { - uint16 v0; - uint16 v1; - uint16 v2; - int count = 0; - count += fread(&v0, sizeof(uint16), 1, stream); - count += fread(&v1, sizeof(uint16), 1, stream); - count += fread(&v2, sizeof(uint16), 1, stream); - if (count != 3) - printf("WorldModelGroup::ReadMaterials: Error reading data, expected 3, read %d\n", count); - - Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, v0, v1, v2)); - } -} - -void WorldModelGroup::ReadMaterials() -{ - Chunk* chunk = SubData->GetChunkByName("MOPY"); - if (!chunk) - return; - - FILE* stream = chunk->GetStream(); - uint32 triangleCount = chunk->Length / 2; - TriangleFlags.reserve(triangleCount); - TriangleMaterials.reserve(triangleCount); - for (uint32 i = 0; i < triangleCount; i++) - { - uint8 tmp; - if (fread(&tmp, sizeof(uint8), 1, stream) != 1) - printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); - TriangleFlags.push_back(tmp); - // Read again for material. - if (fread(&tmp, sizeof(uint8), 1, stream) != 1) - printf("WorldModelGroup::ReadMaterials: Error reading data, expected 1, read 0\n"); - TriangleMaterials.push_back(tmp); - } -} - -void WorldModelGroup::ReadHeader() -{ - Chunk* chunk = Data->GetChunkByName("MOGP"); - if (!chunk) - return; - - FILE* stream = chunk->GetStream(); - Header = WMOGroupHeader::Read(stream); -} - -void WorldModelGroup::ReadBatches() -{ - Chunk* chunk = Data->GetChunkByName("MOBA"); - if (!chunk) - return; - - MOBALength = chunk->Length / 2; - MOBA = new uint16[MOBALength]; - uint32 count = (uint32)fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); - if (count != MOBALength) - printf("WorldModelGroup::ReadBatches: Error reading data, expected %u, read %u\n", MOBALength, count); -} diff --git a/src/tools/mesh_extractor/WorldModelGroup.h b/src/tools/mesh_extractor/WorldModelGroup.h deleted file mode 100644 index c2a68f5cf..000000000 --- a/src/tools/mesh_extractor/WorldModelGroup.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef WMOGROUP_H -#define WMOGROUP_H -#include "ChunkedData.h" -#include "Utils.h" - -class WorldModelGroup -{ -public: - WorldModelGroup(std::string path, int groupIndex); - ChunkedData* Data; - ChunkedData* SubData; - int GroupIndex; - std::string Name; - WMOGroupHeader Header; - - std::vector TriangleFlags; - std::vector TriangleMaterials; - std::vector> Triangles; - std::vector Vertices; - std::vector Normals; - // @ToDo: Research. - uint16* MOBA; - uint32 MOBALength; - - bool HasLiquidData; - bool IsBad; - LiquidHeader LiquidDataHeader; - LiquidData LiquidDataGeometry; -private: - void ReadNormals(); - void ReadLiquid(); - void ReadVertices(); - void ReadTriangles(); - void ReadMaterials(); - void ReadHeader(); - void ReadBatches(); -}; -#endif diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp deleted file mode 100644 index b1e83fa7e..000000000 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "WorldModelHandler.h" -#include "Cache.h" -#include "Chunk.h" -#include "Define.h" -#include "G3D/Matrix4.h" -#include "G3D/Quat.h" -#include "Model.h" -#include "WorldModelRoot.h" -#include - -WorldModelDefinition WorldModelDefinition::Read( FILE* file ) -{ - WorldModelDefinition ret; - int count = 0; - count += fread(&ret.MwidIndex, sizeof(uint32), 1, file); - count += fread(&ret.UniqueId, sizeof(uint32), 1, file); - ret.Position = Vector3::Read(file); - ret.Rotation = Vector3::Read(file); - ret.UpperExtents = Vector3::Read(file); - ret.LowerExtents = Vector3::Read(file); - count += fread(&ret.Flags, sizeof(uint16), 1, file); - count += fread(&ret.DoodadSet, sizeof(uint16), 1, file); - uint32 discard; - count += fread(&discard, sizeof(uint32), 1, file); - - if (count != 5) - printf("WorldModelDefinition::Read: Error reading data, expected 5, read %d\n", count); - return ret; -} - -WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(nullptr), _paths(nullptr) -{ - ReadModelPaths(); - ReadDefinitions(); -} - -void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) -{ - if (!IsSane()) - return; - - uint32 refCount = mcnk->Header.MapObjectRefs; - FILE* stream = mcnk->Source->GetStream(); - fseek(stream, mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); - // Start looping at the last Doodad Ref index - for (uint32 i = mcnk->Header.DoodadRefs; i < refCount; i++) - { - int32 index; - if (fread(&index, sizeof(int32), 1, stream) != 1) - printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); - - if (index < 0 || uint32(index) >= _definitions->size()) - continue; - - WorldModelDefinition wmo = (*_definitions)[index]; - - if (_drawn.find(wmo.UniqueId) != _drawn.end()) - continue; - _drawn.insert(wmo.UniqueId); - - if (wmo.MwidIndex >= _paths->size()) - continue; - - std::string path = (*_paths)[wmo.MwidIndex]; - WorldModelRoot* model = Cache->WorldModelCache.Get(path); - if (!model) - { - model = new WorldModelRoot(path); - Cache->WorldModelCache.Insert(path, model); - } - - Vertices.reserve(1000); - Triangles.reserve(1000); - - InsertModelGeometry(Vertices, Triangles, wmo, model); - } - // Restore the stream position - fseek(stream, mcnk->Source->Offset, SEEK_SET); -} - -void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector>& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate ) -{ - for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) - { - uint32 vertOffset = verts.size(); - for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) - { - Vector3 v = Utils::TransformDoodadVertex(def, *itr2, translate); - // If translate is false, then we were called directly from the TileBuilder to add data to it's _Geometry member, hence, we have to manually convert the vertices to Recast format. - verts.push_back(translate ? v : Utils::ToRecast(v)); // Transform the vertex to world space - } - - for (uint32 i = 0; i < group->Triangles.size(); ++i) - { - // only include colliding tris - if ((group->TriangleFlags[i] & 0x04) != 0 && group->TriangleMaterials[i] != 0xFF) - continue; - Triangle tri = group->Triangles[i]; - tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, tri.V0 + vertOffset, tri.V1 + vertOffset, tri.V2 + vertOffset)); - } - } - - if (def.DoodadSet < root->DoodadSets.size()) - { - DoodadSet set = root->DoodadSets[def.DoodadSet]; - std::vector instances; - instances.reserve(set.CountInstances); - for (uint32 i = set.FirstInstanceIndex; i < (set.CountInstances + set.FirstInstanceIndex); i++) - { - if (i >= root->DoodadInstances.size()) - break; - instances.push_back(root->DoodadInstances[i]); - } - - for (std::vector::iterator instance = instances.begin(); instance != instances.end(); ++instance) - { - Model* model = Cache->ModelCache.Get(instance->File); - if (!model) - { - model = new Model(instance->File); - Cache->ModelCache.Insert(instance->File, model); - } - - if (!model->IsCollidable) - continue; - int vertOffset = verts.size(); - for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) - { - Vector3 v = Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2, false), translate); - verts.push_back(translate ? v : Utils::ToRecast(v)); - } - for (std::vector>::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) - tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); - } - - for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) - { - if (!group->HasLiquidData) - continue; - - const LiquidHeader& liquidHeader = group->LiquidDataHeader; - LiquidData& liquidDataGeometry = group->LiquidDataGeometry; - - for (uint32 y = 0; y < liquidHeader.Height; y++) - { - for (uint32 x = 0; x < liquidHeader.Width; x++) - { - if (!liquidDataGeometry.ShouldRender(x, y)) - continue; - - uint32 vertOffset = verts.size(); - - Vector3 v1 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x][y], x, y, translate); - Vector3 v2 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x + 1][y], x + 1, y, translate); - Vector3 v3 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x][y + 1], x, y + 1, translate); - Vector3 v4 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1, translate); - - verts.push_back(translate ? v1 : Utils::ToRecast(v1)); - verts.push_back(translate ? v2 : Utils::ToRecast(v2)); - verts.push_back(translate ? v3 : Utils::ToRecast(v3)); - verts.push_back(translate ? v4 : Utils::ToRecast(v4)); - - tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); - tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); - } - } - } - } -} - -void WorldModelHandler::ReadDefinitions() -{ - Chunk* chunk = Source->ObjectData->GetChunkByName("MODF"); - if (!chunk) - return; - - const int32 definitionSize = 64; - uint32 definitionCount = chunk->Length / definitionSize; - _definitions = new std::vector; - _definitions->reserve(definitionCount); - FILE* stream = chunk->GetStream(); - for (uint32 i = 0; i < definitionCount; i++) - _definitions->push_back(WorldModelDefinition::Read(stream)); -} - -void WorldModelHandler::ReadModelPaths() -{ - Chunk* mwid = Source->ObjectData->GetChunkByName("MWID"); - Chunk* mwmo = Source->ObjectData->GetChunkByName("MWMO"); - if (!mwid || !mwmo) - return; - - uint32 paths = mwid->Length / 4; - _paths = new std::vector; - _paths->reserve(paths); - for (uint32 i = 0; i < paths; i++) - { - FILE* stream = mwid->GetStream(); - fseek(stream, i * 4, SEEK_CUR); - uint32 offset; - if (fread(&offset, sizeof(uint32), 1, stream) != 1) - printf("WorldModelDefinition::Read: Error reading data, expected 1, read 0\n"); - FILE* dataStream = mwmo->GetStream(); - fseek(dataStream, offset + mwmo->Offset, SEEK_SET); - _paths->push_back(Utils::ReadString(dataStream)); - } -} - -WorldModelHandler::~WorldModelHandler() -{ - delete _definitions; - delete _paths; -} diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h deleted file mode 100644 index 3ea382002..000000000 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef WMODEL_HNDL_H -#define WMODEL_HNDL_H -#include "Define.h" -#include "ObjectDataHandler.h" -#include "Utils.h" -#include "WorldModelRoot.h" - -#include -#include - -class ADT; - -struct WorldModelDefinition : public IDefinition -{ -public: - WorldModelDefinition() {} - - uint32 MwidIndex; - uint32 UniqueId; - Vector3 UpperExtents; - Vector3 LowerExtents; - uint16 Flags; - uint16 DoodadSet; - - static WorldModelDefinition Read(FILE* file); -}; - -class WorldModelHandler : public ObjectDataHandler -{ -public: - WorldModelHandler(ADT* adt); - ~WorldModelHandler(); - - std::vector Vertices; - std::vector> Triangles; - bool IsSane() { return _definitions && _paths; } - static void InsertModelGeometry(std::vector& verts, std::vector>& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate = true); -protected: - void ProcessInternal(MapChunk* data); -private: - void ReadDefinitions(); - void ReadModelPaths(); - std::set _drawn; - std::vector* _definitions; - std::vector* _paths; -}; -#endif diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp deleted file mode 100644 index 574cd2cad..000000000 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "WorldModelRoot.h" -#include "ChunkedData.h" -#include "Utils.h" - -WorldModelRoot::WorldModelRoot( std::string path ) -{ - Data = new ChunkedData(path); - Path = path; - ReadHeader(); - ReadGroups(); - ReadDoodadInstances(); - ReadDoodadSets(); -} - -WorldModelRoot::~WorldModelRoot() -{ - delete Data; -} - -void WorldModelRoot::ReadGroups() -{ - std::string pathBase = Utils::GetPathBase(Path); - Groups.reserve(Header.CountGroups); - for (uint32 i = 0; i < Header.CountGroups; i++) - { - char name[200]; - sprintf(name, "%s_%03u.wmo", pathBase.c_str(), i); - WorldModelGroup group(name, i); - if (!group.IsBad) - Groups.push_back(group); - } -} - -void WorldModelRoot::ReadDoodadSets() -{ - Chunk* chunk = Data->GetChunkByName("MODS"); - if (!chunk) - return; - - FILE* stream = chunk->GetStream(); - ASSERT(chunk->Length / 32 == Header.CountSets && "chunk.Length / 32 == Header.CountSets"); - DoodadSets.reserve(Header.CountSets); - for (uint32 i = 0; i < Header.CountSets; i++) - DoodadSets.push_back(DoodadSet::Read(stream)); -} - -void WorldModelRoot::ReadDoodadInstances() -{ - Chunk* chunk = Data->GetChunkByName("MODD"); - Chunk* nameChunk = Data->GetChunkByName("MODN"); - if (!chunk || !nameChunk) - return; - - const uint32 instanceSize = 40; - uint32 countInstances = chunk->Length / instanceSize; - DoodadInstances.reserve(countInstances); - for (uint32 i = 0; i < countInstances; i++) - { - FILE* stream = chunk->GetStream(); - fseek(stream, instanceSize * i, SEEK_CUR); - DoodadInstance instance = DoodadInstance::Read(stream); - FILE* nameStream = nameChunk->GetStream(); - if (instance.FileOffset >= nameChunk->Length) - continue; - fseek(nameStream, instance.FileOffset, SEEK_CUR); - instance.File = Utils::ReadString(nameStream); - DoodadInstances.push_back(instance); - } -} - -void WorldModelRoot::ReadHeader() -{ - Chunk* chunk = Data->GetChunkByName("MOHD"); - if (!chunk) - return; - - FILE* stream = chunk->GetStream(); - Header = WorldModelHeader::Read(stream); -} diff --git a/src/tools/mesh_extractor/WorldModelRoot.h b/src/tools/mesh_extractor/WorldModelRoot.h deleted file mode 100644 index c285d9c2d..000000000 --- a/src/tools/mesh_extractor/WorldModelRoot.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef WMOROOT_H -#define WMOROOT_H -#include -#include - -#include "ChunkedData.h" -#include "Utils.h" -#include "WorldModelGroup.h" - -class WorldModelRoot -{ -public: - WorldModelRoot(std::string path); - ~WorldModelRoot(); - std::string Path; - ChunkedData* Data; - WorldModelHeader Header; - std::vector DoodadInstances; - std::vector DoodadSets; - std::vector Groups; -private: - void ReadGroups(); - void ReadDoodadSets(); - void ReadDoodadInstances(); - void ReadHeader(); -}; -#endif diff --git a/src/tools/mesh_extractor/readme b/src/tools/mesh_extractor/readme deleted file mode 100644 index 85cd7cfc9..000000000 --- a/src/tools/mesh_extractor/readme +++ /dev/null @@ -1,6 +0,0 @@ -Experimental mesh extractor. -Original work in C# by stschake -Thanks to: -Subv -~ -For helping in the porting to C++ \ No newline at end of file From 8c154e6ef7776762557857ba050bdb337d993a1b Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 29 Apr 2022 11:41:16 -0300 Subject: [PATCH 09/21] chore(CI): Remove version check (#11572) --- apps/ci/ci-pending.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/apps/ci/ci-pending.sh b/apps/ci/ci-pending.sh index 9cc7d14d6..fa3f798d4 100644 --- a/apps/ci/ci-pending.sh +++ b/apps/ci/ci-pending.sh @@ -22,15 +22,6 @@ for i in `find data/sql/updates/pending* -name "*.sql" -type f`; do fi done -for i in `find data/sql/updates/pending* -name "*.sql" -type f`; do - if $(cat "$i"|sed "s/'.*'\(.*\)/\1/g"|grep -q -i -E "version_db_"); then - echo "> version_db check - OK" - else - echo "> version_db check - Failed" - exit 1 - fi -done - for i in `find data/sql/updates/pending* -name "*sql" -type f`; do if $(cat "$i"|sed "s/'.*'\(.*\)/\1/g"|grep -q -i -E "broadcast_text"); then echo "> broadcast_text check - Failed" From 26c66e0d79615cbe9597c75ae2dc44a05323c4a5 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Fri, 29 Apr 2022 20:17:03 -0300 Subject: [PATCH 10/21] chore(Scripts/Spells): Remove a few aura types being passed as spells in the validator (#11576) --- src/server/scripts/Spells/spell_generic.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index bf0847fd9..1bd16c1b7 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1725,11 +1725,6 @@ class spell_gen_remove_flight_auras : public SpellScript { PrepareSpellScript(spell_gen_remove_flight_auras); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_AURA_FLY, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED }); - } - void HandleScript(SpellEffIndex /*effIndex*/) { if (Unit* target = GetHitUnit()) From 769eea2cc0ca1975b2f26d6acd1ef1608710bd3d Mon Sep 17 00:00:00 2001 From: IntelligentQuantum Date: Sun, 1 May 2022 00:09:51 +0430 Subject: [PATCH 11/21] feat(Tools/MMapsGenerator): Improve multithreading of mmaps_generator (#10963) * cherry-pick commit (https://github.com/Shauren/TrinityCore/commit/699edaa0144fa3b0033dc45e24ad74222cc8240e) Co-authored-by: Giacomo Pozzoni --- src/cmake/compiler/clang/settings.cmake | 46 ++++++ src/cmake/showoptions.cmake | 21 +++ src/tools/mmaps_generator/MapBuilder.cpp | 155 ++++++++++++++------ src/tools/mmaps_generator/MapBuilder.h | 116 ++++++++++----- src/tools/mmaps_generator/PathGenerator.cpp | 6 +- 5 files changed, 258 insertions(+), 86 deletions(-) diff --git a/src/cmake/compiler/clang/settings.cmake b/src/cmake/compiler/clang/settings.cmake index d53c673a9..93e85762e 100644 --- a/src/cmake/compiler/clang/settings.cmake +++ b/src/cmake/compiler/clang/settings.cmake @@ -66,6 +66,52 @@ if(WITH_COREDEBUG) message(STATUS "Clang: Debug-flags set (-g3)") endif() +if(MSAN) + target_compile_options(acore-compile-option-interface + INTERFACE + -fno-omit-frame-pointer + -fsanitize=memory + -fsanitize-memory-track-origins + -mllvm + -msan-keep-going=1) + + target_link_options(acore-compile-option-interface + INTERFACE + -fno-omit-frame-pointer + -fsanitize=memory + -fsanitize-memory-track-origins) + + message(STATUS "Clang: Enabled Memory Sanitizer MSan") +endif() + +if(UBSAN) + target_compile_options(acore-compile-option-interface + INTERFACE + -fno-omit-frame-pointer + -fsanitize=undefined) + + target_link_options(acore-compile-option-interface + INTERFACE + -fno-omit-frame-pointer + -fsanitize=undefined) + + message(STATUS "Clang: Enabled Undefined Behavior Sanitizer UBSan") +endif() + +if(TSAN) + target_compile_options(acore-compile-option-interface + INTERFACE + -fno-omit-frame-pointer + -fsanitize=thread) + + target_link_options(acore-compile-option-interface + INTERFACE + -fno-omit-frame-pointer + -fsanitize=thread) + + message(STATUS "Clang: Enabled Thread Sanitizer TSan") +endif() + # -Wno-narrowing needed to suppress a warning in g3d # -Wno-deprecated-register is needed to suppress gsoap warnings on Unix systems. target_compile_options(acore-compile-option-interface diff --git a/src/cmake/showoptions.cmake b/src/cmake/showoptions.cmake index 1d2366a28..08467d8df 100644 --- a/src/cmake/showoptions.cmake +++ b/src/cmake/showoptions.cmake @@ -168,6 +168,27 @@ elseif (WITH_DETAILED_METRICS) add_definitions(-DWITH_DETAILED_METRICS) endif() +if(MSAN) + message("") + message(" *** MSAN - WARNING!") + message(" *** Please note that this is for DEBUGGING WITH MEMORY SANITIZER only!") + add_definitions(-DMSAN) +endif() + +if(UBSAN) + message("") + message(" *** UBSAN - WARNING!") + message(" *** Please note that this is for DEBUGGING WITH UNDEFINED BEHAVIOR SANITIZER only!") + add_definitions(-DUBSAN) +endif() + +if(TSAN) + message("") + message(" *** TSAN - WARNING!") + message(" *** Please note that this is for DEBUGGING WITH THREAD SANITIZER only!") + add_definitions(-DTSAN -DNO_BUFFERPOOL) +endif() + if(BUILD_SHARED_LIBS) message("") message(" *** WITH_DYNAMIC_LINKING - INFO!") diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index dcf7f05c5..2b7fdade4 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -26,15 +26,43 @@ namespace MMAP { + TileBuilder::TileBuilder(MapBuilder* mapBuilder, bool skipLiquid, bool bigBaseUnit, bool debugOutput) : + m_bigBaseUnit(bigBaseUnit), + m_debugOutput(debugOutput), + m_mapBuilder(mapBuilder), + m_terrainBuilder(nullptr), + m_workerThread(&TileBuilder::WorkerThread, this), + m_rcContext(nullptr) + { + m_terrainBuilder = new TerrainBuilder(skipLiquid); + m_rcContext = new rcContext(false); + } + + TileBuilder::~TileBuilder() + { + WaitCompletion(); + + delete m_terrainBuilder; + delete m_rcContext; + } + + void TileBuilder::WaitCompletion() + { + if (m_workerThread.joinable()) + m_workerThread.join(); + } + MapBuilder::MapBuilder(Optional maxWalkableAngle, Optional maxWalkableAngleNotSteep, bool skipLiquid, bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, - bool debugOutput, bool bigBaseUnit, int mapid, const char* offMeshFilePath) : + bool debugOutput, bool bigBaseUnit, int mapid, const char* offMeshFilePath, unsigned int threads) : m_debugOutput (debugOutput), m_offMeshFilePath (offMeshFilePath), + m_threads (threads), m_skipContinents (skipContinents), m_skipJunkMaps (skipJunkMaps), m_skipBattlegrounds (skipBattlegrounds), + m_skipLiquid (skipLiquid), m_maxWalkableAngle (maxWalkableAngle), m_maxWalkableAngleNotSteep (maxWalkableAngleNotSteep), m_bigBaseUnit (bigBaseUnit), @@ -48,6 +76,9 @@ namespace MMAP m_rcContext = new rcContext(false); + // At least 1 thread is needed + m_threads = std::max(1u, m_threads); + discoverTiles(); } @@ -170,29 +201,26 @@ namespace MMAP } /**************************************************************************/ - void MapBuilder::buildAllMaps(unsigned int threads) + void MapBuilder::buildMaps(Optional mapID) { - printf("Using %u threads to extract mmaps\n", threads); + printf("Using %u threads to generate mmaps\n", m_threads); - for (unsigned int i = 0; i < threads; ++i) + for (unsigned int i = 0; i < m_threads; ++i) { - _workerThreads.emplace_back(&MapBuilder::WorkerThread, this); + m_tileBuilders.push_back(new TileBuilder(this, m_skipLiquid, m_bigBaseUnit, m_debugOutput)); } - m_tiles.sort([](MapTiles a, MapTiles b) + if (mapID) { - return a.m_tiles->size() > b.m_tiles->size(); - }); - - for (auto & m_tile : m_tiles) + buildMap(*mapID); + } + else { - uint32 mapId = m_tile.m_mapId; - if (!shouldSkipMap(mapId)) + // Build all maps if no map id has been specified + for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) { - if (threads > 0) - _queue.Push(mapId); - else - buildMap(mapId); + if (!shouldSkipMap(it->m_mapId)) + buildMap(it->m_mapId); } } @@ -205,10 +233,10 @@ namespace MMAP _queue.Cancel(); - for (auto& thread : _workerThreads) - { - thread.join(); - } + for (auto& builder : m_tileBuilders) + delete builder; + + m_tileBuilders.clear(); } /**************************************************************************/ @@ -337,7 +365,8 @@ namespace MMAP getTileBounds(tileX, tileY, data.solidVerts.getCArray(), data.solidVerts.size() / 3, bmin, bmax); // build navmesh tile - buildMoveMapTile(mapId, tileX, tileY, data, bmin, bmax, navMesh); + TileBuilder tileBuilder = TileBuilder(this, m_skipLiquid, m_bigBaseUnit, m_debugOutput); + tileBuilder.buildMoveMapTile(mapId, tileX, tileY, data, bmin, bmax, navMesh); fclose(file); } @@ -352,22 +381,39 @@ namespace MMAP return; } - buildTile(mapID, tileX, tileY, navMesh); + // ToDo: delete the old tile as the user clearly wants to rebuild it + + TileBuilder tileBuilder = TileBuilder(this, m_skipLiquid, m_bigBaseUnit, m_debugOutput); + tileBuilder.buildTile(mapID, tileX, tileY, navMesh); dtFreeNavMesh(navMesh); + + _cancelationToken = true; + + _queue.Cancel(); } - void MapBuilder::WorkerThread() + void TileBuilder::WorkerThread() { while (true) { - uint32 mapId = 0; + TileInfo tileInfo; - _queue.WaitAndPop(mapId); + m_mapBuilder->_queue.WaitAndPop(tileInfo); - if (_cancelationToken) + if (m_mapBuilder->_cancelationToken) return; - buildMap(mapId); + dtNavMesh* navMesh = dtAllocNavMesh(); + if (!navMesh->init(&tileInfo.m_navMeshParams)) + { + printf("[Map %04i] Failed creating navmesh for tile %i,%i !\n", tileInfo.m_mapId, tileInfo.m_tileX, tileInfo.m_tileY); + dtFreeNavMesh(navMesh); + return; + } + + buildTile(tileInfo.m_mapId, tileInfo.m_tileX, tileInfo.m_tileY, navMesh); + + dtFreeNavMesh(navMesh); } } @@ -397,22 +443,28 @@ namespace MMAP // unpack tile coords StaticMapTree::unpackTileID(tile, tileX, tileY); - if (!shouldSkipTile(mapID, tileX, tileY)) - buildTile(mapID, tileX, tileY, navMesh); - - ++m_totalTilesProcessed; + TileInfo tileInfo; + tileInfo.m_mapId = mapID; + tileInfo.m_tileX = tileX; + tileInfo.m_tileY = tileY; + memcpy(&tileInfo.m_navMeshParams, navMesh->getParams(), sizeof(dtNavMeshParams)); + _queue.Push(tileInfo); } dtFreeNavMesh(navMesh); } - - printf("[Map %03i] Complete!\n", mapID); } /**************************************************************************/ - void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) + void TileBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh) { - printf("%u%% [Map %03i] Building tile [%02u,%02u]\n", percentageDone(m_totalTiles, m_totalTilesProcessed), mapID, tileX, tileY); + if(shouldSkipTile(mapID, tileX, tileY)) + { + ++m_mapBuilder->m_totalTilesProcessed; + return; + } + + printf("%u%% [Map %04i] Building tile [%02u,%02u]\n", m_mapBuilder->currentPercentageDone(), mapID, tileX, tileY); MeshData meshData; @@ -424,7 +476,10 @@ namespace MMAP // if there is no data, give up now if (!meshData.solidVerts.size() && !meshData.liquidVerts.size()) + { + ++m_mapBuilder->m_totalTilesProcessed; return; + } // remove unused vertices TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris); @@ -436,16 +491,21 @@ namespace MMAP allVerts.append(meshData.solidVerts); if (!allVerts.size()) + { + ++m_mapBuilder->m_totalTilesProcessed; return; + } // get bounds of current tile float bmin[3], bmax[3]; - getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); + m_mapBuilder->getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax); - m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath); + m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_mapBuilder->m_offMeshFilePath); // build navmesh tile buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh); + + ++m_mapBuilder->m_totalTilesProcessed; } /**************************************************************************/ @@ -524,7 +584,7 @@ namespace MMAP } /**************************************************************************/ - void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, + void TileBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, float bmin[3], float bmax[3], dtNavMesh* navMesh) { @@ -549,7 +609,7 @@ namespace MMAP const TileConfig tileConfig = TileConfig(m_bigBaseUnit); int TILES_PER_MAP = tileConfig.TILES_PER_MAP; float BASE_UNIT_DIM = tileConfig.BASE_UNIT_DIM; - rcConfig config = GetMapSpecificConfig(mapID, bmin, bmax, tileConfig); + rcConfig config = m_mapBuilder->GetMapSpecificConfig(mapID, bmin, bmax, tileConfig); // this sets the dimensions of the heightfield - should maybe happen before border padding rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); @@ -852,7 +912,7 @@ namespace MMAP } /**************************************************************************/ - void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) + void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) const { // this is for elevation if (verts && vertCount) @@ -871,7 +931,7 @@ namespace MMAP } /**************************************************************************/ - bool MapBuilder::shouldSkipMap(uint32 mapID) + bool MapBuilder::shouldSkipMap(uint32 mapID) const { if (m_mapid >= 0) return static_cast(m_mapid) != mapID; @@ -927,7 +987,7 @@ namespace MMAP } /**************************************************************************/ - bool MapBuilder::isTransportMap(uint32 mapID) + bool MapBuilder::isTransportMap(uint32 mapID) const { switch (mapID) { @@ -967,7 +1027,7 @@ namespace MMAP } /**************************************************************************/ - bool MapBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) + bool TileBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) const { char fileName[255]; sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); @@ -990,7 +1050,7 @@ namespace MMAP return true; } - rcConfig MapBuilder::GetMapSpecificConfig(uint32 mapID, float bmin[3], float bmax[3], const TileConfig &tileConfig) + rcConfig MapBuilder::GetMapSpecificConfig(uint32 mapID, float bmin[3], float bmax[3], const TileConfig &tileConfig) const { rcConfig config; memset(&config, 0, sizeof(rcConfig)); @@ -1039,11 +1099,16 @@ namespace MMAP } /**************************************************************************/ - uint32 MapBuilder::percentageDone(uint32 totalTiles, uint32 totalTilesBuilt) + uint32 MapBuilder::percentageDone(uint32 totalTiles, uint32 totalTilesBuilt) const { if (totalTiles) return totalTilesBuilt * 100 / totalTiles; return 0; } + + uint32 MapBuilder::currentPercentageDone() const + { + return percentageDone(m_totalTiles, m_totalTilesProcessed); + } } diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 239553891..e36e1117f 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -94,43 +94,33 @@ namespace MMAP int TILES_PER_MAP; }; - class MapBuilder + struct TileInfo + { + TileInfo() : m_mapId(uint32(-1)), m_tileX(), m_tileY(), m_navMeshParams() {} + + uint32 m_mapId; + uint32 m_tileX; + uint32 m_tileY; + dtNavMeshParams m_navMeshParams; + }; + + // ToDo: move this to its own file. For now it will stay here to keep the changes to a minimum, especially in the cpp file + class MapBuilder; + class TileBuilder { public: - MapBuilder(Optional maxWalkableAngle, - Optional maxWalkableAngleNotSteep, - bool skipLiquid = false, - bool skipContinents = false, - bool skipJunkMaps = true, - bool skipBattlegrounds = false, - bool debugOutput = false, - bool bigBaseUnit = false, - int mapid = -1, - const char* offMeshFilePath = nullptr); + TileBuilder(MapBuilder* mapBuilder, + bool skipLiquid, + bool bigBaseUnit, + bool debugOutput); - ~MapBuilder(); - - // builds all mmap tiles for the specified map id (ignores skip settings) - void buildMap(uint32 mapID); - void buildMeshFromFile(char* name); - - // builds an mmap tile for the specified map and its mesh - void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); - - // builds list of maps, then builds all of mmap tiles (based on the skip settings) - void buildAllMaps(unsigned int threads); + TileBuilder(TileBuilder&&) = default; + ~TileBuilder(); void WorkerThread(); - - private: - // detect maps and tiles - void discoverTiles(); - std::set* getTileList(uint32 mapID); - - void buildNavMesh(uint32 mapID, dtNavMesh*& navMesh); + void WaitCompletion(); void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh); - // move map building void buildMoveMapTile(uint32 mapID, uint32 tileX, @@ -140,18 +130,66 @@ namespace MMAP float bmax[3], dtNavMesh* navMesh); + bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) const; + + private: + bool m_bigBaseUnit; + bool m_debugOutput; + + MapBuilder* m_mapBuilder; + TerrainBuilder* m_terrainBuilder; + std::thread m_workerThread; + // build performance - not really used for now + rcContext* m_rcContext; + }; + + class MapBuilder + { + friend class TileBuilder; + public: + MapBuilder(Optional maxWalkableAngle, + Optional maxWalkableAngleNotSteep, + bool skipLiquid, + bool skipContinents, + bool skipJunkMaps, + bool skipBattlegrounds, + bool debugOutput, + bool bigBaseUnit, + int mapid, + char const* offMeshFilePath, + unsigned int threads); + + ~MapBuilder(); + + void buildMeshFromFile(char* name); + + // builds an mmap tile for the specified map and its mesh + void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY); + + // builds list of maps, then builds all of mmap tiles (based on the skip settings) + void buildMaps(Optional mapID); + + private: + // builds all mmap tiles for the specified map id (ignores skip settings) + void buildMap(uint32 mapID); + // detect maps and tiles + void discoverTiles(); + std::set* getTileList(uint32 mapID); + + void buildNavMesh(uint32 mapID, dtNavMesh*& navMesh); + void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, - float* bmin, float* bmax); + float* bmin, float* bmax) const; void getGridBounds(uint32 mapID, uint32& minX, uint32& minY, uint32& maxX, uint32& maxY) const; - bool shouldSkipMap(uint32 mapID); - bool isTransportMap(uint32 mapID); - bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY); + bool shouldSkipMap(uint32 mapID) const; + bool isTransportMap(uint32 mapID) const; - rcConfig GetMapSpecificConfig(uint32 mapID, float bmin[3], float bmax[3], const TileConfig &tileConfig); + rcConfig GetMapSpecificConfig(uint32 mapID, float bmin[3], float bmax[3], const TileConfig &tileConfig) const; - uint32 percentageDone(uint32 totalTiles, uint32 totalTilesDone); + uint32 percentageDone(uint32 totalTiles, uint32 totalTilesDone) const; + uint32 currentPercentageDone() const; TerrainBuilder* m_terrainBuilder{nullptr}; TileList m_tiles; @@ -159,9 +197,11 @@ namespace MMAP bool m_debugOutput; const char* m_offMeshFilePath; + unsigned int m_threads; bool m_skipContinents; bool m_skipJunkMaps; bool m_skipBattlegrounds; + bool m_skipLiquid; Optional m_maxWalkableAngle; Optional m_maxWalkableAngleNotSteep; @@ -174,8 +214,8 @@ namespace MMAP // build performance - not really used for now rcContext* m_rcContext{nullptr}; - std::vector _workerThreads; - ProducerConsumerQueue _queue; + std::vector m_tileBuilders; + ProducerConsumerQueue _queue; std::atomic _cancelationToken; }; } diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 18e070ae4..469ff7984 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -328,7 +328,7 @@ int main(int argc, char** argv) } MapBuilder builder(maxAngle, maxAngleNotSteep, skipLiquid, skipContinents, skipJunkMaps, - skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath); + skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath, threads); uint32 start = getMSTime(); if (file) @@ -336,9 +336,9 @@ int main(int argc, char** argv) else if (tileX > -1 && tileY > -1 && mapnum >= 0) builder.buildSingleTile(mapnum, tileX, tileY); else if (mapnum >= 0) - builder.buildMap(uint32(mapnum)); + builder.buildMaps(uint32(mapnum)); else - builder.buildAllMaps(threads); + builder.buildMaps({}); if (!silent) printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start)); From bbd760cc1aa6be9c3675aeecdf875672959e4ce5 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sat, 30 Apr 2022 21:41:25 +0200 Subject: [PATCH 12/21] fix(Scripts/IcecrownCitadel): Increases radius of Sindragosa's boundary. (#11579) Fixes #11439 --- .../Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp | 2 +- src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp | 2 +- .../Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp | 2 +- .../scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp | 2 +- .../Northrend/IcecrownCitadel/boss_professor_putricide.cpp | 2 +- src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp | 2 +- .../scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp | 2 +- .../Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp | 2 +- .../HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 5cc183afa..c1582d602 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -311,7 +311,7 @@ public: void UpdateAI(uint32 diff) override { - if (!UpdateVictim() || !CheckInRoom()) + if (!UpdateVictim()) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp index a32e4c5cd..97043531c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp @@ -189,7 +189,7 @@ public: void UpdateAI(uint32 diff) override { - if (!UpdateVictim() || !CheckInRoom()) + if (!UpdateVictim()) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index 31da093cb..7e553e084 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -330,7 +330,7 @@ public: void UpdateAI(uint32 diff) override { - if ((!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) || !CheckInRoom()) + if (!UpdateVictim() && !(events.GetPhaseMask() & PHASE_INTRO_MASK)) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 0fb505436..99ce3c3b6 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -156,7 +156,7 @@ public: void UpdateAI(uint32 diff) override { - if (!UpdateVictim() || !CheckInRoom()) + if (!UpdateVictim()) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 1717ddfd4..cec4d51e8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -524,7 +524,7 @@ public: return; } - if (!UpdateVictim() || !CheckInRoom()) + if (!UpdateVictim()) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index ce1da8377..ddf8897f5 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -258,7 +258,7 @@ public: void UpdateAI(uint32 diff) override { - if (!UpdateVictim() || !CheckInRoom()) + if (!UpdateVictim()) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index dec87549a..2dc2feb74 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -523,7 +523,7 @@ public: void UpdateAI(uint32 diff) override { - if (!UpdateVictim() || !CheckInRoom()) + if (!UpdateVictim()) return; events.Update(diff); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 3fe022a43..829e12173 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -80,7 +80,7 @@ BossBoundaryData const boundaries = { DATA_SISTER_SVALNA, new RectangleBoundary(4291.0f, 4423.0f, 2438.0f, 2653.0f) }, { DATA_VALITHRIA_DREAMWALKER, new RectangleBoundary(4112.5f, 4293.5f, 2385.0f, 2585.0f) }, - { DATA_SINDRAGOSA, new EllipseBoundary(Position(4408.6f, 2484.0f), 100.0, 75.0) } + { DATA_SINDRAGOSA, new EllipseBoundary(Position(4418.6f, 2484.0f), 110.0, 75.0) } }; DoorData const doorData[] = diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp index 4bcd9fe08..bf5660081 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp @@ -164,7 +164,7 @@ public: break; } - if (!UpdateVictim() || !CheckInRoom()) + if (!UpdateVictim()) return; events.Update(diff); From 94123e60f66a6d9ff5040489f6bb1c9359c2e026 Mon Sep 17 00:00:00 2001 From: Patrick Lewis Date: Sat, 30 Apr 2022 22:00:40 -0700 Subject: [PATCH 13/21] chore(CI): add macos-12 (#11242) * chore(CI): add macos-12 * Update SECURITY.md * test changing googletest git_tag to main * update utf8cpp * Update DBCStorageIterator.h Co-Authored-By: Shauren Co-authored-by: Shauren --- .github/SECURITY.md | 1 + .github/workflows/macos_build.yml | 1 + deps/utf8cpp/utf8/checked.h | 64 ++++++----- deps/utf8cpp/utf8/core.h | 43 +++++--- deps/utf8cpp/utf8/cpp11.h | 103 ++++++++++++++++++ deps/utf8cpp/utf8/cpp17.h | 103 ++++++++++++++++++ deps/utf8cpp/utf8/unchecked.h | 78 ++++++++++--- src/cmake/googletest-download.cmake | 2 +- .../shared/DataStores/DBCStorageIterator.h | 8 +- 9 files changed, 340 insertions(+), 63 deletions(-) create mode 100644 deps/utf8cpp/utf8/cpp11.h create mode 100644 deps/utf8cpp/utf8/cpp17.h diff --git a/.github/SECURITY.md b/.github/SECURITY.md index e5f0bf054..b55b3cc60 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -61,6 +61,7 @@ Versions of macOS: | macOS Version | Supported | | ------------- | ------------------ | +| 12 | :white_check_mark: | | 11 | :white_check_mark: | | 10.15 | :white_check_mark: | diff --git a/.github/workflows/macos_build.yml b/.github/workflows/macos_build.yml index a8db0bc82..92ebfbf6a 100644 --- a/.github/workflows/macos_build.yml +++ b/.github/workflows/macos_build.yml @@ -18,6 +18,7 @@ jobs: os: - macos-10.15 - macos-11 + - macos-12 runs-on: ${{ matrix.os }} name: ${{ matrix.os }} if: github.repository == 'azerothcore/azerothcore-wotlk' && (github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'run-build') || github.event.label.name == 'run-build') diff --git a/deps/utf8cpp/utf8/checked.h b/deps/utf8cpp/utf8/checked.h index 133115513..993b7f7c5 100644 --- a/deps/utf8cpp/utf8/checked.h +++ b/deps/utf8cpp/utf8/checked.h @@ -1,4 +1,4 @@ -// Copyright 2006 Nemanja Trifunovic +// Copyright 2006-2016 Nemanja Trifunovic /* Permission is hereby granted, free of charge, to any person or organization @@ -41,8 +41,8 @@ namespace utf8 class invalid_code_point : public exception { uint32_t cp; public: - invalid_code_point(uint32_t cp) : cp(cp) {} - virtual const char* what() const throw() { return "Invalid code point"; } + invalid_code_point(uint32_t codepoint) : cp(codepoint) {} + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid code point"; } uint32_t code_point() const {return cp;} }; @@ -50,7 +50,7 @@ namespace utf8 uint8_t u8; public: invalid_utf8 (uint8_t u) : u8(u) {} - virtual const char* what() const throw() { return "Invalid UTF-8"; } + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-8"; } uint8_t utf8_octet() const {return u8;} }; @@ -58,13 +58,13 @@ namespace utf8 uint16_t u16; public: invalid_utf16 (uint16_t u) : u16(u) {} - virtual const char* what() const throw() { return "Invalid UTF-16"; } + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-16"; } uint16_t utf16_word() const {return u16;} }; class not_enough_room : public exception { public: - virtual const char* what() const throw() { return "Not enough space"; } + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Not enough space"; } }; /// The library API - functions intended to be called by the users @@ -107,7 +107,9 @@ namespace utf8 *out++ = *it; break; case internal::NOT_ENOUGH_ROOM: - throw not_enough_room(); + out = utf8::append (replacement, out); + start = end; + break; case internal::INVALID_LEAD: out = utf8::append (replacement, out); ++start; @@ -174,23 +176,19 @@ namespace utf8 return utf8::peek_next(it, end); } - /// Deprecated in versions that include "prior" - template - uint32_t previous(octet_iterator& it, octet_iterator pass_start) - { - octet_iterator end = it; - while (utf8::internal::is_trail(*(--it))) - if (it == pass_start) - throw invalid_utf8(*it); // error - no lead byte in the sequence - octet_iterator temp = it; - return utf8::next(temp, end); - } - template void advance (octet_iterator& it, distance_type n, octet_iterator end) { - for (distance_type i = 0; i < n; ++i) - utf8::next(it, end); + const distance_type zero(0); + if (n < zero) { + // backward + for (distance_type i = n; i < zero; ++i) + utf8::prior(it, end); + } else { + // forward + for (distance_type i = zero; i < n; ++i) + utf8::next(it, end); + } } template @@ -233,7 +231,7 @@ namespace utf8 template u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) { - while (start != end) { + while (start < end) { uint32_t cp = utf8::next(start, end); if (cp > 0xffff) { //make a surrogate pair *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); @@ -257,7 +255,7 @@ namespace utf8 template u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) { - while (start != end) + while (start < end) (*result++) = utf8::next(start, end); return result; @@ -265,16 +263,21 @@ namespace utf8 // The iterator class template - class iterator : public std::iterator { + class iterator { octet_iterator it; octet_iterator range_start; octet_iterator range_end; public: + typedef uint32_t value_type; + typedef uint32_t* pointer; + typedef uint32_t& reference; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; iterator () {} explicit iterator (const octet_iterator& octet_it, - const octet_iterator& range_start, - const octet_iterator& range_end) : - it(octet_it), range_start(range_start), range_end(range_end) + const octet_iterator& rangestart, + const octet_iterator& rangeend) : + it(octet_it), range_start(rangestart), range_end(rangeend) { if (it < range_start || it > range_end) throw std::out_of_range("Invalid utf-8 iterator position"); @@ -322,6 +325,11 @@ namespace utf8 } // namespace utf8 +#if UTF_CPP_CPLUSPLUS >= 201703L // C++ 17 or later +#include "cpp17.h" +#elif UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later +#include "cpp11.h" +#endif // C++ 11 or later + #endif //header guard - diff --git a/deps/utf8cpp/utf8/core.h b/deps/utf8cpp/utf8/core.h index 693d388c0..de6199f2a 100644 --- a/deps/utf8cpp/utf8/core.h +++ b/deps/utf8cpp/utf8/core.h @@ -30,6 +30,23 @@ DEALINGS IN THE SOFTWARE. #include +// Determine the C++ standard version. +// If the user defines UTF_CPP_CPLUSPLUS, use that. +// Otherwise, trust the unreliable predefined macro __cplusplus + +#if !defined UTF_CPP_CPLUSPLUS + #define UTF_CPP_CPLUSPLUS __cplusplus +#endif + +#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later + #define UTF_CPP_OVERRIDE override + #define UTF_CPP_NOEXCEPT noexcept +#else // C++ 98/03 + #define UTF_CPP_OVERRIDE + #define UTF_CPP_NOEXCEPT throw() +#endif // C++ 11 or later + + namespace utf8 { // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers @@ -49,8 +66,8 @@ namespace internal const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; - const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); - const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; + const uint16_t LEAD_OFFSET = 0xd7c0u; // LEAD_SURROGATE_MIN - (0x10000 >> 10) + const uint32_t SURROGATE_OFFSET = 0xfca02400u; // 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN // Maximum valid value for a Unicode code point const uint32_t CODE_POINT_MAX = 0x0010ffffu; @@ -142,7 +159,7 @@ namespace internal if (!utf8::internal::is_trail(*it)) return INCOMPLETE_SEQUENCE; - + return UTF8_OK; } @@ -165,7 +182,7 @@ namespace internal { if (it == end) return NOT_ENOUGH_ROOM; - + code_point = utf8::internal::mask8(*it); UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) @@ -222,6 +239,9 @@ namespace internal template utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point) { + if (it == end) + return NOT_ENOUGH_ROOM; + // Save the original value of it so we can go back in case of failure // Of course, it does not make much sense with i.e. stream iterators octet_iterator original_it = it; @@ -234,7 +254,7 @@ namespace internal // Get trail octets and calculate the code point utf_error err = UTF8_OK; switch (length) { - case 0: + case 0: return INVALID_LEAD; case 1: err = utf8::internal::get_sequence_1(it, end, cp); @@ -310,18 +330,7 @@ namespace internal ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) ); - } - - //Deprecated in release 2.3 - template - inline bool is_bom (octet_iterator it) - { - return ( - (utf8::internal::mask8(*it++)) == bom[0] && - (utf8::internal::mask8(*it++)) == bom[1] && - (utf8::internal::mask8(*it)) == bom[2] - ); - } + } } // namespace utf8 #endif // header guard diff --git a/deps/utf8cpp/utf8/cpp11.h b/deps/utf8cpp/utf8/cpp11.h new file mode 100644 index 000000000..d93961b04 --- /dev/null +++ b/deps/utf8cpp/utf8/cpp11.h @@ -0,0 +1,103 @@ +// Copyright 2018 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 +#define UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 + +#include "checked.h" +#include + +namespace utf8 +{ + + inline void append(char32_t cp, std::string& s) + { + append(uint32_t(cp), std::back_inserter(s)); + } + + inline std::string utf16to8(const std::u16string& s) + { + std::string result; + utf16to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u16string utf8to16(const std::string& s) + { + std::u16string result; + utf8to16(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::string utf32to8(const std::u32string& s) + { + std::string result; + utf32to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u32string utf8to32(const std::string& s) + { + std::u32string result; + utf8to32(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::size_t find_invalid(const std::string& s) + { + std::string::const_iterator invalid = find_invalid(s.begin(), s.end()); + return (invalid == s.end()) ? std::string::npos : (invalid - s.begin()); + } + + inline bool is_valid(const std::string& s) + { + return is_valid(s.begin(), s.end()); + } + + inline std::string replace_invalid(const std::string& s, char32_t replacement) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); + return result; + } + + inline std::string replace_invalid(const std::string& s) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline bool starts_with_bom(const std::string& s) + { + return starts_with_bom(s.begin(), s.end()); + } + +} // namespace utf8 + +#endif // header guard + diff --git a/deps/utf8cpp/utf8/cpp17.h b/deps/utf8cpp/utf8/cpp17.h new file mode 100644 index 000000000..7bfa86994 --- /dev/null +++ b/deps/utf8cpp/utf8/cpp17.h @@ -0,0 +1,103 @@ +// Copyright 2018 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9 +#define UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9 + +#include "checked.h" +#include + +namespace utf8 +{ + + inline void append(char32_t cp, std::string& s) + { + append(uint32_t(cp), std::back_inserter(s)); + } + + inline std::string utf16to8(std::u16string_view s) + { + std::string result; + utf16to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u16string utf8to16(std::string_view s) + { + std::u16string result; + utf8to16(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::string utf32to8(std::u32string_view s) + { + std::string result; + utf32to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u32string utf8to32(std::string_view s) + { + std::u32string result; + utf8to32(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::size_t find_invalid(std::string_view s) + { + std::string_view::const_iterator invalid = find_invalid(s.begin(), s.end()); + return (invalid == s.end()) ? std::string_view::npos : (invalid - s.begin()); + } + + inline bool is_valid(std::string_view s) + { + return is_valid(s.begin(), s.end()); + } + + inline std::string replace_invalid(std::string_view s, char32_t replacement) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); + return result; + } + + inline std::string replace_invalid(std::string_view s) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline bool starts_with_bom(std::string_view s) + { + return starts_with_bom(s.begin(), s.end()); + } + +} // namespace utf8 + +#endif // header guard + diff --git a/deps/utf8cpp/utf8/unchecked.h b/deps/utf8cpp/utf8/unchecked.h index cb2427166..0e1b51cc7 100644 --- a/deps/utf8cpp/utf8/unchecked.h +++ b/deps/utf8cpp/utf8/unchecked.h @@ -32,13 +32,13 @@ DEALINGS IN THE SOFTWARE. namespace utf8 { - namespace unchecked + namespace unchecked { template octet_iterator append(uint32_t cp, octet_iterator result) { if (cp < 0x80) // one octet - *(result++) = static_cast(cp); + *(result++) = static_cast(cp); else if (cp < 0x800) { // two octets *(result++) = static_cast((cp >> 6) | 0xc0); *(result++) = static_cast((cp & 0x3f) | 0x80); @@ -57,6 +57,46 @@ namespace utf8 return result; } + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = utf8::internal::validate_next(start, end); + switch (err_code) { + case internal::UTF8_OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + out = utf8::unchecked::append (replacement, out); + start = end; + break; + case internal::INVALID_LEAD: + out = utf8::unchecked::append (replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + out = utf8::unchecked::append (replacement, out); + ++start; + // just one replacement mark for the sequence + while (start != end && utf8::internal::is_trail(*start)) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); + return utf8::unchecked::replace_invalid(start, end, out, replacement_marker); + } + template uint32_t next(octet_iterator& it) { @@ -85,13 +125,13 @@ namespace utf8 break; } ++it; - return cp; + return cp; } template uint32_t peek_next(octet_iterator it) { - return utf8::unchecked::next(it); + return utf8::unchecked::next(it); } template @@ -102,18 +142,19 @@ namespace utf8 return utf8::unchecked::next(temp); } - // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) - template - inline uint32_t previous(octet_iterator& it) - { - return utf8::unchecked::prior(it); - } - template void advance (octet_iterator& it, distance_type n) { - for (distance_type i = 0; i < n; ++i) - utf8::unchecked::next(it); + const distance_type zero(0); + if (n < zero) { + // backward + for (distance_type i = n; i < zero; ++i) + utf8::unchecked::prior(it); + } else { + // forward + for (distance_type i = zero; i < n; ++i) + utf8::unchecked::next(it); + } } template @@ -128,7 +169,7 @@ namespace utf8 template octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) - { + { while (start != end) { uint32_t cp = utf8::internal::mask16(*start++); // Take care of surrogate pairs first @@ -138,7 +179,7 @@ namespace utf8 } result = utf8::unchecked::append(cp, result); } - return result; + return result; } template @@ -176,9 +217,14 @@ namespace utf8 // The iterator class template - class iterator : public std::iterator { + class iterator { octet_iterator it; public: + typedef uint32_t value_type; + typedef uint32_t* pointer; + typedef uint32_t& reference; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; iterator () {} explicit iterator (const octet_iterator& octet_it): it(octet_it) {} // the default "big three" are OK diff --git a/src/cmake/googletest-download.cmake b/src/cmake/googletest-download.cmake index 299335d3c..1cc4361e5 100644 --- a/src/cmake/googletest-download.cmake +++ b/src/cmake/googletest-download.cmake @@ -24,7 +24,7 @@ ExternalProject_Add( GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG - release-1.10.0 + main CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/src/server/shared/DataStores/DBCStorageIterator.h b/src/server/shared/DataStores/DBCStorageIterator.h index f940cb0ad..a546cc8c8 100644 --- a/src/server/shared/DataStores/DBCStorageIterator.h +++ b/src/server/shared/DataStores/DBCStorageIterator.h @@ -22,9 +22,15 @@ #include template -class DBCStorageIterator : public std::iterator +class DBCStorageIterator { public: + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using difference_type = std::ptrdiff_t; + using pointer = T*; + using reference = T&; + DBCStorageIterator() : _index(nullptr) { } DBCStorageIterator(T** index, uint32 size, uint32 pos = 0) : _index(index), _pos(pos), _end(size) { From 43db8a6d1338fae91a121740591e083dcaef483e Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sun, 1 May 2022 07:01:10 +0200 Subject: [PATCH 14/21] fix(Core/Movement): Improved pet's follow movement. (#11585) Fixes #9254 --- .../MovementGenerators/TargetedMovementGenerator.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 6720f3049..128a3b25f 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -453,11 +453,10 @@ bool FollowMovementGenerator::DoUpdate(T* owner, uint32 time_diff) else i_path->Clear(); - float distance = _range - target->GetCombatReach(); + target->MovePositionToFirstCollision(targetPosition, owner->GetCombatReach() + _range, target->ToAbsoluteAngle(_angle.RelativeAngle) - target->GetOrientation()); - float relAngle = _angle.RelativeAngle; float x, y, z; - target->GetNearPoint(owner, x, y, z, owner->GetCombatReach(), distance, target->ToAbsoluteAngle(relAngle), 0.f, &targetPosition); + targetPosition.GetPosition(x, y, z); if (owner->IsHovering()) owner->UpdateAllowedPositionZ(x, y, z); From 116deced921c03d785207e5de114f4e22f06f917 Mon Sep 17 00:00:00 2001 From: temperrr Date: Sun, 1 May 2022 08:44:19 +0200 Subject: [PATCH 15/21] Fix(DB/SAI): Prince Thunderaan corpse should despawn after 1 hour. (#11575) --- .../sql/updates/pending_db_world/rev_1651251117611496925.sql | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1651251117611496925.sql diff --git a/data/sql/updates/pending_db_world/rev_1651251117611496925.sql b/data/sql/updates/pending_db_world/rev_1651251117611496925.sql new file mode 100644 index 000000000..9b409c864 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1651251117611496925.sql @@ -0,0 +1,5 @@ +UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 14347; + +DELETE FROM `smart_scripts` WHERE (`entryorguid` = 14347) AND (`source_type` = 0) AND (`id` IN (2)); +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(14347, 0, 2, 0, 20, 0, 100, 0, 7786, 0, 0, 0, 0, 12, 14435, 6, 3600000, 0, 0, 0, 8, 0, 0, 0, 0, -6241.77, 1717.14, 4.25042, 0.680879, 'Highlord Demitrian - On Quest Thunderaan the Windseeker Finished - Summon Creature Prince Thunderaan at XYZO'); From 1a6ed13dac497aedc7d4972b83022854f2a4b616 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Sun, 1 May 2022 06:46:26 +0000 Subject: [PATCH 16/21] chore(DB): import pending files Referenced commit(s): 116deced921c03d785207e5de114f4e22f06f917 --- .../rev_1651251117611496925.sql => db_world/2022_05_01_00.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1651251117611496925.sql => db_world/2022_05_01_00.sql} (95%) diff --git a/data/sql/updates/pending_db_world/rev_1651251117611496925.sql b/data/sql/updates/db_world/2022_05_01_00.sql similarity index 95% rename from data/sql/updates/pending_db_world/rev_1651251117611496925.sql rename to data/sql/updates/db_world/2022_05_01_00.sql index 9b409c864..e32686f4e 100644 --- a/data/sql/updates/pending_db_world/rev_1651251117611496925.sql +++ b/data/sql/updates/db_world/2022_05_01_00.sql @@ -1,3 +1,4 @@ +-- DB update 2022_04_28_00 -> 2022_05_01_00 UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 14347; DELETE FROM `smart_scripts` WHERE (`entryorguid` = 14347) AND (`source_type` = 0) AND (`id` IN (2)); From 8900cab6574cc36472e10d00264b581f367e5639 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sun, 1 May 2022 10:28:20 +0200 Subject: [PATCH 17/21] fix(Core/Minions): Crashfix. (#11592) --- src/server/game/Entities/Creature/TemporarySummon.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index 754a5cdd9..1f2997681 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -334,11 +334,12 @@ void Minion::InitStats(uint32 duration) SetReactState(REACT_PASSIVE); - Unit* owner = GetOwner(); - SetCreatorGUID(owner->GetGUID()); - SetFaction(owner->GetFaction()); - - owner->SetMinion(this, true); + if (Unit* owner = GetOwner()) + { + SetCreatorGUID(owner->GetGUID()); + SetFaction(owner->GetFaction()); + owner->SetMinion(this, true); + } } void Minion::RemoveFromWorld() From cc6528ad7bce71d3631095afe222d7fe47dd2995 Mon Sep 17 00:00:00 2001 From: acidmanifesto Date: Sun, 1 May 2022 08:44:03 -0400 Subject: [PATCH 18/21] Fix (core) water level and ground level correction (#11552) We do not need to excessively have ground level be -2 below the player when underwater. ground level is ground level. no need for a lower adjustment. Most likely left over from from when the shallow water calculations was wrong entirely that lead to false hits with water walking detection due to core side calculations. --- src/server/game/Maps/Map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 733714004..ecf9227f1 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1952,7 +1952,7 @@ inline LiquidData const GridMap::GetLiquidData(float x, float y, float z, float float ground_level = getHeight(x, y); // Check water level and ground level - if (liquid_level >= ground_level && z >= ground_level - 2) + if (liquid_level >= ground_level && z >= ground_level) { // All ok in water -> store data liquidData.Entry = entry; From 5c53af251a2431e61cbb87f8d85e279c4888b804 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Sun, 1 May 2022 17:44:22 +0200 Subject: [PATCH 19/21] fix(DB/Creatures): Added `CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING` flag to Muck Frenzy. (#11589) Fixes #6317 --- data/sql/updates/pending_db_world/rev_1651348454142593100.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1651348454142593100.sql diff --git a/data/sql/updates/pending_db_world/rev_1651348454142593100.sql b/data/sql/updates/pending_db_world/rev_1651348454142593100.sql new file mode 100644 index 000000000..7ea0b5294 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1651348454142593100.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `flags_extra`=`flags_extra`|0x20000000 WHERE `entry`=8236; From 3a35380c1e79538d6aa809b1d05e0e12279a7909 Mon Sep 17 00:00:00 2001 From: AzerothCoreBot Date: Sun, 1 May 2022 15:46:18 +0000 Subject: [PATCH 20/21] chore(DB): import pending files Referenced commit(s): 5c53af251a2431e61cbb87f8d85e279c4888b804 --- .../rev_1651348454142593100.sql => db_world/2022_05_01_01.sql} | 1 + 1 file changed, 1 insertion(+) rename data/sql/updates/{pending_db_world/rev_1651348454142593100.sql => db_world/2022_05_01_01.sql} (67%) diff --git a/data/sql/updates/pending_db_world/rev_1651348454142593100.sql b/data/sql/updates/db_world/2022_05_01_01.sql similarity index 67% rename from data/sql/updates/pending_db_world/rev_1651348454142593100.sql rename to data/sql/updates/db_world/2022_05_01_01.sql index 7ea0b5294..c2584bd99 100644 --- a/data/sql/updates/pending_db_world/rev_1651348454142593100.sql +++ b/data/sql/updates/db_world/2022_05_01_01.sql @@ -1,2 +1,3 @@ +-- DB update 2022_05_01_00 -> 2022_05_01_01 -- UPDATE `creature_template` SET `flags_extra`=`flags_extra`|0x20000000 WHERE `entry`=8236; From 0ffa270c948841f566d03c89033202c7abbaed75 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 2 May 2022 07:55:55 -0300 Subject: [PATCH 21/21] fix(Scripts/TempleOfAhnQiraj): Correct Battleguard Sartura spell ids (#11597) --- .../scripts/Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp index be3cc13fb..f851d2b5c 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_sartura.cpp @@ -33,8 +33,8 @@ enum Sartura SAY_DEATH = 2, SPELL_WHIRLWIND = 26083, - SPELL_ENRAGE = 28747, //Not sure if right ID. - SPELL_ENRAGEHARD = 28798, + SPELL_ENRAGE = 8269, + SPELL_BERSERK = 27680, //Guard Spell SPELL_WHIRLWINDADD = 26038, @@ -166,7 +166,7 @@ public: { if (!HealthAbovePct(20) && !me->IsNonMeleeSpellCast(false)) { - DoCast(me, SPELL_ENRAGE); + DoCast(me, SPELL_ENRAGE, true); Enraged = true; } } @@ -176,7 +176,7 @@ public: { if (EnrageHard_Timer <= diff) { - DoCast(me, SPELL_ENRAGEHARD); + DoCast(me, SPELL_BERSERK, true); EnragedHard = true; } else EnrageHard_Timer -= diff;