PDA

View Full Version : Player Waypoints (Custom Flightpaths, etc.)



Wise
31-07-13, 07:51 PM
Player Waypoints (Custom Flightpaths, etc.)
Tested on 3.3.3a revision of tc (8330)

Description


C++ class, that allows forced movement of player on predefined path
I bring this script to you as it is, I know its got its bugs, but it wasnt intended for this usage. Take it or let it be.
Possible usage

Custom flightpaths (even in Azeroth)
Ground "flight paths" (just an idea :-))
Ingame "movies"


Script is little bit buggy, but nothing serious id say. It wasnt originaly written to serve this prupose, i just wanted something that would allow me to do "ingame animation" for some quest
Bugs (known):

If player (mounted by this script) dispells mount (by right clicking on its icon), spell renews itself (icon), but mount is not shown (your just swimming in air). I dont understand why, if anybody knows, be sure to tell me
At higher speeds (mainly fly mode) it not exactly accurate. With higher speed, theres bigger chance to not land exactly on waypoint, but for example 20 yards away from it (final waypoint land is okay). Script is able to detect such sitation and skips to next waypoint, but it might be a bit messy if waypoints placed badly. Its good not to put waypoints too close to each other (again, mainly for fly mode, walkmode should be ok) and not put them too close to buildings. Walking, running is fine (you end up within 5 yards away from destination in db).
Porting flying player may cause some mess, but relog should fix it




Example of player waypoint movement
http://img121.imageshack.us/img121/310/previewvideo.jpg (http://www.stream.cz/video/478277-wow-emulation-player-waypoints)

What you have to do


Create npc with these flags:


Gossip

Edit following script to suit its needs
Set this npcs ScriptName to npc_player_wp, or whatever name you gave to your script
Add this script into core (see http://www.trinitycore.info/index.php/Howto_customscript )



Kód

Script for npc (Just example of how to use the main class)



#include "ScriptedPch.h"

bool GossipHello_npc_player_wp(Player *player, Creature *_creature)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "TEST FLY", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20);
player->SEND_GOSSIP_MENU(1, _creature->GetGUID());
return true;
}

bool GossipSelect_npc_player_wp(Player *player, Creature *_creature, uint32 sender, uint32 action )
{
if (sender != GOSSIP_SENDER_MAIN)
return false;

if (action == GOSSIP_ACTION_INFO_DEF + 20)
{
player->playerControlledMovement = new PlayerControlledMovement(player);
player->Unmount();
player->SetPosition(_creature->GetPositionX(), _creature->GetPositionY(), _creature->GetPositionZ(), _creature->GetOrientation(), true);
player->PlayerTalkClass->CloseGossip();
player->playerControlledMovement->LoadPath(3); // this is important, number in brackets is number of waypoint path in db
player->PlayerControlledMovementEnabled = true;
}

return true;
}


void AddSC_npc_player_wp()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_player_wp";
newscript->pGossipHello = &GossipHello_npc_player_wp;
newscript->pGossipSelect = &GossipSelect_npc_player_wp;
newscript->RegisterSelf();
}


PlayerControlledMovement.h - put it in src/game



#pragma once

class Node{
public:
Node();
float x;
float y;
float z;
int mount;
int move;
int mode;
int part;
};

typedef std::list<Node *> Nodes;

class PlayerControlledMovement
{
protected:
Player * me;
public:
int flyAnimTimer;
int failedUpdatesCounter;
bool finish;
float oldPosX;
float oldPosY;
float oldPosZ;
void Finish();
int part;
Nodes nodes;
Node * activeNode;
int nodesLenght;
PlayerControlledMovement(Player *p);
void MoveToPoint(Node * n, bool forceSlow);
void Update(uint32 diff);
void LoadPath(int pathid);
Node * GetNextNode(Node * n);
};


PlayerControlledMovement.cpp - put it in src/game

Get it at pastebin - Pastebin.com - #1 paste tool since 2002! (http://pastebin.org/304106)


Edit this file: Player.h
(lines marked with + are supposed to be added, without that +)



#include "ReputationMgr.h"
#include "BattleGround.h"
#include "DBCEnums.h"
#include "LFG.h"
+ #include "PlayerControlledMovement.h"

#include<string>
#include<vector>



class Player : public Unit, public GridObject<Player>
{
friend class WorldSession;
friend void Item::AddToUpdateQueueOf(Player *player);
friend void Item::RemoveFromUpdateQueueOf(Player *player);
public:
explicit Player (WorldSession *session);
~Player ();

+ PlayerControlledMovement * playerControlledMovement;
+ bool PlayerControlledMovementEnabled;

void CleanupsBeforeDelete(bool finalCleanup = true);

static UpdateMask updateVisualBits;
static void InitVisibleBits();

void AddToWorld();


Edit this file: Player.cpp
(lines marked with + are supposed to be added, without that +)


Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this)
{
+ PlayerControlledMovementEnabled = false;

m_speakTime = 0;
m_speakCount = 0;

m_objectType |= TYPEMASK_PLAYER;
m_objectTypeId = TYPEID_PLAYER;

m_valuesCount = PLAYER_END;



void Player::Update(uint32 p_time)
{
if (!IsInWorld())
return;

+ if (PlayerControlledMovementEnabled == true)
+ playerControlledMovement->Update(p_time);

// undelivered mail
if (m_nextMailDelivereTime && m_nextMailDelivereTime <= time(NULL))
{
SendNewMail();
++unReadMails;

// It will be recalculate at mailbox open (for unReadMails important non-0 until mailbox open, it also will be recalculated)
m_nextMailDelivereTime = 0;
}



SQL - import into world DB



-- ----------------------------
-- Table structure for `custom_character_movepaths`
-- ----------------------------
DROP TABLE IF EXISTS `custom_character_movepaths`;
CREATE TABLE `custom_character_movepaths` (
`PathID` int(11) NOT NULL default '0',
`TravelOrder` int(11) NOT NULL default '0',
`x` float default NULL,
`y` float default NULL,
`z` float default NULL,
`mount` int(11) default NULL,
`move` tinyint(4) default NULL,
`spawn` int(11) default NULL,
`mode` smallint(6) default NULL,
`emote` int(11) default NULL,
`wait` int(11) default NULL,
PRIMARY KEY (`PathID`,`TravelOrder`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Few words to that table - There are some unused fields, mainly because it was (and still is) intended to be used in a bit different way. What youv got is like a developement version of my unfinished script a bit edited to serve like title says.
Whats important:

PathID, which is used in npc gossip scripts to make player moving
TravelOrder - number waypoints. Waypoints will follow after each other depending on this order (they are ordered by this field when loading from db)
mount - is ID of mount spell player should have on this waypoint
move - nut sure what this was for, leave it 0
spawn, emote, wait - not yet used, leave blank
mode - speed on given node

1 - bullettime
2 - walk
3 - run
4 - slow ground mount
5 - fast ground mount
6 - fast fly






Credits : Hkarta