• This is a read only backup of the old Emudevs forum. If you want to have anything removed, please message me on Discord: KittyKaev

[LUA + C++] Custom Fly Taxi without Gossip

luzifix

Respected Member
Hello,

i remove the gossip requirement for custom taxi's

UnitMethods.h
Code:
    int GetVehicleBase(lua_State*, Unit*);
    int HasEmptySeat(lua_State*, Unit*);
    int StartTaxi(lua_State*, Unit*);
  + int StartCustomTaxi(lua_State*, Unit*);
    int SetPlayerLock(lua_State*, Unit*);
    int GetNearestPlayer(lua_State*, Unit*);
    int GetNearestGameObject(lua_State*, Unit*);

UnitMethods.cpp
Code:
int LuaUnit::StartTaxi(lua_State* L, Unit* unit)
{
    TO_PLAYER();

    uint32 pathId = luaL_checkunsigned(L, 1);

    LuaTaxiMgr::StartTaxi(player, pathId);
    return 0;
}

+ int LuaUnit::StartCustomTaxi(lua_State* L, Unit* unit)
+ {
+     TO_PLAYER();
+ 
+     uint32 pathId = luaL_checkunsigned(L, 1);
+ 
+     LuaTaxiMgr::StartCustomTaxi(player, pathId);
+     return 0;
+ }

int LuaUnit::SetPlayerLock(lua_State* L, Unit* unit)
{
    TO_PLAYER();

    bool apply = luaL_optbool(L, 1, true);

    if (apply)
    {
        player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED | UNIT_FLAG_SILENCED);
        player->SetClientControl(player, 0);
    }
    else
    {
        player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED | UNIT_FLAG_SILENCED);
        player->SetClientControl(player, 1);
    }
    return 0;
}

LuaFunctions.h
Code:
{"StartTaxi", &LuaUnit::StartTaxi},
+ {"StartCustomTaxi", &LuaUnit::StartCustomTaxi},
{"GossipSendPOI", &LuaUnit::GossipSendPOI},

LuaEngine.h
Code:
    static void StartTaxi(Player* player, uint32 pathid);
  + static void StartCustomTaxi(Player* player, uint32 pathid);
    static uint32 AddPath(std::list<TaxiPathNodeEntry> nodes, uint32 mountA, uint32 mountH, uint32 price = 0, uint32 pathId = 0);

LuaEngine.cpp
Code:
// Lua taxi helper functions
uint32 LuaTaxiMgr::nodeId = 500;
void LuaTaxiMgr::StartTaxi(Player* player, uint32 pathid)
{
    if (pathid >= sTaxiPathNodesByPath.size())
        return;

    TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathid];
    if (path.size() < 2)
        return;

    std::vector<uint32> nodes;
    nodes.resize(2);
    nodes[0] = path[0].index;
    nodes[1] = path[path.size()-1].index;

    player->ActivateTaxiPathTo(nodes);
}

+ void LuaTaxiMgr::StartCustomTaxi(Player* player, uint32 pathid)
+ {
+     if (pathid >= sTaxiPathNodesByPath.size())
+         return;
+ 
+     TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathid];
+     if (path.size() < 2)
+         return;
+ 
+     std::vector<uint32> nodes;
+     nodes.resize(2);
+     nodes[0] = path[0].index;
+     nodes[1] = path[path.size()-1].index;
+*
+     player->ActivateCustomTaxiPathTo(nodes);
+ }

Player.h
Code:
     bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = NULL, uint32 spellid = 0);
   + bool ActivateCustomTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc = NULL, uint32 spellid = 0);
     bool ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid = 0);

Player.cpp
Code:
if (money < totalcost)
    {
        GetSession()->SendActivateTaxiReply(ERR_TAXINOTENOUGHMONEY);
        m_taxi.ClearTaxiDestinations();
        return false;
    }

    //Checks and preparations done, DO FLIGHT
    ModifyMoney(-(int32)totalcost);
    UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
    UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1);

    // prevent stealth flight
    //RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);

    if (sWorld->getBoolConfig(CONFIG_INSTANT_TAXI))
    {
        TaxiNodesEntry const* lastPathNode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]);
        m_taxi.ClearTaxiDestinations();
        TeleportTo(lastPathNode->map_id, lastPathNode->x, lastPathNode->y, lastPathNode->z, GetOrientation());
        return false;
    }
    else
    {
        GetSession()->SendActivateTaxiReply(ERR_TAXIOK);
        GetSession()->SendDoFlight(mount_display_id, sourcepath);
    }
    return true;
}

+ bool Player::ActivateCustomTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc /*= NULL*/, uint32 spellid /*= 0*/)
+ {
+     if (nodes.size() < 2)
+         return false;
+ 
+     // not let cheating with start flight in time of logout process || while in combat || has type state: stunned || has type state: root
+     if (GetSession()->isLogingOut() || IsInCombat() || HasUnitState(UNIT_STATE_STUNNED) || HasUnitState(UNIT_STATE_ROOT))
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXIPLAYERBUSY);
+         return false;
+     }
+ 
+     if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
+         return false;
+ 
+     // taximaster case
+ 
+     // not let cheating with start flight mounted
+     if (IsMounted())
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXIPLAYERALREADYMOUNTED);
+         return false;
+     }
+ 
+     if (IsInDisallowedMountForm())
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXIPLAYERSHAPESHIFTED);
+         return false;
+     }
+     
+     // cast case or scripted call case
+     RemoveAurasByType(SPELL_AURA_MOUNTED);
+ 
+     if (IsInDisallowedMountForm())
+         RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
+ 
+     if (Spell* spell = GetCurrentSpell(CURRENT_GENERIC_SPELL))
+         if (spell->m_spellInfo->Id != spellid)
+             InterruptSpell(CURRENT_GENERIC_SPELL, false);
+ 
+     InterruptSpell(CURRENT_AUTOREPEAT_SPELL, false);
+ 
+     if (Spell* spell = GetCurrentSpell(CURRENT_CHANNELED_SPELL))
+         if (spell->m_spellInfo->Id != spellid)
+             InterruptSpell(CURRENT_CHANNELED_SPELL, true);
+     
+ 
+     uint32 sourcenode = nodes[0];
+ 
+     // starting node too far away (cheat?)
+     TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(sourcenode);
+     if (!node)
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXINOSUCHPATH);
+         return false;
+     }
+ 
+     // check node starting pos data set case if provided
+     /*if (node->x != 0.0f || node->y != 0.0f || node->z != 0.0f)
+     {
+         if (node->map_id != GetMapId() ||
+             (node->x - GetPositionX())*(node->x - GetPositionX())+
+             (node->y - GetPositionY())*(node->y - GetPositionY())+
+             (node->z - GetPositionZ())*(node->z - GetPositionZ()) >
+             (2*INTERACTION_DISTANCE)*(2*INTERACTION_DISTANCE)*(2*INTERACTION_DISTANCE))
+         {
+             GetSession()->SendActivateTaxiReply(ERR_TAXITOOFARAWAY);
+             return false;
+         }
+     }
+     // node must have pos if taxi master case (npc != NULL)
+     else if (npc)
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXIUNSPECIFIEDSERVERERROR);
+         return false;
+     }*/
+ 
+     // Prepare to flight start now
+ 
+     // stop combat at start taxi flight if any
+     CombatStop();
+ 
+     StopCastingCharm();
+     StopCastingBindSight();
+     ExitVehicle();
+ 
+     // stop trade (client cancel trade at taxi map open but cheating tools can be used for reopen it)
+     TradeCancel(true);
+ 
+     // clean not finished taxi path if any
+     m_taxi.ClearTaxiDestinations();
+ 
+     // 0 element current node
+     m_taxi.AddTaxiDestination(sourcenode);
+ 
+     // fill destinations path tail
+     uint32 sourcepath = 0;
+     uint32 totalcost = 0;
+ 
+     uint32 prevnode = sourcenode;
+     uint32 lastnode = 0;
+ 
+     for (uint32 i = 1; i < nodes.size(); ++i)
+     {
+         uint32 path, cost;
+ 
+         lastnode = nodes[i];
+         sObjectMgr->GetTaxiPath(prevnode, lastnode, path, cost);
+ 
+         if (!path)
+         {
+             m_taxi.ClearTaxiDestinations();
+             return false;
+         }
+ 
+         totalcost += cost;
+ 
+         if (prevnode == sourcenode)
+             sourcepath = path;
+ 
+         m_taxi.AddTaxiDestination(lastnode);
+ 
+         prevnode = lastnode;
+     }
+ 
+     // get mount model (in case non taximaster (npc == NULL) allow more wide lookup)
+     //
+     // Hack-Fix for Alliance not being able to use Acherus taxi. There is
+     // only one mount ID for both sides. Probably not good to use 315 in case DBC nodes
+     // change but I couldn't find a suitable alternative. OK to use class because only DK
+     // can use this taxi.
+     uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeam(), npc == NULL || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
+ 
+     // in spell case allow 0 model
+     if ((mount_display_id == 0 && spellid == 0) || sourcepath == 0)
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXIUNSPECIFIEDSERVERERROR);
+         m_taxi.ClearTaxiDestinations();
+         return false;
+     }
+ 
+     uint32 money = GetMoney();
+ 
+     if (npc)
+         totalcost = (uint32)ceil(totalcost*GetReputationPriceDiscount(npc));
+ 
+     if (money < totalcost)
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXINOTENOUGHMONEY);
+         m_taxi.ClearTaxiDestinations();
+         return false;
+     }
+ 
+     //Checks and preparations done, DO FLIGHT
+     ModifyMoney(-(int32)totalcost);
+     UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
+     UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1);
+ 
+     // prevent stealth flight
+     //RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK);
+ 
+     if (sWorld->getBoolConfig(CONFIG_INSTANT_TAXI))
+     {
+         TaxiNodesEntry const* lastPathNode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]);
+         m_taxi.ClearTaxiDestinations();
+         TeleportTo(lastPathNode->map_id, lastPathNode->x, lastPathNode->y, lastPathNode->z, GetOrientation());
+         return false;
+     }
+     else
+     {
+         GetSession()->SendActivateTaxiReply(ERR_TAXIOK);
+         GetSession()->SendDoFlight(mount_display_id, sourcepath);
+     }
+     return true;
+ }

bool Player::ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid /*= 0*/)
{
    TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(taxi_path_id);
    if (!entry)
        return false;

    std::vector<uint32> nodes;

    nodes.resize(2);
    nodes[0] = entry->from;
    nodes[1] = entry->to;

    return ActivateTaxiPathTo(nodes, NULL, spellid);
}

Lua Scirpt
Code:
	local TaxiP = {
                       -- {mapId, x, y, z},
			  {1, -1930, 3060, 0}, 
			  {1, -1940, 3070, 0}, 
			  {1, -1950, 3080, 0}, 
			  {1, -1960, 3090, 0}, 
			  {1, -1970, 3100, 0}, 
			  {1, -1980, 3110, 0}
			  }
     -- AddTaxiPath(pathTable, mountA, mountH, price, pathId)
	AddTaxiPath(TaxiP , MountID, 29662, 0, 70000)
    
     -- plr:StartCustomTaxi(pathId)
	plr:StartCustomTaxi(70000)
 

Rochet2

Moderator / Eluna Dev
Hmm .. I dont get it.
What did you do exactly?
You can already have flight points and flying without gossip.. on eluna
 

Nirelz

Epic Member
Tested it and it dosnt set you on a "flying mount"... it simply just teleports you towards final destination...
 
Top