initial trading post it have mem leak and dragonriding base
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
-- Perks Program - Purchases
|
||||
DROP TABLE IF EXISTS `character_perks_purchases`;
|
||||
CREATE TABLE `character_perks_purchases` (
|
||||
`guid` INT UNSIGNED NOT NULL,
|
||||
`vendor_item_id` INT UNSIGNED NOT NULL,
|
||||
`purchase_time` INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`guid`, `vendor_item_id`),
|
||||
INDEX `idx_guid` (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Perks Program - Frozen Items
|
||||
DROP TABLE IF EXISTS `account_perks_frozen_items`;
|
||||
CREATE TABLE `account_perks_frozen_items` (
|
||||
`account_id` INT UNSIGNED NOT NULL,
|
||||
`vendor_item_id` INT UNSIGNED NOT NULL,
|
||||
`frozen_time` INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`account_id`, `vendor_item_id`),
|
||||
INDEX `idx_account_id` (`account_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Perks Program - Tracked Activities
|
||||
DROP TABLE IF EXISTS `character_perks_tracked_activities`;
|
||||
CREATE TABLE `character_perks_tracked_activities` (
|
||||
`guid` INT UNSIGNED NOT NULL,
|
||||
`activity_id` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`guid`, `activity_id`),
|
||||
INDEX `idx_guid` (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- Perks Program - Activity
|
||||
DROP TABLE IF EXISTS `perk_program_activity`;
|
||||
CREATE TABLE `perk_program_activity` (
|
||||
`ActivityID` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`ActivityID`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
DROP TABLE IF EXISTS `perks_vendor_item`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `perks_vendor_item` (
|
||||
`ID` int unsigned NOT NULL DEFAULT '0',
|
||||
`PerksVendorCategoryID` int NOT NULL DEFAULT '0',
|
||||
`Unknown010001` int unsigned NOT NULL DEFAULT '0',
|
||||
`ItemID` int unsigned NOT NULL DEFAULT '0',
|
||||
`Unknown020001` int unsigned NOT NULL DEFAULT '0',
|
||||
`CreatureDisplayInfoID` int unsigned NOT NULL DEFAULT '0',
|
||||
`Cost` int unsigned NOT NULL DEFAULT '0',
|
||||
`UiModelSceneID` int unsigned NOT NULL DEFAULT '0',
|
||||
`UiGroupInfo` int unsigned NOT NULL DEFAULT '0',
|
||||
`VerifiedBuild` int NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`,`VerifiedBuild`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
@@ -2364,6 +2364,12 @@ ObjectGuid BotSpawner::CreateBotCharacter(uint32 accountId, uint8 race, uint8 cl
|
||||
}
|
||||
}
|
||||
|
||||
// CRITICAL FIX: Clear item update queue before save to prevent Item.cpp:1234 crash
|
||||
// The crash occurs when invalid Item pointers (corrupted/dangling) remain in the
|
||||
// player's item update queue. This can happen during character creation when
|
||||
// items are added but not fully initialized.
|
||||
newChar->GetItemUpdateQueue().clear();
|
||||
|
||||
// Save to database using async-safe PlayerbotCharacterDBInterface
|
||||
CharacterDatabaseTransaction characterTransaction = sPlayerbotCharDB->BeginTransaction();
|
||||
LoginDatabaseTransaction loginTransaction = LoginDatabase.BeginTransaction();
|
||||
|
||||
@@ -965,6 +965,51 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_SEL_PLAYER_INITIATIVE_FAVOR,
|
||||
"SELECT COALESCE(SUM(amount), 0) FROM neighborhood_initiative_contributions WHERE initiativeDbId = ? AND playerGuid = ?",
|
||||
CONNECTION_SYNCH);
|
||||
|
||||
// Perks Program - Purchases
|
||||
PrepareStatement(CHAR_SEL_PERKS_PURCHASES,
|
||||
"SELECT vendor_item_id, purchase_time FROM character_perks_purchases WHERE guid = ?",
|
||||
CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_INS_PERKS_PURCHASE,
|
||||
"INSERT INTO character_perks_purchases (guid, vendor_item_id, purchase_time) VALUES (?, ?, ?)",
|
||||
CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PERKS_PURCHASE,
|
||||
"DELETE FROM character_perks_purchases WHERE guid = ? AND vendor_item_id = ?",
|
||||
CONNECTION_ASYNC);
|
||||
|
||||
// Perks Program - Frozen Items
|
||||
PrepareStatement(CHAR_SEL_ACCOUNT_PERKS_FROZEN_ITEMS,
|
||||
"SELECT vendor_item_id FROM account_perks_frozen_items WHERE account_id = ?",
|
||||
CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_INS_PERKS_FROZEN_ITEM,
|
||||
"INSERT IGNORE INTO account_perks_frozen_items (account_id, vendor_item_id, frozen_time) VALUES (?, ?, ?)",
|
||||
CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PERKS_FROZEN_ITEM,
|
||||
"DELETE FROM account_perks_frozen_items WHERE account_id = ? AND vendor_item_id = ?",
|
||||
CONNECTION_ASYNC);
|
||||
|
||||
// Perks Program - Tracked Activities
|
||||
PrepareStatement(CHAR_SEL_PERKS_TRACKED_ACTIVITIES,
|
||||
"SELECT activity_id FROM character_perks_tracked_activities WHERE guid = ?",
|
||||
CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_INS_PERKS_TRACKED_ACTIVITY,
|
||||
"INSERT IGNORE INTO character_perks_tracked_activities (guid, activity_id) VALUES (?, ?)",
|
||||
CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PERKS_TRACKED_ACTIVITY,
|
||||
"DELETE FROM character_perks_tracked_activities WHERE guid = ? AND activity_id = ?",
|
||||
CONNECTION_ASYNC);
|
||||
|
||||
// Perks Program - Activity
|
||||
PrepareStatement(CHAR_SEL_PERK_PROGRAM_ACTIVITY,
|
||||
"SELECT ActivityID FROM perk_program_activity",
|
||||
CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_DEL_PERK_PROGRAM_ACTIVITY,
|
||||
"DELETE FROM perk_program_activity",
|
||||
CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_REP_PERK_PROGRAM_ACTIVITY,
|
||||
"INSERT INTO perk_program_activity (ActivityID) VALUES (?)",
|
||||
CONNECTION_ASYNC);
|
||||
|
||||
// WowCommunity end
|
||||
}
|
||||
|
||||
|
||||
@@ -799,6 +799,21 @@ enum CharacterDatabaseStatements : uint32
|
||||
CHAR_SEL_PLAYER_INITIATIVE_FAVOR,
|
||||
//WowCommunity end
|
||||
|
||||
// Perks Program
|
||||
CHAR_SEL_PERKS_PURCHASES,
|
||||
CHAR_INS_PERKS_PURCHASE,
|
||||
CHAR_DEL_PERKS_PURCHASE,
|
||||
CHAR_SEL_ACCOUNT_PERKS_FROZEN_ITEMS,
|
||||
CHAR_INS_PERKS_FROZEN_ITEM,
|
||||
CHAR_DEL_PERKS_FROZEN_ITEM,
|
||||
CHAR_SEL_PERKS_TRACKED_ACTIVITIES,
|
||||
CHAR_INS_PERKS_TRACKED_ACTIVITY,
|
||||
CHAR_DEL_PERKS_TRACKED_ACTIVITY,
|
||||
CHAR_SEL_PERK_PROGRAM_ACTIVITY,
|
||||
CHAR_DEL_PERK_PROGRAM_ACTIVITY,
|
||||
CHAR_REP_PERK_PROGRAM_ACTIVITY,
|
||||
//WowCommunity end
|
||||
|
||||
MAX_CHARACTERDATABASE_STATEMENTS
|
||||
};
|
||||
|
||||
|
||||
@@ -2664,6 +2664,12 @@ void HotfixDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(HOTFIX_SEL_DRIVE_CAPABILITY_TIER, "SELECT ID, Acceleration, MaxSpeed, DriveCapabilityID, OrderIndex"
|
||||
" FROM drive_capability_tier WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
|
||||
PREPARE_MAX_ID_STMT(HOTFIX_SEL_DRIVE_CAPABILITY_TIER, "SELECT MAX(ID) + 1 FROM drive_capability_tier", CONNECTION_SYNCH);
|
||||
|
||||
// PerksVendorItem.db2
|
||||
PrepareStatement(HOTFIX_SEL_PERKS_VENDOR_ITEM, "SELECT ID, PerksVendorCategoryID, Unknown010001, ItemID, Unknown020001, CreatureDisplayInfoID, "
|
||||
"Cost, UiModelSceneID, UiGroupInfo FROM perks_vendor_item WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH);
|
||||
PREPARE_MAX_ID_STMT(HOTFIX_SEL_PERKS_VENDOR_ITEM, "SELECT MAX(ID) + 1 FROM perks_vendor_item", CONNECTION_SYNCH);
|
||||
|
||||
//WowCommunity end
|
||||
}
|
||||
|
||||
|
||||
@@ -483,6 +483,9 @@ enum HotfixDatabaseStatements : uint32
|
||||
HOTFIX_SEL_HOLIDAYS,
|
||||
HOTFIX_SEL_HOLIDAYS_MAX_ID,
|
||||
|
||||
HOTFIX_SEL_PERKS_VENDOR_ITEM,
|
||||
HOTFIX_SEL_PERKS_VENDOR_ITEM_MAX_ID,
|
||||
|
||||
HOTFIX_SEL_IMPORT_PRICE_ARMOR,
|
||||
HOTFIX_SEL_IMPORT_PRICE_ARMOR_MAX_ID,
|
||||
|
||||
|
||||
@@ -87,6 +87,9 @@ void WorldDatabaseConnection::DoPrepareStatements()
|
||||
|
||||
PrepareStatement(WORLD_SEL_WARBAND_REPUTATION_FACTIONS, "SELECT factionId FROM warband_reputation_faction", CONNECTION_SYNCH);
|
||||
|
||||
// Perks Program
|
||||
PrepareStatement(WORLD_SEL_PERKS_VENDOR_ITEMS, "SELECT Id, ItemID, MountSpellID, PetSpellID, TransmogSet, ItemModifiedAppearanceID, ToyItem, Cost, Mon FROM perk_programs_vendor_items", CONNECTION_SYNCH);
|
||||
|
||||
}
|
||||
|
||||
WorldDatabaseConnection::WorldDatabaseConnection(MySQLConnectionInfo& connInfo, ConnectionFlags connectionFlags) : MySQLConnection(connInfo, connectionFlags)
|
||||
|
||||
@@ -92,6 +92,10 @@ enum WorldDatabaseStatements : uint32
|
||||
WORLD_SEL_QUEST_GIVER_SPAWNS, // SELECT c.guid, c.id, c.position_x, c.position_y, c.position_z, c.map, ct.faction, COALESCE(c.zoneId, 0) as zoneId FROM creature c INNER JOIN creature_template ct ON c.id = ct.entry WHERE ct.npcflag & 2 != 0
|
||||
WORLD_SEL_WARBAND_REPUTATION_FACTIONS,
|
||||
|
||||
// Perks Program Vendor Items
|
||||
WORLD_SEL_PERKS_VENDOR_ITEMS,
|
||||
// WowCommunity end
|
||||
|
||||
MAX_WORLDDATABASE_STATEMENTS
|
||||
};
|
||||
|
||||
|
||||
@@ -4327,6 +4327,24 @@ struct PerksActivityLoadInfo
|
||||
static constexpr DB2LoadInfo Instance{ Fields, 7, &PerksActivityMeta::Instance, HOTFIX_SEL_PERKS_ACTIVITY };
|
||||
};
|
||||
|
||||
struct PerksVendorItemLoadInfo
|
||||
{
|
||||
static constexpr DB2FieldMeta Fields[9] =
|
||||
{
|
||||
{.IsSigned = false, .Type = FT_INT, .Name = "ID" },
|
||||
{.IsSigned = true, .Type = FT_BYTE, .Name = "PerksVendorCategoryID" },
|
||||
{.IsSigned = true, .Type = FT_INT, .Name = "Unknown010001" },
|
||||
{.IsSigned = true, .Type = FT_INT, .Name = "ItemID" },
|
||||
{.IsSigned = true, .Type = FT_INT, .Name = "Unknown020001" },
|
||||
{.IsSigned = true, .Type = FT_INT, .Name = "CreatureDisplayInfoID" },
|
||||
{.IsSigned = true, .Type = FT_INT, .Name = "Cost" },
|
||||
{.IsSigned = true, .Type = FT_INT, .Name = "UiModelSceneID" },
|
||||
{.IsSigned = true, .Type = FT_INT, .Name = "UiGroupInfo" },
|
||||
};
|
||||
|
||||
static constexpr DB2LoadInfo Instance{ Fields, 9, &PerksVendorItemMeta::Instance, HOTFIX_SEL_PERKS_VENDOR_ITEM };
|
||||
};
|
||||
|
||||
struct PhaseLoadInfo
|
||||
{
|
||||
static constexpr DB2FieldMeta Fields[2] =
|
||||
|
||||
@@ -261,6 +261,7 @@ DB2Storage<PathEntry> sPathStore("Path.db2", &PathLoad
|
||||
DB2Storage<PathNodeEntry> sPathNodeStore("PathNode.db2", &PathNodeLoadInfo::Instance);
|
||||
DB2Storage<PathPropertyEntry> sPathPropertyStore("PathProperty.db2", &PathPropertyLoadInfo::Instance);
|
||||
DB2Storage<PerksActivityEntry> sPerksActivityStore("PerksActivity.db2", &PerksActivityLoadInfo::Instance);
|
||||
DB2Storage<PerksVendorItemEntry> sPerksVendorItemStore("PerksVendorItem.db2", &PerksVendorItemLoadInfo::Instance);
|
||||
DB2Storage<PhaseEntry> sPhaseStore("Phase.db2", &PhaseLoadInfo::Instance);
|
||||
DB2Storage<PhaseXPhaseGroupEntry> sPhaseXPhaseGroupStore("PhaseXPhaseGroup.db2", &PhaseXPhaseGroupLoadInfo::Instance);
|
||||
DB2Storage<PlayerConditionEntry> sPlayerConditionStore("PlayerCondition.db2", &PlayerConditionLoadInfo::Instance);
|
||||
@@ -547,6 +548,7 @@ typedef std::tuple<uint16, uint8, int32> WMOAreaTableKey;
|
||||
typedef std::map<WMOAreaTableKey, WMOAreaTableEntry const*> WMOAreaTableLookupContainer;
|
||||
typedef std::pair<uint32 /*tableHash*/, int32 /*recordId*/> HotfixBlobKey;
|
||||
typedef std::map<HotfixBlobKey, std::vector<uint8>> HotfixBlobMap;
|
||||
typedef std::unordered_map<uint32 /*ActivityTag*/, std::vector<PerksActivityEntry const*>> PerkProgramActivityXTag;
|
||||
using AllowedHotfixOptionalData = std::pair<uint32 /*optional data key*/, bool(*)(std::vector<uint8> const& data) /*validator*/>;
|
||||
|
||||
namespace
|
||||
@@ -648,6 +650,7 @@ namespace
|
||||
std::unordered_map<uint32, std::unordered_set<uint32>> _pvpStatIdsByMap;
|
||||
//WowCommunity
|
||||
std::unordered_map<int32, std::vector<WarbandScenePlacementEntry const*>> _warbandScenePlacementsByScene;
|
||||
PerkProgramActivityXTag _activityXTag;
|
||||
//WowCommunity end
|
||||
}
|
||||
|
||||
@@ -994,6 +997,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul
|
||||
LOAD_DB2(sPathNodeStore);
|
||||
LOAD_DB2(sPathPropertyStore);
|
||||
LOAD_DB2(sPerksActivityStore);
|
||||
LOAD_DB2(sPerksVendorItemStore);
|
||||
LOAD_DB2(sPhaseStore);
|
||||
LOAD_DB2(sPhaseXPhaseGroupStore);
|
||||
LOAD_DB2(sPlayerConditionStore);
|
||||
@@ -3721,4 +3725,23 @@ std::vector<WarbandScenePlacementEntry const*> const* DB2Manager::GetWarbandScen
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_warbandScenePlacementsByScene, static_cast<int32>(warbandSceneId));
|
||||
}
|
||||
|
||||
std::vector<PerksActivityEntry const*> DB2Manager::GetRandomActivitiesXTag()
|
||||
{
|
||||
std::vector<PerksActivityEntry const*> activities;
|
||||
|
||||
for (PerksActivityEntry const* activity : sPerksActivityStore)
|
||||
{
|
||||
if (activity)
|
||||
activities.push_back(activity);
|
||||
}
|
||||
|
||||
if (activities.empty())
|
||||
return {};
|
||||
|
||||
int32 count = std::min(5, static_cast<int32>(activities.size()));
|
||||
Trinity::Containers::RandomResize(activities, count);
|
||||
|
||||
return activities;
|
||||
}
|
||||
//WowCommunity
|
||||
|
||||
@@ -203,6 +203,7 @@ TC_GAME_API extern DB2Storage<MythicPlusSeasonEntry> sMythicPlusS
|
||||
TC_GAME_API extern DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore;
|
||||
TC_GAME_API extern DB2Storage<ParagonReputationEntry> sParagonReputationStore;
|
||||
TC_GAME_API extern DB2Storage<PerksActivityEntry> sPerksActivityStore;
|
||||
TC_GAME_API extern DB2Storage<PerksVendorItemEntry> sPerksVendorItemStore;
|
||||
TC_GAME_API extern DB2Storage<PhaseEntry> sPhaseStore;
|
||||
TC_GAME_API extern DB2Storage<PlayerConditionEntry> sPlayerConditionStore;
|
||||
TC_GAME_API extern DB2Storage<PlayerDataElementAccountEntry> sPlayerDataElementAccountStore;
|
||||
@@ -660,6 +661,7 @@ public:
|
||||
std::unordered_set<uint32> const* GetPVPStatIDsForMap(uint32 mapId) const;
|
||||
//WowCommunity
|
||||
std::vector<WarbandScenePlacementEntry const*> const* GetWarbandScenePlacements(uint32 warbandSceneId) const;
|
||||
std::vector<PerksActivityEntry const*> GetRandomActivitiesXTag();
|
||||
//WowCommunity
|
||||
private:
|
||||
friend class DB2HotfixGeneratorBase;
|
||||
|
||||
@@ -3249,6 +3249,19 @@ struct PerksActivityEntry
|
||||
int32 Priority;
|
||||
};
|
||||
|
||||
struct PerksVendorItemEntry
|
||||
{
|
||||
int32 ID;
|
||||
int8 PerksVendorCategoryID;
|
||||
int32 Unknown010001;
|
||||
int32 ItemID;
|
||||
int32 Unknown020001;
|
||||
int32 CreatureDisplayInfoID;
|
||||
int32 Cost;
|
||||
int32 UiModelSceneID;
|
||||
int32 UiGroupInfo;
|
||||
};
|
||||
|
||||
struct PhaseEntry
|
||||
{
|
||||
uint32 ID;
|
||||
|
||||
@@ -19461,9 +19461,6 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
|
||||
}
|
||||
while (auraResult->NextRow());
|
||||
}
|
||||
|
||||
// TODO: finish dragonriding - this forces old flight mode
|
||||
AddAura(404468, this);
|
||||
}
|
||||
|
||||
void Player::_LoadGlyphAuras()
|
||||
@@ -32571,4 +32568,12 @@ void Player::SendCtrOptions() const
|
||||
SendDirectMessage(ctrOptions.Write());
|
||||
}
|
||||
|
||||
void Player::AddMoveImpulse(Position direction)
|
||||
{
|
||||
WorldPackets::Movement::MoveAddImpulse impulse;
|
||||
impulse.MoverGUID = GetGUID();
|
||||
impulse.SequenceIndex = m_movementCounter++;
|
||||
impulse.Direction = direction;
|
||||
SendMessageToSet(impulse.Write(), true);
|
||||
}
|
||||
//WowCommunity
|
||||
|
||||
@@ -2032,6 +2032,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
|
||||
void ApplyTraitEntryChanges(int32 editedConfigId, WorldPackets::Traits::TraitConfig const& newConfig, bool applyTraits, bool consumeCurrencies);
|
||||
void RenameTraitConfig(int32 editedConfigId, std::string&& newName);
|
||||
void DeleteTraitConfig(int32 deletedConfigId);
|
||||
void AddMoveImpulse(Position direction);
|
||||
void ApplyTraitConfig(int32 configId, bool apply);
|
||||
void ApplyTraitEntry(int32 traitNodeEntryId, int32 rank, int32 grantedRanks, bool apply);
|
||||
void SetActiveCombatTraitConfigID(int32 traitConfigId) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ActiveCombatTraitConfigID), traitConfigId); }
|
||||
|
||||
@@ -8417,7 +8417,9 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
|
||||
{
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_GROUND && !(mountFlags.HasFlag(AreaMountFlags::AllowGroundMounts)))
|
||||
continue;
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLYING && !(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts)))
|
||||
// Allow flying everywhere for players (private server - area flags incomplete in DB2)
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLYING && !(mountFlags.HasFlag(AreaMountFlags::AllowFlyingMounts))
|
||||
&& GetTypeId() != TYPEID_PLAYER)
|
||||
continue;
|
||||
if (mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT && !(mountFlags.HasFlag(AreaMountFlags::AllowSurfaceSwimmingMounts)))
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
///*
|
||||
// * Copyright (C) WowCommunity Project
|
||||
// *
|
||||
// * This SourceCode is NOT free a software. Please hold everything Private
|
||||
// * and read our Terms
|
||||
// */
|
||||
//
|
||||
//#include "PerkProgramData.h"
|
||||
//#include "PerkProgramMgr.h"
|
||||
//#include "Containers.h"
|
||||
//#include "DatabaseEnv.h"
|
||||
//#include "ObjectMgr.h"
|
||||
//#include "DB2Stores.h"
|
||||
//#include <sstream>
|
||||
//#include "GameTime.h"
|
||||
//
|
||||
//PerkProgramDataStoreMgr::PerkProgramDataStoreMgr() {};
|
||||
//
|
||||
//PerkProgramDataStoreMgr::~PerkProgramDataStoreMgr() {};
|
||||
//
|
||||
//PerkProgramDataStoreMgr* PerkProgramDataStoreMgr::instance()
|
||||
//{
|
||||
// static PerkProgramDataStoreMgr instance;
|
||||
// return &instance;
|
||||
//}
|
||||
//
|
||||
//namespace
|
||||
//{
|
||||
// std::unordered_map<uint32, PerkProgramData::PerkVendorItem> _vendorTemplates;
|
||||
// std::vector<PerkProgramData::ActivityTemplate> m_activeActivity;
|
||||
//}
|
||||
//
|
||||
//void PerkProgramDataStoreMgr::Initialize()
|
||||
//{
|
||||
// LoadPerkVendorItem();
|
||||
// LoadActivities();
|
||||
//}
|
||||
//
|
||||
//void PerkProgramDataStoreMgr::LoadPerkVendorItem()
|
||||
//{
|
||||
// TC_LOG_INFO("server.loading", "Loading PerkPrograms Vendor Items Templates ...");
|
||||
// _vendorTemplates.clear();
|
||||
//
|
||||
// if (!sPerksVendorItemStore.GetNumRows())
|
||||
// {
|
||||
// TC_LOG_WARN("server.loading", ">> PerksVendorItem store is empty, skipping vendor items");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// for (PerksVendorItemEntry const* itemVendor : sPerksVendorItemStore)
|
||||
// {
|
||||
// if (!itemVendor)
|
||||
// continue;
|
||||
//
|
||||
// PerkProgramData::PerkVendorItem vendorItem;
|
||||
// vendorItem.Id = itemVendor->ID;
|
||||
// vendorItem.ItemID = itemVendor->ItemID;
|
||||
// vendorItem.MountSpellID = itemVendor->Unknown010001;
|
||||
// vendorItem.PetSpellID = itemVendor->Unknown020001;
|
||||
// vendorItem.TransmogSet = 0;
|
||||
// vendorItem.ItemModifiedAppearanceID = 0;
|
||||
// vendorItem.ToyItem = 0;
|
||||
// vendorItem.Cost = itemVendor->Cost;
|
||||
// vendorItem.CategoryId = itemVendor->PerksVendorCategoryID;
|
||||
//
|
||||
// _vendorTemplates.insert(std::make_pair(itemVendor->ID, vendorItem));
|
||||
// }
|
||||
//
|
||||
// TC_LOG_INFO("server.loading", ">> Loaded {} PerkPrograms Vendor Items Templates", uint32(_vendorTemplates.size()));
|
||||
//}
|
||||
//
|
||||
//std::unordered_map<uint32, PerkProgramData::PerkVendorItem> PerkProgramDataStoreMgr::GetVendorItems()
|
||||
//{
|
||||
// return _vendorTemplates;
|
||||
//}
|
||||
//
|
||||
//PerkProgramData::PerkVendorItem const* PerkProgramDataStoreMgr::GetVendorItem(uint32 entry)
|
||||
//{
|
||||
// auto itr = _vendorTemplates.find(entry);
|
||||
// if (itr != _vendorTemplates.end())
|
||||
// return &itr->second;
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
//
|
||||
//PerkProgramData::PerkVendorItem const* PerkProgramDataStoreMgr::GetRandomVendorItem()
|
||||
//{
|
||||
// if (_vendorTemplates.empty())
|
||||
// return nullptr;
|
||||
//
|
||||
// auto it = _vendorTemplates.begin();
|
||||
// std::advance(it, rand() % _vendorTemplates.size());
|
||||
// return &it->second;
|
||||
//}
|
||||
//
|
||||
//std::vector<PerkProgramData::ActivityTemplate> PerkProgramDataStoreMgr::GetActivities()
|
||||
//{
|
||||
// return m_activeActivity;
|
||||
//}
|
||||
//
|
||||
//uint32 PerkProgramDataStoreMgr::GetActivityCriteriatree(uint32 activityId)
|
||||
//{
|
||||
// for (auto const& ac : m_activeActivity)
|
||||
// {
|
||||
// if (ac.ActivityID == activityId)
|
||||
// return ac.CriteriaTree;
|
||||
// }
|
||||
// return 0;
|
||||
//}
|
||||
//
|
||||
//uint32 PerkProgramDataStoreMgr::GetActivityCurrencyAmount(uint32 activityId)
|
||||
//{
|
||||
// for (auto const& ac : m_activeActivity)
|
||||
// {
|
||||
// if (ac.ActivityID == activityId)
|
||||
// return ac.CurrencyAmount;
|
||||
// }
|
||||
// return 0;
|
||||
//}
|
||||
//
|
||||
//void PerkProgramDataStoreMgr::LoadActivities()
|
||||
//{
|
||||
// CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PERK_PROGRAM_ACTIVITY);
|
||||
// PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
// m_activeActivity.clear();
|
||||
// if (!result)
|
||||
// {
|
||||
// GenerateRandomActivities(false);
|
||||
// return;
|
||||
// }
|
||||
// do
|
||||
// {
|
||||
// Field* fields = result->Fetch();
|
||||
// uint32 activityId = fields[0].GetUInt32();
|
||||
// PerksActivityEntry const* entry = sPerksActivityStore.LookupEntry(activityId);
|
||||
// if (!entry)
|
||||
// continue;
|
||||
// PerkProgramData::ActivityTemplate ac;
|
||||
// ac.ActivityID = entry->ID;
|
||||
// ac.CriteriaTree = entry->CriteriaTreeID;
|
||||
// ac.CurrencyAmount = entry->ThresholdContributionAmount;
|
||||
// ac.Priority = entry->Priority;
|
||||
// m_activeActivity.push_back(ac);
|
||||
//
|
||||
// } while (result->NextRow());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramDataStoreMgr::GenerateRandomActivities(bool /*clearOld*/)
|
||||
//{
|
||||
// CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PERK_PROGRAM_ACTIVITY);
|
||||
// CharacterDatabase.Execute(stmt);
|
||||
// m_activeActivity.clear();
|
||||
//
|
||||
// for (PerksActivityEntry const* db : sDB2Manager.GetRandomActivitiesXTag())
|
||||
// {
|
||||
// PerkProgramData::ActivityTemplate ac;
|
||||
// ac.ActivityID = db->ID;
|
||||
// ac.CriteriaTree = db->CriteriaTreeID;
|
||||
// ac.CurrencyAmount = db->ThresholdContributionAmount;
|
||||
// ac.Priority = db->Priority;
|
||||
// m_activeActivity.push_back(ac);
|
||||
//
|
||||
// stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_PERK_PROGRAM_ACTIVITY);
|
||||
// stmt->setUInt32(0, ac.ActivityID);
|
||||
// CharacterDatabase.Execute(stmt);
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,75 @@
|
||||
///*
|
||||
// * Copyright (C) WowCommunity Project
|
||||
// *
|
||||
// * This SourceCode is NOT free a software. Please hold everything Private
|
||||
// * and read our Terms
|
||||
// */
|
||||
//
|
||||
//#ifndef _PERK_PROGRAM_DATA_STORE_H
|
||||
//#define _PERK_PROGRAM_DATA_STORE_H
|
||||
//
|
||||
//#include "PerksProgramPacketsCommon.h"
|
||||
//#include "PacketUtilities.h"
|
||||
//#include "DatabaseEnv.h"
|
||||
//#include <vector>
|
||||
//#include <unordered_map>
|
||||
//#include <ctime>
|
||||
//
|
||||
//class PerkProgramManager;
|
||||
//
|
||||
//namespace PerkProgramData
|
||||
//{
|
||||
// struct PerkVendorItem
|
||||
// {
|
||||
// uint32 Id;
|
||||
// uint32 ItemID;
|
||||
// uint32 MountSpellID;
|
||||
// uint32 PetSpellID;
|
||||
// uint32 TransmogSet;
|
||||
// uint32 ItemModifiedAppearanceID;
|
||||
// uint32 ToyItem;
|
||||
// time_t AvailableUntil;
|
||||
// uint32 Cost;
|
||||
// uint32 CategoryId;
|
||||
//
|
||||
// };
|
||||
//
|
||||
// struct ActivityTemplate
|
||||
// {
|
||||
// uint32 ActivityID;
|
||||
// uint32 CriteriaTree;
|
||||
// uint32 Priority;
|
||||
// uint32 CurrencyAmount;
|
||||
// };
|
||||
//};
|
||||
//
|
||||
//class TC_GAME_API PerkProgramDataStoreMgr
|
||||
//{
|
||||
// PerkProgramDataStoreMgr();
|
||||
// ~PerkProgramDataStoreMgr();
|
||||
//
|
||||
//public:
|
||||
// static PerkProgramDataStoreMgr* instance();
|
||||
//
|
||||
// void Initialize();
|
||||
//
|
||||
// std::unordered_map<uint32, PerkProgramData::PerkVendorItem> GetVendorItems();
|
||||
// PerkProgramData::PerkVendorItem const* GetVendorItem(uint32 entry);
|
||||
// PerkProgramData::PerkVendorItem const* GetRandomVendorItem();
|
||||
//
|
||||
// std::vector<PerkProgramData::ActivityTemplate> GetActivities();
|
||||
// uint32 GetActivityCriteriatree(uint32 activityId);
|
||||
// uint32 GetActivityCurrencyAmount(uint32 activityId);
|
||||
//
|
||||
//private:
|
||||
//
|
||||
// void LoadPerkVendorItem();
|
||||
// void LoadActivities();
|
||||
// void GenerateRandomActivities(bool clearOld);
|
||||
// time_t m_activityTime;
|
||||
//
|
||||
//};
|
||||
//
|
||||
//#define sPerkProgramDataStore PerkProgramDataStoreMgr::instance()
|
||||
//
|
||||
//#endif
|
||||
@@ -0,0 +1,430 @@
|
||||
///*
|
||||
// * Copyright (C) WowCommunity Project
|
||||
// *
|
||||
// * This SourceCode is NOT free a software. Please hold everything Private
|
||||
// * and read our Terms
|
||||
// */
|
||||
//
|
||||
//#include "Common.h"
|
||||
//#include "CollectionMgr.h"
|
||||
//#include "ObjectMgr.h"
|
||||
//#include "PerkProgramMgr.h"
|
||||
//#include "WorldSession.h"
|
||||
//#include "Guild.h"
|
||||
//#include "GuildMgr.h"
|
||||
//#include "Player.h"
|
||||
//#include "Creature.h"
|
||||
//#include "PerkProgramData.h"
|
||||
//#include "DatabaseEnv.h"
|
||||
//#include "ScriptMgr.h"
|
||||
//#include "AccountMgr.h"
|
||||
//#include <sstream>
|
||||
//#include "SpellInfo.h"
|
||||
//#include "SpellMgr.h"
|
||||
//#include "Language.h"
|
||||
//#include "SpellPackets.h"
|
||||
//#include "Chat.h"
|
||||
//#include "DB2Stores.h"
|
||||
//#include "Pet.h"
|
||||
//#include "Item.h"
|
||||
//#include "MiscPackets.h"
|
||||
//#include "Unit.h"
|
||||
//#include "GameTime.h"
|
||||
//#include "PerksProgramPackets.h"
|
||||
//
|
||||
//using namespace PerkPrograms;
|
||||
//
|
||||
//PerkProgramManager::PerkProgramManager(WorldSession* session)
|
||||
//{
|
||||
// _session = session;
|
||||
// if (session->GetPlayer())
|
||||
// m_player = session->GetPlayer();
|
||||
//
|
||||
// m_currencyAmount = 0;
|
||||
//}
|
||||
//
|
||||
//PerkProgramManager::~PerkProgramManager()
|
||||
//{
|
||||
//};
|
||||
//
|
||||
//void PerkProgramManager::SendVendorItems(Creature* vendor, std::vector<uint32> purchasedItems)
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_AVAILABLE_ITEMS;
|
||||
//
|
||||
// uint32 cameraId = 0;
|
||||
//
|
||||
// switch (vendor->GetEntry())
|
||||
// {
|
||||
// case PerkPrograms::VENDOR_HORDE:
|
||||
// cameraId = PerkPrograms::CAMERA_HORDE;
|
||||
// break;
|
||||
// case PerkPrograms::VENDOR_ALLIANCE:
|
||||
// cameraId = PerkPrograms::CAMERA_ALLIANCE;
|
||||
// break;
|
||||
// default:
|
||||
// cameraId = 0;
|
||||
// break;
|
||||
// }
|
||||
// perks.Params.VendorItem.VendorGuid = vendor->GetGUID();
|
||||
//
|
||||
// if (cameraId != 0)
|
||||
// {
|
||||
// std::list<Creature*> list;
|
||||
// _session->GetPlayer()->GetCreatureListWithEntryInGrid(list, cameraId, 100);
|
||||
//
|
||||
// for (auto cr1 : list)
|
||||
// {
|
||||
// perks.Params.VendorItem.ModelSceneCameraGuid = cr1->GetGUID();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (auto items : sPerkProgramDataStore->GetVendorItems())
|
||||
// {
|
||||
// WorldPackets::PerksProgram::PerksVendorItem vendorItem;
|
||||
// vendorItem.VendorItemID = items.second.Id;
|
||||
// vendorItem.MountID = items.second.MountSpellID;
|
||||
// vendorItem.BattlePetSpeciesID = items.second.PetSpellID;
|
||||
// vendorItem.ItemModifiedAppearanceID = items.second.ItemModifiedAppearanceID;
|
||||
// vendorItem.ToyID = items.second.ToyItem;
|
||||
// vendorItem.TransmogSetID = items.second.TransmogSet;
|
||||
// vendorItem.Price = items.second.Cost;
|
||||
// vendorItem.CategoryType = items.second.CategoryId;
|
||||
// vendorItem.Disabled = false;
|
||||
// vendorItem.AvailableUntil = items.second.AvailableUntil;
|
||||
// perks.Params.VendorItem.FrozenPerksVendorItems.emplace_back(vendorItem);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//bool PerkProgramManager::IsAccountWideItem(uint32 item)
|
||||
//{
|
||||
// bool level = false;
|
||||
// if (auto i = sPerkProgramDataStore->GetVendorItem(item))
|
||||
// {
|
||||
// switch (i->CategoryId)
|
||||
// {
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
|
||||
// level = true;
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// return level;
|
||||
//}
|
||||
//
|
||||
//bool PerkProgramManager::IsItemAlreadyOwned(PerkProgramData::PerkVendorItem const* vendorItem)
|
||||
//{
|
||||
// if (!vendorItem)
|
||||
// return true;
|
||||
//
|
||||
// switch (vendorItem->CategoryId)
|
||||
// {
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
|
||||
// return m_player->GetSession()->GetCollectionMgr()->HasToy(vendorItem->ToyItem);
|
||||
// // case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
|
||||
// // return m_player->GetMountCollection()->Has(vendorItem->MountSpellID);
|
||||
// // case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
|
||||
// // return m_player->GetSession()->GetCollectionMgr()->HasTransmogSet(vendorItem->TransmogSet);
|
||||
// // case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG:
|
||||
// // return m_player->GetSession()->GetCollectionMgr()->HasItemAppearance(vendorItem->ItemModifiedAppearanceID);
|
||||
// // case PerkPrograms::PERKS_VENDOR_CATEGORY_PETS:
|
||||
// // return m_player->GetBattlePetCollection()->HasPet(vendorItem->PetSpellID);
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::GrantItem(PerkProgramData::PerkVendorItem const* vendorItem)
|
||||
//{
|
||||
// if (!vendorItem)
|
||||
// return;
|
||||
//
|
||||
// switch (vendorItem->CategoryId)
|
||||
// {
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
|
||||
// {
|
||||
// m_player->GetSession()->GetCollectionMgr()->AddToy(vendorItem->ToyItem, false, false);
|
||||
// break;
|
||||
// }
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
|
||||
// {
|
||||
// m_player->LearnSpell(vendorItem->MountSpellID, false);
|
||||
// break;
|
||||
// }
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
|
||||
// {
|
||||
// m_player->GetSession()->GetCollectionMgr()->AddTransmogSet(vendorItem->TransmogSet);
|
||||
// break;
|
||||
// }
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG:
|
||||
// {
|
||||
// m_player->GetSession()->GetCollectionMgr()->AddItemAppearance(vendorItem->ItemModifiedAppearanceID);
|
||||
// break;
|
||||
// }
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_PETS:
|
||||
// {
|
||||
// // m_player->AddBattlePet(vendorItem->PetSpellID);
|
||||
// break;
|
||||
// }
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_CONSUMABLES:
|
||||
// {
|
||||
// m_player->AddItem(vendorItem->ItemID, 1);
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::RemoveGrantedItem(PerkProgramData::PerkVendorItem const* vendorItem)
|
||||
//{
|
||||
// if (!vendorItem)
|
||||
// return;
|
||||
//
|
||||
// switch (vendorItem->CategoryId)
|
||||
// {
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TOYS:
|
||||
// break;
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_MOUNTS:
|
||||
// m_player->RemoveSpell(vendorItem->MountSpellID, false, true);
|
||||
// break;
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG_SETS:
|
||||
// break;
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_TRANSMOG:
|
||||
// break;
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_PETS:
|
||||
// break;
|
||||
// case PerkPrograms::PERKS_VENDOR_CATEGORY_CONSUMABLES:
|
||||
// m_player->DestroyItemCount(vendorItem->ItemID, 1, true);
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::BuyItem(uint32 itemId, ObjectGuid /*vendor*/)
|
||||
//{
|
||||
// auto const* vendorItem = sPerkProgramDataStore->GetVendorItem(itemId);
|
||||
// if (!vendorItem)
|
||||
// {
|
||||
// SendPerksProgramError(1);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (m_currencyAmount < vendorItem->Cost)
|
||||
// {
|
||||
// SendPerksProgramError(2);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (IsItemAlreadyOwned(vendorItem))
|
||||
// {
|
||||
// SendPerksProgramError(3);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// m_currencyAmount -= vendorItem->Cost;
|
||||
// m_player->ModifyCurrency(PERKS_PROGRAM_CURRENCY, -static_cast<int32>(vendorItem->Cost));
|
||||
//
|
||||
// GrantItem(vendorItem);
|
||||
//
|
||||
// RecordPurchase(itemId, GameTime::GetGameTime());
|
||||
//
|
||||
// SendBuyItemResult(itemId);
|
||||
// SendCurrencyRefresh();
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendBuyItemResult(int32 itemId)
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_BUY_ITEM;
|
||||
// perks.Params.BuyItem.VendorItemID = itemId;
|
||||
//
|
||||
// WorldPackets::PerksProgram::JamTimePair time;
|
||||
// time.BuyTime = GameTime::GetGameTime();
|
||||
// time.VendorItemID = itemId;
|
||||
// perks.Params.BuyItem.TimePair.emplace_back(time);
|
||||
//
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendCurrencyRefresh()
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_CURRENCY_REFRESH;
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendPerksProgramError(uint32 errorCode)
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_ERROR;
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::RecordPurchase(uint32 itemId, time_t purchaseTime)
|
||||
//{
|
||||
// m_recentPurchases.push_back(std::make_pair(itemId, purchaseTime));
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::RefundItem(int32 itemId)
|
||||
//{
|
||||
// auto it = std::find_if(m_recentPurchases.begin(), m_recentPurchases.end(),
|
||||
// [itemId](std::pair<uint32, time_t> const& p) { return p.first == static_cast<uint32>(itemId); });
|
||||
//
|
||||
// if (it == m_recentPurchases.end())
|
||||
// {
|
||||
// SendPerksProgramError(4);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (GameTime::GetGameTime() - it->second > REFUND_WINDOW_SECONDS)
|
||||
// {
|
||||
// SendPerksProgramError(5);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// auto const* vendorItem = sPerkProgramDataStore->GetVendorItem(itemId);
|
||||
// if (!vendorItem)
|
||||
// return;
|
||||
//
|
||||
// RemoveGrantedItem(vendorItem);
|
||||
//
|
||||
// m_currencyAmount += vendorItem->Cost;
|
||||
// m_player->ModifyCurrency(PERKS_PROGRAM_CURRENCY, static_cast<int32>(vendorItem->Cost));
|
||||
//
|
||||
// m_recentPurchases.erase(it);
|
||||
//
|
||||
// SendRefundSuccess(itemId);
|
||||
// SendCurrencyRefresh();
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendRefundSuccess(int32 itemId)
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_REFUND_SUCCESS;
|
||||
// perks.Params.BuyItem.VendorItemID = itemId;
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::CartCheckout(std::vector<uint32> const& vendorItemIDs)
|
||||
//{
|
||||
// uint32 totalCost = 0;
|
||||
//
|
||||
// for (uint32 itemId : vendorItemIDs)
|
||||
// {
|
||||
// auto const* item = sPerkProgramDataStore->GetVendorItem(itemId);
|
||||
// if (!item)
|
||||
// {
|
||||
// SendPerksProgramError(1);
|
||||
// return;
|
||||
// }
|
||||
// totalCost += item->Cost;
|
||||
// }
|
||||
//
|
||||
// if (m_currencyAmount < totalCost)
|
||||
// {
|
||||
// SendPerksProgramError(2);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// for (uint32 itemId : vendorItemIDs)
|
||||
// {
|
||||
// auto const* item = sPerkProgramDataStore->GetVendorItem(itemId);
|
||||
// if (!item)
|
||||
// continue;
|
||||
//
|
||||
// if (IsItemAlreadyOwned(item))
|
||||
// continue;
|
||||
//
|
||||
// m_currencyAmount -= item->Cost;
|
||||
// m_player->ModifyCurrency(PERKS_PROGRAM_CURRENCY, -static_cast<int32>(item->Cost));
|
||||
//
|
||||
// GrantItem(item);
|
||||
// RecordPurchase(itemId, GameTime::GetGameTime());
|
||||
// }
|
||||
//
|
||||
// SendCartCheckoutSuccess();
|
||||
// SendCurrencyRefresh();
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendCartCheckoutSuccess()
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_PURCHASE_CART;
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendPerksProgramStatus()
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_CURRENCY_REFRESH;
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendPendingRewards()
|
||||
//{
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SetFrozenItem(int32 itemId, bool clear)
|
||||
//{
|
||||
// if (clear)
|
||||
// {
|
||||
// m_frozenItems.clear();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// auto const* item = sPerkProgramDataStore->GetVendorItem(itemId);
|
||||
// if (item)
|
||||
// {
|
||||
// m_frozenItems.clear();
|
||||
// m_frozenItems.push_back(*item);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// WorldPackets::PerksProgram::PerksProgramResult perks;
|
||||
// perks.Type = PerkPrograms::RESULT_FROZEN_ITEM;
|
||||
// _session->SendPacket(perks.Write());
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::AddTrackedActivity(uint32 activityId)
|
||||
//{
|
||||
// if (std::find(m_trackedActivities.begin(), m_trackedActivities.end(), activityId) == m_trackedActivities.end())
|
||||
// {
|
||||
// m_trackedActivities.push_back(activityId);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::RemoveTrackedActivity(uint32 activityId)
|
||||
//{
|
||||
// auto it = std::find(m_trackedActivities.begin(), m_trackedActivities.end(), activityId);
|
||||
// if (it != m_trackedActivities.end())
|
||||
// {
|
||||
// m_trackedActivities.erase(it);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void PerkProgramManager::SendPerksProgramActivities()
|
||||
//{
|
||||
// WorldPackets::PerksProgram::PerksProgramActivityUpdate activity;
|
||||
//
|
||||
// activity.TimeUntilStart = GameTime::GetGameTime();
|
||||
// // activity.TimeUntilEnd = sWorld->GetNextPerksProgramReset();
|
||||
//
|
||||
// for (auto ac : sPerkProgramDataStore->GetActivities())
|
||||
// {
|
||||
// activity.ActivityIDs.push_back(ac.ActivityID);
|
||||
//
|
||||
// }
|
||||
// _session->SendPacket(activity.Write());
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,113 @@
|
||||
///*
|
||||
// * Copyright (C) WowCommunity Project
|
||||
// *
|
||||
// * This SourceCode is NOT free a software. Please hold everything Private
|
||||
// * and read our Terms
|
||||
// */
|
||||
//
|
||||
//#ifndef __TRINITY_PERKPROGRAMMGR_H
|
||||
//#define __TRINITY_PERKPROGRAMMGR_H
|
||||
//
|
||||
//#include "Common.h"
|
||||
//#include "PerksProgramPacketsCommon.h"
|
||||
//#include "PerkProgramData.h"
|
||||
//
|
||||
//class WorldSession;
|
||||
//class Player;
|
||||
//class Creature;
|
||||
//
|
||||
//#define PERKS_PROGRAM_CURRENCY 2032
|
||||
//
|
||||
//namespace PerkPrograms
|
||||
//{
|
||||
// enum PerksVendorCategoryType : uint32
|
||||
// {
|
||||
// PERKS_VENDOR_CATEGORY_NONE = 0,
|
||||
// PERKS_VENDOR_CATEGORY_MOUNTS = 1,
|
||||
// PERKS_VENDOR_CATEGORY_PETS = 2,
|
||||
// PERKS_VENDOR_CATEGORY_TOYS = 3,
|
||||
// PERKS_VENDOR_CATEGORY_TRANSMOG = 4,
|
||||
// PERKS_VENDOR_CATEGORY_TRANSMOG_SETS = 5,
|
||||
// PERKS_VENDOR_CATEGORY_CONSUMABLES = 6,
|
||||
// };
|
||||
//
|
||||
// enum ItemCollectionType : uint32
|
||||
// {
|
||||
// ITEM_COLLECTION_NONE = 0,
|
||||
// ITEM_COLLECTION_APPEARANCE = 1,
|
||||
// ITEM_COLLECTION_MOUNT = 2,
|
||||
// ITEM_COLLECTION_TOY = 3,
|
||||
// ITEM_COLLECTION_PET = 4,
|
||||
// ITEM_COLLECTION_HEIRLOOM = 5,
|
||||
// ITEM_COLLECTION_ILLUSION = 6,
|
||||
// ITEM_COLLECTION_ENSEMBLE = 7,
|
||||
// };
|
||||
//
|
||||
// enum NpcVendorAndCameras : uint32
|
||||
// {
|
||||
// CAMERA_HORDE = 183978,
|
||||
// CAMERA_ALLIANCE = 1,
|
||||
// VENDOR_HORDE = 185473,
|
||||
// VENDOR_ALLIANCE = 3,
|
||||
// };
|
||||
//
|
||||
// enum ResultType : uint32
|
||||
// {
|
||||
// RESULT_NONE = 0,
|
||||
// RESULT_BUY_ITEM = 2,
|
||||
// RESULT_AVAILABLE_ITEMS = 5,
|
||||
// RESULT_PURCHASE_CART = 6,
|
||||
// RESULT_REFUND_SUCCESS = 7,
|
||||
// RESULT_ERROR = 10,
|
||||
// RESULT_CURRENCY_REFRESH = 11,
|
||||
// RESULT_FROZEN_ITEM = 12,
|
||||
// RESULT_ACTIVITY_UPDATE = 13,
|
||||
// };
|
||||
//
|
||||
//}
|
||||
//
|
||||
//class TC_GAME_API PerkProgramManager
|
||||
//{
|
||||
//
|
||||
//public:
|
||||
// explicit PerkProgramManager(WorldSession* session);
|
||||
// ~PerkProgramManager();
|
||||
//
|
||||
// void SendVendorItems(Creature* vendor, std::vector<uint32> purchasedItems);
|
||||
// void BuyItem(uint32 itemId, ObjectGuid vendor);
|
||||
// bool IsAccountWideItem(uint32 item);
|
||||
//
|
||||
// void SetCurrencyAmount(uint32 amount) { m_currencyAmount = amount; }
|
||||
// uint32 GetCurrencyAmount() { return m_currencyAmount; }
|
||||
//
|
||||
// void SendPerksProgramActivities();
|
||||
// void SendPerksProgramStatus();
|
||||
// void SendPendingRewards();
|
||||
// void SetFrozenItem(int32 itemId, bool clear);
|
||||
// void RefundItem(int32 itemId);
|
||||
// void CartCheckout(std::vector<uint32> const& itemIds);
|
||||
// void AddTrackedActivity(uint32 activityId);
|
||||
// void RemoveTrackedActivity(uint32 activityId);
|
||||
//
|
||||
//private:
|
||||
// void GrantItem(PerkProgramData::PerkVendorItem const* vendorItem);
|
||||
// void RemoveGrantedItem(PerkProgramData::PerkVendorItem const* vendorItem);
|
||||
// bool IsItemAlreadyOwned(PerkProgramData::PerkVendorItem const* vendorItem);
|
||||
// void SendBuyItemResult(int32 itemId);
|
||||
// void SendRefundSuccess(int32 itemId);
|
||||
// void SendCartCheckoutSuccess();
|
||||
// void SendCurrencyRefresh();
|
||||
// void SendPerksProgramError(uint32 errorCode);
|
||||
// void RecordPurchase(uint32 itemId, time_t purchaseTime);
|
||||
//
|
||||
// WorldSession* _session;
|
||||
// Player* m_player;
|
||||
// uint32 m_currencyAmount;
|
||||
// std::vector<PerkProgramData::PerkVendorItem> m_frozenItems;
|
||||
// std::vector<std::pair<uint32, time_t>> m_recentPurchases;
|
||||
// std::vector<uint32> m_trackedActivities;
|
||||
//
|
||||
// static constexpr uint32 REFUND_WINDOW_SECONDS = 2 * 60 * 60;
|
||||
//};
|
||||
//
|
||||
//#endif
|
||||
@@ -2826,6 +2826,28 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
target->SetDriveCapabilityID(mountCapability->DriveCapabilityID, false);
|
||||
target->CastSpell(target, mountCapability->ModSpellAuraID, this);
|
||||
}
|
||||
|
||||
// Private server: always enable flying for players with riding skills
|
||||
if (Player* player = target->ToPlayer())
|
||||
{
|
||||
if (player->HasSpell(90265) || player->HasSpell(34091) || player->HasSpell(34090))
|
||||
{
|
||||
target->SetCanFly(true);
|
||||
if (player->HasAura(404468)) // Steady Flight mode
|
||||
{
|
||||
target->SetCanAdvFly(false);
|
||||
}
|
||||
else // Skyriding mode (default)
|
||||
{
|
||||
target->SetCanAdvFly(true);
|
||||
target->SetCanDoubleJump(true);
|
||||
target->SetFlightCapabilityID(1, true);
|
||||
// Cast Vigor aura - required by CasterAuraSpell check for active abilities
|
||||
if (!player->HasAura(372773))
|
||||
player->CastSpell(player, 372773, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2848,8 +2870,13 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(GetAmount()))
|
||||
target->RemoveAurasDueToSpell(mountCapability->ModSpellAuraID, target->GetGUID());
|
||||
|
||||
// Clear all flight flags on dismount
|
||||
target->SetCanFly(false);
|
||||
target->SetCanAdvFly(false);
|
||||
target->SetCanDoubleJump(false);
|
||||
target->SetFlightCapabilityID(0, true);
|
||||
target->SetDriveCapabilityID(0, true);
|
||||
// Remove Vigor aura on dismount
|
||||
target->RemoveAura(372773);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3353,6 +3353,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
|
||||
const_cast<SpellInfo&>(spellInfo).AttributesCu |= SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED;
|
||||
}
|
||||
|
||||
// Dragonriding flight style auras - applied fresh on login, do not save
|
||||
for (uint32 spellId : { 404464u, 404468u, 372773u })
|
||||
for (SpellInfo const& spellInfo : _GetSpellInfo(spellId))
|
||||
const_cast<SpellInfo&>(spellInfo).AttributesCu |= SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED;
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo custom attributes in {} ms", GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
@@ -5176,12 +5181,6 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->AttributesEx4 |= SPELL_ATTR4_AURA_IS_BUFF;
|
||||
});
|
||||
|
||||
// TODO: temporary, remove with dragonriding
|
||||
ApplySpellFix({ 404468 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesCu |= SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED;
|
||||
});
|
||||
|
||||
// Sigil of Flame
|
||||
ApplySpellFix({ 204598 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
|
||||
@@ -34,13 +34,58 @@ enum DragonridingSpells
|
||||
SPELL_DRAGONRIDING_WHIRLING_SURGE = 361584,
|
||||
SPELL_DRAGONRIDING_LAUNCH_BOOST = 392752,
|
||||
SPELL_DRAGONRIDING_LIFT_OFF = 374763,
|
||||
SPELL_STEADY_FLIGHT = 404468,
|
||||
SPELL_SKYRIDING = 404464,
|
||||
SPELL_SKYRIDING_BASICS = 376777,
|
||||
SPELL_SWITCH_FLIGHT_STYLE = 436854,
|
||||
SPELL_VIGOR = 372773,
|
||||
SPELL_LIFT_OFF_3 = 386451,
|
||||
};
|
||||
|
||||
// Blizzlike impulse values from sniff data:
|
||||
// Launch Boost: (0, 0, 45.0) ? pure upward, magnitude 45.0, sent on spell hit (before periodic aura)
|
||||
// Whirling Surge: magnitude 5.0 per tick ? facing+pitch oriented, 5-6 ticks, periodic aura (3s duration)
|
||||
// Skyward Ascent: horizontal 12.25 + Z 49.0 ? magnitude ~50.51, single impulse
|
||||
// Surge Forward: magnitude 30.0 ? facing+pitch oriented, single burst (estimated; not directly observable in sniff)
|
||||
// Spell 436854 - Switch Flight Style
|
||||
class spell_switch_flight : public SpellScript
|
||||
{
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
bool hadSkyriding = caster->HasAura(SPELL_SKYRIDING);
|
||||
|
||||
caster->RemoveAura(SPELL_SKYRIDING);
|
||||
caster->RemoveAura(SPELL_STEADY_FLIGHT);
|
||||
|
||||
if (hadSkyriding)
|
||||
{
|
||||
caster->CastSpell(caster, SPELL_STEADY_FLIGHT, true);
|
||||
caster->RemoveAura(SPELL_VIGOR);
|
||||
if (caster->IsMounted())
|
||||
{
|
||||
caster->SetCanAdvFly(false);
|
||||
caster->SetCanDoubleJump(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
caster->CastSpell(caster, SPELL_SKYRIDING, true);
|
||||
if (!caster->HasAura(SPELL_VIGOR))
|
||||
caster->CastSpell(caster, SPELL_VIGOR, true);
|
||||
if (caster->IsMounted())
|
||||
{
|
||||
caster->SetCanAdvFly(true);
|
||||
caster->SetCanDoubleJump(true);
|
||||
caster->SetFlightCapabilityID(1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_switch_flight::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
static void SendFacingImpulse(Unit* caster, float speed)
|
||||
{
|
||||
@@ -188,6 +233,7 @@ class spell_dragonriding_launch_boost_aura : public AuraScript
|
||||
|
||||
void AddSC_dragonriding_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_switch_flight);
|
||||
RegisterSpellAndAuraScriptPair(spell_dragonriding_whirling_surge, spell_dragonriding_whirling_surge_aura);
|
||||
RegisterSpellAndAuraScriptPair(spell_dragonriding_launch_boost, spell_dragonriding_launch_boost_aura);
|
||||
RegisterSpellScript(spell_dragonriding_surge_forward);
|
||||
|
||||
Reference in New Issue
Block a user