Jump to content
  • Announcements

    • Xmat

      Pravidlo pro postování v TTT

      Do sekce Tipy, triky, tutoriály nepatří žádné dotazy.   Postujte sem vaše návody, tipy a různé další věci jež uznáte za vhodné sdělit zdejšímu osazenstvu, ale veškeré dotazy směřujte do sekce Všeobecná diskuse.
    • Replik

      Seznam návodů a důležitých témat v této sekci

      Pro lepší přehlednost jsem vytvořil tento seznam, který vás, méně zkušené, lépe provede touto sekcí. Věřím, že zde najdete, co hledáte. Vypsané jsou návody, které jsou oficiálně uznané jako návody. Běžné diskuze, které neposkytují postupy a rady zvěřejněny nejsou.   Instalace vlastního MaNGOS Serveru Díky těmto návodům budete (měli by jste být) schopni vytvořit a následně spustit váš vlastní server. Nastavení je pro verze s i bez datadisku.   Instalace MaNGOS Serveru (bez datadisku TBC) - Autor Benny Instalace MaNGOS Serveru (s datadiskem TBC) - Autor Malfik Instalace MaNGOS Serveru v prostředí Linux - Autor charlie Instalace MaNGOS Serveru v prostředí Linux - Autor kupkoid   Chyby a jejich řešení při přihlašování k serveru - Autor Cybe   Zálohování uživatelských dat   Dávkový soubor (BAT soubor) pro vytvoření SQL záloh - Autor Replik   Kompilování - tvoření vlastních release (revizí)   Tvorba kompilací pro Win32 (MangoScript) - Autor bLuma   Ostatní - těžko zařaditelné, ale neznamená to, že nejsou dobré   VIP Systém - Autor charlie Tvorba Webových stránek pro MaNGOS - Autor zahuba Tvorba teleportačních NPC (MangoScript) - Autor Replik Registrační web (původně předělaná SPORA) Funkční pro Antrix i MaNGOS - Autor Replik Nastavení a spuštění Minimanager pro MaNGOS - Autor BlackMartin Nastavení MaNGOS Website - Autor Artorius   Samozřejmě jsou zde i jiné návody, ale tyto jsou nejvíce používané, proto věřím, že vám budou nápomocné. Tuto sekci budeme upravovat podle potřeby. Pokud by jste něco nenašli nebo si nevěděli rady, hledejte na fóru a teprve potom založte vlastní topik. Pokud nějaký autor vytvoří kvalitní návod a chtěl by ho zveřejnit i v tomto seznamu, doporučuji, aby mi napsal zprávu skrze PM.   Díky a přeji hezký den na WoWResource   Replik
    • Aristo

      Příspěvky tam, kde nemají co dělat

      Dodržujte zákaz přispívání do topiků s repaky pokud si to zakladatelé nepřejí!! Opakované psaní příspěvků bude trestáno warnem.
    • Aristo

      Používání spoilerů

      Poslední dobou má většina uživatelů fora zvláštní nutkání postovat extrémně dlouhé texty nebo kódy, které zabírají v nejedenom případu i 80% obsahu celé stránky a hodně tak zvedají nepřehlednost v topiku. Chtěl bych všechny uživatele požádat, aby při postování citací, jakýchkoliv kódů, errorů, atp... delších než 30 řádků používali funkci spoileru.   Funkci vyvoláte příkazem [spoiler] text [/spoiler]   Ukázka:  

Hookyns

Members
  • Content count

    243
  • Joined

  • Last visited

  • Days Won

    10

Posts posted by Hookyns


  1. upadek fora... doba je jinde nez pred par lety, kdy wow emulaci resili nadsenci do C++ a SQL, s vidinou zdokonaleni se ;) dneska servery resi vetsinou jen kinderi, co nemaj 300,- mesicne na offik a neumej cist (jak se tu nekdo muze zeptat co ma delat, a postnout log kde je: apply DB patches.) :)

     

    Reseni me napada - zavest povinne pravidlo - nez se zeptate zkuste 10 minut googlit. Pri nedodrzeni ban, ip ban, delete. Ono by je to preslo ;)

    Ani by nemuseli googlit, všechny ty informace jsou zde, ale je to zde tolikrát a v takovém množství, že to nikdy nikdo nenajde.

    Mám zde také problém něco najít a to vím co hledám a kde to mám hledat. Představ si člověka, který je zde poprvé, nemá šanci zde vůbec nic najít.

     

    Také mi ještě za těch několik let, co zde působím, není jasné, kam postovat dotazy (myslím to tak, že nikdy není určeno, kde se mám ptát), všechno je to zamixované do sebe.

     

    V sekcích MaNGOS, TC, OC a ostatní emu bych udělal podsekci "Dotazy" or something like this.

    A do těch ostatních podsekcí bych zakázal postovat dotazy, aby se docílilo toho, že tam budou jen hotová řešení => nebude třeba se prodírat přes stovky topiců bez významu, abych našel ten jeden návod, který je až někde na konci mezi těmi všemi dotazy.

     

    A jak jsou ty iconky TBC, WotLK, Cata, které lze přiřadit před název topicu, udělat bych něco podobného, aby šel před název hodit otazník, aby to znázorňovalo, že se tam někdo na něco ptá, tudíž pro člověka, který hledá navod, je to bezvýznamný topic.

     

    Je to jen taková bezvýznamná úvaha...

    • Upvote 4

  2. Ne, v serveru nebudeš nic měnit, tam jsou tyto čísla již nastavena, pokud si je neměnil.

    Jde o to, že ty čísla, která jsou tam uvedena (v configu), musíš povolit v portforwarding.

    A čísla, která tam jsou jako výchozí jsou 3724 a 8085. Tyto čísla dej do portforwarding a přesměruj je na tvou local IP (IP adresa tvého PC v domácí síti) zjistíš tak, že spustíš cmd (příkazový řádek) a napíšeš tam ipconfig


  3. Jen doplním, pro přesnost.

    V configu nic neměň, tam nech adresu na 0.0.0.0.

    Ale jak je zmíně v předchozím příspěvku: databáze -> authDB -> realmlist a zde změnit IP.

    Samozřejmě ještě budeš muset povolit PortForwarding skrze tvůj router (pokud v domácí síti nějaký je).


  4. Zdravím,

    před pár dny jsem řešil problém s tím, jak udělat vlastní spell následně nascriptovaný v Core. Bohužel mi zde nebyl schopen nikdo pomoci, tak jsem byl odkázán sám na sebe, jako vždy. Řešení jsem nenalezl ani na google na zahraničních fórech/portálech a tak jsem procházel core a snažil jsem se něco najít. Našel jsem nějaké věci rozprášené po celém core a zjišťoval jsem co a jak.

     

    Tento způsob vyžaduje editaci klienta.

     

    Pojďme tedy k věci.

     

    Co je potřeba?

    • Nějaký DBC editor (například MyDBCEditor)
    • MPQ editor (například Ladik's MPQ Editor)
    • PNG <-> BLP converter (pokud tedy chcete vlastní ikonu u spellu - ingame)
    • Nějaký edtor audia (pokud chcete ke spellu vlastní zvuk)
    • Samozřejmě funkční server (včetně source) s databází, apod.
    • Nějaké všeobecné znalosti DBC, databáze, serveru -> C++
    • Znalosti editace DBC a klienta tj. práce s DBC editorem a MPQ editorem
    • Hlava a trpělivost

    Postup

    1)
    Vy
    tvoření patche

    Nebudu zde popisovat, jak se patch vytváří a jak se s MPQ editorem zachází.

    Vytvořte
    nový .MPQ
    soubor a pojmenujte jej "
    patch-X
    ".

    V patchy vytvořte složku
    DBFilesClient
    , do které na konci nahrajete všechny vámi upravené DBC soubory.

     

    2)
    Editace
    Spell.dbc

    Zde je nutné vytvořit
    nový záznam
    (řádek), s ID větší než poslední ID v řadě. Já jsem začínal od 100 000.

    Vytvořil jsem PDF s menším přehledem polí, které budeme potřebovat.

    Vytvořte si tedy nový záznam a vyplňte sloupce podle představy vašeho spellu.

     

    Spell Icon

    Pokud tedy chcete vlastní ikonku u spellu, musíte vytvořit obrázek 24x24px v PNG, překonvertovat na BLP a tento obrázek nahrát do patche, kam si jej umístíte je jen na vás.

    Poté otevřeme SpellIcon.dbc a vložíme nový záznam. První sloupec je ID Icony (zvolte vlastní) a druhý je cesta k našemu obrázku (od kořenového adresáře patche).

    !! POZOR !! na konci cesty nebude přípona, bude to tedy cca "
    custom\images\mojeico
    ".

     

    3)
    Inicializace spellu

    V core upravíme soubor
    SpellMgr.cpp.

    Půjdeme na
    řádek cca 2900
    , kde by měly být
    case od switche

    Můžete zkusit hledat
    case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)

    Přidejte zde další case s vašim spellID ->
    case: #spellid
    Stačí jen tohle na jeden řádek, nemusí zde být break;

     

    4)
    Vytvoření scriptu
    pro spell

    Tuhle část nemám plně zmapovanou, bude to tedy na vás si to doplnit.

    Možná se vám nebude pozdávat můj syntax, jsem webdeveloper a C++ jsem se nikdy neučil, jsem zvyklý na PHP syntax, tak to píši tak.

     

    V jádře je příkladový script, a ten vypadá následovně
    :
    class spell_ex_5581 : public SpellScriptLoader {
    public:
    spell_ex_5581() : SpellScriptLoader("spell_ex_5581") { }
    
    class spell_ex_5581SpellScript : public SpellScript {
    // initialize script, this macro does compile time check for type of the function - prevents possible issues
    // if you have assigned wrong type of function to a hook you'll receive type conversion error during build
    // this line is required, otherwise you'll get XXXHandlerFunction - identifier not found errors
    PrepareSpellScript(spell_ex_5581SpellScript);
    
    std::string localVariable;
    char* localVariable2;
    
    // function called on server startup
    // checks if script has data required for it to work
    bool Validate(SpellInfo const* /*spellEntry*/) {
    // check if spellid 70522 exists in dbc, we will trigger it later
    if (!sSpellMgr->GetSpellInfo(SPELL_TRIGGERED))
    return false;
    return true;
    }
    
    // function called just after script is added to spell
    // we initialize local variables if needed
    bool Load() {
    localVariable = "we're using local variable";
    localVariable2 = new char();
    return true;
    // return false - script will be immediately removed from the spell
    // for example - we don't want this script to be executed on a creature
    // if (GetCaster()->GetTypeID() != TYPEID_PLAYER)
    // return false;
    }
    
    // function called just before script delete
    // we free allocated memory
    void Unload() {
    delete localVariable2;
    }
    
    void HandleBeforeCast() {
    // this hook is executed before anything about casting the spell is done
    // after this hook is executed all the machinery starts
    sLog->outInfo(LOG_FILTER_GENERAL, "Caster just finished preparing the spell (cast bar has expired)");
    }
    
    void HandleOnCast() {
    // cast is validated and spell targets are selected at this moment
    // this is a last place when the spell can be safely interrupted
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell is about to do take reagents, power, launch missile, do visuals and instant spell effects");
    }
    
    void HandleAfterCast() {
    sLog->outInfo(LOG_FILTER_GENERAL, "All immediate Actions for the spell are finished now");
    // this is a safe for triggering additional effects for a spell without interfering
    // with visuals or with other effects of the spell
    //GetCaster()->CastSpell(target, SPELL_TRIGGERED, true);
    }
    
    SpellCastResult CheckRequirement() {
    // in this hook you can add additional requirements for spell caster (and throw a client error if reqs're not passed)
    // in this case we're disallowing to select non-player as a target of the spell
    //if (!GetExplTargetUnit() || GetExplTargetUnit()->ToPlayer())
    //return SPELL_FAILED_BAD_TARGETS;
    return SPELL_CAST_OK;
    }
    
    
    void HandleDummyLaunch(SpellEffIndex /*effIndex*/) {
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell %u with SPELL_EFFECT_DUMMY is just launched!", GetSpellInfo()->Id);
    }
    
    void HandleDummyLaunchTarget(SpellEffIndex /*effIndex*/) {
    uint64 targetGUID = 0;
    if (Unit* unitTarget = GetHitUnit())
    targetGUID = unitTarget->GetGUID();
    // we're handling SPELL_EFFECT_DUMMY in effIndex 0 here
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell %u with SPELL_EFFECT_DUMMY is just launched at it's target: " UI64FMTD "!", GetSpellInfo()->Id, targetGUID);
    }
    
    void HandleDummyHit(SpellEffIndex /*effIndex*/) {
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell %u with SPELL_EFFECT_DUMMY has hit!", GetSpellInfo()->Id);
    }
    
    void HandleDummyHitTarget(SpellEffIndex /*effIndex*/) {
    sLog->outInfo(LOG_FILTER_GENERAL, "SPELL_EFFECT_DUMMY is hits it's target!");
    // make caster cast a spell on a unit target of effect
    if (Unit* target = GetHitUnit())
    GetCaster()->CastSpell(target, SPELL_TRIGGERED, true);
    }
    
    void HandleBeforeHit() {
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell is about to hit target!");
    }
    
    void HandleOnHit() {
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell just hit target!");
    }
    
    void HandleAfterHit() {
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell just finished hitting target!");
    }
    
    void FilterTargets(std::list<unit*>& /*targetList*/) {
    // usually you want this call for Area Target spells
    sLog->outInfo(LOG_FILTER_GENERAL, "Spell is about to add targets from targetList to final targets!");
    }
    
    // register functions used in spell script - names of these functions do not matter
    void Register() {
    // we're registering our functions here
    BeforeCast += SpellCastFn(spell_ex_5581SpellScript::HandleBeforeCast);
    OnCast += SpellCastFn(spell_ex_5581SpellScript::HandleOnCast);
    AfterCast += SpellCastFn(spell_ex_5581SpellScript::HandleAfterCast);
    OnCheckCast += SpellCheckCastFn(spell_ex_5581SpellScript::CheckRequirement);
    // function HandleDummy will be called when spell is launched, independant from targets selected for spell, just before default effect 0 launch handler
    OnEffectLaunch += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyLaunch, EFFECT_0, SPELL_EFFECT_DUMMY);
    // function HandleDummy will be called when spell is launched at target, just before default effect 0 launch at target handler
    OnEffectLaunchTarget += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyLaunchTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
    // function HandleDummy will be called when spell hits it's destination, independant from targets selected for spell, just before default effect 0 hit handler
    OnEffectHit += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyHit, EFFECT_0, SPELL_EFFECT_DUMMY);
    // function HandleDummy will be called when unit is hit by spell, just before default effect 0 hit target handler
    OnEffectHitTarget += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
    // this will prompt an error on startup because effect 0 of spell 49375 is set to SPELL_EFFECT_DUMMY, not SPELL_EFFECT_APPLY_AURA
    //OnEffectHitTarget += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
    // this will make HandleDummy function to be called on first != 0 effect of spell 49375
    //OnEffectHitTarget += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_FIRST_FOUND, SPELL_EFFECT_ANY);
    // this will make HandleDummy function to be called on all != 0 effect of spell 49375
    //OnEffectHitTarget += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY);
    // bind handler to BeforeHit event of the spell
    BeforeHit += SpellHitFn(spell_ex_5581SpellScript::HandleBeforeHit);
    // bind handler to OnHit event of the spell
    OnHit += SpellHitFn(spell_ex_5581SpellScript::HandleOnHit);
    // bind handler to AfterHit event of the spell
    AfterHit += SpellHitFn(spell_ex_5581SpellScript::HandleAfterHit);
    // bind handler to OnUnitTargetSelect event of the spell
    //OnUnitTargetSelect += SpellUnitTargetFn(spell_ex_5581SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER);
    }
    };
    
    // Vytvoříme spell
    SpellScript* GetSpellScript() const {
    return new spell_ex_5581SpellScript();
    }
    }

     

    Trochu zjednodušeně:
    class spell_priklad : public SpellScriptLoader {
    public:
    	spell_priklad() : SpellScriptLoader("spell_priklad") { }
    
    	 class spell_prikladSpellScript : public SpellScript {
    		PrepareSpellScript(spell_prikladSpellScript);
    
    		// Tato funkce se má údájně volat při přidání spellu na postavu
    		bool Load() {
    			// return false - script will be immediately removed from the spell
    			// for example - we don't want this script to be executed on a creature
    			// if (GetCaster()->GetTypeID() != TYPEID_PLAYER)
    			// return false;
    		}
    
    		// Tato funkce se má údajně volat před odebráním spellu
    		void Unload() {
    			// akce
    		}
    
    		// Požadavky pro spell...
    		SpellCastResult CheckRequirement() {
    			// in this hook you can add additional requirements for spell caster (and throw a client error if reqs're not passed)
    			// in this case we're disallowing to select non-player as a target of the spell
    			//if (!GetExplTargetUnit() || GetExplTargetUnit()->ToPlayer())
    			//return SPELL_FAILED_BAD_TARGETS;
    			return SPELL_CAST_OK;
    		}
    
    		// Tahle funkce se volá po vycastění spellu
    		void HandleAfterCast() {
    			// Nějaká akce třeba teleportace, snížení HP => DMG, apod.
    		}
    
    		// Zaregistrujeme funkce, které budeme chtít provádět při použití spellu
    		void Register() {
    			AfterCast += SpellCastFn(spell_prikladSpellScript::HandleAfterCast);
    			OnCheckCast += SpellCheckCastFn(spell_prikladSpellScript::CheckRequirement);
    		}
    	};
    
    	// Vytvoříme spell
    	SpellScript* GetSpellScript() const {
    		return new spell_prikladSpellScript();
    	}
    };
    
    // Musíme přidat ještě "odkaz" do ScriptLoaderu
    void AddSC_spell_priklad() {
    new spell_priklad();
    }

     

    5)
    Vložit záznam
    do databáze

    Aby se náš script mohl nějak zavolat, musíme někde určit, jaký script k našemu spellu patří.

    To uděláme ve world DB v tabulce
    spell_script_names
    , kde
    první sloupec je ID
    našeho spellu a
    druhý je naše ScriptName

     

     

    Po dokončení všech kroků jen zavřete otevřené MPQ a vložíte jej do WoWDir\Data, zkompilujete core a zapnete server (v serverových DBC musí být také námi editované .dbc soubory).

    Ingame jen dáte .learn NAŠE_SPELL_ID a můžete si (snad) užívat kýženého výsledku.

     

    EDIT: Reaguji na příspěvek od uživatele frytiks, takže odpověď pro všechny

    Tam kde zmiňuji Spell ID (tedy ID našeho spellu), myslím tím ID, které jste zadali v DBC, což je ID spellu.

     

    Původní topic:

    Zdravím,

    snažím se vytvořit vlastní spell, ale potřeboval bych radu od zkušenějších.

     

    Chci vytvořit spell, který mě "teleportuje" na vybrané místo, tím vybraným místem myslím to, že po kliku na spell se objeví ten zelený kruh, abych vybral místo (např. Force of Nature), a po potvrzení místa se provede C++ script na teleport.

     

    Co jsem zatím pochopil, spell se musí vytvořit ve spell.dbc, to jsem udělal, vytvořil jsem si i vlastní ikonu pro spell a ingame to funguje, spell jsem se normálně naučil, odebírá požadované množství many a castí se požadovanou dobu.

    Ale jak tam mám přidat ten výběr pozice a hlavně jak to ve výsledku navázat na core, abych mohl nascriptovat akci?

     

    V core mám vytvořený soubor se scriptem pro spell podle příkladu, který je v core obsažen, ale nějak nechápu, jak si server daný script přiřadí k tomu spellu.

    Ano, udává se tam scriptname a v DB jsem našel spell_script_names, kde se přiřazují ID spellu ke scriptname, ale nezdá se mi, že by se script při castu spustil.

     

    Proto píši tento topic a žádám někoho o radu.

    3.3.5a (nejnovější rev)

     

     

    EDIT:

    Tak už jsem přišel na to, jak napojit vytvořený spell ze spell.dbc na C++ script tak, aby se po castingu provedl.

    Teď ještě jak udělat ten targeting (výběr místa tím zeleným kruhem).

     

    • Upvote 4

  5. Má OC v realm DB tabulku account_access?

    Pokud ano, je v ní sloupec RealmID? Pokud ne, zkus jej vytvořit, teoreticky by se tak měl fixnout ten error.

    Ale lepší by bylo v kódu webu upravit ten dotaz.

    Dost možná to také nemá nic společného s account_access, protože to má spojitost s účty tzn. ten error by se měl zobrazit maximálně až po loginu.


  6. Potkat tě takhle na ulici, tak si říkám, kdo zase plánuje invazi :boat::thumbup1:

    Mohu tě uklidnit, na ulici mě na 99% takhle neuvidíš :D

     

    EDIT (pro příspěvek podemnou): Na zbraň mám pouzdro, ale když jedu na nějakou akci, zbraně nechávám v kufru (pochopitelně), když jdu třeba na benzinku nebo do obchodu :D


  7. No, záleží na definici slova nedaří.

    SQL vypadá v pořádku, pokud tím nedaří myslíš, že ingame neportuje, nezobrazí se v daném NPC vůbec nic, je to tím, že nemáš u daného NPC nastavený gossip.

    Pro `npcflag` nastav 1, teď tam máš 0.


  8. Zdravím,

    s LUA nedělám, ale po dvou minutách na google ti mohu sepsat toto:

    i = 1
    while i  > 0 do
     print "Hello world!"
     i = i + 1
     usleep (m * 1000)
    end
    

    Nezaručuji funkčnost, nikdy jsem s LUA nedělal, ale podle zkušeností z ostatních jazyků si myslím, že to fungovat bude.


  9. Vau, ďakujem. Mimochodom, sranda je vtom, že to uložene v .png je ! :(

    To, co si sem dal, je v jpg, je to přímo v linku.

     

    Jinak je to pěkné.

    Hlavně si se zbavil velkého a nečitelného fontu, to mi nejvíce vadilo na předešlém designu. :)

     

    Jediné, na co bych upozornil, je pozadí. Pokud používáš obrázky do pozadí, tak buď musí být dostatečně velké tj. 1920x1080px a nebo je musíš nějak zpřechodovat do barvy.

    Píšu to jakož to koder, protože většina designerů na takové věci kašle a poté je těžké to nakódovat tak, aby to bylo plně optimalizované.

    Udělají PSD široké např 1200px a obr. na pozadí je od kraje ke kraji. Já když takový obrázek vložím bez úprav na pozadí stránky, každý, kdo má větší rozlišení, to bude mít useklé a opravdu to nevypadá dobře.


  10. Na začátečníka to není špatné.

     

    Určitě musíš zesvětlit písmo, které je ve spodní části tlačítek v horním menu. Je to takřka nečitelné.

    To samé text u přihlašování.

    Když jsme ještě u textu, písmo v novinkách je příliš velké. Dejme tomu, že nadpis je OK, včetně data i autora, ale přímo ten text je velký. Zmenši jej na 11px možná 12px.

     

    Ikonky na sociální sítě bych dal světlejší, možná i v originálních barvách, bude to působit trochu živěji. Stránka je celkově dost tmavá, potřebuje vdechnout život.

    Stránkování pokud možno trochu zmenšit, to písmo je také velké.

    A na konec footer. Copyright bych napsal drobnějším písmem na stejném řádku jako ty ostatní položky, takto je to vytržené.

     

    Jinak si myslím, že na začátečníka je to celkem povedené.

×