diff --git a/data/sql/updates/pending_db_world/rev_1567205199450545499.sql b/data/sql/updates/pending_db_world/rev_1567205199450545499.sql new file mode 100644 index 000000000..690c59eb1 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1567205199450545499.sql @@ -0,0 +1,8 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1567205199450545499'); + +DELETE FROM `trinity_string` WHERE `entry` IN (30077,30078,30079); +INSERT INTO `trinity_string` (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) +VALUES +(30077,'Toggle Instant Flight',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(30078,'Instant Flight ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(30079,'Instant Flight OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6b366583f..a0d65ae5f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -933,6 +933,8 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this) m_charmAISpells[i] = 0; m_applyResilience = true; + + m_isInstantFlightOn = true; } Player::~Player() @@ -14989,6 +14991,9 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool menu->GetGossipMenu().AddGossipMenuItemData(itr->second.OptionID, itr->second.ActionMenuID, itr->second.ActionPoiID); } } + + if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && npcflags & UNIT_NPC_FLAG_FLIGHTMASTER) + menu->GetGossipMenu().AddMenuItem(-1, GOSSIP_ICON_INTERACT_1, GetSession()->GetTrinityString(LANG_TOGGLE_INSTANT_FLIGHT), 0, GOSSIP_ACTION_TOGGLE_INSTANT_FLIGHT, "", 0, false); // instant flight toggle option } void Player::SendPreparedGossip(WorldObject* source) @@ -15041,6 +15046,22 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men uint32 gossipOptionId = item->OptionType; uint64 guid = source->GetGUID(); + if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && source->GetTypeId() == TYPEID_UNIT) + { + if (gossipOptionId == GOSSIP_ACTION_TOGGLE_INSTANT_FLIGHT && source->GetUInt32Value(UNIT_NPC_FLAGS) & UNIT_NPC_FLAG_FLIGHTMASTER) + { + ToggleInstantFlight(); + + if (m_isInstantFlightOn) + GetSession()->SendNotification(LANG_INSTANT_FLIGHT_ON); + else + GetSession()->SendNotification(LANG_INSTANT_FLIGHT_OFF); + + PlayerTalkClass->SendCloseGossip(); + return; + } + } + if (source->GetTypeId() == TYPEID_GAMEOBJECT) { if (gossipOptionId > GOSSIP_OPTION_QUESTGIVER) @@ -15203,6 +15224,11 @@ uint32 Player::GetDefaultGossipMenuForSource(WorldObject* source) return 0; } +void Player::ToggleInstantFlight() +{ + m_isInstantFlightOn = !m_isInstantFlightOn; +} + /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ @@ -21754,7 +21780,7 @@ bool Player::ActivateTaxiPathTo(std::vector const& nodes, Creature* npc //RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK); // Xinef: dont use instant flight paths if spellid is present (custom calls use spellid = 1) - if (sWorld->getBoolConfig(CONFIG_INSTANT_TAXI) && !spellid) + if ((sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 1 || (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && m_isInstantFlightOn)) && !spellid) { TaxiNodesEntry const* lastPathNode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]); m_taxi.ClearTaxiDestinations(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 09fb52a6e..d63164a81 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -909,6 +909,11 @@ enum PlayerCommandStates CHEAT_WATERWALK = 0x10 }; +enum InstantFlightGossipAction +{ + GOSSIP_ACTION_TOGGLE_INSTANT_FLIGHT = 500 +}; + class PlayerTaxi { public: @@ -1395,6 +1400,8 @@ class Player : public Unit, public GridObject uint32 GetGossipTextId(WorldObject* source); static uint32 GetDefaultGossipMenuForSource(WorldObject* source); + void ToggleInstantFlight(); + /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ @@ -2961,6 +2968,8 @@ class Player : public Unit, public GridObject // duel health and mana reset attributes uint32 healthBeforeDuel; uint32 manaBeforeDuel; + + bool m_isInstantFlightOn; }; void AddItemsSetItem(Player* player, Item* item); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 1c5eb863c..81f7e35c9 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -19310,8 +19310,13 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) uint32 appendValue = m_uint32Values[UNIT_NPC_FLAGS]; if (creature) + { + if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && appendValue & UNIT_NPC_FLAG_FLIGHTMASTER) + appendValue |= UNIT_NPC_FLAG_GOSSIP; // flight masters need NPC gossip flag to show instant flight toggle option + if (!target->CanSeeSpellClickOn(creature)) appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK; + } fieldBuffer << uint32(appendValue); } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 92a91490c..99d1b7010 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1308,5 +1308,10 @@ enum TrinityStrings LANG_BAN_IP_YOUPERMBANNEDMESSAGE_WORLD = 11018, LANG_MUTED_PLAYER = 30000, // Mute for player 2 hour + + // Instant Flight + LANG_TOGGLE_INSTANT_FLIGHT = 30077, + LANG_INSTANT_FLIGHT_ON = 30078, + LANG_INSTANT_FLIGHT_OFF = 30079 }; #endif diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 05186efaf..12ac17b07 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -901,7 +901,7 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL_DIFFERENCE] = sConfigMgr->GetIntDefault("RecruitAFriend.MaxDifference", 4); m_bool_configs[CONFIG_ALL_TAXI_PATHS] = sConfigMgr->GetBoolDefault("AllFlightPaths", false); - m_bool_configs[CONFIG_INSTANT_TAXI] = sConfigMgr->GetBoolDefault("InstantFlightPaths", false); + m_int_configs[CONFIG_INSTANT_TAXI] = sConfigMgr->GetIntDefault("InstantFlightPaths", 0); m_bool_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfigMgr->GetBoolDefault("Instance.IgnoreLevel", false); m_bool_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfigMgr->GetBoolDefault("Instance.IgnoreRaid", false); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index c530005a0..681774bc6 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -91,7 +91,6 @@ enum WorldBoolConfigs CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND, CONFIG_ALLOW_TWO_SIDE_TRADE, CONFIG_ALL_TAXI_PATHS, - CONFIG_INSTANT_TAXI, CONFIG_INSTANCE_IGNORE_LEVEL, CONFIG_INSTANCE_IGNORE_RAID, CONFIG_INSTANCE_GMSUMMON_PLAYER, @@ -270,7 +269,7 @@ enum WorldIntConfigs CONFIG_CHAT_CHANNEL_LEVEL_REQ, CONFIG_CHAT_WHISPER_LEVEL_REQ, CONFIG_CHAT_SAY_LEVEL_REQ, - CONFIG_PARTY_LEVEL_REQ, + CONFIG_PARTY_LEVEL_REQ, CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN, CONFIG_TRADE_LEVEL_REQ, CONFIG_TICKET_LEVEL_REQ, @@ -339,6 +338,7 @@ enum WorldIntConfigs CONFIG_WARDEN_NUM_OTHER_CHECKS, CONFIG_BIRTHDAY_TIME, CONFIG_SOCKET_TIMEOUTTIME_ACTIVE, + CONFIG_INSTANT_TAXI, INT_CONFIG_VALUE_COUNT }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 57a39f133..3379052c6 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1187,6 +1187,7 @@ AllFlightPaths = 0 # of making them wait while flying. # Default: 0 - (Disabled) # 1 - (Enabled) +# 2 - (Enabled, but the player can toggle instant flight off or on at each flight master) InstantFlightPaths = 0