Szerző Téma: Custom Flighpaths  (Megtekintve 3893 alkalommal)

Nem elérhető Action

  • Adminisztrátor
  • Cube Head
  • *****
  • Hozzászólások: 1235
  • IBF Mester!
  • Op. Rendszer: Windows 8.1
Custom Flighpaths
« Dátum: 2010 Július 19, 11:00:13 pm »
Ez a modifikáció csak a 8600-as revtől mükődik.

Nos kezdjük az adatbázissal:

Importáljuk ez a pár sort a world adatbázisba:

-- ----------------------------
-- Tábla szerkezet `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;


Jöjjön a scriptünk:

flight.cpp:

#include "ScriptPCH.h"
 
bool GossipHello_npc_player_wp(Player *player, Creature *_creature)
{
        player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, "Repulni szeretnek!", 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);
                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();
}
Ezt a scriptet másoljuk be az src/server/scripts/Custom mappába

src/server/scripts/CMakeLists.txt-be ilesszük be ezt a sort:
Custom/flight.cpp

Nyíssuk meg az src/server/game/Scripting/Scriptloader.cpp-t

//custom alá ilesszük be ezt:

[code]
void AddSC_npc_player_wp();
A következő //custom alá pedig ezt:

AddSC_npc_player_wp();
Mentsük el.

Nah és most jön a core modifikáció:

Hozzunk létre az src/server/game-ban egy flight mappát.

Hozzunk létre egy PlayerControlledMovement.h -t a flight mappába aminek a tartalma:
#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);
};
Hozzunk létre egy PlayerControlledMovement.cpp -t a flight mappába aminek a tartalma:
#include "pchdef.h"
#include "PlayerControlledMovement.h"
#include "PointMovementGenerator.h"
#include "ScriptPCH.h"
#include "Creature.h"
#include <stdio.h>
#include <time.h>
#include <list>
 
extern DatabaseType WorldDatabase;
 
Node::Node() {}
 
PlayerControlledMovement::PlayerControlledMovement(Player *p)
{
        me = p;
}
 
void PlayerControlledMovement::Finish()
{
        me->GetMotionMaster()->Clear();
        if(activeNode->mode == 6)
        {
                Node * n = new Node();
                n->x = me->GetPositionX();
                n->y = me->GetPositionY();
                n->z = me->GetPositionZ();
                n->mode = 6;
                n->mount = activeNode->mount;
                n->move = true;
                n->part = nodesLenght;
                me->CastSpell(me, 45472, true);
        }
 
        me->SetClientControl(me, true);
        me->RemoveAurasDueToSpell(60865);
        if (activeNode->mount != 0)
                me->RemoveAurasDueToSpell(activeNode->mount);
        me->PlayerControlledMovementEnabled = false;
        me->SetFlying(false);
        finish = false;
}
 
void PlayerControlledMovement::Update(uint32 diff)
{
        if ((me->GetPositionX()- activeNode->x) < 5 && (me->GetPositionX()- activeNode->x) > -5  
                && (me->GetPositionY() - activeNode->y) < 5 && (me->GetPositionY() - activeNode->y) > -5
                && (me->GetPositionZ() - activeNode->z) < 5 && (me->GetPositionZ() - activeNode->z) > -5)
        {
                if (nodesLenght != activeNode->part)
                {
                        MoveToPoint(GetNextNode(activeNode), false);
                }
                else
                        Finish();
        }
        else
        {
                if (oldPosX == me->GetPositionX() && oldPosY == me->GetPositionY() && oldPosZ == me->GetPositionZ())
                {
                        failedUpdatesCounter++;
                        if (failedUpdatesCounter == 5)
                        {
                                if (nodesLenght != activeNode->part)
                                        MoveToPoint(GetNextNode(activeNode), false);
                                else
                                        MoveToPoint(activeNode, true);
                        }
                }
                else
                        failedUpdatesCounter = 0;
 
                oldPosX = me->GetPositionX();
                oldPosY = me->GetPositionY();
                oldPosZ = me->GetPositionZ();
        }
 
        if (me->isInCombat())
                Finish();
 
        if (finish)
        {
                if (activeNode->mode == 6 && flyAnimTimer <= diff)
                {
                        if (SpellEntry const *spellInfo = sSpellStore.LookupEntry( 60865 ))
                        {
                                Aura * aura = Aura::TryCreate(spellInfo, me, me);
                                aura->SetDuration(10000);
                        }
 
                        flyAnimTimer = 9000;
                }
                else if (activeNode->mode == 6)
                        flyAnimTimer -= diff;
                        
                if (activeNode->mount != 0)
                {
                        if (!me->HasAura(activeNode->mount))
                        {
                                if(!me->IsMounted())
                                {
                                        me->RemoveAllAuras();
 
                                        if (SpellEntry const *spellInfo = sSpellStore.LookupEntry( activeNode->mount ))
                                                Aura::TryCreate(spellInfo, me, me);
                                }
                        }
                }
                else
                {
                        if (me->GetMountID() != 0)
                        {
                                me->Unmount();
                        }
                }
        }
}
 
void PlayerControlledMovement::MoveToPoint(Node * n, bool forceSlow)
{
        if (n->move == 0)
                me->SetClientControl(me, false);
        else
                me->SetClientControl(me, true);
 
        if (n->mode == 6)
        {
                me->AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE);
                flyAnimTimer = 0;
                me->SetFlying(true);
        }
        else
        {
                me->SetFlying(false);
                me->RemoveUnitMovementFlag(MOVEMENTFLAG_FLY_MODE);
        }
 
        activeNode = n;
        oldPosX = me->GetPositionX();
        oldPosZ = me->GetPositionZ();
        oldPosY = me->GetPositionY();
        failedUpdatesCounter = 0;
        float speed;
        switch (activeNode->mode)
        {
                case 1:
                        speed = 1.0f;
                        break;
                case 2:
                        speed = 3.0f;
                        break;
                case 3:
                        speed = 6.5f;
                        break;
                case 4:
                        speed = 8.0f;
                        break;
                case 5:
                        speed = 10.0f;
                        break;
                case 6:
                        speed = 25.0f;
                        break;
                default:
                        speed = 1.0f;
                        break;
        }
        if (!forceSlow)
                me->GetMotionMaster()->MoveCharge(n->x, n->y, n->z, speed, EVENT_CHARGE);
        else
                me->GetMotionMaster()->MovePoint(me->GetGUIDLow(), n->x, n->y, n->z);
}
 
Node * PlayerControlledMovement::GetNextNode(Node * n)
{
        Nodes::iterator j;
    for (j = nodes.begin(); j != nodes.end(); ++j)
        {
                Node * nod = *j;
                if (nod->part == n->part + 1)
                {
                        if (n->mount != nod->mount)
                                me->RemoveAurasDueToSpell(n->mount);
                        return nod;              
                }
        }
}
 
void PlayerControlledMovement::LoadPath(int pathid)
{
        QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT x, y, z, mount, move, mode FROM custom_character_movepaths WHERE PathID = %u ORDER BY TravelOrder ASC", pathid);
        //                                                                                                                0  1  2  3      4     5  
        if(result)
        {
                nodes.clear();
                int i = 0;
                do
                {
                        Field *fields = result->Fetch();
                        i++;
                        Node * n = new Node();
                        n->part = i;
                        n->x = fields[0].GetFloat();
                        n->y = fields[1].GetFloat();
                        n->z = fields[2].GetFloat();
                        n->mount = fields[3].GetInt32();
                        n->move = fields[4].GetInt32();
                        n->mode = fields[5].GetInt32();
                        nodes.push_back(n);
                        if (i == 1)
                                MoveToPoint(n, false);
                }   while (result->NextRow());
                nodesLenght = i;
        }
}
Nyíssuk meg a player.h-t és a +-jelesekkel egészítsük ki:

#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();


Nyíssuk meg a player.cpp-t és a +-jelesekkel egészítsük ki:

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;
    }
Mentés.

Következő lépés:

src/server/scripts/Cmakelist.txt-be ilesszük be az alábbi sort a 94.sorba:

${CMAKE_SOURCE_DIR}/src/server/game/flight

src/server/scripts/game/Cmakelist.txt-be ilesszük be ezeket:

flight/PlayerControlledMovement.h
flight/PlayerControlledMovement.cpp
Majd a 226. sorba:

${CMAKE_SOURCE_DIR}/src/server/game/flight
És az utolsó lépés:

make
make install
NPC a scripthez:
INSERT  INTO `creature_template` (`entry`, `difficulty_entry_1`,  `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`,  `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`,  `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`,  `faction_A`, `faction_H`, `npcflag`, `speed`, `scale`, `rank`, `mindmg`,  `maxdmg`, `dmgschool`, `attackpower`, `dmg_multiplier`,  `baseattacktime`, `rangeattacktime`, `unit_class`, `unit_flags`,  `dynamicflags`, `family`, `trainer_type`, `trainer_spell`,  `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`,  `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`,  `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`,  `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`,  `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`,  `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`,  `Health_mod`, `Mana_mod`, `Armor_mod`, `RacialLeader`, `questItem1`,  `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`,  `movementId`, `RegenHealth`, `equipment_id`, `mechanic_immune_mask`,  `flags_extra`, `ScriptName`, `WDBVerified`)  values('100000','0','0','0','0','0','28766','0','0','0','Joseph','AirPort','','0','80','80','2','35','35','1','1','1','0','0','0','0','0','1','0','0','2','0','0','0','0','0','0','0','0','0','0','7','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','','0','3','1.77381','5.50826','1','0','0','0','0','0','0','0','0','1','0','0','0','npc_player_wp','11403');
Szerver restart és .npc add 100000


A leírást készítette, Drestor !
[/code]
« Utoljára szerkesztve: 2010 Július 19, 11:52:49 pm írta Action »
A WORD elszáll, az írás megmarad.

Girosz

  • Vendég
Re:Custom Flighpaths
« Válasz #1 Dátum: 2010 Július 20, 12:01:22 am »
Commandok a scripthez.

.flight add
.flight mod
.flight del

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27