Modifikace MaNGOSe: Porovnání verzí
m |
m |
||
Řádek 3: | Řádek 3: | ||
# Soubor Chat.h musí obsahovat jeho hlavičku ve třídě ChatHandler s viditelností protected (někde mezi půlkou až koncem souboru). Návratová hodnota každého příkazu je bool a vstupními argumenty je const char*. Jako šablonu lze tedy vždy použít: '''bool Handle<NázevPříkazu>Command(const char *args);''' | # Soubor Chat.h musí obsahovat jeho hlavičku ve třídě ChatHandler s viditelností protected (někde mezi půlkou až koncem souboru). Návratová hodnota každého příkazu je bool a vstupními argumenty je const char*. Jako šablonu lze tedy vždy použít: '''bool Handle<NázevPříkazu>Command(const char *args);''' | ||
# Je nutné vytvořit kód příkazu, vzhledem ke struktuře přístupových práv v MaNGOSu (rozdělených na 0,1,2,3) se příkazy řadí do souborů Level<0-3>.cpp, případně debugcmds.cpp (na umístění nezáleží, je nutné pouze, aby pro funkce které příkaz vyžaduje byly na začátku definovány odpovídající hlavičkové soubory, poté je možno tělo metody umístit na kterékoliv místo v těchto souborech). Návratová hodnota je true pokud vše proběhlo v pořádku, při návratu false je oznámen Syntax error. | # Je nutné vytvořit kód příkazu, vzhledem ke struktuře přístupových práv v MaNGOSu (rozdělených na 0,1,2,3) se příkazy řadí do souborů Level<0-3>.cpp, případně debugcmds.cpp (na umístění nezáleží, je nutné pouze, aby pro funkce které příkaz vyžaduje byly na začátku definovány odpovídající hlavičkové soubory, poté je možno tělo metody umístit na kterékoliv místo v těchto souborech). Návratová hodnota je true pokud vše proběhlo v pořádku, při návratu false je oznámen Syntax error. | ||
− | # Zbývá nastavit na jaký .příkaz bude ve hře tento kód vykonán. Toto se nastavuje v souboru Chat.cpp v poli commandTable (nebo jiném pokud chcete zařadit do nějaké podkategorie příkazů nebo vytvořit vlastní). Řádek pak obsahuje: '''{ "příkazVeHře", SEC_<nowiki><přístopová práva></nowiki>, &ChatHandler::Handle<NázevPříkazu>Command, "", <NULL nebo název dalšího pole příkazů> },''' Prázdný řetězec slouží jako pole pro nápovědu, která je načtena z databáze. Nový příkaz bude fungovat i bez záznamu v db v tabulce commands, ale nebude obsahovat nápovědu. (na konci každého pole je nutné ponechat null-ový záznam, vlastní řádek s definicí příkazu je možno vložit kamkoliv do požadovaného pole příkazů) | + | # Zbývá nastavit na jaký .příkaz bude ve hře tento kód vykonán. Toto se nastavuje v souboru Chat.cpp v poli commandTable (nebo jiném pokud chcete zařadit do nějaké podkategorie příkazů nebo vytvořit vlastní). Řádek pak obsahuje: '''{ "příkazVeHře", SEC_<nowiki><přístopová práva></nowiki>, <true/false>, &ChatHandler::Handle<NázevPříkazu>Command, "", <NULL nebo název dalšího pole příkazů> },''' Prázdný řetězec slouží jako pole pro nápovědu, která je načtena z databáze. <True/false> udává, zda-li je příkaz možné vyvolat i z konzole mangose (při true), pokud příkaz není napsán tak, aby fungoval i z konzole může dojít ke crashi (pro zde uvedené příkazy dávejte false, pokud není uvedeno jinak). Nový příkaz bude fungovat i bez záznamu v db v tabulce commands, ale nebude obsahovat nápovědu. (na konci každého pole je nutné ponechat null-ový záznam, vlastní řádek s definicí příkazu je možno vložit kamkoliv do požadovaného pole příkazů) |
== Když hráč zabije hráče == | == Když hráč zabije hráče == | ||
Řádek 37: | Řádek 37: | ||
bool HandleBgCommand(const char* args); | bool HandleBgCommand(const char* args); | ||
Chat.cpp: | Chat.cpp: | ||
− | { "bg", SEC_PLAYER, | + | { "bg", SEC_PLAYER, false, &ChatHandler::HandleBgCommand, "", NULL }, |
Level0.cpp: | Level0.cpp: | ||
// na začátku souboru musí být hlavička: | // na začátku souboru musí být hlavička: |
Verze z 29. 10. 2008, 08:12
Obsah
Vytvoření vlastního příkazu
Na vytvoření nového příkazu je nutné definovat ho na několika místech.
- Soubor Chat.h musí obsahovat jeho hlavičku ve třídě ChatHandler s viditelností protected (někde mezi půlkou až koncem souboru). Návratová hodnota každého příkazu je bool a vstupními argumenty je const char*. Jako šablonu lze tedy vždy použít: bool Handle<NázevPříkazu>Command(const char *args);
- Je nutné vytvořit kód příkazu, vzhledem ke struktuře přístupových práv v MaNGOSu (rozdělených na 0,1,2,3) se příkazy řadí do souborů Level<0-3>.cpp, případně debugcmds.cpp (na umístění nezáleží, je nutné pouze, aby pro funkce které příkaz vyžaduje byly na začátku definovány odpovídající hlavičkové soubory, poté je možno tělo metody umístit na kterékoliv místo v těchto souborech). Návratová hodnota je true pokud vše proběhlo v pořádku, při návratu false je oznámen Syntax error.
- Zbývá nastavit na jaký .příkaz bude ve hře tento kód vykonán. Toto se nastavuje v souboru Chat.cpp v poli commandTable (nebo jiném pokud chcete zařadit do nějaké podkategorie příkazů nebo vytvořit vlastní). Řádek pak obsahuje: { "příkazVeHře", SEC_<přístopová práva>, <true/false>, &ChatHandler::Handle<NázevPříkazu>Command, "", <NULL nebo název dalšího pole příkazů> }, Prázdný řetězec slouží jako pole pro nápovědu, která je načtena z databáze. <True/false> udává, zda-li je příkaz možné vyvolat i z konzole mangose (při true), pokud příkaz není napsán tak, aby fungoval i z konzole může dojít ke crashi (pro zde uvedené příkazy dávejte false, pokud není uvedeno jinak). Nový příkaz bude fungovat i bez záznamu v db v tabulce commands, ale nebude obsahovat nápovědu. (na konci každého pole je nutné ponechat null-ový záznam, vlastní řádek s definicí příkazu je možno vložit kamkoliv do požadovaného pole příkazů)
Když hráč zabije hráče
Pro možnost přidání peněz nebo předmětu za zabití hráče. Otevřete soubor Unit.cpp a najděte metodu DealDamage(). Poté nalezněte podmínku if (health <= damage) a blok pod touto podmínkou zpracovává zabití nepřítele. Pro ověření, že hráč zabil hráče stačí jednoduchá podmínka if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER). Pokud chcete ověřit i zda-li hráč byl z druhé frakce přidejte podmínku ((Player*)this)->GetTeam() != ((Player*)pVictim)->GetTeam(), případně přidat vlastní další podmínky (ověření levelu, opakovaného zabíjení,...)
- Pro udělení pěnez stačí požít funkci Player::ModifyMoney(<o kolik>);
- Pro přidání itemu lze použít:
#define LOOT_ITEM_ID 9014555 /* entry předmětu */ #define LOOT_ITEM_COUNT 1 /* počet předmětů, které obdrží */ if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)this)->GetTeam() != ((Player*)pVictim)->GetTeam()) { Player *me = (Player*)this; ItemPosCountVec dest; uint32 no_space_count = 0, count = LOOT_ITEM_COUNT; uint8 msg = me->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, LOOT_ITEM_ID, count, &no_space_count); if( msg != EQUIP_ERR_OK ) count -= no_space_count; if (count != 0 && !dest.empty()) { Item* item = me->StoreNewItem( dest, LOOT_ITEM_ID, true, Item::GenerateItemRandomPropertyId(LOOT_ITEM_ID)); if(item) me->SendNewItem(item,count,false,false); } }
Příkazy
Připojení do fronty na battleground
Pro MaNGOS bez Arena patche
Hlavička Chat.h:
bool HandleBgCommand(const char* args);
Chat.cpp:
{ "bg", SEC_PLAYER, false, &ChatHandler::HandleBgCommand, "", NULL },
Level0.cpp:
// na začátku souboru musí být hlavička: #include "BattleGround.h" // tělo příkazu - umístit někam do souboru (např. na konec za vše ostatní) bool ChatHandler::HandleBgCommand(const char* args) { if (!*args) return false; uint8 bgTypeId = 0; if (stricmp(args, "wsg") == 0) { bgTypeId = 2; } else if (stricmp(args, "ab" ) == 0) { bgTypeId = 3; } else if (stricmp(args, "eye") == 0) { bgTypeId = 7; } if (bgTypeId >= MAX_BATTLEGROUND_TYPES || !bgTypeId) return false; Player* me = m_session->GetPlayer(); if (me->InBattleGround() || !me->CanJoinToBattleground()) return false; BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId); if (!bg) return false; if (me->InBattleGroundQueueForBattleGroundType(bgTypeId)) return false; uint32 queueSlot = me->AddBattleGroundQueueId(bgTypeId); if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES) return false; me->SetBattleGroundEntryPoint(me->GetMapId(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); WorldPacket data; sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, me->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0); m_session->SendPacket(&data); sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].AddPlayer(me, bgTypeId); return true; }
Pouštění hudby všem hráčům
V souboru debugcmds.cpp najděte metodu ChatHandler::HandlePlaySound2Command a uvnitř nahraďte
m_session->GetPlayer()->PlaySound(soundid, false);
za
WorldPacket data(SMSG_PLAY_SOUND, 4); data << soundid; sWorld.SendGlobalMessage(&data);
Poté ve hře můžete pustit všem hudbu pomocí příkazu .debug ps <id hudby>
Portnutí všech hráčů za GM
Hráč může portnutí odmítnout, ti kdo přijmou budou portnuti na GM, které příkaz použilo +- 1yard do okolí a 2y nad (aby nedošlo k propadnutí pod zem)
bool ChatHandler::HandlePortAllToMe(const char* args) { HashMapHolder<Player>::MapType map = ObjectAccessor::Instance().GetPlayers(); Player* me = m_session->GetPlayer(); float x,y,z; me->GetPosition(x, y, z); // resp. GetClosePoint() to, ale nenajde gameobjekty ve vzduchu. z += 2.0f; WorldPacket data(SMSG_SUMMON_REQUEST, 8+4+4); data << uint64(me->GetGUID()); // summoner guid data << uint32(me->GetZoneId()); // summoner zone data << uint32(MAX_PLAYER_SUMMON_DELAY*1000); // auto decline after msecs for(HashMapHolder<Player>::MapType::iterator it = map.begin(); it != map.end(); it++) { if (it->second == me) continue; it->second->SetSummonPoint(me->GetMapId(), x + (rand_norm()*2-1), y + (rand_norm()*2-1), z); it->second->GetSession()->SendPacket(&data); } return true; }