Beyond the Teleporter
A look at C++ scripting Written by GastricPenguin
Gossip scripts here on MMOwned are everywhere. There are plenty of guides and releases that detail how you can create your very own NPC
teleporter. The thing they don't tell you is that teleporters are not the only thing that can be accomplished by writing a C++ script. Why, a
gossip script can be used for anything you can think of. How does an Item that checks your current position, and if you are within a certain
pre-defined range launches you up into the air, sound? What about an NPC that heals you when you shout "Help!"? There's hardly a limit you
could reach (within reason) when creating a C++ script. Enough of the talk however, let's see some demonstrations!
Demonstration of a non-teleporter item script
[yt]<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/V5F8X93aJBU&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/V5F8X93aJBU&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>[/yt]
Demonstration of a script using a chat hook:
[yt]<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/ytC5B-zT6sA&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/ytC5B-zT6sA&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>[/yt]
Pretty cool, huh? The best part is that these scripts are very small and easy to write. Let's take a look at the first script.
Code:
//COMPATIBLE WITH THE ASPIRE CORE ONLY
#include "StdAfx.h"
#include "Setup.h"
#define BLIGHT_EXPLOSION 61126
#define LAUNCH 16716
#define SUICIDE 7
//This is a class that is called after the item is activated
//We have it at the top so the shared_ptr<Aftermath> can be used without errors
//'public EventableObject' is also needed for the shared_ptr
class Aftermath : public EventableObject
{
public:
void Explode(PlayerPointer Plr)
{
Plr->CastSpell(Plr, BLIGHT_EXPLOSION, 0);
//Fun spell for visuals (does cause high damage to opponents if in combat)
Plr->CastSpell(Plr, SUICIDE, 0);
//Kills the player (for lack of a better way)
}
};
class SCRIPT_DECL Launcher : public GossipScript
{
public:
void GossipHello(ObjectPointer pObject, PlayerPointer Plr, bool AutoSend)
{
shared_ptr<Aftermath> am;
//opens a shared ptr for the Aftermath class
Plr->CastSpell(Plr, LAUNCH, 0);
//Launch the player sky-high
TimedEvent *te = TimedEvent::Allocate(am, new CallbackP1<Aftermath, PlayerPointer>(am, &Aftermath::Explode, Plr), 0, 2950, 1);
sWorld.event_AddEvent(te);
//Add a timed event to kill the player 3 seconds later. This TimedEvent calls void Explode() in the Aftermath class after (roughly) 3 seconds
}
void GossipEnd(ObjectPointer pObject, PlayerPointer Plr)
{
GossipScript::GossipEnd(pObject, Plr);
}
void Destroy()
{
delete this;
}
};
void SetupLauncher(ScriptMgr * mgr)
{
GossipScript * gs = (GossipScript*) new Launcher();
mgr->register_item_gossip_script(44560, gs);
}
It may be intimidating to look at, but I assure you it is a very simple concept. Just read the commented lines for more information about what is
going on in the script. The second script looks as such: (again, refer to the comments for more information)
Code:
//COMPATIBLE WITH THE ASPIRE CORE ONLY
#include "StdAfx.h"
#include "Setup.h"
#define ETERNAL_AFFECTION 30878
using namespace std;
//Why use the std namespace? We are working with strings, that's why!
bool OnChat(PlayerPointer pPlayer, uint32 Type, uint32 Lang, string Message, string Misc)
{
string input = Message;
//Here we make a copy of the chat message so we can mess with it
transform(input.begin(), input.end(), input.begin(), tolower);
//This function takes the new copy and converts all characters to lowercase
if(strstr(input.c_str(), "i need healing"))
//if "i need healing" has been said, we continue!
{
CreaturePointer Healer =
pPlayer->GetMapMgr()->GetInterface()->SpawnCreature(50016, pPlayer->GetPositionX(),
pPlayer->GetPositionY(), pPlayer->GetPositionZ(), 0, true, false, 0, 0);
//Let's spawn us a healer! The next 4 lines are easy to understand
Healer->SendChatMessage(12, 0, "I'm here to help!");
Healer->CastSpell(pPlayer, ETERNAL_AFFECTION, 0);
Healer->Despawn(5000, 0);
}
return true;
}
void SetupChatHealer(ScriptMgr * mgr)
{
mgr->register_hook(SERVER_HOOK_EVENT_ON_CHAT, OnChat);
}
Why do people neglect writing scripts in C++?
For some reason, people believe that their precious Lua script can do anything they want. Although
that is entirely false, I believe that the main reason why people do not prefer a C++ script is the fact they are introduced to the language
incorrectly. Most C++ guides here on MMOwned are directed towards writing teleporters (aside from mager who released that lovely creature
structure here). Teleporters may be fun and all, but gossip scripts are intimidating. An average C++ Gossip Script ranges from 100 to 150 lines
of code! That is way too much to be looking at for a novice, no matter how well you write the guide. My advice for those out there who have
been introduced to C++ in the wrong light, start off with something small like a simple hook. C++ is a very versatile language that can be your best
friend when you get the hang of things!