@@ -87,6 +87,63 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemPrototype const * item)
8787 return ITEM_USAGE_NONE;
8888}
8989
90+ static bool IsClothMaterial (uint32 itemId, uint32 botSkill)
91+ {
92+ static std::map<uint32, uint32> firstAidMaterials;
93+ static bool initialized = false ;
94+ if (!initialized)
95+ {
96+ initialized = true ;
97+ for (uint32 i = 0 ; i < sSkillLineAbilityStore .GetNumRows (); ++i)
98+ {
99+ SkillLineAbilityEntry const * entry = sSkillLineAbilityStore .LookupEntry (i);
100+ if (!entry || entry->skillId != SKILL_FIRST_AID)
101+ continue ;
102+ SpellEntry const * spell = sSpellStore .LookupEntry (entry->spellId );
103+ if (!spell)
104+ continue ;
105+ for (int r = 0 ; r < MAX_SPELL_REAGENTS; ++r)
106+ {
107+ if (spell->Reagent [r] <= 0 )
108+ continue ;
109+ uint32 reagentId = (uint32)spell->Reagent [r];
110+ uint32 greyAt = entry->max_value ;
111+ auto it = firstAidMaterials.find (reagentId);
112+ if (it == firstAidMaterials.end () || greyAt > it->second )
113+ firstAidMaterials[reagentId] = greyAt;
114+ }
115+ }
116+ }
117+ auto it = firstAidMaterials.find (itemId);
118+ if (it == firstAidMaterials.end ())
119+ return false ;
120+ return it->second == 0 || botSkill < it->second ;
121+ }
122+
123+ static bool IsSkillMaterial (uint32 skillId, uint32 itemId)
124+ {
125+ static std::map<uint32,std::set<uint32>> skillMaterials;
126+ if (skillMaterials[skillId].size ()==0 )
127+ {
128+ for (uint32 i = 0 ; i < sSkillLineAbilityStore .GetNumRows (); ++i)
129+ {
130+ SkillLineAbilityEntry const * entry = sSkillLineAbilityStore .LookupEntry (i);
131+ if (!entry || entry->skillId != skillId)
132+ continue ;
133+ SpellEntry const * spell = sSpellStore .LookupEntry (entry->spellId );
134+ if (!spell)
135+ continue ;
136+ for (int r = 0 ; r < MAX_SPELL_REAGENTS; ++r)
137+ {
138+ if (spell->Reagent [r] <= 0 )
139+ continue ;
140+ skillMaterials[skillId].insert ((uint32)spell->Reagent [r]);
141+ }
142+ }
143+ }
144+ return skillMaterials[skillId].count (itemId) > 0 ;
145+ }
146+
90147bool ItemUsageValue::IsItemUsefulForSkill (ItemPrototype const * proto)
91148{
92149 switch (proto->Class )
@@ -99,6 +156,24 @@ bool ItemUsageValue::IsItemUsefulForSkill(ItemPrototype const * proto)
99156 case ITEM_SUBCLASS_DEVICES:
100157 return bot->HasSkill (SKILL_ENGINEERING);
101158 }
159+ if (bot->HasSkill (SKILL_FIRST_AID) && IsClothMaterial (proto->ItemId , bot->GetSkillValue (SKILL_FIRST_AID)))
160+ return true ;
161+ if (bot->HasSkill (SKILL_HERBALISM) && IsSkillMaterial (SKILL_ALCHEMY, proto->ItemId ))
162+ return true ;
163+ if (bot->HasSkill (SKILL_ALCHEMY) && IsSkillMaterial (SKILL_ALCHEMY, proto->ItemId ))
164+ return true ;
165+ if (bot->HasSkill (SKILL_TAILORING) && IsSkillMaterial (SKILL_TAILORING, proto->ItemId ))
166+ return true ;
167+ if (bot->HasSkill (SKILL_SKINNING) && IsSkillMaterial (SKILL_LEATHERWORKING, proto->ItemId ))
168+ return true ;
169+ if (bot->HasSkill (SKILL_LEATHERWORKING) && IsSkillMaterial (SKILL_LEATHERWORKING, proto->ItemId ))
170+ return true ;
171+ if (bot->HasSkill (SKILL_MINING) && IsSkillMaterial (SKILL_MINING, proto->ItemId ))
172+ return true ;
173+ if (bot->HasSkill (SKILL_BLACKSMITHING) && IsSkillMaterial (SKILL_BLACKSMITHING, proto->ItemId ))
174+ return true ;
175+ if (bot->HasSkill (SKILL_ENGINEERING) && IsSkillMaterial (SKILL_ENGINEERING, proto->ItemId ))
176+ return true ;
102177 break ;
103178 case ITEM_CLASS_RECIPE:
104179 {
0 commit comments