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:  
Sign in to follow this  
lopitr

c++ uprava targetu u spellu

Recommended Posts

Dobrý den. Mám trochu menší problém. Chtěl bych zakázat aby spell http://www.wowhead.com/spell=3411 , nešel používat na pety. A tak jsem si zašel do Spell.cpp a tam jsi napsal tohle.

 

      else if (m_spellInfo->Id == 3411) // Intervene
              {
                  Unit *unit = m_targets.GetUnitTarget(); 
                  if (!unit || unit->ToCreature()->isPet()) 
                  return SPELL_FAILED_BAD_TARGETS; 
              }

 

Co se stalo? po kompilaci a restartu serveru mě už spell nešel použít ani na hráče. Ani na pety.

 

Na co se chci zeptat? Jestli někoho z Vás napadne lepší řešení. A nebo alespoň směr kterým jít dál.

Mě napadlo třeba si zkusit projet Unit.cpp (je to jen návrh) jestli tam není case s tímhle spellem a zkusit to zapsat tam. Ale netuším co by to udělalo. Předem děkuji za každou odpověď.

Share this post


Link to post
Share on other sites

Nedělám sice s jádrem EMU, dokonce ani s Cpp (pouze s jinými jazyky), ale přesto to zkusím.

 

Pokud si přidal jen if (!unit || unit->ToCreature()->isPet()) a dobře jsem to pochopil, tak si tu podmínku špatně definoval.

Ptáš se, jestliže to není hráč nebo je to pet tak to vrátí fail daného spellu. Zkus or vyměnit za and a nebo odstraň !unit ||.

 

Rada od amatéra taky rada ne? Za pokus nic nedáš.

Share this post


Link to post
Share on other sites

Taky by bylo dobrý napsat, kam jsi to přímo připsal (do jaký metody, na jaký číslo řádku...).

 

Tak tedy předpokládám že jsi to přidal do metody SpellCastResult Spell::CheckCast(bool strict). Zkus třeba hned na začátek přidat něco takovýho:

A) pokud chceš zakázat použití na pety:

    if (m_spellInfo->Id == 3411 && m_targets.getUnitTarget()->isPet())
       return SPELL_FAILED_BAD_TARGETS;

B) pokud chceš aby ten spell šel použít JEN na hráče:

    if (m_spellInfo->Id == 3411 && m_targets.getUnitTarget()->GetTypeId() != TYPEID_PLAYER)
       return SPELL_FAILED_TARGET_NOT_PLAYER;

 

Pochopitelně nezapomeň to tvoje původní zcela odstranit nebo uzavřít jako poznámku ( /* ... */ ).

Snad to bude fungovat, nezkoušel jsem to. To co psal Hookyns má taky smysl.

  • Upvote 1

Share this post


Link to post
Share on other sites

Ad Hookyns naprosto chybná představa, kontrola !unit testuje, zda-li vrácený ukazatel typu Unit* není NULL. Což nastane, pokud ze spellu žádný cíl nebyl vybrán. V tomto případě se ještě nerozhoduje o druhu jednotky, může to být hráč, npc i pet. Volat metody na NULL ukazateli způsobí crash, proto je to nezbytné zkontrolovat. Může se stát (bugem, hackem, ...), že cíl spellu nebude platný.

Ad Wolf lepší, ale nebezpečné, může způsobit crash.

 

Správná a bezpečná kontrola musí být:

Unit *unit = m_targets.GetUnitTarget(); 
if (!unit || unit->isPet()) 
   return SPELL_FAILED_BAD_TARGETS; 

 

Pokud to ovlivnilo použití na hráče tak to může být špatným umístěním kontroly. Sama o sobě se hráčů nedotkne (ani ta původní verze, ta spíše způsobí crash).

Share this post


Link to post
Share on other sites

To se ale opět vracíme k myšlence, proč to vlastně nejde. Kvůli ToCreature() možná? Umístění jo? V metodě CheckCast to má snad jediný logický význam, nevim kam to on psal.

Koukám že by to co jsem napsal výš, nebylo dobrý kdyby to bylo napsaný hned na začátku metody. Bylo by dobrý si najít místo, kde se vytváří Unit *target a prověřuje se.

    Unit *target = m_targets.getUnitTarget();

   // In pure self-cast spells, the client won't send any unit target
   if (!target && (m_targets.getTargetMask() == TARGET_FLAG_SELF || m_targets.getTargetMask() & TARGET_FLAG_UNIT_CASTER)) // TARGET_FLAG_SELF == 0, remember!
       target = m_caster;

   if (target)
   {
       // target state requirements (not allowed state), apply to self also
       if (!m_IsTriggeredSpell && m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot), m_spellInfo, m_caster))
           return SPELL_FAILED_TARGET_AURASTATE;

       if (m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell))
           return SPELL_FAILED_TARGET_AURASTATE;

       if (m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell))
           return SPELL_FAILED_TARGET_AURASTATE;

       if (!m_IsTriggeredSpell && target == m_caster && m_spellInfo->AttributesEx & SPELL_ATTR1_CANT_TARGET_SELF)
           return SPELL_FAILED_BAD_TARGETS;

       // Nasledujici 2 radky jsem pridal
       if (m_spellInfo->Id == 3411 && target != m_caster && target->isPet())
           return SPELL_FAILED_BAD_TARGETS;

  • Upvote 1

Share this post


Link to post
Share on other sites

Ano Wolfe přesně tam.

 

Výpis z Case:

 

case SPELL_EFFECT_DUMMY:
           {
               if (m_spellInfo->Id == 51582)          // Rocket Boots Engaged
               {
                   if (m_caster->IsInWater())
                       return SPELL_FAILED_ONLY_ABOVEWATER;
               }
               else if (m_spellInfo->SpellIconID == 156)    // Holy Shock
               {
                   // spell different for friends and enemies
                   // hurt version required facing
                   if (m_targets.GetUnitTarget() && !m_caster->IsFriendlyTo(m_targets.GetUnitTarget()) && !m_caster->HasInArc(static_cast<float>(M_PI), m_targets.GetUnitTarget()))
                       return SPELL_FAILED_UNIT_NOT_INFRONT;
               }
               else if (m_spellInfo->SpellIconID == 33 && m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_SHAMAN_FIRE_NOVA)
               {
                   if (!m_caster->m_SummonSlot[1])
                       return SPELL_FAILED_SUCCESS;
               }
               else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] == 0x2000) // Death Coil (DeathKnight)
               {
                   Unit* target = m_targets.GetUnitTarget();
                   if (!target || (target->IsFriendlyTo(m_caster) && target->GetCreatureType() != CREATURE_TYPE_UNDEAD))
                       return SPELL_FAILED_BAD_TARGETS;
               }
               else if (m_spellInfo->Id == 19938)          // Awaken Peon
               {
                   Unit *unit = m_targets.GetUnitTarget();
                   if (!unit || !unit->HasAura(17743))
                       return SPELL_FAILED_BAD_TARGETS;
               }

              else if (m_spellInfo->Id == 3411) // zde je ten kod co mě dělá problémy
              {
                  Unit *unit = m_targets.GetUnitTarget(); 
                  if (!unit || unit->ToCreature()->isPet()) 
                  return SPELL_FAILED_BAD_TARGETS; 
              }

               else if (m_spellInfo->Id == 52264)          // Deliver Stolen Horse
               {
                   if (!m_caster->FindNearestCreature(28653, 5))
                       return SPELL_FAILED_OUT_OF_RANGE;
               }
               else if (m_spellInfo->Id == 31789)          // Righteous Defense
               {
                   if (m_caster->GetTypeId() != TYPEID_PLAYER)
                       return SPELL_FAILED_DONT_REPORT;

                   Unit* target = m_targets.GetUnitTarget();
                   if (!target || !target->IsFriendlyTo(m_caster) || target->getAttackers().empty())
                       return SPELL_FAILED_BAD_TARGETS;

               }
               break;
           }

 

Jinak děkuji že jste se na to podívali.

Edited by lopitr

Share this post


Link to post
Share on other sites

V tom případě přicházíme na problém, že ani nevíš, kde se ten spell zablokoval. Tento úsek filtruje kontroly, podle druhu spell efektu a tvůj spell obsahuje charge, apply aura, null (dle wowhead nebo máš v DBC něco jiného?). Do sekce DUMMY se ten kód nemůže dostat a blokace nastává někde jinde.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×