Сборник патчей
|
|
Daemon | Дата: Суббота, 26.05.2012, 23:21 | Сообщение # 1 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| И так, ловите скрипт на Анонс бана, кика и мута
Code # HG changeset patch # User MaDo # Date 1326554394 -10800 # Node ID 66812d47f6bcca7a5dd58ebfdb2d5472f77c2b00 # Parent cb04a4a860fb5b33f03bb677ced3d0171efc33df Ba_Kick_Mute_Announce
diff -r cb04a4a860fb5b33f03bb677ced3d0171efc33df -r 66812d47f6bcca7a5dd58ebfdb2d5472f77c2b00 src/server/game/Chat/Commands/Level2.cpp --- a/src/server/game/Chat/Commands/Level2.cpp Sun Jan 01 21:00:11 2012 +0300 +++ b/src/server/game/Chat/Commands/Level2.cpp Sat Jan 14 18:19:54 2012 +0300 @@ -46,6 +46,9 @@ //mute player for some times bool ChatHandler::HandleMuteCommand(const char* args) { + + std::string announce; + char* nameStr; char* delayStr; extractOptFirstArg((char*)args, &nameStr, &delayStr); @@ -57,6 +60,13 @@ if (mutereason != NULL) mutereasonstr = mutereason;
+ if(!mutereason) + { + PSendSysMessage("You must enter a reason of mute"); + SetSentErrorMessage(true); + return false; + } + Player* target; uint64 target_guid; std::string target_name; @@ -104,6 +114,16 @@
PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notspeaktime, mutereasonstr.c_str());
+ announce = "The character '"; + announce += nameStr; + announce += "' was muted for "; + announce += delayStr; + announce += " minutes by the character '"; + announce += m_session->GetPlayerName(); + announce += "'. The reason is: "; + announce += mutereason; + HandleAnnounceCommand(announce.c_str()); + return true; }
@@ -224,6 +244,9 @@ //kick player bool ChatHandler::HandleKickPlayerCommand(const char *args) { + + std::string announce; + Player* target = NULL; std::string playerName; if (!extractPlayerTarget((char*)args, &target, NULL, &playerName)) @@ -246,6 +269,14 @@ PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str());
target->GetSession()->KickPlayer(); + + announce = "The character '"; + announce += target->GetName(); + announce += "' was kicked by the character '"; + announce += m_session->GetPlayerName(); + announce += "'."; + HandleAnnounceCommand(announce.c_str()); + return true; }
diff -r cb04a4a860fb5b33f03bb677ced3d0171efc33df -r 66812d47f6bcca7a5dd58ebfdb2d5472f77c2b00 src/server/game/Chat/Commands/Level3.cpp --- a/src/server/game/Chat/Commands/Level3.cpp Sun Jan 01 21:00:11 2012 +0300 +++ b/src/server/game/Chat/Commands/Level3.cpp Sat Jan 14 18:19:54 2012 +0300 @@ -2919,6 +2919,8 @@ { if (!*args) return false; + + std::string announce;
char* cnameOrIP = strtok ((char*)args, " "); if (!cnameOrIP) @@ -2984,6 +2986,21 @@ SetSentErrorMessage(true); return false; } + + if (mode == BAN_CHARACTER) + announce = "The character '"; + else if (mode == BAN_IP) + announce = "The IP '"; + else + announce = "Account '"; + announce += nameOrIP.c_str(); + announce += "' was banned for "; + announce += duration; + announce += " by the character '"; + announce += m_session->GetPlayerName(); + announce += "'. The reason is: "; + announce += reason; + HandleAnnounceCommand(announce.c_str());
return true; }
Сообщение отредактировал Arxangel14 - Суббота, 26.05.2012, 23:21 |
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:21 | Сообщение # 2 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Патч на "Поиск спутников " Code # HG changeset patch # User MaDo # Date 1329557811 -14400 # Node ID 14b1cfd493358176e24160d652e4c822b3b8f234 # Parent 37536e6e494d4180e243ddf08bd98e7e3eb1322b LFG all location
diff -r 37536e6e494d4180e243ddf08bd98e7e3eb1322b -r 14b1cfd493358176e24160d652e4c822b3b8f234 src/server/game/Entities/Player/Player.cpp --- a/src/server/game/Entities/Player/Player.cpp Sat Feb 18 13:30:49 2012 +0400 +++ b/src/server/game/Entities/Player/Player.cpp Sat Feb 18 13:36:51 2012 +0400 @@ -5554,6 +5554,10 @@ bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone) { + // Player can join LFG anywhere + if (channel->flags & CHANNEL_DBC_FLAG_LFG && sWorld->getBoolConfig(CONFIG_LFG_LOCATION_ALL)) + return true; + if (channel->flags & CHANNEL_DBC_FLAG_ZONE_DEP && zone->flags & AREA_FLAG_ARENA_INSTANCE) return false; diff -r 37536e6e494d4180e243ddf08bd98e7e3eb1322b -r 14b1cfd493358176e24160d652e4c822b3b8f234 src/server/game/World/World.cpp --- a/src/server/game/World/World.cpp Sat Feb 18 13:30:49 2012 +0400 +++ b/src/server/game/World/World.cpp Sat Feb 18 13:36:51 2012 +0400 @@ -1274,6 +1274,8 @@ // MySQL ping time interval m_int_configs[CONFIG_DB_PING_INTERVAL] = ConfigMgr::GetIntDefault("MaxPingTime", 30); + + m_bool_configs[CONFIG_LFG_LOCATION_ALL] = ConfigMgr::GetBoolDefault("LFG.Location.All", true); // misc m_bool_configs[CONFIG_PDUMP_NO_PATHS] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowPaths", true); diff -r 37536e6e494d4180e243ddf08bd98e7e3eb1322b -r 14b1cfd493358176e24160d652e4c822b3b8f234 src/server/game/World/World.h --- a/src/server/game/World/World.h Sat Feb 18 13:30:49 2012 +0400 +++ b/src/server/game/World/World.h Sat Feb 18 13:36:51 2012 +0400 @@ -156,6 +156,7 @@ CONFIG_DUNGEON_FINDER_ENABLE, CONFIG_AUTOBROADCAST, CONFIG_ALLOW_TICKETS, + CONFIG_LFG_LOCATION_ALL, CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES, CONFIG_PRESERVE_CUSTOM_CHANNELS, CONFIG_PDUMP_NO_PATHS, diff -r 37536e6e494d4180e243ddf08bd98e7e3eb1322b -r 14b1cfd493358176e24160d652e4c822b3b8f234 src/server/worldserver/worldserver.conf.dist --- a/src/server/worldserver/worldserver.conf.dist Sat Feb 18 13:30:49 2012 +0400 +++ b/src/server/worldserver/worldserver.conf.dist Sat Feb 18 13:36:51 2012 +0400 @@ -2846,6 +2846,13 @@ PlayerDump.DisallowOverwrite = 1 +# +# Includes satellite to search for work elsewhere LFG +# Default: 0 - Disable +# 1 - Enable + +LFG.Location.All = 0 + # ###################################################################################################
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:22 | Сообщение # 3 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Суть мода:
Создается таблица, в которой хранится гуид, игрока ид морфа и размер (.mod scale) и, при входе игрока, данные берутся из этой таблицы. Данные пока заносятся вручную. Будьте осторожны со значениями.
Мод не тестил, ибо видуха сгорела. Просьба протестить. Подсоединяется к скрипт системе как обычный скрипт.
В планах: Добавить дополнительных проверок, имплементировать вкл/выкл мода через конфиг, реализовать занесение данных в таблицу при использовании, собственно команд .mod morph и .mod scale.
При репосте куда либо, просьба указывать автора патча. А то я смотрю на AC-WEB мои скрипты репостят от своего имени...
Собственно код с запросом в базу characters:
Code #include "ScriptPCH.h"
/* create table `character_morphs`( `guid` int(10) UNSIGNED NOT NULL COMMENT 'Character guid' DEFAULT '0', `morph` int(5) UNSIGNED NOT NULL COMMENT 'Character morph' DEFAULT '0', `scale` float(2) UNSIGNED NOT NULL COMMENT 'Character scale' DEFAULT '1', PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'Charaster morphs'; */
class morphing_on_login : public PlayerScript { public: morphing_on_login() : PlayerScript("morphing_on_login") {}
void OnLogin(Player* player) { int64 pguid = player->GetGUID(); QueryResult morph = CharacterDatabase.PQuery("SELECT morph from character_morphs WHERE guid = '%u'", pguid); QueryResult scale = CharacterDatabase.PQuery("SELECT scale from character_morphs WHERE guid = '%u'", pguid);
if (morph) player->SetDisplayId(morph->Fetch()->GetUInt32());
if (scale) player->SetFloatValue(OBJECT_FIELD_SCALE_X, scale->Fetch()->GetFloat()); } };
void AddSC_morphing_on_login() { new morphing_on_login(); }
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:23 | Сообщение # 4 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Еще 1 патч на VIP
Нпс предназначен для близлайк серверов.
и так что умеет данный нпс.
1-Ренейм (за ап) 2-Смена внешности (за ап) 3-Смена рассы и класса (за ап) 4-Сохранение персонажа онлайн 5-Сброс талантов 6-Ридинг (верховая езда) 7-Получение маунтов 8-бафы 9-отхил 10-Снятие маски смерти и дезертира и полное востановление маны и хп 11-Сброс кд 12-Морфы 13-Cброс кд на дейли и викли квесты. 14-два новых меню маунтов. 15-Возможность получить 4 36ти слотовые сумки (проверка на итем)
скачать
|
|
| |
Reeb | Дата: Суббота, 26.05.2012, 23:23 | Сообщение # 5 |
Reeb
Группа: Администраторы
Сообщений: 202
Награды: 1
Репутация: 100
Статус:
| Полезно.
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:23 | Сообщение # 6 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Обменник АП - ХОНОР Code #include "scriptPCH.h" #define GOSSIP_ITEM_ARENA_TO_HONOR "Сменить 100 Арены на 15000 Хонора" #define GOSSIP_ITEM_HONOR_TO_ARENA "Сменить 15000 Хонора на 100 Арены" class npc_arena_honor : public CreatureScript { public: npc_arena_honor() : CreatureScript("npc_arena_honor") {} bool OnGossipHello(Player* pPlayer, Creature* pCreature) { pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_ARENA_TO_HONOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_HONOR_TO_ARENA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); pPlayer->SEND_GOSSIP_MENU(3961,pCreature->GetGUID()); return true; } bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { if (uiAction == GOSSIP_ACTION_INFO_DEF+1) { if (pPlayer->GetArenaPoints() >= 100) { pPlayer->ModifyArenaPoints(-100); pPlayer->ModifyHonorPoints(+15000); }else { pCreature->MonsterWhisper("Недостаточно очков Арены.", pPlayer->GetGUID()); } pPlayer->CLOSE_GOSSIP_MENU(); return true; } if (uiAction == GOSSIP_ACTION_INFO_DEF+2) { if (pPlayer->GetHonorPoints() >= 15000) { pPlayer->ModifyHonorPoints(-15000); pPlayer->ModifyArenaPoints(+100); }else { pCreature->MonsterWhisper("Недостаточно Хонора.", pPlayer->GetGUID()); } pPlayer->CLOSE_GOSSIP_MENU(); return true; } return true; } void AddSC_npc_arena_honor() { new npc_arena_honor; }
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:24 | Сообщение # 7 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| В данном паке лежит: AC2.patch XP-After-Level-100.patch Wintergrasp.patch (OLO) VIP-Account.patch PVPRanks.patch TeleNPC.patch
качайте
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:24 | Сообщение # 8 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Воздушный Бой ЦЛК
скачать
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:24 | Сообщение # 9 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Патч на Арена-Спектатора через команды
Code diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 4ad00f5..5356680 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1237,16 +1237,19 @@ void Battleground::EventPlayerLoggedOut(Player* player) m_Players[guid].OfflineRemoveTime = sWorld->GetGameTime() + MAX_OFFLINE_TIME; if (GetStatus() == STATUS_IN_PROGRESS) { - // drop flag and handle other cleanups - RemovePlayer(player, guid, GetPlayerTeam(guid)); + if (!player->isSpectator()) + { + // drop flag and handle other cleanups + RemovePlayer(player, guid, GetPlayerTeam(guid));
- // 1 player is logging out, if it is the last, then end arena! - if (isArena()) - if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam()))) - EndBattleground(GetOtherTeam(player->GetTeam())); + // 1 player is logging out, if it is the last, then end arena! + if (isArena()) + if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam()))) + EndBattleground(GetOtherTeam(player->GetTeam())); + } } - - player->LeaveBattleground(); + if (!player->isSpectator()) + player->LeaveBattleground(); }
// This method should be called only once ... it adds pointer to queue diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 185ac48..70b2885 100755 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -355,6 +355,9 @@ ChatCommand* ChatHandler::getCommandTable() { "notify", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleNotifyCommand>, "", NULL }, { "gmnotify", SEC_MODERATOR, true, OldHandler<&ChatHandler::HandleGMNotifyCommand>, "", NULL }, { "appear", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleAppearCommand>, "", NULL }, + { "spectate", SEC_PLAYER, false, OldHandler<&ChatHandler::HandleSpectateCommand>, "", NULL }, + { "spectatecancel", SEC_PLAYER, false, OldHandler<&ChatHandler::HandleSpectateCancelCommand>, "", NULL }, + { "spectatefrom", SEC_PLAYER, false, OldHandler<&ChatHandler::HandleSpectateFromCommand>, "", NULL }, { "summon", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleSummonCommand>, "", NULL }, { "groupsummon", SEC_MODERATOR, false, OldHandler<&ChatHandler::HandleGroupSummonCommand>, "", NULL }, { "commands", SEC_PLAYER, true, OldHandler<&ChatHandler::HandleCommandsCommand>, "", NULL }, diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 24652fc..a744d7a 100755 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -255,6 +255,9 @@ class ChatHandler
bool HandleSummonCommand(const char* args); bool HandleAppearCommand(const char* args); + bool HandleSpectateCommand(const char* args); + bool HandleSpectateCancelCommand(const char* args); + bool HandleSpectateFromCommand(const char* args); bool HandleGroupSummonCommand(const char* args); bool HandleRecallCommand(const char* args); bool HandleAnnounceCommand(const char* args); diff --git a/src/server/game/Chat/Commands/Level0.cpp b/src/server/game/Chat/Commands/Level0.cpp index 97173f7..3449d9e 100755 --- a/src/server/game/Chat/Commands/Level0.cpp +++ b/src/server/game/Chat/Commands/Level0.cpp @@ -157,3 +157,163 @@ bool ChatHandler::HandleServerMotdCommand(const char* /*args*/) return true; }
+bool ChatHandler::HandleSpectateCommand(const char *args) +{ + Player* target; + uint64 target_guid; + std::string target_name; + if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) + return false; + + Player* _player = m_session->GetPlayer(); + if (target == _player || target_guid == _player->GetGUID()) + { + SendSysMessage(LANG_CANT_TELEPORT_SELF); + SetSentErrorMessage(true); + return false; + } + + // check online security + if (HasLowerSecurity(target, 0)) + return false; + + std::string chrNameLink = playerLink(target_name); + + if (_player->isInCombat()) + { + SendSysMessage(LANG_YOU_IN_COMBAT); + SetSentErrorMessage(true); + return false; + } + + if (!target) + { + SendSysMessage(LANG_PLAYER_NOT_EXIST_OR_OFFLINE); + SetSentErrorMessage(true); + return false; + } + + if (_player->GetMap()->IsBattlegroundOrArena() && !_player->isSpectator()) + { + PSendSysMessage("You are already on battleground or arena."); + SetSentErrorMessage(true); + return false; + } + + Map* cMap = target->GetMap(); + if (!cMap->IsBattlegroundOrArena()) + { + PSendSysMessage("Player didnt found in arena."); + SetSentErrorMessage(true); + return false; + } + + if (_player->GetMap()->IsBattleground()) + { + PSendSysMessage("Cant do that while you are on battleground."); + SetSentErrorMessage(true); + return false; + } + // all's well, set bg id + // when porting out from the bg, it will be reset to 0 + _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); + // remember current position as entry point for return at bg end teleportation + if (!_player->GetMap()->IsBattlegroundOrArena()) + _player->SetBattlegroundEntryPoint(); + + if (target->isSpectator()) + { + PSendSysMessage("Can`t do that. Your target is spectator."); + SetSentErrorMessage(true); + return false; + } + + PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + // to point to see at target with same orientation + float x, y, z; + target->GetContactPoint(_player, x, y, z); + + _player->SetSpectate(true); + _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); + _player->SetPhaseMask(target->GetPhaseMask(), true); + + return true; +} + +bool ChatHandler::HandleSpectateCancelCommand(const char */*args*/) +{ + Player* _player = m_session->GetPlayer(); + + if (!_player->isSpectator()) + { + PSendSysMessage("You are not spectator."); + SetSentErrorMessage(true); + return false; + } + + _player->CancelSpectate(); + _player->TeleportToBGEntryPoint(); + + return true; +} + +bool ChatHandler::HandleSpectateFromCommand(const char *args) +{ + Player* target; + uint64 target_guid; + std::string target_name; + if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) + return false; + + Player* _player = m_session->GetPlayer(); + + // check online security + if (HasLowerSecurity(target, 0)) + return false; + + if (!_player->isSpectator()) + { + PSendSysMessage("You are not spectator, spectate someone first."); + SetSentErrorMessage(true); + return false; + } + + if (target->isSpectator() && target != _player) + { + PSendSysMessage("Can`t do that. Your target is spectator."); + SetSentErrorMessage(true); + return false; + } + + if (_player->GetMap() != target->GetMap()) + { + PSendSysMessage("Cant do that. Different arenas?"); + SetSentErrorMessage(true); + return false; + } + + //check for arena preperation + //if exists than battle didn`t begin + if (target->HasAura(32728) || target->HasAura(32727)) + { + PSendSysMessage("Cant do that. Arena didn`t started."); + SetSentErrorMessage(true); + return false; + } + + (target == _player) ? _player->SetViewpoint(_player->getSpectateFrom(), false) : + _player->SetViewpoint(target, true); + return true; +} + diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index de1b0f8..6dcb89a 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -443,6 +443,9 @@ void GameObject::Update(uint32 diff)
if (ok) { + if (Player *tmpPlayer = ok->ToPlayer()) + if (tmpPlayer->isSpectator()) + return; // some traps do not have spell but should be triggered if (goInfo->trap.spellId) CastSpell(ok, goInfo->trap.spellId); @@ -1016,6 +1019,10 @@ void GameObject::SwitchDoorOrButton(bool activate, bool alternative /* = false *
void GameObject::Use(Unit* user) { + if (Player *tmpPlayer = user->ToPlayer()) + if (tmpPlayer->isSpectator()) + return; + // by default spell caster is user Unit* spellCaster = user; uint32 spellId = 0; @@ -1590,6 +1597,10 @@ void GameObject::Use(Unit* user)
void GameObject::CastSpell(Unit* target, uint32 spellId) { + if (Player *tmpPlayer = target->ToPlayer()) + if (tmpPlayer->isSpectator()) + return; + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) return; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b59c8c0..9d736bb 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -852,6 +852,10 @@ Player::Player (WorldSession* session): Unit(), m_achievementMgr(this), m_reputa
isDebugAreaTriggers = false;
+ spectatorFlag = false; + spectateCanceled = false; + spectateFrom = NULL; + SetPendingBind(0, 0); }
@@ -2308,7 +2312,12 @@ bool Player::TeleportToBGEntryPoint() ScheduleDelayedOperation(DELAYED_BG_MOUNT_RESTORE); ScheduleDelayedOperation(DELAYED_BG_TAXI_RESTORE); ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE); - return TeleportTo(m_bgData.joinPos); + bool result = TeleportTo(m_bgData.joinPos); + + if (isSpectator() && result) + SetSpectate(false); + + return result; }
void Player::ProcessDelayedOperations() @@ -2715,6 +2724,7 @@ Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
GameObject* Player::GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const { + sLog->outString("GetGameObjectIfCanInteractWith"); if (GameObject* go = GetMap()->GetGameObject(guid)) { if (go->GetGoType() == type) @@ -2851,6 +2861,78 @@ void Player::SetGMVisible(bool on) } }
+void Player::SetSpectate(bool on) +{ + if (on) + { + //add aspectof the cheetah + AddAura(5118, this); + spectatorFlag = true; + + m_ExtraFlags |= PLAYER_EXTRA_GM_ON; + setFaction(35); + + if (Pet* pet = GetPet()) + { + pet->setFaction(35); + pet->getHostileRefManager().setOnlineOfflineState(false); + RemovePet(pet, PET_SAVE_AS_CURRENT); + } + + UnsummonPetTemporaryIfAny(); + + RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + ResetContestedPvP(); + + getHostileRefManager().setOnlineOfflineState(false); + CombatStopWithPets(); + + + m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_ADMINISTRATOR); + } + else + { + uint32 newPhase = 0; + AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE); + if (!phases.empty()) + for (AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) + newPhase |= (*itr)->GetMiscValue(); + + if (!newPhase) + newPhase = PHASEMASK_NORMAL; + + SetPhaseMask(newPhase, false); + + m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON; + setFactionForRace(getRace()); + RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); + RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_ALLOW_CHEAT_SPELLS); + + if (Pet* pet = GetPet()) + { + pet->setFaction(getFaction()); + pet->getHostileRefManager().setOnlineOfflineState(true); + } + + if (spectateFrom) + SetViewpoint(spectateFrom, false); + + // restore FFA PvP Server state + if (sWorld->IsFFAPvPRealm()) + SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); + + // restore FFA PvP area state, remove not allowed for GM mounts + UpdateArea(m_areaUpdateId); + + getHostileRefManager().setOnlineOfflineState(true); + m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_PLAYER); + spectateCanceled = false; + spectatorFlag = false; + RemoveAura(5118); + } + UpdateObjectVisibility(); +} + bool Player::IsGroupVisibleFor(Player const* p) const { switch (sWorld->getIntConfig(CONFIG_GROUP_VISIBILITY)) @@ -22817,9 +22899,19 @@ void Player::StopCastingBindSight() }
void Player::SetViewpoint(WorldObject* target, bool apply) -{ +{ if (apply) { + if (target->ToPlayer() == this) + return; + + //remove Viewpoint if already have + if (isSpectator() && spectateFrom) + { + SetViewpoint(spectateFrom, false); + spectateFrom = NULL; + } + sLog->outDebug(LOG_FILTER_MAPS, "Player::CreateViewpoint: Player %s create seer %u (TypeId: %u).", GetName(), target->GetEntry(), target->GetTypeId());
if (!AddUInt64Value(PLAYER_FARSIGHT, target->GetGUID())) @@ -22832,7 +22924,12 @@ void Player::SetViewpoint(WorldObject* target, bool apply) UpdateVisibilityOf(target);
if (target->isType(TYPEMASK_UNIT) && !GetVehicle()) + { + if (isSpectator()) + spectateFrom = (Unit*)target; + ((Unit*)target)->AddPlayerToVision(this); + } } else { @@ -22847,6 +22944,9 @@ void Player::SetViewpoint(WorldObject* target, bool apply) if (target->isType(TYPEMASK_UNIT) && !GetVehicle()) ((Unit*)target)->RemovePlayerFromVision(this);
+ if (isSpectator()) + spectateFrom = NULL; + //must immediately set seer back otherwise may crash m_seer = this;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 8ee7d1a..e5bd4a9 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1157,6 +1157,11 @@ class Player : public Unit, public GridObject<Player> void SetTaxiCheater(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; } bool isGMVisible() const { return !(m_ExtraFlags & PLAYER_EXTRA_GM_INVISIBLE); } void SetGMVisible(bool on); + bool isSpectateCanceled() { return spectateCanceled; } + bool CancelSpectate() { spectateCanceled = true; } + Unit* getSpectateFrom() { return spectateFrom; } + bool isSpectator() const { return spectatorFlag; } + void SetSpectate(bool on); bool Has310Flyer(bool checkAllSpells, uint32 excludeSpellId = 0); void SetHas310Flyer(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_HAS_310_FLYER; else m_ExtraFlags &= ~PLAYER_EXTRA_HAS_310_FLYER; } void SetPvPDeath(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_PVP_DEATH; else m_ExtraFlags &= ~PLAYER_EXTRA_PVP_DEATH; } @@ -2854,6 +2859,11 @@ class Player : public Unit, public GridObject<Player> InstanceTimeMap _instanceResetTimes; uint32 _pendingBindId; uint32 _pendingBindTimer; + + //flag for spectator system + bool spectatorFlag; + bool spectateCanceled; + Unit *spectateFrom; };
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 5a7645b..1ca2de8 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3988,6 +3988,11 @@ void Unit::RemoveArenaAuras() { AuraApplication const* aurApp = iter->second; Aura const* aura = aurApp->GetBase(); + //allow aspect for spectator + if (Player *tmpPlayer = ToPlayer() ) + if (tmpPlayer->isSpectator() && aura->GetId() == 5118) + ++iter; + if (!(aura->GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_UNK21) // don't remove stances, shadowform, pally/hunter auras && !aura->IsPassive() // don't remove passive auras && (aurApp->IsPositive() || !(aura->GetSpellInfo()->AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT))) // not negative death persistent auras diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 306af9c..3dcc26e 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2591,6 +2591,8 @@ bool BattlegroundMap::AddPlayerToMap(Player* player)
void BattlegroundMap::RemovePlayerFromMap(Player* player, bool remove) { + if (player->isSpectator() && !player->isSpectateCanceled()) + player->SetSpectate(false); sLog->outDetail("MAP: Removing player '%s' from bg '%u' of map '%s' before relocating to another map", player->GetName(), GetInstanceId(), GetMapName()); Map::RemovePlayerFromMap(player, remove); } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index e1c5b90..09fdc3d 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4604,6 +4604,10 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_ONLY_INDOORS; }
+ if (Player *tmpPlayer = m_caster->ToPlayer()) + if(tmpPlayer->isSpectator() && m_spellInfo->Id != 5118) + return SPELL_FAILED_SPELL_UNAVAILABLE; + // only check at first call, Stealth auras are already removed at second call // for now, ignore triggered spells if (strict && !(_triggeredCastFlags & TRIGGERED_IGNORE_SHAPESHIFT)) diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index ab077af..8ed1173 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -134,6 +134,8 @@ public: } char const* name = itr->second->GetName(); uint8 security = itrSec; + if (security == 0) + continue; uint8 max = ((16 - strlen(name)) / 2); uint8 max2 = max; if ((max + max2 + strlen(name)) == 16)
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:25 | Сообщение # 10 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Chat Spy Патч на то, чтобы читать ЛС
смотрим
Сообщение отредактировал Arxangel14 - Суббота, 26.05.2012, 23:25 |
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:26 | Сообщение # 11 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Камень возвращения без КД (через ядро)
Code #include "ScriptPCH.h"
/* UPDATE item_template SET spellid_1 = 0, spellcooldown_1 = 0, spellcategorycooldown_1 = 0, spellcategorycooldown_2 = 0, spellcategorycooldown_3 = 0, spellcategorycooldown_4 = 0, spellcategorycooldown_5 = 0, ScriptName = "hearthstone_without_cooldown" WHERE entry = 6948; */
class hearthstone_without_cooldown : public ItemScript { public: hearthstone_without_cooldown() : ItemScript("hearthstone_without_cooldown") {}
bool OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const&) { if ((pPlayer->isInCombat()) || (pPlayer->isInFlight()) || (pPlayer->isDead())) { pPlayer->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, NULL); return false; }
if (pPlayer->IsMounted()) { pPlayer->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, pItem, NULL); return false; }
pPlayer->RemoveSpellCooldown(8690,true); pPlayer->CastSpell(pPlayer,8690,false);
return false; } };
void AddSC_hearthstone_without_cooldown() { hearthstone_without_cooldown(); }
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:26 | Сообщение # 12 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Патч на "NPC-CUSTOMIZE" (Спасибо Cemak / PandateDogmen)
Code #include "ScriptPCH.h"
enum ActCustomizeMaster { ACTION_RENAME = 1001, ACTION_CUSTOMIZE = 1002, ACTION_CONFIRM_RENAME = 1003, ACTION_CONFIRM_CUSTOMIZE = 1004 };
#define RENAME_GOLD_COST 60000000000 // Цена за смену имени (Указывать в медных монетах) #define CUSTOMIZE_GOLD_COST 90000000000 // Цена за смену внешности (Указывать в медных монетах)
#define GOSSIP_MENU_RENAME "Я Хочу Сменить Имя Персонажа" #define GOSSIP_MENU_CUSTOMIZE "Я хочу Сменить Внешность Персонажа" #define GOSSIP_MENU_RENAME_CONFIRM "Стоимость 100 очков арены Продолжить?" // Меню Стоимости смены имени #define GOSSIP_MENU_CUSTOMIZE_CONFIRM "Стоимость 200 очков арены Продолжить?" // Меню Стоимости смены внешности
#define SEND_CHAT_MSG_NOT_ARENA "У Вас Не Достаточно Очков арены!" #define SEND_CHAT_MSG_RENAME_COMPLETE "Оплата Успешно Произведена Сделайте Логаут и Введите Новое Имя Персонажа.Не Забудьте После Смены Имени,Выйти Из Игры и Удалить Из Клиента Папку Cache!" #define SEND_CHAT_MSG_CUSTOMIZE_COMPLETE "Оплата Успешно Произведена Сделайте Логаут и Измените Внешность Персонажа.Не Забудьте После Смены Внешности,Выйти Из Игры и Удалить Из Клиента Папку Cache!"
class npc_customize_master : public CreatureScript { public: npc_customize_master() : CreatureScript("npc_customize_master") { }
bool OnGossipHello(Player* player, Creature* creature) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MENU_RENAME, GOSSIP_SENDER_MAIN, ACTION_RENAME); player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MENU_CUSTOMIZE, GOSSIP_SENDER_MAIN, ACTION_CUSTOMIZE); player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); return true; }
bool OnGossipSelect(Player* player, Creature* creature, uint32 uiSender, uint32 uiAction) { if (uiSender != GOSSIP_SENDER_MAIN) return false;
player->PlayerTalkClass->ClearMenus();
switch (uiAction) { case ACTION_RENAME: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MENU_RENAME_CONFIRM, GOSSIP_SENDER_MAIN, ACTION_CONFIRM_RENAME); player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); break; case ACTION_CUSTOMIZE: player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MENU_CUSTOMIZE_CONFIRM, GOSSIP_SENDER_MAIN, ACTION_CONFIRM_CUSTOMIZE); player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); break; case ACTION_CONFIRM_RENAME: if (player->GetArenaPoints() < 100) //ренейм за 100 очков арены. { creature->MonsterWhisper(SEND_CHAT_MSG_NOT_ARENA , player->GetGUID()); }else{ creature->MonsterWhisper(SEND_CHAT_MSG_RENAME_COMPLETE, player->GetGUID()); // player->ModifyMoney(-RENAME_GOLD_COST); player->ModifyArenaPoints(-100); player->SetAtLoginFlag(AT_LOGIN_RENAME); } player->CLOSE_GOSSIP_MENU(); break; case ACTION_CONFIRM_CUSTOMIZE: if (player->GetArenaPoints() < 200) // смена внешности за 200 очков арены { creature->MonsterWhisper(SEND_CHAT_MSG_NOT_ARENA , player->GetGUID()); }else{ creature->MonsterWhisper(SEND_CHAT_MSG_CUSTOMIZE_COMPLETE, player->GetGUID()); //player->ModifyMoney(-CUSTOMIZE_GOLD_COST); player->ModifyArenaPoints(-200); player->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); } player->CLOSE_GOSSIP_MENU(); break; default: player->CLOSE_GOSSIP_MENU(); } return true; } };
void AddSC_npc_customize_master() { new npc_customize_master(); }
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:26 | Сообщение # 13 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Пассивный античит АС3
Смотрим
|
|
| |
Daemon | Дата: Суббота, 26.05.2012, 23:27 | Сообщение # 14 |
Капрал
Группа: Пользователи
Сообщений: 79
Награды: 0
Репутация: 120
Статус:
| Приветствуйте патч на "Воздушный Бой" Рабочий Придётся подогнать под ласт реву
Смотрим.
|
|
| |
Inferios | Дата: Понедельник, 28.05.2012, 12:04 | Сообщение # 15 |
Группа: Удаленные
| Dynamic Teleporter Решил выложить патч на динамического телепортера. Чем отличается он от остальных? Все манипуляции с телепортером осуществляются в игре, с помощью команд. Доступно 4 команды: - tp addpoint; - tp addmenu; - tp list; - tp remove; Подробное описание команд и их синтаксис можете посмотреть в sql файле.
С помощью данных команд, можно построить многоуровневые меню телепортаций, не замарачиваясь на координатах.
Патч в ядро: Code diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 6322151..e7890cb 100755 @@ -63,6 +63,10 @@ void AddSC_wp_commandscript(); void AddSC_gps_commandscript(); #ifdef SCRIPTS +//custom +void AddSC_npc_teleporter(); +void AddSC_tp_commandscript(); + //world void AddSC_areatrigger_scripts(); void AddSC_emerald_dragons(); @@ -1234,5 +1238,7 @@ void AddCustomScripts() #ifdef SCRIPTS /* This is where custom scripts should be added. */ + AddSC_npc_teleporter(); + AddSC_tp_commandscript(); #endif } diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt index 1570ca1..5daea6c 100644 @@ -10,6 +10,7 @@ set(scripts_STAT_SRCS ${scripts_STAT_SRCS} + Custom/npc_teleporter.cpp ) message(" -> Prepared: Custom") diff --git a/src/server/scripts/Custom/npc_teleporter.cpp b/src/server/scripts/Custom/npc_teleporter.cpp new file mode 100644 @@ -0,0 +1,317 @@ +#include "ScriptPCH.h" + +enum ActionType { + ACTION_TYPE_SUBMENU, + ACTION_TYPE_POINT +}; + +class npc_teleporter : public CreatureScript +{ +public: + npc_teleporter() : CreatureScript("npc_teleporter") { } + + bool OnGossipHello(Player *player, Creature *creature) + { + if (!player || !creature) + return false; + + return ActionSubmenu(player, creature, 0); + } + + bool OnGossipSelect(Player *player, Creature *creature, uint32 sender, uint32 action ) + { + if (player->isInCombat()) + { + player->CLOSE_GOSSIP_MENU(); + creature->MonsterTextEmote("You are in combat!", 0, true); + return false; + } + + QueryResult result = WorldDatabase.PQuery("SELECT type FROM teleporter_actions WHERE action = %u", action); + if (result && result->GetRowCount() > 0) + { + Field *fields = result->Fetch(); + uint8 aType = fields[0].GetUInt8(); + switch (aType) + { + case ACTION_TYPE_SUBMENU: + ActionSubmenu(player, creature, action); + break; + case ACTION_TYPE_POINT: + ActionTeleport(player, action); + break; + default: + sLog->outString("Unknown action type in `teleporter_actions`."); + } + } + + return true; + } + + bool ActionTeleport(Player *player, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + QueryResult result = WorldDatabase.PQuery("SELECT map, x, y, z, o FROM teleporter_points WHERE action = %u", action); + if (result && result->GetRowCount() > 0) + { + Field *fields = result->Fetch(); + + uint8 map = fields[0].GetUInt8(); + float tmpX = fields[1].GetFloat(); + float tmpY = fields[2].GetFloat(); + float tmpZ = fields[3].GetFloat(); + float tmpO = fields[4].GetFloat(); + + return player->TeleportTo(map, tmpX, tmpY, tmpZ, tmpO); + } + + return false; + } + + bool ActionSubmenu(Player *player, Creature *creature, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (!player->isInCombat()) + { + // 0 1 2 3 + QueryResult result = WorldDatabase.PQuery("SELECT text, icon, action, faction FROM teleporter_menu WHERE showAction = %u ORDER BY id", action); + if (result && result->GetRowCount() > 0) + { + do + { + Field *fields = result->Fetch(); + + std::string text = fields[0].GetString(); + uint8 icon = fields[1].GetUInt8(); + uint32 action = fields[2].GetUInt32(); + uint8 faction = fields[3].GetUInt8(); + + if ((faction == 1 && player->GetTeam() == HORDE) || + (faction == 2 && player->GetTeam() == ALLIANCE)) + continue; + + player->ADD_GOSSIP_ITEM(icon, text, GOSSIP_SENDER_MAIN, action); + } + while (result->NextRow()); + } + } + + player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); + + return true; + } +}; + +void AddSC_npc_teleporter() +{ + new npc_teleporter; +} + + +class tp_commandscript : public CommandScript +{ +public: + tp_commandscript() : CommandScript("tp_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand tpCommandTable[] = + { + { "addpoint", SEC_MODERATOR, false, &HandleTpAddPointCommand, "", NULL }, + { "addmenu", SEC_MODERATOR, false, &HandleTpAddMenuCommand, "", NULL }, + { "remove", SEC_MODERATOR, false, &HandleTpRemoveCommand, "", NULL }, + { "list", SEC_MODERATOR, false, &HandleTpListCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "tp", SEC_MODERATOR, false, NULL, "", tpCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + // args = "Name" submenu icon faction + static bool HandleTpAddPointCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + std::string sArgs = args; + + //search name arg + std::string name; + int32 firstS = sArgs.find("\""); + int32 secondS = sArgs.find("\"", firstS + 1); + if (!secondS || firstS == secondS || secondS - firstS == sArgs.size()) + return false; + name = sArgs.substr(firstS + 1, secondS - 1); + sArgs.replace(0, secondS + 1, ""); + + //search submenu arg + uint32 endPos = sArgs.find(" ", 1); + if (!endPos) + return false; + std::string sSM = sArgs.substr(1, endPos); + uint32 submenu = atoi(sSM.c_str()); + sArgs.replace(0, endPos, ""); + + //search icon + endPos = sArgs.find(" ", 1); + if (!endPos) + return false; + std::string sIco = sArgs.substr(1, endPos); + uint32 icon = atoi(sIco.c_str()); + sArgs.replace(0, endPos, ""); + + //search faction + std::string sFaction = sArgs.substr(1); + uint32 faction = atoi(sFaction.c_str()); + + sLog->outString("%s; %u, %u, %u", name.c_str(), submenu, icon, faction); + + uint32 action; + QueryResult result = WorldDatabase.PQuery("SELECT MAX(action) FROM teleporter_menu"); + if (result) + { + Field* fields = result->Fetch(); + action = fields[0].GetUInt32() + 1; + } + else + action = 1; + + WorldDatabase.PQuery("INSERT INTO teleporter_menu (action, showAction, text, icon, faction) VALUES (%u, %u, '%s', %u, %u)", action, submenu, name.c_str(), icon, faction); + WorldDatabase.PQuery("INSERT INTO teleporter_actions (action, type) VALUES (%u, %u)", action, ACTION_TYPE_POINT); + + Player *player = handler->GetSession()->GetPlayer(); + float x = player->GetPositionX(); + float y = player->GetPositionY(); + float z = player->GetPositionZ(); + float o = player->GetOrientation(); + uint32 map = player->GetMapId(); + WorldDatabase.PQuery("INSERT INTO teleporter_points (action, map, x, y, z, o) VALUES (%u, %u, %f, %f, %f, %f)", action, map, x, y, z, o); + return true; + } + + static bool HandleTpAddMenuCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + std::string sArgs = args; + + //search name arg + std::string name; + int32 firstS = sArgs.find("\""); + int32 secondS = sArgs.find("\"", firstS + 1); + if (!secondS || firstS == secondS || secondS - firstS == sArgs.size()) + return false; + name = sArgs.substr(firstS + 1, secondS - 1); + sArgs.replace(0, secondS + 1, ""); + + //search submenu arg + uint32 endPos = sArgs.find(" ", 1); + if (!endPos) + return false; + std::string sSM = sArgs.substr(1, endPos); + uint32 submenu = atoi(sSM.c_str()); + sArgs.replace(0, endPos, ""); + + //search icon + endPos = sArgs.find(" ", 1); + if (!endPos) + return false; + std::string sIco = sArgs.substr(1, endPos); + uint32 icon = atoi(sIco.c_str()); + sArgs.replace(0, endPos, ""); + + //search faction + std::string sFaction = sArgs.substr(1); + uint32 faction = atoi(sFaction.c_str()); + + sLog->outString("%s; %u, %u, %u", name.c_str(), submenu, icon, faction); + + uint32 action; + QueryResult result = WorldDatabase.PQuery("SELECT MAX(action) FROM teleporter_menu"); + if (result) + { + Field* fields = result->Fetch(); + action = fields[0].GetUInt32() + 1; + } + else + action = 1; + + WorldDatabase.PQuery("INSERT INTO teleporter_menu (action, showAction, text, icon, faction) VALUES (%u, %u, '%s', %u, %u)", action, submenu, name.c_str(), icon, faction); + WorldDatabase.PQuery("INSERT INTO teleporter_actions (action, type) VALUES (%u, %u)", action, ACTION_TYPE_SUBMENU); + + return true; + } + + + static void PrintSubMenus(ChatHandler* handler, uint32 action, std::string space) + { + QueryResult result = WorldDatabase.PQuery("SELECT action, text, faction FROM teleporter_menu WHERE showAction = %u ORDER BY id", action); + if (result && result->GetRowCount() > 0) + { + do + { + Field *fields = result->Fetch(); + + uint32 _action = fields[0].GetUInt32(); + std::string text = fields[1].GetString(); + uint8 faction = fields[2].GetUInt8(); + + handler->PSendSysMessage("%s %u - \"%s\" - %u", space.c_str(), _action, text.c_str(), faction); + PrintSubMenus(handler, _action, space + " "); + } + while (result->NextRow()); + } + + } + + static bool HandleTpListCommand(ChatHandler* handler, char const* args) + { + handler->PSendSysMessage("*----------------------------"); + handler->PSendSysMessage("ID - \"Name\" - Faction"); + PrintSubMenus(handler, 0, ""); + handler->PSendSysMessage("----------------------------*"); + + return true; + } + + static void RemoveAction(uint32 action) + { + if (!action) + return; + + QueryResult result = WorldDatabase.PQuery("SELECT action FROM teleporter_menu WHERE showAction = %u ORDER BY id", action); + if (result && result->GetRowCount() > 0) + { + do + { + Field *fields = result->Fetch(); + uint32 _action = fields[0].GetUInt32(); + RemoveAction(_action); + } + while (result->NextRow()); + } + WorldDatabase.PQuery("DELETE FROM teleporter_menu WHERE action = %u", action); + WorldDatabase.PQuery("DELETE FROM teleporter_points WHERE action = %u", action); + WorldDatabase.PQuery("DELETE FROM teleporter_actions WHERE action = %u", action); + } + + static bool HandleTpRemoveCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + uint32 action = atoi(args); + RemoveAction(action); + return true; + } +}; + +void AddSC_tp_commandscript() +{ + new tp_commandscript(); +} Патч в базу: Code DROP TABLE IF EXISTS `teleporter_menu`; CREATE TABLE `teleporter_menu` ( `id` int(10) unsigned AUTO_INCREMENT, `action` int(10) unsigned DEFAULT '0', `showAction` int(10) unsigned DEFAULT '0', `text` varchar(100) NOT NULL, `icon` int(3) unsigned DEFAULT '0', `faction` int(3) unsigned DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `teleporter_actions`; CREATE TABLE `teleporter_actions` ( `action` int(10) unsigned NOT NULL, `type` int(3) unsigned DEFAULT '0', PRIMARY KEY (`action`) );
DROP TABLE IF EXISTS `teleporter_points`; CREATE TABLE `teleporter_points` ( `action` int(10) unsigned NOT NULL, `map` int(1) unsigned DEFAULT '0', `x` float(10) NOT NULL, `y` float(10) NOT NULL, `z` float(10) NOT NULL, `o` float(10) NOT NULL, PRIMARY KEY (`action`) );
DELETE FROM creature_template WHERE entry = '190000';
INSERT INTO creature_template (entry, modelid1, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, Health_mod, Mana_mod, Armor_mod, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, dmg_multiplier, unit_class, unit_flags, type, type_flags, InhabitType, RegenHealth, flags_extra, ScriptName) VALUES ('190000', '21769', "Yarrrr!", "SoS Teleporter", 'Directions', '50000', 71, 71, 1.56, 1.56, 1.56, 35, 35, 3, 1, 1.14286, 1.25, 1, 1, 1, 2, 7, 138936390, 3, 1, 2, 'npc_teleporter');
DELETE FROM `command` WHERE `name` = 'tp'; INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp', 0, 'Syntax: .tp $subcommand.\nUse .help tp.'); DELETE FROM `command` WHERE `name` = 'tp addpoint'; INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp addpoint', 2, 'Syntax: .tp addpoint "#name" #submenu #icon #faction\nFor #submenu check tp list id.\n#icon see GossipOptionIcon declaration.\n#Faction - 0 -all, 1 - alliance, 2 -horde.'); DELETE FROM `command` WHERE `name` = 'tp addmenu'; INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp addmenu', 2, 'Syntax: .tp addmenu "#name" #submenu #icon #faction\nFor #submenu check tp list id.\n#icon see GossipOptionIcon declaration.\n#Faction - 0 -all, 1 - alliance, 2 -horde.'); DELETE FROM `command` WHERE `name` = 'tp list'; INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp list', 1, 'Syntax: .tp list\nList of menus in teleporter...'); DELETE FROM `command` WHERE `name` = 'tp remove'; INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp remove', 2, 'Syntax: .tp remove #id\nLook #id in .tp list.');
|
|
| |