Last active
April 19, 2018 10:35
-
-
Save mindsear/51a02e40180b9b4665ba757e1a91ff0b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Fixed and explained Srzm's script | |
http://www.ac-web.org/forums/showthread.php?231858-Help-Getting-started-with-Custom-NPC-and-Boss-Scripting | |
I'm using Trinity Core 3.3.5 (22-march-2018 updated version) | |
-- ================================================================================================================================== | |
-- This is the npc I used in my database | |
Set @Entry = 55000, | |
@Npc_Name = "Test", | |
@Subname = "", | |
@ModelID = 31833, | |
@Level = 80, | |
@ScriptName = "Innkeeperhealer"; | |
INSERT INTO `world`.`creature_template` (`entry`, `modelid1`, `name`, `subname`, `minlevel`, `maxlevel`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `type`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `DamageModifier`, `ExperienceModifier`, `RegenHealth`, `ScriptName`, `VerifiedBuild`) VALUES | |
(@Entry, @ModelID, @Npc_Name, @Subname, @Level, @Level, 35, 1, 1, 1.14286, 1, 1, 2000, 2000, 1, 1, 2, 0, 2048, 7, 1, 50, 50, 1, 1, 1, 1, @ScriptName, 12340); | |
-- ================================================================================================================================== | |
Short video showing the NPC that uses this script | |
https://streamable.com/l50ah | |
*/ | |
#include "ScriptMgr.h" | |
#include "ScriptedGossip.h" | |
#include "ScriptedCreature.h" | |
#include "GossipDef.h" | |
#include "Creature.h" | |
#include "Player.h" | |
#include "WorldSession.h" | |
enum GossipMenuID | |
{ | |
/* it's easier to understand and search if you're using string instead of plain numbers */ | |
Menu_Close1 = 1, | |
Menu_Close2 = 2, | |
Menu_Heal1, | |
Menu_Heal2, | |
Menu_Morph, | |
Menu_DeMorph, | |
Menu_ShowBank, | |
Menu_ShowMailBox, | |
Menu_NPC_SAY, | |
Menu_NPC_YELL, | |
Menu_NPC_Whisper, | |
Menu_BuffNpc, | |
Menu_BuffPlayer, | |
Menu_RemoveBuffNpc, | |
Menu_RemoveBuffPlayer, | |
}; | |
enum Spells | |
{ | |
GREATER_HEAL = 71931, | |
POWER_WORD_FORTITUDE = 48161, // Power infuses the target increasing their Stamina by 165 for 30 min. (Rank 8) | |
SOME_OTHER_SPELL = 123 | |
}; | |
#define CLOSE1 "I wanna close the window THIS way!" | |
#define CLOSE2 "No, better close it THIS way..!" | |
#define HEAL1 "Heal me! (function SetFullHealth())" | |
#define HEAL2 "Heal me! (cast a healing spell)" | |
#define Morph_plr "Morph Me into a crab" | |
#define DeMorph_plr "DeMorph Me" | |
#define Show_Bank "Show Bank" | |
#define Show_MailBox "Show Mail" | |
#define Npc_Say "Say Something" | |
#define Npc_Yell "Yell Something" | |
#define Npc_Whisper "Whisper Something" | |
#define Buff_NPC "Buff npc" | |
#define Buff_Player "Buff player" | |
#define RemoveBuff_NPC "Remove Buff from npc" | |
#define RemoveBuff_Player "Remove Buff from player" | |
// gossip text id can be taken from world database, npc_text table. For example id 1 = "Greetings, $n." ($n means player's name) | |
#define GOSSIP_TEXT_ID_HEY_CITIZEN 197 // "Hey citizen! You look like a stout one. We guards are spread a little thin out here, and I could use you help..." | |
class Innkeeperhealer : public CreatureScript | |
{ | |
public: | |
Innkeeperhealer() : CreatureScript("Innkeeperhealer") {} | |
struct InnkeeperhealerAI : public ScriptedAI | |
{ | |
InnkeeperhealerAI(Creature* creature) : ScriptedAI(creature) { } | |
bool GossipHello(Player* plr) override | |
{ | |
//if (true) // What is this ?? I don't think you need it ( no logic behind this if statement) | |
//{ | |
/* Option 1: Closing the Gossip Menu with the text: "I wanna close the window THIS way!" */ | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, CLOSE1, GOSSIP_SENDER_MAIN, Menu_Close1); | |
/* Option 2: Closing the Gossip Menu with the text: "No, better close it THIS way..!" */ | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, CLOSE2, GOSSIP_SENDER_MAIN, Menu_Close2); | |
// I've added the healing menus | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, HEAL1, GOSSIP_SENDER_MAIN, Menu_Heal1); | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, HEAL2, GOSSIP_SENDER_MAIN, Menu_Heal2); | |
//this is another example - morph player | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Morph_plr, GOSSIP_SENDER_MAIN, Menu_Morph); | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, DeMorph_plr, GOSSIP_SENDER_MAIN, Menu_DeMorph); | |
// show player's bank ui | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Show_Bank, GOSSIP_SENDER_MAIN, Menu_ShowBank); | |
// show player's mailbox ui | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Show_MailBox, GOSSIP_SENDER_MAIN, Menu_ShowMailBox); | |
// npc say something | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Npc_Say, GOSSIP_SENDER_MAIN, Menu_NPC_SAY); | |
// npc yell something | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Npc_Yell, GOSSIP_SENDER_MAIN, Menu_NPC_YELL); | |
// npc whisper something | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Npc_Whisper, GOSSIP_SENDER_MAIN, Menu_NPC_Whisper); | |
// buff npc | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Buff_NPC, GOSSIP_SENDER_MAIN, Menu_BuffNpc); | |
// remove buff from npc | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, RemoveBuff_NPC, GOSSIP_SENDER_MAIN, Menu_RemoveBuffNpc); | |
// buff player | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, Buff_Player, GOSSIP_SENDER_MAIN, Menu_BuffPlayer); | |
// remove buff from player | |
AddGossipItemFor(plr, GOSSIP_ICON_CHAT, RemoveBuff_Player, GOSSIP_SENDER_MAIN, Menu_RemoveBuffPlayer); | |
/* Display both of those options when a player talks to me. */ | |
SendGossipMenuFor(plr, GOSSIP_TEXT_ID_HEY_CITIZEN, me->GetGUID()); | |
//} | |
return true; | |
} | |
bool GossipSelect(Player* plr, uint32 /*menuId*/, uint32 uiAction) override | |
{ | |
/* If there is no player around, don't do anything. */ | |
//if (!plr) // There is no need for this check | |
// return false; | |
uint32 const action = plr->PlayerTalkClass->GetGossipOptionAction(uiAction); // this line should be first | |
ClearGossipMenuFor(plr); // this should be the second line, otherwise it wouldn't work | |
switch (action) | |
{ | |
/* | |
In c++ you can do "case 1: case 2: case n: DO SOMETHING break;" if | |
you want all cases to do the same thing. It's not a must but it looks easier and less writing | |
of the same function/s for all cases. | |
e.g. | |
case 1: | |
case 2: | |
CloseGossipMenuFor(player); | |
break; | |
*/ | |
case Menu_Close1: | |
CloseGossipMenuFor(plr); | |
break; // You forgot to add the break for the case | |
case Menu_Close2: | |
CloseGossipMenuFor(plr); | |
break; // You forgot to add the break for the case | |
case Menu_Heal1: // Heal the player: you can either use a healing spell or a tc function | |
if (plr->GetHealthPct() == 100.0f) | |
{ | |
plr->GetSession()->SendAreaTriggerMessage("Your health is already full."); | |
} | |
else // if player's health is less than 100% | |
{ | |
plr->SetFullHealth(); | |
plr->GetSession()->SendAreaTriggerMessage("Your health has been restored."); | |
CloseGossipMenuFor(plr); | |
} | |
break; | |
case Menu_Heal2: // Heal the player: you can either use a healing spell or a tc function | |
// in this case "me" is the npc who's casting the spell. If you want the player to cast the spell, just replace me with plr | |
me->CastSpell(plr, GREATER_HEAL, false); // the third argument is either true (don't cast the spell) or false (cast the spell) | |
plr->GetSession()->SendAreaTriggerMessage("You've been healed."); | |
CloseGossipMenuFor(plr); | |
break; | |
case Menu_Morph: | |
plr->SetDisplayId(999); // display id 999 = crab ( these ID's can be found in CreatureDisplayInfo.dbc and CreatureModelData.dbc) | |
break; | |
case Menu_DeMorph: | |
plr->DeMorph(); | |
break; | |
case Menu_ShowBank: | |
plr->GetSession()->SendShowBank(plr->GetGUID()); | |
break; | |
case Menu_ShowMailBox: | |
plr->GetSession()->SendShowMailBox(plr->GetGUID()); | |
break; | |
case Menu_NPC_SAY: | |
me->Say("I'm saying Something!", LANG_UNIVERSAL, plr); | |
break; | |
case Menu_NPC_YELL: | |
me->Yell("I'm yelling Something!", LANG_UNIVERSAL, plr); | |
break; | |
case Menu_NPC_Whisper: | |
me->Whisper("I'm whispering Something!", LANG_UNIVERSAL, plr); | |
break; | |
case Menu_BuffNpc: | |
me->AddAura(POWER_WORD_FORTITUDE, me); | |
break; | |
case Menu_RemoveBuffNpc: | |
me->RemoveAura(POWER_WORD_FORTITUDE); | |
break; | |
case Menu_BuffPlayer: | |
me->AddAura(POWER_WORD_FORTITUDE, plr); | |
break; | |
case Menu_RemoveBuffPlayer: | |
plr->RemoveAura(POWER_WORD_FORTITUDE); | |
break; | |
} | |
CloseGossipMenuFor(plr); // if cases are missing this, you can add it here for all cases to close after functions are executed. | |
return true; | |
} | |
}; | |
CreatureAI* GetAI(Creature* creature) const override | |
{ | |
return new InnkeeperhealerAI(creature); | |
} | |
}; | |
void ADDSC_Innkeeperhealer() | |
{ | |
new Innkeeperhealer(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment