DAOCSkilla


Disclaimer:  DAOCSkilla is, without question, a violation of the Myhic Dark Age of Camelot Terms of Service (ToS).  Use of  daocskilla may result in your accounts being suspended or banned.  The Excalibur developers provide no warranty of this software's operation or the consequences of using it.  Please enjoy responsibly.

Table of Contents

License
Contacting
Requrements
QuickLaunch
Main screen
Connection setup
Excalibur window
Keyboard shortcuts
Tracing and Debugging
Mobseen file format
Delveseen file format
Slot descriptions
Resume last connection
Real time chat log
Macroing
General notes
Show map nav nodes
Autosell hinges and powerskill items
AFK message
Macro script
Macro tradeskill
Stack odds
PowerSkill buy
Spellcraft help
NOD files
Remote control
Questions
Appendix

License

DaocSkilla is released under the GNU Public License and is available free of charge and without warranty.

Contacting

The home of daocskilla is the Excalibur Project on SourceForge.  Please use the forums there for support and suggestions.  http://sourceforge.net/projects/excalibar/
Note:  The project page on SourceForge is excalibar not excalibur.

Requirements

- The stable DaocSkilla zip file extracted with "Use folder names" on.  http://capnbry.net/daoc/daocskilla.php
- A network card over which DAoC traffic flows.  DaocSkilla does not work over dial-ups under Windows 2000 and WindowsXP.
- WinPCAP v3 installed.  This can be downloaded from http://winpcap.polito.it/
- A video card and drivers that support at least OpenGL version 1.2.  For full functionality, 1.3 with GLUT should be used.
- If Dark Age of Cameot is not installed in C:\Mytic\Isles\ then you must launch daocskilla and close it once, then edit edit the daocskilla.ini and change the DAOCPath option to reflect where Dark Age is installed.

Main screen

dlg_main

QuickLaunch

QuickLaunch allows you to used cached login information to launch immediately into the Dark Age client, bypassing the normal login sequence.  Why would you want to do that?  Because it's friggin annoying to have to go through the new EUALA speiel every time you log in another account.  The disadvantage is that you still have to use the regular patcher to get new versions.  You cannot run an old game.dll against a newer version server. You must patch manually every time there is a patch.  Once the patcher is done, just close the login dialog.
Your login information is stored locally in the daocskilla.ini.  Use the "Remove" button to delete a cached login.  The quicklaunch function requires that your DAOCPath is set properly. 

Connection setup

dlg_connection
The first thing you'll need to do is set up your connection.  Do this by clicking the button next to the "Set up connection" label.  There are 3 basic modes of operation:
  1. Sniff packets and process locally
    This is where you'll run DaocSkilla and have it process the packets and show the radar on the on the local machine.  You'll want to run daoc in a window if you do this, or else you won't be able to see daocskilla.  To run in this mode:
    This method can also be used if you're running daocskilla on another machine and you have a hub (not a router or switch).  You may need to turn on "Promiscuous capture" to get it to work.
  2. Sniff packets and send them to another machine
    This is good if you have a second machine and wish to run daoc full-screen.  You'll run two copies of daocskilla, and have one send the packets to the other.  To run in this mode:
  3. Collect packets sent from another daocskilla instance
    Use this in conjunction with #2 to provide a remote display of daoc running on another machine.  WinPCAP does not need to be installed on the collector machine.

Excalibur window

dlg_excalibur
The Excalibur window is the 'radar' window which displays players, mobs, and objects in your immediate vicinity.  The approximate maximum
range of the radar is 6000' metric Dark Age units.  Press F1 to display a list of options for the radar window.

In the default display, the yellow triangle in the middle is you.  The rings are there to help estimate scale and range.  The red ring is 500',
the green ring is 1500', the white ring is 6000'.  The green cone extending from you is an approximation of what you can actually see in your DAoC
window when your clipping plane is set far. Larger mobs are visible sooner.  The slider at the bottom of the screen adjusts the range of the radar.

Objects are colored based on their con color.  Objects with a colored ring around them are players, and the ring indicates their home realm.
Players in your guild have their highlight ring colored half teal.  Players in your group have their highlight ring colored half orange.

Keyboard Shortcuts
Left - Scroll map left Right - Scroll map right Up - Scroll map up Down - Scroll map down
Home - Recenter radar on player F1 - Show preferences dialog F2 - Show / Hide mob list PgUp - Zoom in
PgDown - Zoom out A - Toggle invader warning B - Toggle background map C - Toggle range circles
D - Toggle "Draw AI destination" F - Toggle "Draw friendly players" G - Toggle map overlay grid H - Toggle HUD
I - Add pushpin at current loc M - Toggle display filter (Mobs) O - Toggle display filter (Objects) P - Toggle display filter (Players)
R - Toggle "Draw rulers" T - Toggle "Stay on top" U - Toggle display filter (Unknown) V - Toggle vector maps
Y - Toggle "Show typetag" and moblist text



Tracing and Debugging
dlg_debuggin
This dialog is useful for recording and playing back daoc sessions.  Mostly this is used for debugging.
Format of mobseen file
Column No
Description
0
MOBseen (literal text)
1
Zone number
2
Zone X
3
Zone Y
4
Zone Z
5
Mob Level
6
Mob name
7
TypeTag (e.g. Poison Merchant, Thane Trainer)

Format of delveseen file
Column No
Description
0
DELVE (literal text)
1
Realm (0 - Unknown, 1 - Albion, 2 - Midgard, 3 - Hibernia)
2
Countless description, in quotes (if the description begins with a number, it is removed)
3
HEX Slot the item was in when it was delved.  This is not where the item can go, unless it is equipped when it is delved.  See below for a list of slots.
4
Stack count.  May not be acurate in all cases
5
Condition
6
Durability
7
Quality
8
Bonus
9
Level
10
Color
11
HEX Item ID.  This does not uniquely identify the item, just the icon and mesh used by the item.
12
Number of lines of delve text which follows
13+
Delve text, in quotes.  Note: blank delve text lines are removed.

Slot Descriptions
Slot ID
Location
0x0a
Left Hand
0x0b
Right Hand
0x0c
2 Handed Slot
0x0d
Ranged Slot
0x0e
Thrown Slot
0x15
Head
0x16
Hands
0x17
Feet
0x18
Jewelery
0x19
Chest
0x1a
Cloak
0x1b
Legs
0x1c
Sleeves
0x1d
Necklace
0x20
Belt
0x21
Left Wrist
0x22
Right Wrist
0x23
Left Finger
0x24
Right Finger
0x28-0x48
Inventory Bags
0x6e-0x95
Standard Vault

Resume last connection

If doacskilla crashes mid-session, this might be able to pick up the stream back from where it left off.  Everything current will appear as an Unknown Object but new objects should display properly.  This is only meant to be used as a crutch until you can safely relog into Dark Age.

Real time chat log

Records a chat.log just like daoc does, except it runs real-time rather than buffered like theirs does.

Macroing


WARNING:  The macroing code is unmaintained and unsupported.  It may not perform correctly and you may lose precious items.  The best way to learn the ins and outs is to read the source.  If you are willing to accept the risks associated with letting an untested application spend your money and sell your stuff, then edit your daocskilla.ini and add to the [Main] section EnableMacroing=1.

General Notes

Show nav map nodes

dlg_mapnodes
Displays a rendering of the currently loaded navigation map.  Not really useful unless you're writing your own .NOD files.

Autosell hinges and powerskill items

If you have an NPC selected (actually if you have anything selected), this will automatically sell back hinges, cloaks, and any item on your powerskill list.  For this to work, F2 should be mapped to quicksell, and your inventory tab should be open.  Masterpiece items are never auto sold.  Autosell is triggered when you have something selected by a change to your inventory and had a 1 in 7 chance of starting.  Once it starts, all items deemed sellable are sold.  You need to be in range of the selected NPC to be able to autosell.

AFK message

dlg_afk
This is a feature I wish Mythic would have implemented like back in 2001, but took until late 2003 to get in.  If you get a tell while this window is open, it will reply immediately with the message you specify.

Macro script

dlg_tellscript
This loads the Windows Scripting Host and runs a script calling events in your code as things happen in-game.  This was really never completed due to the vast amount of work needed to expose all the daocskilla objects over COM.  See the appendix for a description of the interface available.

Macro tradeskill

dlg_macrotradeskills
This is "Homer's Bird" of tradeskilling.  It just presses a key every time you build an item.  All the intelligence required of a LGM crafter in 2 lines of code.  The Macro Tradeskill action is triggered by the completion (success or failure) of any tradeskill item.  You'll need to manually 'kick start' the process by pressing the first key of your progression manually.  You can stop daocskilla by moving and cancelling your product, closing the Macro window, or by stopping your build manually.

Stack Odds
There was a good amout of talk going around a while back about if you could get more masterpieces by "loading the odds in your favor"; creating low-cost items until you're on a bad streak, then switching over to make your item now that the random number you're looking for should be coming up soon.  It's a load of crap of course, since each build is independant and each has an equal chance of being what you want regardless of your current streak.  I've done extensive testing (on the order of hundreds of thousands of items) and it doesn't make a bit of difference.  If it makes you feel better though, feel free to try it. out.

PowerSkill Buy

dlg_macropowerskillbuyThis buys the supplies from a vendor to craft with.  Powerskill buy is triggered by a vendor window opening.  This is usually used in conjuction with the Macro Tradeskill window.  PowerSkill Buy will buy the necessary supplies to craft, then navigate your ForgeNode and begin Macro Tradeskill in 5 seconds.  When it is out of supplies it will navigate back to the MerchantNode.  You must manually start purchasing by right-clicking the merchant.  If you do not have a forge node assigned, Macro Tradeskill must be manually started.  It is controlled by a Profile which defines what skill you're working. 

The profile is just an INI file in the daocskilla directory.  The following entries from the INI are used:
Name
Default
Description
DefaultMinPurchase 1
Materials for making this many items will be purchased.
SkillName
The name of the skill you're advancing as it appears in your characters abilities tab in daoc.  Note that the skill name (e.g. Armorcraft) usually differs from the recipe skill name (e.g. Armorcrafting)
RecipeSkillName
The name of the skill you are advancing as it appears in the daoc recipe file.  Note that the recipe skill name (e.g. Armorcrafting) usually differs from the skill name (e.g. Armorcraft)
LocaleNodeListName
The .NOD file which contains a list of relevant nodes for moving your character to the vendor and craft area.
MerchantNodeName
The name of the node where the merchant is, and where daocskilla should go when it runs out of supplies.
ForgeNodeName
The name of the node where you can craft, where daocskilla goes when it has materials it needs.
RecipeRealm 1
What realm you're in.  1=Albion 2=Midgard 3=Hibernia
HowOrange 0
When AutoAdvance is on, this is how orange an item you want to make is.  This will also adjust the skill levels noted next to the item in the list, but not affect its con color.
UseMBuy 1
Use /mbuy to buy items from the vendor rather than clicking a bajillion times.
IncludeRecipes
Only include recipes that match this list.  Comma-delimited list, wildcards are supported, spaces must be enclosed in quotes.  (e.g. "raw * Jewel",*Rune)  A blank IncludeRecipes matches every recipe.
ExcludeRecipes
Exclude recipes that match this list.  Comma-delimited list, wildcards are supported, spaces must be enclosed in quotes.  (e.g. "raw * Jewel",*Rune)  A blank ExcludeRecipes matches no recipes.
AutoStartProgression 1
Should "Macro Tradeskill" automatically be started on arrival at the ForgeNode?
AutoDeselectMerchant 1
Should the merchant be automatically unselected for you on arrival at the ForgeNode?  This is to prevent autosell from firing if your merchant node is too far from the forge node.
AutoQuickbarSlot 0
The slot to put the recipe in on arrival at the forge node, or 0 to disable auto-quickbar. Note:  The tradeskill icon (e.g. Tailoring) must be in slot 1, therefore valid slots would be 2-10.  If this is set, then Macro Tradeskills' progression will also automatically be set to this value on arrival.
MerchantName
When arriving at MerchantNodeName, attempt to select this merchant using F9.  If no merchant name is specified, daocskilla will attempt to select the merchant sells the first material listed for the recipe.

Spellcraft Help

dlg_macrospellcraft
This is used to help configure spellcrafting gems, and overrides the functionality of both the Macro Tradeskill and PowerSkill Buy windows.  Right clicking the dialog will allow you to load and save an item's gem configuration.  The SC point value might be wrong in some instances, so you may not want to trust it.

NOD files

.NOD files are a collection of world-coordinate points and their connecting paths. Basically:
"Nodename",region,x,y,z,head,radius
nodelink1
nodelink2
nodelink3
Let's look at an example from jord.nod included with the DaocSkilla zip. The second node in the file is:
"Aaric1",101,29588,35270,8005,203,75
NWMerchantArea
The name is Aaric1 in Region 101, loc 29588,35720,8005. The implementation does nothing with heading, but when I created this node I was facing 203 (SW I think). The radius is 75, which means that if I am within 75 imperial dark age units from the loc, I'm considered there. There is also a link from this node to the node named NWMerchantArea. By saying it is linked, this means that there is a one-way path, straight and direct, from this node to the NWMerchantArea node.  Links are specified one per line and must begin with whitespace. A line which begins right at the first column indicates the end of the link list and the start of a new node.

"But Bry, that's a lot of tedious typing of coordinates ", you say. Actually, the easiest way to enter them is to use the remote control interface. Just run to where you want the node and type "NodeAdd (name)". If you want to link the new node to another exisiting node, the easiest way is "LinkNearestTo (other node)". This adds a two-way link to and from the other node. Making a path is easy:
NodeClear
NodeAdd start
(run a bit)
NodeAdd step1
LinkNearestTo start
(run a bit)
NodeAdd step2
LinkNearestTo step1
(run a bit)
NodeAdd step3
LinkNearestTo step2
(run a bit)
NodeAdd finish
LinkNearestTo step3
NodeSave my_new_path

Now when you want to run from anywhere along the path to the "finish" node. Just type PathTo finish. You will move to the nearest node, then travel from there along your path to finish. You can also GotoNode, which will run directly to that node without following your path. Or TurnToNode, which will point you in the direction of your node.

Remote control

DaocSkilla has a built-in telnet server used for controlling it remotely when DAoC is running full screen.  To connect, telnet to the daocskilla machine on port 9023.  You should receive a banner indicating that you have connected to daocskilla.  Type `help` to get a list of commands.  Commands are case-insensitive.
Exit Close the connection to the remote administator.
Loc Return current zone-adjusted location information
Get Get the value of in internal variable.
Stop Stop all autonomous actions.
Help Display this help.
Quit Quit Dark Age of Camelot
ArrowUp Press and hold the Up arrow.  Use 'stop' to release.
ArrowDown Press and hold the Down arrow.  Use 'stop' to release.
ArrowLeft Press and hold the Left arrow.  Use 'stop' to release.
ArrowRight Press and hold the Right arrow.  Use 'stop' to release.
QuickBarPage (page)
Set the current quickbar page to <page>.  Valid values are 1-10.
TurnTo (heading)
Set the player heading to <heading> degrees. (zone-relative)
Jump Make the player jump.
TurnRateRecal Recalibrate the turn rate metric.
GotoXY (x,y)
Move the player to zone-adjusted loc <x>,<y>.
NodeList ([nodename]) List all nodes in the map node list.  If a <nodename> is specified, only <nodename> is listed.
NodeAdd (name) Add a node to the map node list at the current position and heading.
NodeNearest Find the name of the node in the map node list closest to the current position.
LeftClick (x,y)
Simulate a left mouse click at <x>,<y>.
RightClick (x,y)
Simulate a right mouse click at <x>,<y>.
Zone Dump information about the current zone.
CharList Dump the list of characters on this account.
RawLoc Return current raw location information.
/
Send command directly to DAoC.
GotoNode (nodename) Move the player directly to map node <name>.
NodeSave (filename) Save the map node list to <filename>.
NodeLoad (filename) Load the map node list from <filename>.
NodeClear Clear the map node list.
Set Set the value of in internal variable.
PathTo (nodename) Move the player to map node <name> via pathing if available.
MoveInv (frombag,frompos,tobag,topos) Move an inventory item. (1-based indexes).
TurnToNode (nodename) Set the player heading to face map node <nodename>.
LinkNearestTo (nodename) Link the node nearest the player to map node <nodename> as well as a reciprical link from <nodename> to the nearest node.
DumpPath (nodename) Display the path that will be taken from nearest node to <nodename>.
Inventory Dump the contents of the player's inventory.
Skills Dump a list of the player's tradeskills.
Spells Dump a list of the player's spells.
Abilities Dump a list of the player's abilities.
Specs Dump a list of the player's specializations.
Styles Dump a list of the player's combat styles.
Currency Display the amount of currency on the current local character.
CloseDialog Clicks the OK button on a dialog.  If no dialog is visible then the click will still be issued.
Commission Display information about the current tradeskill commission.
AutoMode ([mode]) Sets automation mode to <mode>.  Options are none, and trade.  Setting to None disables AutoMode.  Setting to Trade makes your charater run
QuickLaunch ([index or name]) Launch character from the QuickLaunch list. Lists characters available for quicklaunch if no index is given.
SelectNPC (name)
Use the SelectFriendly key and attempt to select the NPC <name>.
SendKeys (keys)
Do a SendKeys call to the DAOC client.  Extended key syntax is available if the DAOC window has focus.
AttemptNPCRightClick
Attempt to right click the NPC in the middle of the screen.

Questions

  1. The list of mobs on the left is blank!  They show up on the map but not on the list.
    You have "Show NPC type tag" turned on.  Press Y to toggle the option, or turn off the checkbox on the options dialog.
  2. Why is the "Background image maps" option in the Excalibur prefs greyed out?
    This option requires that your video card driver supports compressed textures.  This is standard in OpenGL 1.3.
  3. What is GLUT?
    GLUT stands for OpenGL Utility Toolkit, and is a collection of helper functions for OpenGL applications.  It was originally written by Mark Kilgard, ported to Win32 by Nate Robins.  If you do not have GLUT you can download it from http://www.xmission.com/~nate/glut.html.  All you need is to put glut32.dll in your windows system directory, or in the same directory as daocskilla.
  4. The background image maps are pretty blurry.  Are their higher quality versions?
    Yes.  The free background image maps are very low resolution.  You can create your own using Mapper from randomly.org.  You'll then need to convert them into DDS format using the DXTC texture tools in either Photoshop or using the command-line tools.  You want color DXTC1, no mipmaps.  Their size can be anywhere from 16x16 up to 4 times the largest texture that your video card can support.
  5. How far can DaocSkilla 'see'?
    The maximum range the server sends positon updates for mobiles and players is around 6000 Imperial Dark Age Length Units (IDALU).  This is the distance represented by the default largest gray range circle.  For comparison, a "zone" is 65,536 IDALU in each direction.  This means that you can 'see' about 2.7% of a zone at any time.  The Dark Age client will show you anything within 3300 IDALU (adjusted upward by the height of the object), in about an 80 degree Field of View while in first person mode.
  6. Can DaocSkilla see stealthed players?
    DaocSkilla can not see stealthed players that you could not see normally in their ghosted state.  No radar hack can.  The server only sends data on stealth players to the client if the stealther fails his pulsing stealth check and goes into ghosted mode.  There are occasions when an NPC might cause a failure of the stealth pulse though.  Also, sometimes you'll get a message saying "Player X is stealthed" when player X hasn't been announced.  This is called an "Anonymous Stealther" and indicates someone is stealthed near (~1000 IDALU) you but you can't see them.
  7. How come not every enemy player has their class displayed?
    The class-guessing system can only detect the classes of players wearing classic epic armor.
  8. I've got "Track Character Logins" checked, but no characters are listed in the box.
    The characters listed in the quicklaunch list are cached logins for characters daocskilla has seen you play. Two things must happen for a character to be added to the list. 1) The character you want to play has to have been logged into the game (not just the login screen, actually in game) at least once. 2) DaocSkilla must be working, i.e. when you logged in the character the server ping label should have a server ping, not say 'Disconnected'.
  9. Do I start DAoC or daocskilla first?
    DaocSkilla must be started and your adapter opened before starting Dark Age.
  10. How do I delete or rename a pushpin?
    There is no UI for deleting or renaming a pushpin at this time.  To delete or rename one, edit the .PIN file using a text editor.  You may also directly add pins to the file following the format described in the file.  Note:  the first line of the file is always discarded.
  11. What do I use to compile the source for daocskilla?
    DaocSkilla is written in Borland Delphi 6.  Borland used to have a free download of the Personal Edition of Delphi 6, but has removed the download from their site.  I've heard it is still available from this site.  If not try a google, kazaa, or eMule search.  You'll also need some units from the Delphi OpenGL Toolkit [delphi3d.net] if you want to compile the radar screen.

Appendix

IDAOCControl
  Main interface.  It is the "default object", i.e. you are
  always running in its namespace.  There is also an instance available:
  JavaScript
    var DAOCControl = new CDAOCControl()
  VBScript
    Dim DAOCControl as DAOCSkilla.CDAOCControl

  Methods:
    [
    id(0x00000001),
    helpstring("Send /quit")
    ]
    HRESULT _stdcall QuitDAOC( void );
    [
    id(0x00000002),
    helpstring("Change quickbar page.  Valid indexes 0-9")
    ]
    HRESULT _stdcall SetQuickbarPage([in] long dwPage );
    [
    id(0x00000003),
    helpstring("Jump!")
    ]
    HRESULT _stdcall Jump( void );
    [
    id(0x00000004),
    helpstring("Sends keystrokes to DAOC.  Various special keys are handled e.g. [cr]")
    ]
    HRESULT _stdcall SendKeys([in] BSTR bsKeys );
    [
    id(0x00000005),
    helpstring("Perform a left mouse click at X, Y")
    ]
    HRESULT _stdcall LeftClick([in] long X, [in] long Y );
    [
    id(0x00000006),
    helpstring("Perform a right mouse click at X, Y")
    ]
    HRESULT _stdcall RightClick([in] long X, [in] long Y );
    [
    id(0x00000007),
    helpstring("Stop all autonomous actions being performed by the engine, including AutoBuy, PathTo, etc")
    ]
    HRESULT _stdcall StopAllActions( void );
    [
    id(0x00000008),
    helpstring("Sleep for the specified number of milliseconds")
    ]
    HRESULT _stdcall Sleep([in] long dwTime );
    [
    id(0x00000009),
    helpstring("Select group member 1-8.")
    ]
    HRESULT _stdcall SelectGroupMember([in] long dwIndex );
    [
    id(0x0000000A),
    helpstring("Send a message to the engine\'s logger")
    ]
    HRESULT _stdcall Log([in] BSTR bsMessage );
    [
    id(0x0000000B),
    helpstring("Face current target.")
    ]
    HRESULT _stdcall Face( void );
    [
    id(0x0000000C),
    helpstring("Follow current target.")
    ]
    HRESULT _stdcall Follow( void );
    [
    id(0x0000000D),
    helpstring("Stick current target.")
    ]
    HRESULT _stdcall Stick( void );
    [
    id(0x0000000E),
    helpstring("Send a /send or /tell message to a player.")
    ]
    HRESULT _stdcall ChatSend([in] BSTR bsWho, [in] BSTR bsMessage );
    [
    id(0x0000000F),
    helpstring("Say the message via open /say")
    ]
    HRESULT _stdcall ChatSay([in] BSTR bsMessage );
    [
    id(0x00000010),
    helpstring("Say message in guild chat via /gu")
    ]
    HRESULT _stdcall ChatGuild([in] BSTR bsMessage );
    [
    id(0x00000011),
    helpstring("Say message in alliance chat via /as")
    ]
    HRESULT _stdcall ChatAlliance([in] BSTR bsMessage );
    [
    id(0x00000012),
    helpstring("Say message in chat group chat via /c")
    ]
    HRESULT _stdcall ChatChat([in] BSTR bsMessage );
    [
    id(0x00000013),
    helpstring("Say message in group chat via /g")
    ]
    HRESULT _stdcall ChatGroup([in] BSTR bsMessage );

  Events:
    To register for an event, create a function with the name:
      DAOCControl_<eventname>()
    For example, to register for the OnChatSendIncoming event in VB script:
      Sub DAOCControl_OnChatSendIncoming(ByVal Who, ByVal Message)
      End Sub
    [
    id(0x00000001),
    helpstring("Called when the connection is first established.  Only one OnConnect event fires no matter how many times the player switches characters on the same account.")
    ]
    HRESULT OnConnect( void );
    [
    id(0x00000002),
    helpstring("Called when the connection is broken, either via Quitting or Link Death.")
    ]
    HRESULT OnDisconnect( void );
    [
    id(0x00000003),
    helpstring("Called when someone sends your character a direct /send or /tell message.")
    ]
    HRESULT OnChatSendIncoming([in] BSTR bsWho, [in] BSTR bwMessage );
    [
    id(0x00000004),
    helpstring("Called when a popup box appears on the screen (e.g. \"You have received a task!\" or \"Servers coming down in 5 minutes!\")")
    ]
    HRESULT OnPopupMessage([in] BSTR bsMessage );
    [
    id(0x00000005),
    helpstring("Called when you recieve a tradeskill commission task.")
    ]
    HRESULT OnTradeskillCommissionAssigned( void );
    [
    id(0x00000006),
    helpstring("Called when you finish a tradeskill commission task by delivering.")
    ]
    HRESULT OnTradeskillTaskCompleted( void );
    [
    id(0x00000007),
    helpstring("Called when you sucessfully make a tradeskill item.")
    ]
    HRESULT OnTradeskillSuccess([in] long iQuality );
    [
    id(0x00000008),
    helpstring("Called when you fail to make a tradeskill item.")
    ]
    HRESULT OnTradeskillFailure( void );
    [
    id(0x00000009),
    helpstring("Called when you have reached your tradeskill cap for your primary skill and must visit your master to advance again.")
    ]
    HRESULT OnTradeskillCapped( void );
    [
    id(0x0000000A),
    helpstring("Called every time the client sends a player position update to the server.")
    ]
    HRESULT OnPlayerPosUpdate( void );
    [
    id(0x0000000B),
    helpstring("Called when a character logs in, about the time the Loading... bar shows up.  This is called every time a player switches characters as well.")
    ]
    HRESULT OnCharacterLogin( void );
    [
    id(0x0000000C),
    helpstring("Called when you arrive at your PathTo or GotoNode destination.")
    ]
    HRESULT OnArriveAtGotoDest( void );
    [
    id(0x0000000D),
    helpstring("Called when the active path changes.")
    ]
    HRESULT OnPathChanged( void );
    [
    id(0x0000000E),
    helpstring("Called every time the player selects a mob / player / npc / object.  NOTE:  This is actually called twice on most selections, once to unselect the old object, once to select the new object.")
    ]
    HRESULT OnSelectedObjectChanged( void );