Custom Flighpaths

Indította Action, 2010 július 19, 10:00:13 DÉLUTÁN

Előző téma - Következő téma

Action

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]
A WORD elszáll, az írás megmarad.

Girosz


Powered by EzPortal