Skip to content

Instantly share code, notes, and snippets.

@devovh
Forked from Rochet2/!ItemEnchantVisuals.md
Created June 19, 2014 01:08
Show Gist options
  • Save devovh/5413a997d5df39a4f743 to your computer and use it in GitHub Desktop.
Save devovh/5413a997d5df39a4f743 to your computer and use it in GitHub Desktop.

####About When you loot a weapon, there is a 25% chance it will have a random visual effect. The chance can be edited. If you enchant the weapon, the visual effect is lost and replaced by the enchant visual. In total there are 38 different visuals. Note that not all items can have an enchant visual.
http://rochet2.github.io/?page=Item_Enchant_Visuals

####Installation Download gist
Apply the the diff with git bash using command git apply ItemEnchantVisuals.diff
Supported TC version: https://github.com/TrinityCore/TrinityCore/commit/e4c57d839d83a7e735d4b651827e2dca1ddc68cd

####Usage Kill NPC, loot weapon, hope you get an enchant visual.

diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index eb9392f..edb7fa7 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -12451,12 +12451,13 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem)
}
}
+extern uint32 GetItemEnchantVisual(Player* player, Item* item);
void Player::SetVisibleItemSlot(uint8 slot, Item* pItem)
{
if (pItem)
{
SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetEntry());
- SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 0, pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
+ SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 0, GetItemEnchantVisual(this, pItem));
SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 1, pItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT));
}
else
@@ -24731,6 +24732,7 @@ void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore cons
}
}
+extern void SetRandomEnchantVisual(Player* player, Item* item);
void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
{
QuestItem* qitem = NULL;
@@ -24806,6 +24808,7 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
if (loot->containerID > 0)
loot->DeleteLootItemFromContainerItemDB(item->itemid);
+ SetRandomEnchantVisual(this, newitem);
}
else
SendEquipError(msg, NULL, NULL, item->itemid);
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index f3a1803..a4e34a4 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -397,6 +397,7 @@ void WorldSession::DoLootRelease(uint64 lguid)
loot->RemoveLooter(player->GetGUID());
}
+extern void SetRandomEnchantVisual(Player* player, Item* item);
void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
{
uint8 slotid;
@@ -479,6 +480,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count);
target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count);
+ SetRandomEnchantVisual(target, newitem);
// mark as looted
item.count=0;
item.is_looted=true;
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 7365d59..36fee4a 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -1437,6 +1437,7 @@ void AddBattlegroundScripts()
#ifdef SCRIPTS
/* This is where custom scripts' loading functions should be declared. */
+void AddSC_item_enchant_visuals();
#endif
void AddCustomScripts()
@@ -1444,5 +1445,6 @@ void AddCustomScripts()
#ifdef SCRIPTS
/* This is where custom scripts should be added. */
+ AddSC_item_enchant_visuals();
#endif
}
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
index 78db719..cb72081 100644
--- a/src/server/scripts/Custom/CMakeLists.txt
+++ b/src/server/scripts/Custom/CMakeLists.txt
@@ -10,6 +10,7 @@
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
+ Custom/enchant_visuals.cpp
)
message(" -> Prepared: Custom")
diff --git a/src/server/scripts/Custom/enchant_visuals.cpp b/src/server/scripts/Custom/enchant_visuals.cpp
new file mode 100644
index 0000000..7bca09d
--- /dev/null
+++ b/src/server/scripts/Custom/enchant_visuals.cpp
@@ -0,0 +1,129 @@
+/*
+Author: Rochet2
+Source: http://emudevs.com/showthread.php/53-Lua-Enchant-visual-system-and-gossip
+Converted to C++
+
+About:
+All weapons looted have a 25% chance to have a random enchant *visual*
+This is purely visual fun and the visual will be replaced when the weapon is enchanted.
+
+This script is 100% automatic. Just add it to your source.
+*/
+
+#define CHANCE 0.25
+
+// Do not edit anything below
+
+#include "ScriptPCH.h"
+
+static const uint32 ItemEnchants[] = {3789, 3854, 3273, 3225, 3870, 1899, 2674, 2675, 2671, 2672, 3365, 2673, 2343, 425, 3855, 1894, 1103, 1898, 3345, 1743, 3093, 1900, 3846, 1606, 283, 1, 3265, 2, 3, 3266, 1903, 13, 26, 7, 803, 1896, 2666, 25};
+static const uint32 ItemEnchants_size = sizeof(ItemEnchants)/sizeof(*ItemEnchants);
+typedef UNORDERED_MAP<uint32, uint32> EnchantStoreType;
+typedef UNORDERED_MAP<uint32, EnchantStoreType> ItemStoreType;
+static ItemStoreType ItemStore;
+
+uint32 GetItemEnchantVisual(Player* player, Item* item)
+{
+ if (!player || !item)
+ return 0;
+
+ uint32 iguid = item->GetGUIDLow();
+ EnchantStoreType* EnchantStore = NULL;
+ ItemStoreType::iterator it = ItemStore.find(player->GetGUIDLow());
+ if (it != ItemStore.end())
+ EnchantStore = &it->second;
+ bool hasVisual = (EnchantStore && EnchantStore->find(iguid) != EnchantStore->end());
+ uint32 enchant = item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT);
+
+ if (enchant)
+ {
+ if (hasVisual)
+ {
+ CharacterDatabase.PExecute("DELETE FROM custom_item_enchant_visuals WHERE iguid = %u", iguid);
+ EnchantStore->erase(iguid);
+ player->SaveToDB();
+ }
+ return enchant;
+ }
+ if (hasVisual)
+ return (*EnchantStore)[iguid];
+ return 0;
+}
+
+void SetRandomEnchantVisual(Player* player, Item* item)
+{
+ if (!player || !item)
+ return;
+ const ItemTemplate* temp = item->GetTemplate();
+ if (temp->Class != ITEM_CLASS_WEAPON)
+ return;
+ if (temp->SubClass == ITEM_SUBCLASS_WEAPON_BOW ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_GUN ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_obsolete ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_FIST ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_THROWN ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_SPEAR ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_WAND ||
+ temp->SubClass == ITEM_SUBCLASS_WEAPON_FISHING_POLE)
+ return;
+ if (rand_norm() >= CHANCE)
+ return;
+
+ uint32 enchant = ItemEnchants[urand(0, ItemEnchants_size)];
+ uint32 iguid = item->GetGUIDLow();
+ CharacterDatabase.PExecute("REPLACE INTO custom_item_enchant_visuals (iguid, display) VALUES (%u, %u)", iguid, enchant);
+ ItemStore[player->GetGUIDLow()][iguid] = enchant;
+ player->SaveToDB();
+ player->SetVisibleItemSlot(EQUIPMENT_SLOT_MAINHAND, player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND));
+ player->SetVisibleItemSlot(EQUIPMENT_SLOT_OFFHAND, player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND));
+}
+
+class item_enchant_visuals : public PlayerScript
+{
+public:
+ item_enchant_visuals() : PlayerScript("item_enchant_visuals")
+ {
+ const char* sql =
+ "CREATE TABLE IF NOT EXISTS `custom_item_enchant_visuals` ("
+ " `iguid` INT(10) UNSIGNED NOT NULL COMMENT 'item DB guid',"
+ " `display` INT(10) UNSIGNED NOT NULL COMMENT 'enchantID',"
+ " PRIMARY KEY (`iguid`)"
+ ")"
+ "COMMENT='stores the enchant IDs for the visuals'"
+ "COLLATE='latin1_swedish_ci'"
+ "ENGINE=InnoDB;";
+ CharacterDatabase.DirectExecute(sql);
+ CharacterDatabase.DirectExecute("DELETE FROM custom_item_enchant_visuals WHERE NOT EXISTS(SELECT 1 FROM item_instance WHERE custom_item_enchant_visuals.iguid = item_instance.guid)");
+ }
+
+ void OnLogin(Player* player)
+ {
+ QueryResult result = CharacterDatabase.PQuery("SELECT iguid, display FROM custom_item_enchant_visuals WHERE iguid IN(SELECT guid FROM item_instance WHERE owner_guid = %u)", player->GetGUIDLow());
+ if (result)
+ {
+ uint32 pguid = player->GetGUIDLow();
+ do
+ {
+ uint32 iguid = result->Fetch()[0].GetUInt32();
+ uint32 display = result->Fetch()[1].GetUInt32();
+ ItemStore[pguid][iguid] = display;
+ }
+ while (result->NextRow());
+
+ player->SetVisibleItemSlot(EQUIPMENT_SLOT_MAINHAND, player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND));
+ player->SetVisibleItemSlot(EQUIPMENT_SLOT_OFFHAND, player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND));
+ }
+ }
+
+ void OnLogout(Player* player)
+ {
+ ItemStore.erase(player->GetGUIDLow());
+ }
+};
+
+void AddSC_item_enchant_visuals()
+{
+ new item_enchant_visuals;
+}
+#undef CHANCE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment