TrinityCore
Loading...
Searching...
No Matches
npc_professions.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19SDName: Npc_Professions
20SD%Complete: 100
21SDComment: Provides learn/unlearn/relearn-options for professions.
22SDCategory: NPCs/GOBs
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "GameObjectAI.h"
27#include "Item.h"
28#include "Log.h"
29#include "Player.h"
30#include "ScriptedCreature.h"
31#include "ScriptedGossip.h"
32#include "SpellInfo.h"
33#include "SpellMgr.h"
34#include "WorldSession.h"
35
36/*
37A few notes for future developement:
38- It's possible blacksmithing still require some tweaks and adjustments due to the way we _have_ to use reputation.
39*/
40
41/*###
42# generic defines
43###*/
44
45#define GOSSIP_SENDER_LEARN 50
46#define GOSSIP_SENDER_UNLEARN 51
47#define GOSSIP_SENDER_CHECK 52
48
49/*###
50# gossip item and box texts
51###*/
52
54{
55 GOSSIP_SPELLFIRE = 8531, // Gidge Spellweaver
56 GOSSIP_MOONCLOTH = 8530, // Nasmara Moonsong
57 GOSSIP_SHADOWEAVE = 8532, // Andrion Darkspinner
58 GOSSIP_DRAGON1 = 3067, // Peter Galen
59 GOSSIP_DRAGON2 = 3068, // Thorkaf Dragoneye
60 GOSSIP_ELEMENTAL1 = 3070, // Sarah Tanner
61 GOSSIP_ELEMENTAL2 = 3069, // Brumn Winterhoof
62 GOSSIP_TRIBAL1 = 3072, // Caryssia Moonhunter
63 GOSSIP_TRIBAL2 = 3071, // Se'Jib
64 GOSSIP_SMITHOMNI1 = 3182, // Myolor Sunderfury
65 GOSSIP_SMITHOMNI2 = 3187, // Krathok Moltenfist
66 GOSSIP_WEAPON1 = 3201, // Ironus Coldsteel
67 GOSSIP_WEAPON2 = 3202, // Borgosh Corebender
68 GOSSIP_ARMOR1 = 597, // Grumnus Steelshaper
69 GOSSIP_ARMOR2 = 3203, // Okothos Ironrager
70 GOSSIP_HAMMER = 6090, // Lilith the Lithe
71 GOSSIP_AXE = 6089, // Kilram
72 GOSSIP_SWORD = 6091, // Seril Scourgebane
73 GOSSIP_TRANSMUTE = 8542, // Zarevhi
74 GOSSIP_ELIXIR = 8540, // Lorokeem
75 GOSSIP_POTION = 7571, // Lauranna Thar'well
76 GOSSIP_ZAP = 6092, // Zap Farflinger
77 GOSSIP_JHORDY = 6094, // Jhordy Lapforge
78 GOSSIP_KABLAM = 8308, // Kablamm Farflinger
79 GOSSIP_SMILES = 8306, // Smiles O'Byron
82};
83
84/*###
85# spells defines
86###*/
88{
89 S_WEAPON = 9787,
90 S_ARMOR = 9788,
91 S_HAMMER = 17040,
92 S_AXE = 17041,
93 S_SWORD = 17039,
94
98 S_LEARN_AXE = 39098,
100
106
107 S_REP_ARMOR = 17451,
109
113 REP_AXE = 570,
115
116 S_DRAGON = 10656,
117 S_ELEMENTAL = 10658,
118 S_TRIBAL = 10660,
119
123
127
128 S_GOBLIN = 20222,
129 S_GNOMISH = 20219,
130
133
136
137 S_SPELLFIRE = 26797,
138 S_MOONCLOTH = 26798,
140
144
148
149 S_TRANSMUTE = 28672,
150 S_ELIXIR = 28677,
151 S_POTION = 28675,
152
156
160};
161
162/*###
163# specialization trainers
164###*/
166{
167 /* Blacksmithing */
168 N_TRAINER_SMITHOMNI1 = 11145, // Myolor Sunderfury
169 N_TRAINER_SMITHOMNI2 = 11176, // Krathok Moltenfist
170 N_TRAINER_WEAPON1 = 11146, // Ironus Coldsteel
171 N_TRAINER_WEAPON2 = 11178, // Borgosh Corebender
172 N_TRAINER_ARMOR1 = 5164, // Grumnus Steelshaper
173 N_TRAINER_ARMOR2 = 11177, // Okothos Ironrager
174 N_TRAINER_HAMMER = 11191, // Lilith the Lithe
175 N_TRAINER_AXE = 11192, // Kilram
176 N_TRAINER_SWORD = 11193, // Seril Scourgebane
177
178 /* Leatherworking */
179 N_TRAINER_DRAGON1 = 7866, // Peter Galen
180 N_TRAINER_DRAGON2 = 7867, // Thorkaf Dragoneye
181 N_TRAINER_ELEMENTAL1 = 7868, // Sarah Tanner
182 N_TRAINER_ELEMENTAL2 = 7869, // Brumn Winterhoof
183 N_TRAINER_TRIBAL1 = 7870, // Caryssia Moonhunter
184 N_TRAINER_TRIBAL2 = 7871, // Se'Jib
185
186 /* Tailoring */
187 N_TRAINER_SPELLFIRE = 22213, // Gidge Spellweaver
188 N_TRAINER_MOONCLOTH = 22208, // Nasmara Moonsong
189 N_TRAINER_SHADOWEAVE = 22212, // Andrion Darkspinner
190
191 /* Alchemy */
192 N_TRAINER_TRANSMUTE = 22427, // Zarevhi
193 N_TRAINER_ELIXIR = 19052, // Lorokeem
194 N_TRAINER_POTION = 17909, // Lauranna Thar'well
195
196};
197
204
205/*###
206# formulas to calculate unlearning cost
207###*/
208
209int32 DoLearnCost(Player* /*player*/) //tailor
210{
211 return 200000;
212}
213
214int32 DoHighUnlearnCost(Player* /*player*/) //tailor
215{
216 return 1500000;
217}
218
219int32 DoMedUnlearnCost(Player* player) //blacksmith, leatherwork
220{
221 uint8 level = player->GetLevel();
222 if (level < 51)
223 return 250000;
224 else if (level < 66)
225 return 500000;
226 else
227 return 1000000;
228}
229
230int32 DoLowUnlearnCost(Player* player) //blacksmith
231{
232 uint8 level = player->GetLevel();
233 if (level < 66)
234 return 50000;
235 else
236 return 100000;
237}
238
239void ProcessCastaction(Player* player, Creature* creature, uint32 spellId, uint32 triggeredSpellId, int32 cost)
240{
241 if (!(spellId && player->HasSpell(spellId)) && player->HasEnoughMoney(cost))
242 {
243 player->CastSpell(player, triggeredSpellId, true);
244 player->ModifyMoney(-cost);
245 }
246 else
247 player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, 0, 0);
248 CloseGossipMenuFor(player);
249}
250
251/*###
252# unlearning related profession spells
253###*/
254
255bool EquippedOk(Player* player, uint32 spellId)
256{
257 SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellId);
258 if (!spell)
259 return false;
260
261 for (SpellEffectInfo const& spellEffectInfo : spell->GetEffects())
262 {
263 uint32 reqSpell = spellEffectInfo.TriggerSpell;
264 if (!reqSpell)
265 continue;
266
267 Item* item = nullptr;
269 {
270 item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, j);
271 if (item && item->GetTemplate()->RequiredSpell == reqSpell)
272 {
273 //player has item equipped that require specialty. Not allow to unlearn, player has to unequip first
274 TC_LOG_DEBUG("scripts", "player attempt to unlearn spell {}, but item {} is equipped.", reqSpell, item->GetEntry());
275 return false;
276 }
277 }
278 }
279 return true;
280}
281
283{
284 switch (type)
285 {
286 case S_UNLEARN_WEAPON: // S_UNLEARN_WEAPON
287 player->RemoveSpell(36125); // Light Earthforged Blade
288 player->RemoveSpell(36128); // Light Emberforged Hammer
289 player->RemoveSpell(36126); // Light Skyforged Axe
290 break;
291 case S_UNLEARN_ARMOR: // S_UNLEARN_ARMOR
292 player->RemoveSpell(36122); // Earthforged Leggings
293 player->RemoveSpell(36129); // Heavy Earthforged Breastplate
294 player->RemoveSpell(36130); // Stormforged Hauberk
295 player->RemoveSpell(34533); // Breastplate of Kings
296 player->RemoveSpell(34529); // Nether Chain Shirt
297 player->RemoveSpell(34534); // Bulwark of Kings
298 player->RemoveSpell(36257); // Bulwark of the Ancient Kings
299 player->RemoveSpell(36256); // Embrace of the Twisting Nether
300 player->RemoveSpell(34530); // Twisting Nether Chain Shirt
301 player->RemoveSpell(36124); // Windforged Leggings
302 break;
303 case S_UNLEARN_HAMMER: // S_UNLEARN_HAMMER
304 player->RemoveSpell(36262); // Dragonstrike
305 player->RemoveSpell(34546); // Dragonmaw
306 player->RemoveSpell(34545); // Drakefist Hammer
307 player->RemoveSpell(36136); // Lavaforged Warhammer
308 player->RemoveSpell(34547); // Thunder
309 player->RemoveSpell(34567); // Deep Thunder
310 player->RemoveSpell(36263); // Stormherald
311 player->RemoveSpell(36137); // Great Earthforged Hammer
312 break;
313 case S_UNLEARN_AXE: // S_UNLEARN_AXE
314 player->RemoveSpell(36260); // Wicked Edge of the Planes
315 player->RemoveSpell(34562); // Black Planar Edge
316 player->RemoveSpell(34541); // The Planar Edge
317 player->RemoveSpell(36134); // Stormforged Axe
318 player->RemoveSpell(36135); // Skyforged Great Axe
319 player->RemoveSpell(36261); // Bloodmoon
320 player->RemoveSpell(34543); // Lunar Crescent
321 player->RemoveSpell(34544); // Mooncleaver
322 break;
323 case S_UNLEARN_SWORD: // S_UNLEARN_SWORD
324 player->RemoveSpell(36258); // Blazefury
325 player->RemoveSpell(34537); // Blazeguard
326 player->RemoveSpell(34535); // Fireguard
327 player->RemoveSpell(36131); // Windforged Rapier
328 player->RemoveSpell(36133); // Stoneforged Claymore
329 player->RemoveSpell(34538); // Lionheart Blade
330 player->RemoveSpell(34540); // Lionheart Champion
331 player->RemoveSpell(36259); // Lionheart Executioner
332 break;
333 case S_UNLEARN_DRAGON: // S_UNLEARN_DRAGON
334 player->RemoveSpell(36076); // Dragonstrike Leggings
335 player->RemoveSpell(36079); // Golden Dragonstrike Breastplate
336 player->RemoveSpell(35576); // Ebon Netherscale Belt
337 player->RemoveSpell(35577); // Ebon Netherscale Bracers
338 player->RemoveSpell(35575); // Ebon Netherscale Breastplate
339 player->RemoveSpell(35582); // Netherstrike Belt
340 player->RemoveSpell(35584); // Netherstrike Bracers
341 player->RemoveSpell(35580); // Netherstrike Breastplate
342 break;
343 case S_UNLEARN_ELEMENTAL: // S_UNLEARN_ELEMENTAL
344 player->RemoveSpell(36074); // Blackstorm Leggings
345 player->RemoveSpell(36077); // Primalstorm Breastplate
346 player->RemoveSpell(35590); // Primalstrike Belt
347 player->RemoveSpell(35591); // Primalstrike Bracers
348 player->RemoveSpell(35589); // Primalstrike Vest
349 break;
350 case S_UNLEARN_TRIBAL: // S_UNLEARN_TRIBAL
351 player->RemoveSpell(35585); // Windhawk Hauberk
352 player->RemoveSpell(35587); // Windhawk Belt
353 player->RemoveSpell(35588); // Windhawk Bracers
354 player->RemoveSpell(36075); // Wildfeather Leggings
355 player->RemoveSpell(36078); // Living Crystal Breastplate
356 break;
357 case S_UNLEARN_GOBLIN: // S_UNLEARN_GOBLIN
358 player->RemoveSpell(30565); // Foreman's Enchanted Helmet
359 player->RemoveSpell(30566); // Foreman's Reinforced Helmet
360 player->RemoveSpell(30563); // Goblin Rocket Launcher
361 player->RemoveSpell(56514); // Global Thermal Sapper Charge
362 player->RemoveSpell(36954); // Dimensional Ripper - Area 52
363 player->RemoveSpell(23486); // Dimensional Ripper - Everlook
364 player->RemoveSpell(23078); // Goblin Jumper Cables XL
365 player->RemoveSpell(72952); // Shatter Rounds
366 break;
367 case S_UNLEARN_GNOMISH: // S_UNLEARN_GNOMISH
368 player->RemoveSpell(30575); // Gnomish Battle Goggles
369 player->RemoveSpell(30574); // Gnomish Power Goggles
370 player->RemoveSpell(56473); // Gnomish X-Ray Specs
371 player->RemoveSpell(30569); // Gnomish Poultryizer
372 player->RemoveSpell(30563); // Ultrasafe Transporter - Toshley's Station
373 player->RemoveSpell(23489); // Ultrasafe Transporter - Gadgetzan
374 player->RemoveSpell(23129); // World Enlarger
375 player->RemoveSpell(23096); // Gnomish Alarm-o-Bot
376 player->RemoveSpell(72953); // Iceblade Arrow
377 break;
378 case S_UNLEARN_SPELLFIRE: // S_UNLEARN_SPELLFIRE
379 player->RemoveSpell(26752); // Spellfire Belt
380 player->RemoveSpell(26753); // Spellfire Gloves
381 player->RemoveSpell(26754); // Spellfire Robe
382 break;
383 case S_UNLEARN_MOONCLOTH: // S_UNLEARN_MOONCLOTH
384 player->RemoveSpell(26760); // Primal Mooncloth Belt
385 player->RemoveSpell(26761); // Primal Mooncloth Shoulders
386 player->RemoveSpell(26762); // Primal Mooncloth Robe
387 break;
388 case S_UNLEARN_SHADOWEAVE: // S_UNLEARN_SHADOWEAVE
389 player->RemoveSpell(26756); // Frozen Shadoweave Shoulders
390 player->RemoveSpell(26757); // Frozen Shadoweave Boots
391 player->RemoveSpell(26758); // Frozen Shadoweave Robe
392 break;
393 }
394}
395
396void ProcessUnlearnAction(Player* player, Creature* creature, uint32 spellId, uint32 alternativeSpellId, int32 cost)
397{
398 if (EquippedOk(player, spellId))
399 {
400 if (player->HasEnoughMoney(cost))
401 {
402 player->CastSpell(player, spellId, true);
403 ProfessionUnlearnSpells(player, spellId);
404 player->ModifyMoney(-cost);
405 if (alternativeSpellId)
406 creature->CastSpell(player, alternativeSpellId, true);
407 }
408 else
409 player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, 0, 0);
410 }
411 else
412 player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, nullptr, nullptr);
413 CloseGossipMenuFor(player);
414}
415
416/*###
417# start menues blacksmith
418###*/
419
421{
422public:
423 npc_prof_blacksmith() : CreatureScript("npc_prof_blacksmith") { }
424
426 {
427 npc_prof_blacksmithAI(Creature* creature) : ScriptedAI(creature) { }
428
429 inline bool HasWeaponSub(Player* player)
430 {
431 return (player->HasSpell(S_HAMMER) || player->HasSpell(S_AXE) || player->HasSpell(S_SWORD));
432 }
433
434 bool OnGossipHello(Player* player) override
435 {
436 if (me->IsQuestGiver())
437 player->PrepareQuestMenu(me->GetGUID());
438
439 if (me->IsVendor())
441
442 if (me->IsTrainer())
444
445 uint32 creatureId = me->GetEntry();
446 //WEAPONSMITH & ARMORSMITH
447 if (player->GetBaseSkillValue(SKILL_BLACKSMITHING) >= 225)
448 {
449 uint8 level = player->GetLevel();
450 uint32 gossipOption = 0;
451 if (level < 66)
452 gossipOption = 1;
453 else
454 gossipOption = 2;
455 switch (creatureId)
456 {
458 if (!player->HasSpell(S_ARMOR) && !player->HasSpell(S_WEAPON) && player->GetReputationRank(REP_ARMOR) >= REP_FRIENDLY)
460 if (!player->HasSpell(S_WEAPON) && !player->HasSpell(S_ARMOR) && player->GetReputationRank(REP_WEAPON) >= REP_FRIENDLY)
462 break;
464 if (!player->HasSpell(S_ARMOR) && !player->HasSpell(S_WEAPON) && player->GetReputationRank(REP_ARMOR) >= REP_FRIENDLY)
466 if (!player->HasSpell(S_WEAPON) && !player->HasSpell(S_ARMOR) && player->GetReputationRank(REP_WEAPON) >= REP_FRIENDLY)
468 break;
470 if (player->HasSpell(S_WEAPON))
472 break;
474 if (player->HasSpell(S_WEAPON))
476 break;
477 case N_TRAINER_ARMOR1:
478 if (player->HasSpell(S_ARMOR))
480 break;
481 case N_TRAINER_ARMOR2:
482 if (player->HasSpell(S_ARMOR))
484 break;
485 }
486 }
487 //WEAPONSMITH SPEC
488 if (player->HasSpell(S_WEAPON) && player->GetLevel() > 49 && player->GetBaseSkillValue(SKILL_BLACKSMITHING) >= 250)
489 {
490 uint8 level = player->GetLevel();
491 uint32 gossipOption = 0;
492 if (level < 51)
493 gossipOption = 2;
494 else if (level < 66)
495 gossipOption = 3;
496 else
497 gossipOption = 4;
498 switch (creatureId)
499 {
500 case N_TRAINER_HAMMER:
501 if (!HasWeaponSub(player))
503 if (player->HasSpell(S_HAMMER))
505 break;
506 case N_TRAINER_AXE:
507 if (!HasWeaponSub(player))
509 if (player->HasSpell(S_AXE))
511 break;
512 case N_TRAINER_SWORD:
513 if (!HasWeaponSub(player))
515 if (player->HasSpell(S_SWORD))
517 break;
518 }
519 }
520
521 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
522 return true;
523 }
524
525 void SendActionMenu(Player* player, uint32 action)
526 {
527 switch (action)
528 {
530 player->GetSession()->SendListInventory(me->GetGUID());
531 break;
533 player->GetSession()->SendTrainerList(me);
534 break;
535 //Learn Armor/Weapon
536 case GOSSIP_ACTION_INFO_DEF + 1:
537 if (!player->HasSpell(S_ARMOR))
538 {
539 player->CastSpell(player, S_LEARN_ARMOR, true);
540 //_Creature->CastSpell(player, S_REP_ARMOR, true);
541 }
542 CloseGossipMenuFor(player);
543 break;
544 case GOSSIP_ACTION_INFO_DEF + 2:
545 if (!player->HasSpell(S_WEAPON))
546 {
547 player->CastSpell(player, S_LEARN_WEAPON, true);
548 //_Creature->CastSpell(player, S_REP_WEAPON, true);
549 }
550 CloseGossipMenuFor(player);
551 break;
552 //Unlearn Armor/Weapon
553 case GOSSIP_ACTION_INFO_DEF + 3:
554 if (HasWeaponSub(player))
555 {
556 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
557 }
558 else
560 break;
561 case GOSSIP_ACTION_INFO_DEF + 4:
563 break;
564 //Learn Hammer/Axe/Sword
565 case GOSSIP_ACTION_INFO_DEF + 5:
566 player->CastSpell(player, S_LEARN_HAMMER, true);
567 CloseGossipMenuFor(player);
568 break;
569 case GOSSIP_ACTION_INFO_DEF + 6:
570 player->CastSpell(player, S_LEARN_AXE, true);
571 CloseGossipMenuFor(player);
572 break;
573 case GOSSIP_ACTION_INFO_DEF + 7:
574 player->CastSpell(player, S_LEARN_SWORD, true);
575 CloseGossipMenuFor(player);
576 break;
577 //Unlearn Hammer/Axe/Sword
578 case GOSSIP_ACTION_INFO_DEF + 8:
580 break;
581 case GOSSIP_ACTION_INFO_DEF + 9:
583 break;
584 case GOSSIP_ACTION_INFO_DEF + 10:
586 break;
587 }
588 }
589
590 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
591 {
592 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
593 ClearGossipMenuFor(player);
594 SendActionMenu(player, action);
595 return true;
596 }
597 };
598
599 CreatureAI* GetAI(Creature* creature) const override
600 {
601 return new npc_prof_blacksmithAI(creature);
602 }
603};
604
605/*###
606# engineering trinkets
607###*/
608
626
628{
629public:
630 npc_engineering_tele_trinket() : CreatureScript("npc_engineering_tele_trinket") { }
631
633 {
635
636 bool CanLearn(Player* player, uint32 textId, uint32 altTextId, uint32 skillValue, uint32 reqSpellId, uint32 spellId, uint32& npcTextId)
637 {
638 bool res = false;
639 npcTextId = textId;
640 if (player->GetBaseSkillValue(SKILL_ENGINEERING) >= skillValue && player->HasSpell(reqSpellId))
641 {
642 if (!player->HasSpell(spellId))
643 res = true;
644 else
645 npcTextId = altTextId;
646 }
647 return res;
648 }
649
650 bool OnGossipHello(Player* player) override
651 {
652 uint32 npcTextId = 0;
653 uint32 gossipItem;
654 bool canLearn = false;
655
656 if (player->HasSkill(SKILL_ENGINEERING))
657 {
658 switch (me->GetEntry())
659 {
660 case NPC_ZAP:
661 canLearn = CanLearn(player, 6092, 0, 260, S_GOBLIN, SPELL_TO_EVERLOOK, npcTextId);
662 if (canLearn)
663 gossipItem = GOSSIP_ZAP;
664 break;
665 case NPC_JHORDY:
666 canLearn = CanLearn(player, 7251, 7252, 260, S_GNOMISH, SPELL_TO_GADGET, npcTextId);
667 if (canLearn)
668 gossipItem = GOSSIP_JHORDY;
669 break;
670 case NPC_KABLAM:
671 canLearn = CanLearn(player, 10365, 0, 350, S_GOBLIN, SPELL_TO_AREA52, npcTextId);
672 if (canLearn)
673 gossipItem = GOSSIP_KABLAM;
674 break;
675 case NPC_SMILES:
676 canLearn = CanLearn(player, 10363, 0, 350, S_GNOMISH, SPELL_TO_TOSHLEY, npcTextId);
677 if (canLearn)
678 gossipItem = GOSSIP_SMILES;
679 break;
680 }
681 }
682
683 if (canLearn)
684 AddGossipItemFor(player, gossipItem, 2, me->GetEntry(), GOSSIP_ACTION_INFO_DEF + 1);
685
686 SendGossipMenuFor(player, npcTextId ? npcTextId : player->GetGossipTextId(me), me->GetGUID());
687 return true;
688 }
689
690 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
691 {
692 uint32 const sender = player->PlayerTalkClass->GetGossipOptionSender(gossipListId);
693 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
694 ClearGossipMenuFor(player);
695 if (action == GOSSIP_ACTION_INFO_DEF + 1)
696 CloseGossipMenuFor(player);
697
698 if (sender != me->GetEntry())
699 return true;
700
701 switch (sender)
702 {
703 case NPC_ZAP:
704 player->CastSpell(player, SPELL_LEARN_TO_EVERLOOK, false);
705 break;
706 case NPC_JHORDY:
707 player->CastSpell(player, SPELL_LEARN_TO_GADGET, false);
708 break;
709 case NPC_KABLAM:
710 player->CastSpell(player, SPELL_LEARN_TO_AREA52, false);
711 break;
712 case NPC_SMILES:
713 player->CastSpell(player, SPELL_LEARN_TO_TOSHLEY, false);
714 break;
715 }
716
717 return true;
718 }
719 };
720
721 CreatureAI* GetAI(Creature* creature) const override
722 {
723 return new npc_engineering_tele_trinketAI(creature);
724 }
725};
726
727// Object ID - 177226
728// Book "Soothsaying for dummies"
744
746{
747 public:
748 go_soothsaying_for_dummies() : GameObjectScript("go_soothsaying_for_dummies") { }
749
751 {
753
754 bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
755 {
756 if (menuId != GOSSIP_ID)
757 return false;
758
759 switch (gossipListId)
760 {
762 ProcessUnlearnAction(player, nullptr, S_UNLEARN_GNOMISH, 0, 0); // cost is handled by gossip code
763 break;
765 ProcessUnlearnAction(player, nullptr, S_UNLEARN_GOBLIN, 0, 0);
766 break;
768 player->CastSpell(player, S_LEARN_GNOMISH, true);
769 break;
771 player->CastSpell(player, S_LEARN_GOBLIN, true);
772 break;
774 player->CastSpell(player, S_LEARN_DRAGON, true);
775 break;
777 player->CastSpell(player, S_LEARN_ELEMENTAL, true);
778 break;
780 player->CastSpell(player, S_LEARN_TRIBAL, true);
781 break;
782 default:
783 return false;
784 }
785
786 CloseGossipMenuFor(player);
787 return true; // prevent further processing
788 }
789 };
790
791 GameObjectAI* GetAI(GameObject* go) const override
792 {
793 return new go_soothsaying_for_dummiesAI(go);
794 }
795};
796
797/*###
798# start menues leatherworking
799###*/
800
802{
803public:
804 npc_prof_leather() : CreatureScript("npc_prof_leather") { }
805
807 {
808 npc_prof_leatherAI(Creature* creature) : ScriptedAI(creature) { }
809
810 bool OnGossipHello(Player* player) override
811 {
812 if (me->IsQuestGiver())
813 player->PrepareQuestMenu(me->GetGUID());
814
815 if (me->IsVendor())
817
818 if (me->IsTrainer())
820
821 if (player->HasSkill(SKILL_LEATHERWORKING) && player->GetBaseSkillValue(SKILL_LEATHERWORKING) >= 250 && player->GetLevel() > 49)
822 {
823 uint8 level = player->GetLevel();
824 uint32 gossipOption = 0;
825 if (level < 51)
826 gossipOption = 2;
827 else if (level < 66)
828 gossipOption = 3;
829 else
830 gossipOption = 4;
831 switch (me->GetEntry())
832 {
834 if (player->HasSpell(S_DRAGON))
836 break;
838 if (player->HasSpell(S_DRAGON))
840 break;
842 if (player->HasSpell(S_ELEMENTAL))
844 break;
846 if (player->HasSpell(S_ELEMENTAL))
848 break;
850 if (player->HasSpell(S_TRIBAL))
852 break;
854 if (player->HasSpell(S_TRIBAL))
856 break;
857 }
858 }
859
860 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
861 return true;
862 }
863
864 void SendActionMenu(Player* player, uint32 action)
865 {
866 switch (action)
867 {
869 player->GetSession()->SendListInventory(me->GetGUID());
870 break;
872 player->GetSession()->SendTrainerList(me);
873 break;
874 //Unlearn Leather
875 case GOSSIP_ACTION_INFO_DEF + 1:
877 break;
878 case GOSSIP_ACTION_INFO_DEF + 2:
880 break;
881 case GOSSIP_ACTION_INFO_DEF + 3:
883 break;
884 }
885 }
886
887 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
888 {
889 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
890 ClearGossipMenuFor(player);
891 SendActionMenu(player, action);
892 return true;
893 }
894 };
895
896 CreatureAI* GetAI(Creature* creature) const override
897 {
898 return new npc_prof_leatherAI(creature);
899 }
900};
901
902/*###
903# start menues tailoring
904###*/
905
907{
908public:
909 npc_prof_tailor() : CreatureScript("npc_prof_tailor") { }
910
912 {
913 npc_prof_tailorAI(Creature* creature) : ScriptedAI(creature) { }
914
915 inline bool HasTailorSpell(Player* player)
916 {
917 return (player->HasSpell(S_MOONCLOTH) || player->HasSpell(S_SHADOWEAVE) || player->HasSpell(S_SPELLFIRE));
918 }
919
920 bool OnGossipHello(Player* player) override
921 {
922 if (me->IsQuestGiver())
923 player->PrepareQuestMenu(me->GetGUID());
924
925 if (me->IsVendor())
927
928 if (me->IsTrainer())
930
931 //TAILORING SPEC
932 if (player->HasSkill(SKILL_TAILORING) && player->GetBaseSkillValue(SKILL_TAILORING) >= 350 && player->GetLevel() > 59)
933 {
934 if (player->GetQuestRewardStatus(10831) || player->GetQuestRewardStatus(10832) || player->GetQuestRewardStatus(10833))
935 {
936 switch (me->GetEntry())
937 {
939 if (!HasTailorSpell(player))
941 if (player->HasSpell(S_SPELLFIRE))
943 break;
945 if (!HasTailorSpell(player))
947 if (player->HasSpell(S_MOONCLOTH))
949 break;
951 if (!HasTailorSpell(player))
953 if (player->HasSpell(S_SHADOWEAVE))
955 break;
956 }
957 }
958 }
959
960 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
961 return true;
962 }
963
964 void SendActionMenu(Player* player, uint32 action)
965 {
966 switch (action)
967 {
969 player->GetSession()->SendListInventory(me->GetGUID());
970 break;
972 player->GetSession()->SendTrainerList(me);
973 break;
974 //Learn Tailor
975 case GOSSIP_ACTION_INFO_DEF + 1:
977 break;
978 case GOSSIP_ACTION_INFO_DEF + 2:
980 break;
981 case GOSSIP_ACTION_INFO_DEF + 3:
983 break;
984 //Unlearn Tailor
985 case GOSSIP_ACTION_INFO_DEF + 4:
987 break;
988 case GOSSIP_ACTION_INFO_DEF + 5:
990 break;
991 case GOSSIP_ACTION_INFO_DEF + 6:
993 break;
994 }
995 }
996
997 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
998 {
999 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
1000 ClearGossipMenuFor(player);
1001 SendActionMenu(player, action);
1002 return true;
1003 }
1004 };
1005
1006 CreatureAI* GetAI(Creature* creature) const override
1007 {
1008 return new npc_prof_tailorAI(creature);
1009 }
1010};
1011
1012/*###
1013# start menues alchemy
1014###*/
1016{
1017public:
1018 npc_prof_alchemy() : CreatureScript("npc_prof_alchemy") { }
1019
1021 {
1022 npc_prof_alchemyAI(Creature* creature) : ScriptedAI(creature) { }
1023
1024 inline bool HasAlchemySpell(Player* player)
1025 {
1026 return (player->HasSpell(S_TRANSMUTE) || player->HasSpell(S_ELIXIR) || player->HasSpell(S_POTION));
1027 }
1028
1029 bool OnGossipHello(Player* player) override
1030 {
1031 if (me->IsQuestGiver())
1032 player->PrepareQuestMenu(me->GetGUID());
1033
1034 if (me->IsVendor())
1036
1037 if (me->IsTrainer())
1039
1040 if (player->HasSkill(SKILL_ALCHEMY) && player->GetBaseSkillValue(SKILL_ALCHEMY) >= 350 && player->GetLevel() > 67)
1041 {
1043 {
1044 switch (me->GetEntry())
1045 {
1047 if (!HasAlchemySpell(player))
1049 if (player->HasSpell(S_TRANSMUTE))
1051 break;
1052 case N_TRAINER_ELIXIR:
1053 if (!HasAlchemySpell(player))
1055 if (player->HasSpell(S_ELIXIR))
1057 break;
1058 case N_TRAINER_POTION:
1059 if (!HasAlchemySpell(player))
1061 if (player->HasSpell(S_POTION))
1063 break;
1064 }
1065 }
1066 }
1067
1068 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
1069 return true;
1070 }
1071
1072 void SendActionMenu(Player* player, uint32 action)
1073 {
1074 switch (action)
1075 {
1077 player->GetSession()->SendListInventory(me->GetGUID());
1078 break;
1080 player->GetSession()->SendTrainerList(me);
1081 break;
1082 //Learn Alchemy
1083 case GOSSIP_ACTION_INFO_DEF + 1:
1085 break;
1086 case GOSSIP_ACTION_INFO_DEF + 2:
1088 break;
1089 case GOSSIP_ACTION_INFO_DEF + 3:
1091 break;
1092 //Unlearn Alchemy
1093 case GOSSIP_ACTION_INFO_DEF + 4:
1095 break;
1096 case GOSSIP_ACTION_INFO_DEF + 5:
1098 break;
1099 case GOSSIP_ACTION_INFO_DEF + 6:
1101 break;
1102 }
1103 }
1104
1105 bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
1106 {
1107 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
1108 ClearGossipMenuFor(player);
1109 SendActionMenu(player, action);
1110 return true;
1111 }
1112 };
1113
1114 CreatureAI* GetAI(Creature* creature) const override
1115 {
1116 return new npc_prof_alchemyAI(creature);
1117 }
1118};
1119
1121{
1122 new npc_prof_blacksmith();
1125 new npc_prof_leather();
1126 new npc_prof_tailor();
1127 new npc_prof_alchemy();
1128}
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint32_t uint32
Definition Define.h:133
@ EQUIP_ERR_CLIENT_LOCKED_OUT
Definition ItemDefines.h:65
@ BUY_ERR_NOT_ENOUGHT_MONEY
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
@ EQUIPMENT_SLOT_END
Definition Player.h:571
@ EQUIPMENT_SLOT_START
Definition Player.h:551
#define INVENTORY_SLOT_BAG_0
Definition Player.h:547
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const &guid)
void AddGossipItemFor(Player *player, GossipOptionIcon icon, std::string const &text, uint32 sender, uint32 action)
void ClearGossipMenuFor(Player *player)
void CloseGossipMenuFor(Player *player)
@ GOSSIP_SENDER_MAIN
@ GOSSIP_ACTION_TRADE
@ GOSSIP_ACTION_TRAIN
@ GOSSIP_ACTION_INFO_DEF
@ REP_FRIENDLY
@ SKILL_BLACKSMITHING
@ SKILL_LEATHERWORKING
@ SKILL_TAILORING
@ SKILL_ENGINEERING
@ SKILL_ALCHEMY
#define sSpellMgr
Definition SpellMgr.h:738
Creature *const me
Definition CreatureAI.h:82
Definition Item.h:62
ItemTemplate const * GetTemplate() const
Definition Item.cpp:535
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetGossipOptionSender(uint32 selection) const
Definition GossipDef.h:268
uint32 GetGossipOptionAction(uint32 selection) const
Definition GossipDef.h:269
bool GetQuestRewardStatus(uint32 quest_id) const
Definition Player.cpp:15626
bool ModifyMoney(int32 amount, bool sendError=true)
Definition Player.cpp:22339
WorldSession * GetSession() const
Definition Player.h:1719
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9552
bool HasSkill(uint32 skill) const
Definition Player.cpp:5871
bool HasEnoughMoney(uint32 amount) const
Definition Player.h:1410
uint16 GetBaseSkillValue(uint32 skill) const
Definition Player.cpp:5934
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param) const
Definition Player.cpp:13118
void RemoveSpell(uint32 spell_id, bool disabled=false, bool learn_low_rank=true)
Definition Player.cpp:3391
void PrepareQuestMenu(ObjectGuid guid)
Definition Player.cpp:14270
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0) const
Definition Player.cpp:13075
ReputationRank GetReputationRank(uint32 faction_id) const
Definition Player.cpp:6303
bool HasSpell(uint32 spell) const override
Definition Player.cpp:3853
uint32 GetGossipTextId(uint32 menuId, WorldObject *source)
Definition Player.cpp:14233
PlayerMenu * PlayerTalkClass
Definition Player.h:1969
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > const & GetEffects() const
Definition SpellInfo.h:482
bool IsTrainer() const
Definition Unit.h:1102
bool IsQuestGiver() const
Definition Unit.h:1103
bool IsVendor() const
Definition Unit.h:1101
uint8 GetLevel() const
Definition Unit.h:889
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
void SendListInventory(ObjectGuid guid)
void SendTrainerList(Creature *npc)
GameObjectAI * GetAI(GameObject *go) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
ProfessionSpells
@ S_LEARN_WEAPON
@ S_GNOMISH
@ S_LEARN_DRAGON
@ S_LEARN_GNOMISH
@ S_LEARN_GOBLIN
@ S_AXE
@ S_TRIBAL
@ S_WEAPON
@ S_GOBLIN
@ S_REP_WEAPON
@ S_SWORD
@ S_UNLEARN_SWORD
@ REP_HAMMER
@ S_LEARN_POTION
@ S_LEARN_MOONCLOTH
@ S_LEARN_ELEMENTAL
@ S_UNLEARN_WEAPON
@ S_DRAGON
@ S_MOONCLOTH
@ S_UNLEARN_SPELLFIRE
@ S_UNLEARN_TRANSMUTE
@ S_UNLEARN_SHADOWEAVE
@ S_LEARN_ARMOR
@ S_LEARN_ELIXIR
@ S_UNLEARN_TRIBAL
@ S_HAMMER
@ S_UNLEARN_HAMMER
@ S_LEARN_HAMMER
@ S_UNLEARN_DRAGON
@ REP_SWORD
@ S_LEARN_SPELLFIRE
@ S_LEARN_TRANSMUTE
@ S_LEARN_SHADOWEAVE
@ S_SPELLFIRE
@ S_ELEMENTAL
@ S_UNLEARN_ELIXIR
@ S_LEARN_AXE
@ REP_ARMOR
@ S_ELIXIR
@ S_SHADOWEAVE
@ S_UNLEARN_ELEMENTAL
@ S_UNLEARN_GOBLIN
@ S_TRANSMUTE
@ S_UNLEARN_GNOMISH
@ S_REP_ARMOR
@ REP_AXE
@ S_LEARN_SWORD
@ S_UNLEARN_MOONCLOTH
@ REP_WEAPON
@ S_ARMOR
@ S_UNLEARN_AXE
@ S_UNLEARN_ARMOR
@ S_UNLEARN_POTION
@ S_POTION
@ S_LEARN_TRIBAL
void AddSC_npc_professions()
@ GOSSIP_SMITHOMNI2
@ GOSSIP_ARMOR2
@ GOSSIP_ELEMENTAL1
@ GOSSIP_WEAPON1
@ GOSSIP_MOONCLOTH
@ GOSSIP_POTION
@ GOSSIP_TRIBAL1
@ GOSSIP_SPELLFIRE
@ GOSSIP_TRIBAL2
@ GOSSIP_TRANSMUTE
@ GOSSIP_SHADOWEAVE
@ GOSSIP_SMILES
@ GOSSIP_WEAPON2
@ GOSSIP_AXE
@ GOSSIP_DRAGON1
@ GOSSIP_UNLEARN
@ GOSSIP_ELEMENTAL2
@ GOSSIP_JHORDY
@ GOSSIP_SWORD
@ GOSSIP_DRAGON2
@ GOSSIP_ARMOR1
@ GOSSIP_ZAP
@ GOSSIP_SMITHOMNI1
@ GOSSIP_KABLAM
@ GOSSIP_ELIXIR
@ GOSSIP_HAMMER
@ GOSSIP_LEARN
#define GOSSIP_SENDER_CHECK
void ProfessionUnlearnSpells(Player *player, uint32 type)
#define GOSSIP_SENDER_LEARN
int32 DoHighUnlearnCost(Player *)
int32 DoMedUnlearnCost(Player *player)
bool EquippedOk(Player *player, uint32 spellId)
SoothsayingForDummies
@ OPTION_LEARN_GNOMISH
@ OPTION_LEARN_TRIBAL
@ OPTION_LEARN_ELEMENTAL
@ OPTION_UNLEARN_GNOMISH
@ OPTION_UNLEARN_GOBLIN
@ OPTION_LEARN_GOBLIN
@ OPTION_LEARN_DRAGONSCALE
@ GOSSIP_ID
int32 DoLowUnlearnCost(Player *player)
ProfessionQuest
@ Q_MASTER_POTION
@ Q_MASTER_TRANSMUTE
@ Q_MASTER_ELIXIR
void ProcessCastaction(Player *player, Creature *creature, uint32 spellId, uint32 triggeredSpellId, int32 cost)
#define GOSSIP_SENDER_UNLEARN
SpecializationTrainers
@ N_TRAINER_TRANSMUTE
@ N_TRAINER_SMITHOMNI1
@ N_TRAINER_SMITHOMNI2
@ N_TRAINER_AXE
@ N_TRAINER_ELIXIR
@ N_TRAINER_SHADOWEAVE
@ N_TRAINER_ELEMENTAL1
@ N_TRAINER_ARMOR1
@ N_TRAINER_HAMMER
@ N_TRAINER_TRIBAL1
@ N_TRAINER_POTION
@ N_TRAINER_WEAPON1
@ N_TRAINER_DRAGON1
@ N_TRAINER_MOONCLOTH
@ N_TRAINER_ARMOR2
@ N_TRAINER_SPELLFIRE
@ N_TRAINER_DRAGON2
@ N_TRAINER_WEAPON2
@ N_TRAINER_SWORD
@ N_TRAINER_ELEMENTAL2
@ N_TRAINER_TRIBAL2
void ProcessUnlearnAction(Player *player, Creature *creature, uint32 spellId, uint32 alternativeSpellId, int32 cost)
EngineeringTrinkets
@ SPELL_LEARN_TO_EVERLOOK
@ NPC_SMILES
@ SPELL_TO_GADGET
@ NPC_ZAP
@ NPC_JHORDY
@ SPELL_TO_EVERLOOK
@ SPELL_TO_AREA52
@ SPELL_LEARN_TO_GADGET
@ SPELL_LEARN_TO_AREA52
@ SPELL_LEARN_TO_TOSHLEY
@ SPELL_TO_TOSHLEY
@ NPC_KABLAM
int32 DoLearnCost(Player *)
uint32 RequiredSpell
bool OnGossipSelect(Player *player, uint32 menuId, uint32 gossipListId) override
bool CanLearn(Player *player, uint32 textId, uint32 altTextId, uint32 skillValue, uint32 reqSpellId, uint32 spellId, uint32 &npcTextId)
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
void SendActionMenu(Player *player, uint32 action)
bool OnGossipHello(Player *player) override
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
void SendActionMenu(Player *player, uint32 action)
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
bool OnGossipHello(Player *player) override
bool OnGossipHello(Player *player) override
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
void SendActionMenu(Player *player, uint32 action)
void SendActionMenu(Player *player, uint32 action)
bool OnGossipHello(Player *player) override
bool OnGossipSelect(Player *player, uint32, uint32 gossipListId) override
Gossips
Definition zulaman.cpp:55