Ir para conteúdo
  • 0

[AJUDA] Paladim não ataca no mesmo sqm


Douglas V

Pergunta

Olá gente, meu server está quase pronto <3, porem, está tendo um probleminha, quando um player sobe a escada e fica no mesmo sqm que o player inimigo, ele nao consegue atacar.

Somente os players melee conseguem atacar no mesmo sqm. Os que usam spear, bolts ...., não consegue atacar, se poderem ajudar eu agradeço muito.  (na SD ele ataca perfeitamente)

( Imagem relatada do pequeno probleminha)problema n1.png

58051d508deee_probleman1.thumb.png.3c96a9cb747a12886b27c9f9ddfcb08c.png

Link para o comentário
Compartilhar em outros sites

12 respostass a esta questão

Posts Recomendados

  • 0

Olá, minha verson é esta, e não só quando sobe a escada, mas quando o player fique no mesmo quadrado. e é somente com os players que usam weapons a distancia, com exceção dos mages.

Veja os exemplos amigo

58054e478a656_tibia2.png.e19c524e890b15e650f76d80fd431cf1.png

problema n2.png

problema n3.png

58054e478a656_tibia2.png.e19c524e890b15e650f76d80fd431cf1.png.d1da3be481b618d75e501916b840f750.png

58061da737dc7_probleman2.thumb.png.9ef1d0eb65af4bff211a55271c186e8d.png

58061db980f19_probleman3.thumb.png.75795d648d5444fd13fa8b901f0bdf1c.png

Link para o comentário
Compartilhar em outros sites

  • 0

Desde que tu usas esse servidor ele contém esse erro? Se sim, o problema pode ser no código fonte (ja que seu servidor foi compilado por terceiros); se não, poste o script usado pela arma.

Link para o comentário
Compartilhar em outros sites

  • 0

@Poccnn Anos atrás eu só dei um crt+c e crt+v em um otserver 0.4 e até hoje o meu server funciona perfeitamente ( eu ainda estou com problemas com o escudo das guild )

mas a pasta do meu server está assim (cheio de lixo)

tibia 3.png

5806945147401_tibia3.thumb.png.2e24c404f9fecfef97cfb7b10e48000b.png

Link para o comentário
Compartilhar em outros sites

  • 0

Isso vai dar trabalho...

Eu te recomendo formar uma equipe, principalmente de programadores - o que é muito difícil de arrumar - para, tanto analisar os códigos, quanto para refazer os necessarios.

 

Se tu quer resolver apenas a questão do bug da arma, posta os dois scripts de weapons.

Pode ser que resolva com esses scripts.

Link para o comentário
Compartilhar em outros sites

  • 0

@Poccnn

Script weapons.xml

Citar

<?xml version="1.0" encoding="UTF-8"?>
<weapons>
    <!-- Rods -->
    <wand id="2182" level="7" mana="2" min="10" max="15" type="earth" event="function" value="default"> <!-- Snakebite Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="2186" level="13" mana="3" min="10" max="20" type="ice" event="function" value="default"> <!-- Moonlight Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="2185" level="19" mana="5" min="20" max="30" type="death" event="function" value="default"> <!-- Necrotic Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="8911" level="22" mana="5" min="20" max="30" type="ice" event="function" value="default"> <!-- Northwind Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="2181" level="26" mana="8" min="30" max="40" type="earth" event="function" value="default"> <!-- Terra Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="2183" level="33" mana="13" min="40" max="50" type="ice" event="function" value="default"> <!-- Hailstorm Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="8912" level="37" mana="13" min="50" max="60" type="earth" event="function" value="default"> <!-- Springsprout Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="8910" level="42" mana="13" min="60" max="70" type="death" event="function" value="default"> <!-- Underworld Rod -->
        <vocation id="2"/>
    </wand>
    <wand id="7958" level="100" mana="15" min="550" max="570" type="holy" event="function" value="default"> <!-- Vip Rod -->
        <vocation id="2"/>
                                   <vocation id="6"/>
    </wand>
    <wand id="12609" level="120" mana="20" min="450" max="470" type="holy" event="function" value="default"> <!-- staff of Baiak -->
        <vocation id="2"/>
        <vocation id="1"/>
    </wand>
    <wand id="7735" level="22" mana="5" min="679" max="700" type="holy" event="function" value="default"> <!-- Staff Rox -->
        <vocation id="2"/>
        <vocation id="1"/>
    </wand>
    <wand id="2437" level="1" mana="1" min="100" max="150" type="holy" event="function" value="default"> <!-- staff Al Vocation -->
        <vocation id="2"/>
        <vocation id="1"/>
        <vocation id="3"/>
        <vocation id="4"/>
        <vocation id="5"/>
        <vocation id="6"/>
        <vocation id="7"/>
        <vocation id="8"/>

                  </wand>
    <wand id="7414" level="100" mana="15" min="550" max="550" type="holy" event="function" value="default"> <!-- Vip Wand -->
        <vocation id="2"/>
        <vocation id="1"/>
    </wand>

    <!-- Wands -->
    <wand id="2190" level="7" mana="2" min="5" max="15" type="energy" event="function" value="default"> <!-- Wand of Vortex -->
        <vocation id="1"/>
    </wand>
    <wand id="2191" level="13" mana="3" min="10" max="20" type="fire" event="function" value="default"> <!-- Wand of Dragonbreath -->
        <vocation id="1"/>
    </wand>
    <wand id="2188" level="19" mana="5" min="20" max="30" type="death" event="function" value="default"> <!-- Wand of Decay -->
        <vocation id="1"/>
    </wand>
    <wand id="8921" level="22" mana="5" min="30" max="40" type="fire" event="function" value="default"> <!-- Wand of Draconia -->
        <vocation id="1"/>
    </wand>
    <wand id="2189" level="26" mana="8" min="40" max="30" type="energy" event="function" value="default"> <!-- Wand of Cosmic Energy -->
        <vocation id="1"/>
    </wand>
    <wand id="2187" level="33" mana="13" min="30" max="40" type="fire" event="function" value="default"> <!-- Wand of Inferno -->
        <vocation id="1"/>
    </wand>
    <wand id="8920" level="37" mana="13" min="40" max="50" type="energy" event="function" value="default"> <!-- Wand of Starmstorm -->
        <vocation id="1"/>
    </wand>
    <wand id="8922" level="42" mana="13" min="50" max="60" type="death" event="function" value="default"> <!-- Wand of Voodoo -->
        <vocation id="1"/>
    </wand>
    <wand id="2184" level="100" mana="15" min="79" max="100" type="death" event="function" value="default"> <!-- Wand of Baiak -->
        <vocation id="1"/>
    </wand>
    <wand id="2453" level="100" mana="35" min="3500" max="4000" type="holy" event="function" value="default"> <!-- Donate Wand -->
        <vocation id="1"/>
        <vocation id="5" showInDescription="0"/>
        <vocation id="2"/>
        <vocation id="6" showInDescription="0"/>
    </wand>
    <wand id="7451" level="100" mana="35" min="1500" max="2000" type="death" event="function" value="default"> <!-- Vip Wand -->
        <vocation id="1"/>
        <vocation id="5" showInDescription="0"/>
        <vocation id="2"/>
        <vocation id="6" showInDescription="0"/>
    </wand>
    <wand id="7424" level="100" mana="35" min="3000" max="3500" type="ice" event="function" value="default"> <!-- Vip Wand -->
        <vocation id="1"/>
        <vocation id="5" showInDescription="0"/>
        <vocation id="2"/>
        <vocation id="6" showInDescription="0"/>
    </wand>
    <wand id="2453" level="100" mana="35" min="3600" max="4100" type="holy" event="function" value="default"> <!-- Donate Wand -->
        <vocation id="1"/>
        <vocation id="5" showInDescription="0"/>
        <vocation id="2"/>
        <vocation id="6" showInDescription="0"/>
    </wand>

    <!-- Swords -->
    <melee id="2413" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7385" level="20" unproperly="1" event="function" value="default"/>
    <melee id="2377" level="20" unproperly="1" event="function" value="default"/>
    <melee id="11303" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7408" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7449" level="25" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="2392" level="30" unproperly="1" event="function" value="default"/>
    <melee id="2407" level="30" unproperly="1" event="function" value="default"/>
    <melee id="2438" level="30" unproperly="1" event="function" value="default"/>
    <melee id="7407" level="30" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7406" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="2451" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7404" level="40" unproperly="1" event="function" value="default"/>
    <melee id="7386" level="40" unproperly="1" event="function" value="default"/>
    <melee id="2446" level="45" unproperly="1" event="function" value="default"/>
    <melee id="7402" level="45" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7383" level="50" unproperly="1" event="function" value="default"/>
    <melee id="7391" level="50" unproperly="1" event="function" value="default"/>
    <melee id="11300" level="50" unproperly="1" event="function" value="default"/>
    <melee id="11301" level="55" unproperly="1" event="function" value="default"/>
    <melee id="7416" level="55" unproperly="1" event="function" value="default"/>
    <melee id="2393" level="55" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7384" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7382" level="60" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7417" level="65" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
    <melee id="7403" level="65" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
    <melee id="7418" level="70" unproperly="1" event="function" value="default"/>
    <melee id="7405" level="70" unproperly="1" event="function" value="default"/>
    <melee id="7390" level="75" unproperly="1" event="function" value="default"/>
    <melee id="6528" level="75" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="2400" level="80" unproperly="1" event="function" value="default"/>
    <melee id="8930" level="100" unproperly="1" event="function" value="default"/>
    <melee id="12610" level="100" unproperly="1" event="function" value="default"/>
    <melee id="8932" level="100" unproperly="1" event="function" value="default"/>
    <melee id="2408" level="120" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="8931" level="140" unproperly="1" event="function" value="default"/>
    <melee id="2390" level="140" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
        <!-- Fire -->
    <melee id="7745" level="50" unproperly="1" event="function" value="default"/>
    <melee id="7746" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7747" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7748" level="45" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
        <!-- Ice -->
    <melee id="7764" level="50" unproperly="1" event="function" value="default"/>
    <melee id="7765" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7766" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7767" level="45" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
        <!-- Earth -->
    <melee id="7855" level="50" unproperly="1" event="function" value="default"/>
    <melee id="7856" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7857" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7858" level="45" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
        <!-- Energy -->
    <melee id="7870" level="50" unproperly="1" event="function" value="default"/>
    <melee id="7871" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7872" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7873" level="45" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>

    <!-- Axes -->
    <melee id="2429" level="20" unproperly="1" event="function" value="default"/>
    <melee id="2435" level="20" unproperly="1" event="function" value="default"/>
    <melee id="2425" level="20" unproperly="1" event="function" value="default"/>
    <melee id="2430" level="25" unproperly="1" event="function" value="default"/>
    <melee id="2387" level="25" unproperly="1" event="function" value="default"/>
    <melee id="2381" level="25" unproperly="1" event="function" value="default"/>
    <melee id="2440" level="25" unproperly="1" event="function" value="default"/>
    <melee id="2426" level="25" unproperly="1" event="function" value="default"/>
    <melee id="11317" level="25" unproperly="1" event="function" value="default"/>
    <melee id="3962" level="30" unproperly="1" event="function" value="default"/>
    <melee id="7454" level="30" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="2432" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7380" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7456" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7419" level="40" unproperly="1" event="function" value="default"/>
    <melee id="7413" level="40" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7412" level="45" unproperly="1" event="function" value="default"/>
    <melee id="7436" level="45" unproperly="1" event="function" value="default"/>
    <melee id="7411" level="50" unproperly="1" event="function" value="default"/>
    <melee id="2447" level="50" unproperly="1" event="function" value="default"/>
    <melee id="7388" level="55" unproperly="1" event="function" value="default"/>
    <melee id="2427" level="55" unproperly="1" event="function" value="default"/>
    <melee id="7389" level="60" unproperly="1" event="function" value="default"/>
    <melee id="2414" level="60" unproperly="1" event="function" value="default"/>
    <melee id="11299" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7433" level="65" unproperly="1" event="function" value="default"/>
    <melee id="2454" level="65" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="2443" level="70" unproperly="1" event="function" value="default"/>
    <melee id="7420" level="70" unproperly="1" event="function" value="default"/>
    <melee id="7434" level="75" unproperly="1" event="function" value="default"/>
    <melee id="6553" level="75" unproperly="1" event="function" value="default"/>
    <melee id="7455" level="80" unproperly="1" event="function" value="default"/>
    <melee id="7435" level="85" unproperly="1" event="function" value="default"/>
    <melee id="7453" level="85" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="2431" level="90" unproperly="1" event="function" value="default"/>
    <melee id="2415" level="95" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="8924" level="110" unproperly="1" event="function" value="default"/>
    <melee id="8926" level="120" unproperly="1" event="function" value="default"/>
    <melee id="8925" level="130" unproperly="1" event="function" value="default"/>
        <!-- Fire -->
    <melee id="7749" level="20" event="function" value="default"/>
    <melee id="7750" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7751" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7752" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7753" level="65" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
        <!-- Ice -->
    <melee id="7768" level="20" event="function" value="default"/>
    <melee id="7769" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7770" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7771" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7772" level="65" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
        <!-- Earth -->
    <melee id="7859" level="20" event="function" value="default"/>
    <melee id="7860" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7861" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7862" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7863" level="65" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
        <!-- Energy -->
    <melee id="7874" level="20" event="function" value="default"/>
    <melee id="7875" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7876" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7877" level="35" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="7878" level="65" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>

    <!-- Clubs -->
    <melee id="2423" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7381" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7425" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7432" level="20" unproperly="1" event="function" value="default"/>
    <melee id="2434" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7387" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7379" level="25" unproperly="1" event="function" value="default"/>
    <melee id="7430" level="30" unproperly="1" event="function" value="default"/>
    <melee id="2436" level="30" unproperly="1" event="function" value="default"/>
    <melee id="7437" level="30" unproperly="1" event="function" value="default"/>
    <melee id="7424" level="30" unproperly="1" event="function" value="default"/>
    <melee id="7452" level="30" unproperly="1" event="function" value="default">
        <vocation id="4"/>
    </melee>
    <melee id="3961" level="35" unproperly="1" event="function" value="default"/>
    <melee id="2445" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7451" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7392" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7426" level="40" unproperly="1" event="function" value="default"/>
    <melee id="2424" level="45" unproperly="1" event="function" value="default"/>
    <melee id="7427" level="45" unproperly="1" event="function" value="default"/>
    <melee id="2391" level="50" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
    <melee id="7410" level="55" unproperly="1" event="function" value="default"/>
    <melee id="7428" level="55" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
    <melee id="11302" level="55" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
    <melee id="7415" level="60" unproperly="1" event="function" value="default"/>
                  <melee id="7414" level="100" unproperly="1" event="function" value="default">
        <vocation id="1"/>
        <vocation id="5" showInDescription="0"/>
    </melee>
    <melee id="7421" level="65" unproperly="1" event="function" value="default"/>
    <melee id="2444" level="65" unproperly="1" event="function" value="default"/>
    <melee id="2452" level="70" unproperly="1" event="function" value="default"/>
    <melee id="7422" level="70" unproperly="1" event="function" value="default"/>
    <melee id="7429" level="75" unproperly="1" event="function" value="default"/>
    <melee id="7431" level="80" unproperly="1" event="function" value="default"/>
    <melee id="2421" level="85" unproperly="1" event="function" value="default"/>
    <melee id="7423" level="85" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
    <melee id="8928" level="100" unproperly="1" event="function" value="default"/>
    <melee id="8929" level="100" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
    <melee id="8927" level="120" unproperly="1" event="function" value="default"/>
        <!-- Fire -->
    <melee id="7754" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7755" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7756" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7757" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7758" level="50" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
        <!-- Ice -->
    <melee id="7773" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7774" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7775" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7776" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7777" level="50" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
        <!-- Earth -->
    <melee id="7864" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7865" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7866" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7867" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7868" level="50" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>
        <!-- Energy -->
    <melee id="7879" level="20" unproperly="1" event="function" value="default"/>
    <melee id="7880" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7881" level="60" unproperly="1" event="function" value="default"/>
    <melee id="7882" level="35" unproperly="1" event="function" value="default"/>
    <melee id="7883" level="50" unproperly="1" event="function" value="default">
        <vocation id="4"/>
        <vocation id="8" showInDescription="0"/>
    </melee>

    <!-- Bows and Crossbows -->
    <distance id="8849" level="45" unproperly="1" event="function" value="default"> <!-- Modified Crossbow -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8850" level="60" swing="yes" unproperly="1" event="function" value="default"> <!-- Vip Bolter -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8853" level="80" unproperly="1" event="function" value="default"> <!-- Ironworker -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8852" level="100" unproperly="1" event="function" value="default"> <!-- Devileye -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8851" level="130" unproperly="1" event="function" value="default"> <!-- Royal Crossbow -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8857" level="40" unproperly="1" event="function" value="default"> <!-- Silkweaver Bow -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8855" level="50" unproperly="1" event="function" value="default"> <!-- Composite Hornbow -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8856" level="60" unproperly="1" event="function" value="default"> <!-- Yol's Bow -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8858" level="70" unproperly="1" event="function" value="default"> <!-- Elethriel's Elemental Bow -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="8854" level="80" unproperly="1" event="function" value="default"> <!-- Warsinger Bow -->
        <vocation id="3"/>
        <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="5907" level="60" swing="yes" unproperly="1" event="function" value="default"> <!-- Donate Slingshot -->
    <vocation id="3"/>
    <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="7366" level="60" swing="yes" unproperly="1" event="function" value="default"> <!-- Free Star -->
    <vocation id="3"/>
    <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="7368" level="60" swing="yes" unproperly="1" event="function" value="default"> <!-- Assassin Star -->
    <vocation id="3"/>
    <vocation id="7" showInDescription="0"/>
    </distance>
    <distance id="2389" level="60" swing="yes" unproperly="1" event="function" value="default"> <!-- Spear -->
    <vocation id="3"/>
    <vocation id="7" showInDescription="0"/>
    </distance>

<distance id="2545" swing="true" event="script" value="poison_arrow.lua"/>
<distance id="2546" swing="true" event="script" value="burst_arrow.lua"/>
<distance id="7366" swing="true" event="script" value="viper_star.lua"/>
<distance id="7838" type="energy" swing="true" event="function" value="default"/>
<distance id="7839" type="ice" swing="true" event="function" value="default"/>
<distance id="7840" type="fire" swing="true" event="function" value="default"/>
<distance id="7850" type="earth" swing="true" event="function" value="default"/>
<distance id="2544" swing="true" event="function" value="default"/> <!-- Arrow -->
<distance id="2543" swing="true" event="function" value="default"/> <!-- Bolt -->
<distance id="2389" swing="true" event="function" value="default"/> <!-- Spear -->
<distance id="3965" level="20" swing="true" event="function" value="default"/> <!-- Hunting Spear -->
<distance id="7378" level="25" swing="true" event="function" value="default"/> <!-- Royal Spear -->
<distance id="7367" level="42" swing="true" event="function" value="default"/> <!-- Enchanted Spear -->
<distance id="7368" level="80" swing="true" event="function" value="default"/> <!-- Assassin Star -->
<distance id="7364" level="20" swing="true" event="function" value="default"/> <!-- Sniper Arrow -->
<distance id="7365" level="40" swing="true" event="function" value="default"/> <!-- Onyx Arrow -->
<distance id="7363" level="30" swing="true" event="function" value="default"/> <!-- Piercing Bolt -->
<distance id="2547" level="55" swing="true" event="function" value="default"/> <!-- Power Bolt -->
<distance id="6529" level="70" swing="true" event="function" value="default"/> <!-- Infernal Bolt -->
</weapons>
 

 

Link para o comentário
Compartilhar em outros sites

  • 0

@Poccnn

Sorry, este aqui??

Weapons CPP (tem o  wapons.h se precisar)

 

 

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////
#include "otpch.h"
#include "weapons.h"

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#include "game.h"
#include "configmanager.h"
#include "tools.h"

extern Game g_game;
extern ConfigManager g_config;
extern Weapons* g_weapons;

Weapons::Weapons():
	m_interface("Weapon Interface")
{
	m_interface.initState();
}

const Weapon* Weapons::getWeapon(const Item* item) const
{
	if(!item)
		return NULL;

	WeaponMap::const_iterator it = weapons.find(item->getID());
	if(it != weapons.end())
		return it->second;

	return NULL;
}

void Weapons::clear()
{
	for(WeaponMap::iterator it = weapons.begin(); it != weapons.end(); ++it)
		delete it->second;

	weapons.clear();
	m_interface.reInitState();
}

bool Weapons::loadDefaults()
{
	for(uint32_t i = 0; i <= Item::items.size(); ++i)
	{
		const ItemType* it = Item::items.getElement(i);
		if(!it || weapons.find(it->id) != weapons.end())
			continue;

		if(it->weaponType != WEAPON_NONE)
		{
			switch(it->weaponType)
			{
				case WEAPON_AXE:
				case WEAPON_SWORD:
				case WEAPON_CLUB:
				case WEAPON_FIST:
				{
					if(WeaponMelee* weapon = new WeaponMelee(&m_interface))
					{
						weapon->configureWeapon(*it);
						weapons[it->id] = weapon;
					}

					break;
				}

				case WEAPON_DIST:
					if(it->ammoType != AMMO_NONE)
						break;

				case WEAPON_AMMO:
				{
					if(WeaponDistance* weapon = new WeaponDistance(&m_interface))
					{
						weapon->configureWeapon(*it);
						weapons[it->id] = weapon;
					}

					break;
				}

				default:
					break;
			}
		}
	}

	return true;
}

Event* Weapons::getEvent(const std::string& nodeName)
{
	std::string tmpNodeName = asLowerCaseString(nodeName);
	if(tmpNodeName == "melee")
		return new WeaponMelee(&m_interface);

	if(tmpNodeName == "distance" || tmpNodeName == "ammunition" || tmpNodeName == "ammo")
		return new WeaponDistance(&m_interface);

	if(tmpNodeName == "wand" || tmpNodeName == "rod")
		return new WeaponWand(&m_interface);

	return NULL;
}

bool Weapons::registerEvent(Event* event, xmlNodePtr, bool override)
{
	Weapon* weapon = dynamic_cast<Weapon*>(event);
	if(!weapon)
		return false;

	WeaponMap::iterator it = weapons.find(weapon->getID());
	if(it == weapons.end())
	{
		weapons[weapon->getID()] = weapon;
		return true;
	}

	if(override)
	{
		delete it->second;
		it->second = weapon;
		return true;
	}

	std::clog << "[Warning - Weapons::registerEvent] Duplicate registered item with id: " << weapon->getID() << std::endl;
	return false;
}

int32_t Weapons::getMaxMeleeDamage(int32_t attackSkill, int32_t attackValue)
{
	return (int32_t)std::ceil((attackSkill * (attackValue * 0.05)) + (attackValue * 0.5));
}

int32_t Weapons::getMaxWeaponDamage(int32_t level, int32_t attackSkill, int32_t attackValue, float attackFactor)
{
	return (int32_t)std::ceil((2 * (attackValue * (attackSkill + 5.8) / 25 + (level - 1) / 10.)) / attackFactor);
}

Weapon::Weapon(LuaInterface* _interface):
	Event(_interface)
{
	id = 0;
	level = 0;
	magLevel = 0;
	mana = 0;
	manaPercent = 0;
	soul = 0;
	exhaustion = 0;
	premium = false;
	enabled = true;
	wieldUnproperly = false;
	swing = true;
	ammoAction = AMMOACTION_NONE;
	params.blockedByArmor = true;
	params.blockedByShield = true;
	params.combatType = COMBAT_PHYSICALDAMAGE;
}

bool Weapon::configureEvent(xmlNodePtr p)
{
	int32_t intValue, wieldInfo = 0;
	std::string strValue;
	if(!readXMLInteger(p, "id", intValue))
	{
		std::clog << "Error: [Weapon::configureEvent] Weapon without id." << std::endl;
		return false;
	}

	id = intValue;
	if(readXMLInteger(p, "lv", intValue) || readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue))
	{
	 	level = intValue;
		if(level > 0)
			wieldInfo |= WIELDINFO_LEVEL;
	}

	if(readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglvl", intValue) || readXMLInteger(p, "maglevel", intValue))
	{
	 	magLevel = intValue;
		if(magLevel > 0)
			wieldInfo |= WIELDINFO_MAGLV;
	}

	if(readXMLInteger(p, "mana", intValue))
	 	mana = intValue;

	if(readXMLInteger(p, "manapercent", intValue))
	 	manaPercent = intValue;

	if(readXMLInteger(p, "soul", intValue))
	 	soul = intValue;

	if(readXMLInteger(p, "exhaust", intValue) || readXMLInteger(p, "exhaustion", intValue))
		exhaustion = intValue;

	if(readXMLString(p, "prem", strValue) || readXMLString(p, "premium", strValue))
	{
		premium = booleanString(strValue);
		if(premium)
			wieldInfo |= WIELDINFO_PREMIUM;
	}

	if(readXMLString(p, "enabled", strValue))
		enabled = booleanString(strValue);

	if(readXMLString(p, "unproperly", strValue))
		wieldUnproperly = booleanString(strValue);

	if(readXMLString(p, "swing", strValue))
		swing = booleanString(strValue);

	if(readXMLString(p, "type", strValue))
		params.combatType = getCombatType(strValue);

	std::string error;
	StringVec vocStringVec;

	xmlNodePtr vocationNode = p->children;
	while(vocationNode)
	{
		if(!parseVocationNode(vocationNode, vocWeaponMap, vocStringVec, error))
			std::clog << "[Warning - Weapon::configureEvent] " << error << std::endl;

		vocationNode = vocationNode->next;
	}

	if(!vocWeaponMap.empty())
		wieldInfo |= WIELDINFO_VOCREQ;

	if(wieldInfo)
	{
		ItemType& it = Item::items.getItemType(id);
		it.minReqMagicLevel = getReqMagLv();
		it.minReqLevel = getReqLevel();

		it.wieldInfo = wieldInfo;
		it.vocationString = parseVocationString(vocStringVec);
	}

	return configureWeapon(Item::items[getID()]);
}

bool Weapon::loadFunction(const std::string& functionName)
{
	std::string tmpFunctionName = asLowerCaseString(functionName);
	if(tmpFunctionName == "internalloadweapon" || tmpFunctionName == "default")
	{
		m_scripted = EVENT_SCRIPT_FALSE;
		return configureWeapon(Item::items[getID()]);
	}

	return false;
}

bool Weapon::configureWeapon(const ItemType& it)
{
	id = it.id;
	return true;
}

int32_t Weapon::playerWeaponCheck(Player* player, Creature* target) const
{
	const Position& playerPos = player->getPosition();
	const Position& targetPos = target->getPosition();
	if(playerPos.z != targetPos.z)
		return 0;

	const ItemType& it = Item::items[getID()];
	int32_t range = it.shootRange;
	if(it.weaponType == WEAPON_AMMO)
		range = player->getShootRange();

	if(std::max(std::abs(playerPos.x - targetPos.x), std::abs(playerPos.y - targetPos.y)) > range)
		return 0;

	if(player->hasFlag(PlayerFlag_IgnoreEquipCheck))
		return 100;

	if(!enabled)
		return 0;

	if(player->getMana() < getManaCost(player))
		return 0;

	if(player->getSoul() < soul)
		return 0;

	if(isPremium() && !player->isPremium())
		return 0;

	if(!vocWeaponMap.empty() && vocWeaponMap.find(player->getVocationId()) == vocWeaponMap.end())
		return 0;

	int32_t modifier = 100;
	if(player->getLevel() < getReqLevel())
	{
		if(!isWieldedUnproperly())
			return 0;

		double penalty = (getReqLevel() - player->getLevel()) * 0.02;
		if(penalty > 0.5)
			penalty = 0.5;

		modifier -= (int32_t)(modifier * penalty);
	}

	if(player->getMagicLevel() < getReqMagLv())
	{
		if(isWieldedUnproperly())
			return 0;

		double penalty = (getReqMagLv() - player->getMagicLevel()) * 0.02;
		if(penalty > 0.5)
			penalty = 0.5;

		modifier -= (int32_t)(modifier * penalty);
	}

	return modifier;
}

bool Weapon::useWeapon(Player* player, Item* item, Creature* target) const
{
	int32_t modifier = playerWeaponCheck(player, target);
	if(!modifier)
		return false;

	return internalUseWeapon(player, item, target, modifier);
}

bool Weapon::useFist(Player* player, Creature* target)
{
	const Position& playerPos = player->getPosition();
	const Position& targetPos = target->getPosition();
	if(!Position::areInRange<1,1>(playerPos, targetPos))
		return false;

	float attackFactor = player->getAttackFactor();
	int32_t attackSkill = player->getSkill(SKILL_FIST, SKILL_LEVEL), attackValue = g_config.getNumber(ConfigManager::FIST_BASE_ATTACK);

	double maxDamage = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
	if(random_range(1, 100) < g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE))
	{
		maxDamage = std::pow(maxDamage, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
		player->sendCritical();
	}

	Vocation* vocation = player->getVocation();
	if(vocation && vocation->getMultiplier(MULTIPLIER_MELEE) != 1.0)
		maxDamage *= vocation->getMultiplier(MULTIPLIER_MELEE);

	maxDamage = std::floor(maxDamage);
	int32_t damage = -random_range(0, (int32_t)maxDamage, DISTRO_NORMAL);

	CombatParams fist;
	fist.blockedByArmor = true;
	fist.blockedByShield = true;
	fist.combatType = COMBAT_PHYSICALDAMAGE;

	Combat::doCombatHealth(player, target, damage, damage, fist);
	if(!player->hasFlag(PlayerFlag_NotGainSkill) && player->getAddAttackSkill())
		player->addSkillAdvance(SKILL_FIST, 1);

	return true;
}

bool Weapon::internalUseWeapon(Player* player, Item* item, Creature* target, int32_t modifier) const
{
	if(isScripted())
	{
		LuaVariant var;
		var.type = VARIANT_NUMBER;
		var.number = target->getID();
		executeUseWeapon(player, var);
	}
	else
	{
		int32_t damage = (getWeaponDamage(player, target, item) * modifier) / 100;
		Combat::doCombatHealth(player, target, damage, damage, params);
	}

	onUsedAmmo(player, item, target->getTile());
	onUsedWeapon(player, item, target->getTile());
	return true;
}

bool Weapon::internalUseWeapon(Player* player, Item* item, Tile* tile) const
{
	if(isScripted())
	{
		LuaVariant var;
		var.type = VARIANT_TARGETPOSITION;
		var.pos = tile->getPosition();
		executeUseWeapon(player, var);
	}
	else
	{
		Combat::postCombatEffects(player, tile->getPosition(), params);
		g_game.addMagicEffect(tile->getPosition(), MAGIC_EFFECT_POFF);
	}

	onUsedAmmo(player, item, tile);
	onUsedWeapon(player, item, tile);
	return true;
}

void Weapon::onUsedWeapon(Player* player, Item* item, Tile*) const
{
	if(!player->hasFlag(PlayerFlag_NotGainSkill))
	{
		skills_t skillType;
		uint32_t skillPoint = 0;
		if(getSkillType(player, item, skillType, skillPoint))
			player->addSkillAdvance(skillType, skillPoint);
	}

	if(!player->hasFlag(PlayerFlag_HasNoExhaustion) && exhaustion > 0)
		player->addExhaust(exhaustion, EXHAUST_COMBAT);

	int32_t manaCost = getManaCost(player);
	if(manaCost > 0)
	{
		player->changeMana(-manaCost);
		if(!player->hasFlag(PlayerFlag_NotGainMana) && (player->getZone() != ZONE_HARDCORE
			|| !g_config.getBool(ConfigManager::PVPZONE_ADDMANASPENT)))
			player->addManaSpent(manaCost);
	}

	if(!player->hasFlag(PlayerFlag_HasInfiniteSoul) && soul > 0)
		player->changeSoul(-soul);
}

void Weapon::onUsedAmmo(Player* player, Item* item, Tile* destTile) const
{
	if(!g_config.getBool(ConfigManager::REMOVE_WEAPON_AMMO))
		return;

	switch(ammoAction)
	{
		case AMMOACTION_REMOVECOUNT:
			g_game.transformItem(item, item->getID(), std::max((int32_t)0, ((int32_t)item->getItemCount()) - 1));
			break;

		case AMMOACTION_REMOVECHARGE:
			g_game.transformItem(item, item->getID(), std::max((int32_t)0, ((int32_t)item->getCharges()) - 1));
			break;

		case AMMOACTION_MOVE:
			g_game.internalMoveItem(player, item->getParent(), destTile, INDEX_WHEREEVER, item, 1, NULL, FLAG_NOLIMIT);
			break;

		case AMMOACTION_MOVEBACK:
			break;

		default:
			if(item->hasCharges())
				g_game.transformItem(item, item->getID(), std::max((int32_t)0, ((int32_t)item->getCharges()) - 1));

			break;
	}
}

int32_t Weapon::getManaCost(const Player* player) const
{
	if(mana)
		return mana;

	return manaPercent ? (player->getMaxMana() * manaPercent) / 100 : 0;
}

bool Weapon::executeUseWeapon(Player* player, const LuaVariant& var) const
{
	//onUseWeapon(cid, var)
	if(m_interface->reserveEnv())
	{
		ScriptEnviroment* env = m_interface->getEnv();
		if(m_scripted == EVENT_SCRIPT_BUFFER)
		{
			env->setRealPos(player->getPosition());
			std::stringstream scriptstream;

			scriptstream << "local cid = " << env->addThing(player) << std::endl;
			env->streamVariant(scriptstream, "var", var);

			scriptstream << m_scriptData;
			bool result = true;
			if(m_interface->loadBuffer(scriptstream.str()))
			{
				lua_State* L = m_interface->getState();
				result = m_interface->getGlobalBool(L, "_result", true);
			}

			m_interface->releaseEnv();
			return result;
		}
		else
		{
			#ifdef __DEBUG_LUASCRIPTS__
			char desc[60];
			sprintf(desc, "onUseWeapon - %s", player->getName().c_str());
			env->setEvent(desc);
			#endif

			env->setScriptId(m_scriptId, m_interface);
			env->setRealPos(player->getPosition());

			lua_State* L = m_interface->getState();
			m_interface->pushFunction(m_scriptId);

			lua_pushnumber(L, env->addThing(player));
			m_interface->pushVariant(L, var);

			bool result = m_interface->callFunction(2);
			m_interface->releaseEnv();
			return result;
		}
	}
	else
	{
		std::clog << "[Error - Weapon::executeUseWeapon] Call stack overflow" << std::endl;
		return false;
	}
}

WeaponMelee::WeaponMelee(LuaInterface* _interface):
	Weapon(_interface)
{
	elementType = COMBAT_NONE;
	elementDamage = 0;
}

bool WeaponMelee::configureWeapon(const ItemType& it)
{
	elementType = it.abilities.elementType;
	elementDamage = it.abilities.elementDamage;
	return Weapon::configureWeapon(it);
}

bool WeaponMelee::useWeapon(Player* player, Item* item, Creature* target) const
{
	if(!Weapon::useWeapon(player, item, target))
		return false;

	if(elementDamage && elementType != COMBAT_NONE)
	{
		CombatParams element;
		element.combatType = elementType;

		int32_t damage = getElementDamage(player, item);
		Combat::doCombatHealth(player, target, damage, damage, element);
	}

	return true;
}

bool WeaponMelee::getSkillType(const Player* player, const Item* item,
	skills_t& skill, uint32_t& skillpoint) const
{
	skillpoint = 0;
	if(player->getAddAttackSkill())
	{
		switch(player->getLastAttackBlockType())
		{
			case BLOCK_ARMOR:
			case BLOCK_NONE:
				skillpoint = 1;
				break;

			case BLOCK_DEFENSE:
			default:
				skillpoint = 0;
				break;
		}
	}

	switch(item->getWeaponType())
	{
		case WEAPON_SWORD:
		{
			skill = SKILL_SWORD;
			return true;
		}

		case WEAPON_CLUB:
		{
			skill = SKILL_CLUB;
			return true;
		}

		case WEAPON_AXE:
		{
			skill = SKILL_AXE;
			return true;
		}

		case WEAPON_FIST:
		{
			skill = SKILL_FIST;
			return true;
		}

		default:
			break;
	}

	return false;
}

int32_t WeaponMelee::getWeaponDamage(const Player* player, const Creature*, const Item* item, bool maxDamage /*= false*/) const
{
	int32_t attackSkill = player->getWeaponSkill(item), attackValue = std::max((int32_t)0,
		(int32_t(item->getAttack() + item->getExtraAttack()) - elementDamage));
	float attackFactor = player->getAttackFactor();

	double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
	if(random_range(1, 100) < g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE))
	{
		maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
		player->sendCritical();
	}

	Vocation* vocation = player->getVocation();
	if(vocation && vocation->getMultiplier(MULTIPLIER_MELEE) != 1.0)
		maxValue *= vocation->getMultiplier(MULTIPLIER_MELEE);

	int32_t ret = (int32_t)std::floor(maxValue);
	if(maxDamage)
		return -ret;

	return -random_range(0, ret, DISTRO_NORMAL);
}

int32_t WeaponMelee::getElementDamage(const Player* player, const Item* item) const
{
	int32_t attackSkill = player->getWeaponSkill(item);
	float attackFactor = player->getAttackFactor();

	double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, elementDamage, attackFactor);
	if(random_range(1, 100) < g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE))
	{
		maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
		player->sendCritical();
	}

	Vocation* vocation = player->getVocation();
	if(vocation && vocation->getMultiplier(MULTIPLIER_MELEE) != 1.0)
		maxValue *= vocation->getMultiplier(MULTIPLIER_MELEE);

	return -random_range(0, (int32_t)std::floor(maxValue), DISTRO_NORMAL);
}

WeaponDistance::WeaponDistance(LuaInterface* _interface):
	Weapon(_interface)
{
	hitChance = -1;
	maxHitChance = breakChance = ammoAttackValue = 0;
	swing = params.blockedByShield = false;
}

bool WeaponDistance::configureWeapon(const ItemType& it)
{
	if(it.ammoType != AMMO_NONE) //hit chance on two-handed weapons is limited to 90%
		maxHitChance = 90;
	else //one-handed is set to 75%
		maxHitChance = 75;

	if(it.hitChance > 0)
		hitChance = it.hitChance;

	if(it.maxHitChance > 0)
		maxHitChance = it.maxHitChance;

	if(it.breakChance > 0)
		breakChance = it.breakChance;

	if(it.ammoAction != AMMOACTION_NONE)
		ammoAction = it.ammoAction;

	params.effects.distance = it.shootType;
	ammoAttackValue = it.attack;
	return Weapon::configureWeapon(it);
}

int32_t WeaponDistance::playerWeaponCheck(Player* player, Creature* target) const
{
	const ItemType& it = Item::items[id];
	if(it.weaponType == WEAPON_AMMO)
	{
		if(Item* item = player->getWeapon(true))
		{
			if(const Weapon* weapon = g_weapons->getWeapon(item))
				return weapon->playerWeaponCheck(player, target);
		}
	}

	return Weapon::playerWeaponCheck(player, target);
}

bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) const
{
	int32_t modifier = playerWeaponCheck(player, target);
	if(!modifier)
		return false;

	int32_t chance = hitChance;
	if(chance == -1)
	{
		//hit chance is based on distance to target and distance skill
		const Position& playerPos = player->getPosition();
		const Position& targetPos = target->getPosition();

		uint32_t distance = std::max(std::abs(playerPos.x - targetPos.x), std::abs(
			playerPos.y - targetPos.y)), skill = player->getSkill(SKILL_DIST, SKILL_LEVEL);
		if(maxHitChance == 75)
		{
			//chance for one-handed weapons
			switch(distance)
			{
				case 1:
					chance = (uint32_t)((float)std::min(skill, (uint32_t)74)) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)2.4 * std::min(skill, (uint32_t)28)) + 8;
					break;
				case 3:
					chance = (uint32_t)((float)1.55 * std::min(skill, (uint32_t)45)) + 6;
					break;
				case 4:
					chance = (uint32_t)((float)1.25 * std::min(skill, (uint32_t)58)) + 3;
					break;
				case 5:
					chance = (uint32_t)((float)std::min(skill, (uint32_t)74)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)0.8 * std::min(skill, (uint32_t)90)) + 3;
					break;
				case 7:
					chance = (uint32_t)((float)0.7 * std::min(skill, (uint32_t)104)) + 2;
					break;
				default:
					chance = hitChance;
					break;
			}
		}
		else if(maxHitChance == 90)
		{
			//formula for two-handed weapons
			switch(distance)
			{
				case 1:
					chance = (uint32_t)((float)1.2 * std::min(skill, (uint32_t)74)) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)3.2 * std::min(skill, (uint32_t)28));
					break;
				case 3:
					chance = (uint32_t)((float)2.0 * std::min(skill, (uint32_t)45));
					break;
				case 4:
					chance = (uint32_t)((float)1.55 * std::min(skill, (uint32_t)58));
					break;
				case 5:
					chance = (uint32_t)((float)1.2 * std::min(skill, (uint32_t)74)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)1.0 * std::min(skill, (uint32_t)90));
					break;
				case 7:
					chance = (uint32_t)((float)1.0 * std::min(skill, (uint32_t)90));
					break;
				default:
					chance = hitChance;
					break;
			}
		}
		else if(maxHitChance == 100)
		{
			switch(distance)
			{
				case 1:
					chance = (uint32_t)((float)1.35 * std::min(skill, (uint32_t)73)) + 1;
					break;
				case 2:
					chance = (uint32_t)((float)3.2 * std::min(skill, (uint32_t)30)) + 4;
					break;
				case 3:
					chance = (uint32_t)((float)2.05 * std::min(skill, (uint32_t)48)) + 2;
					break;
				case 4:
					chance = (uint32_t)((float)1.5 * std::min(skill, (uint32_t)65)) + 2;
					break;
				case 5:
					chance = (uint32_t)((float)1.35 * std::min(skill, (uint32_t)73)) + 1;
					break;
				case 6:
					chance = (uint32_t)((float)1.2 * std::min(skill, (uint32_t)87)) - 4;
					break;
				case 7:
					chance = (uint32_t)((float)1.1 * std::min(skill, (uint32_t)90)) + 1;
					break;
				default:
					chance = hitChance;
					break;
			}
		}
		else
			chance = maxHitChance;
	}

	if(item->getWeaponType() == WEAPON_AMMO)
	{
		Item* bow = player->getWeapon(true);
		if(bow && bow->getHitChance() != -1)
			chance += bow->getHitChance();
	}

	if(random_range(1, 100) > chance)
	{
		//we failed attack, miss!
		Tile* destTile = target->getTile();
		if(!Position::areInRange<1,1,0>(player->getPosition(), target->getPosition()))
		{
			std::vector<std::pair<int32_t, int32_t> > destList;
			destList.push_back(std::make_pair(-1, -1));
			destList.push_back(std::make_pair(-1, 0));
			destList.push_back(std::make_pair(-1, 1));
			destList.push_back(std::make_pair(0, -1));
			destList.push_back(std::make_pair(0, 0));
			destList.push_back(std::make_pair(0, 1));
			destList.push_back(std::make_pair(1, -1));
			destList.push_back(std::make_pair(1, 0));
			destList.push_back(std::make_pair(1, 1));

			std::random_shuffle(destList.begin(), destList.end());
			Position destPos = target->getPosition();

			Tile* tmpTile = NULL;
			for(std::vector<std::pair<int32_t, int32_t> >::iterator it = destList.begin(); it != destList.end(); ++it)
			{
				if((tmpTile = g_game.getTile(destPos.x + it->first, destPos.y + it->second, destPos.z))
					&& !tmpTile->hasProperty(IMMOVABLEBLOCKSOLID) && tmpTile->ground)
				{
					destTile = tmpTile;
					break;
				}
			}
		}

		Weapon::internalUseWeapon(player, item, destTile);
	}
	else
		Weapon::internalUseWeapon(player, item, target, modifier);

	return true;
}

void WeaponDistance::onUsedAmmo(Player* player, Item* item, Tile* destTile) const
{
	if(!g_config.getBool(ConfigManager::REMOVE_WEAPON_AMMO))
		return;

	if(ammoAction == AMMOACTION_MOVEBACK && breakChance > 0 && random_range(1, 100) <= breakChance)
		g_game.transformItem(item, item->getID(), std::max(0, item->getItemCount() - 1));
	else
		Weapon::onUsedAmmo(player, item, destTile);
}

int32_t WeaponDistance::getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage /*= false*/) const
{
	int32_t attackValue = ammoAttackValue;
	if(item->getWeaponType() == WEAPON_AMMO)
	{
		if(Item* bow = const_cast<Player*>(player)->getWeapon(true))
			attackValue += bow->getAttack() + bow->getExtraAttack();
	}

	int32_t attackSkill = player->getSkill(SKILL_DIST, SKILL_LEVEL);
	float attackFactor = player->getAttackFactor();

	double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
	if(random_range(1, 100) < g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE))
	{
		maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
		player->sendCritical();
	}

	Vocation* vocation = player->getVocation();
	if(vocation && vocation->getMultiplier(MULTIPLIER_DISTANCE) != 1.0)
		maxValue *= vocation->getMultiplier(MULTIPLIER_DISTANCE);

	int32_t ret = (int32_t)std::floor(maxValue);
	if(maxDamage)
		return -ret;

	int32_t minValue = 0;
	if(target)
	{
		if(target->getPlayer())
			minValue = (int32_t)std::ceil(player->getLevel() * 0.1);
		else
			minValue = (int32_t)std::ceil(player->getLevel() * 0.2);
	}

	return -random_range(minValue, ret, DISTRO_NORMAL);
}

bool WeaponDistance::getSkillType(const Player* player, const Item*,
	skills_t& skill, uint32_t& skillpoint) const
{
	skill = SKILL_DIST;
	skillpoint = 0;

	if(player->getAddAttackSkill())
	{
		switch(player->getLastAttackBlockType())
		{
			case BLOCK_NONE:
				skillpoint = 2;
				break;

			case BLOCK_ARMOR:
				skillpoint = 1;
				break;

			case BLOCK_DEFENSE:
			default:
				skillpoint = 0;
				break;
		}
	}
	return true;
}

WeaponWand::WeaponWand(LuaInterface* _interface):
	Weapon(_interface)
{
	minChange = 0;
	maxChange = 0;
	params.blockedByArmor = false;
	params.blockedByShield = false;
}

bool WeaponWand::configureEvent(xmlNodePtr p)
{
	if(!Weapon::configureEvent(p))
		return false;

	int32_t intValue;
	if(readXMLInteger(p, "min", intValue))
		minChange = intValue;

	if(readXMLInteger(p, "max", intValue))
		maxChange = intValue;

	return true;
}

bool WeaponWand::configureWeapon(const ItemType& it)
{
	params.effects.distance = it.shootType;
	return Weapon::configureWeapon(it);
}

int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
	float multiplier = 1.0f;
	if(Vocation* vocation = player->getVocation())
		multiplier = vocation->getMultiplier(MULTIPLIER_WAND);

	int32_t maxValue = (int32_t)(maxChange * multiplier);
	if(maxDamage)
	{
		player->sendCritical();
		return -maxValue;
	}

	int32_t minValue = (int32_t)(minChange * multiplier);
	return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

 

@Poccnn

Weapons.h

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////

#ifndef __WEAPONS__
#define __WEAPONS__
#include "otsystem.h"

#include "const.h"
#include "combat.h"

#include "baseevents.h"
#include "luascript.h"

#include "player.h"
#include "item.h"

class Weapon;
class WeaponMelee;
class WeaponDistance;
class WeaponWand;

class Weapons : public BaseEvents
{
	public:
		Weapons();
		virtual ~Weapons() {clear();}

		bool loadDefaults();
		const Weapon* getWeapon(const Item* item) const;

		static int32_t getMaxMeleeDamage(int32_t attackSkill, int32_t attackValue);
		static int32_t getMaxWeaponDamage(int32_t level, int32_t attackSkill, int32_t attackValue, float attackFactor);

	protected:
		virtual std::string getScriptBaseName() const {return "weapons";}
		virtual void clear();

		virtual Event* getEvent(const std::string& nodeName);
		virtual bool registerEvent(Event* event, xmlNodePtr p, bool override);

		virtual LuaInterface& getInterface() {return m_interface;}
		LuaInterface m_interface;

		typedef std::map<uint32_t, Weapon*> WeaponMap;
		WeaponMap weapons;
};

class Weapon : public Event
{
	public:
		Weapon(LuaInterface* _interface);
		virtual ~Weapon() {}

		static bool useFist(Player* player, Creature* target);

		virtual bool loadFunction(const std::string& functionName);
		virtual bool configureEvent(xmlNodePtr p);
		virtual bool configureWeapon(const ItemType& it);

		virtual int32_t playerWeaponCheck(Player* player, Creature* target) const;

		uint16_t getID() const {return id;}
		CombatParams getCombatParam() const {return params;}
		virtual bool interruptSwing() const {return !swing;}

		virtual bool useWeapon(Player* player, Item* item, Creature* target) const;
		virtual int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const = 0;
		virtual int32_t getElementDamage(const Player*, const Creature*) const {return 0;}

		uint32_t getReqLevel() const {return level;}
		uint32_t getReqMagLv() const {return magLevel;}
		bool hasExhaustion() const {return exhaustion;}
		bool isPremium() const {return premium;}
		bool isWieldedUnproperly() const {return wieldUnproperly;}

	protected:
		virtual std::string getScriptEventName() const {return "onUseWeapon";}
		virtual std::string getScriptEventParams() const {return "cid, var";}

		bool executeUseWeapon(Player* player, const LuaVariant& var) const;

		bool internalUseWeapon(Player* player, Item* item, Creature* target, int32_t modifier) const;
		bool internalUseWeapon(Player* player, Item* item, Tile* tile) const;

		virtual void onUsedWeapon(Player* player, Item* item, Tile* destTile) const;
		virtual void onUsedAmmo(Player* player, Item* item, Tile* destTile) const;
		virtual bool getSkillType(const Player*, const Item*, skills_t&, uint32_t&) const {return false;}

		int32_t getManaCost(const Player* player) const;

		uint16_t id;
		uint32_t exhaustion;
		bool enabled, premium, wieldUnproperly, swing;
		int32_t level, magLevel, mana, manaPercent, soul;

		AmmoAction_t ammoAction;
		CombatParams params;

	private:
		VocationMap vocWeaponMap;
};

class WeaponMelee : public Weapon
{
	public:
		WeaponMelee(LuaInterface* _interface);
		virtual ~WeaponMelee() {}

		virtual bool configureWeapon(const ItemType& it);

		virtual bool useWeapon(Player* player, Item* item, Creature* target) const;
		virtual int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const;
		virtual int32_t getElementDamage(const Player* player, const Item* item) const;

	protected:
		virtual bool getSkillType(const Player* player, const Item* item, skills_t& skill, uint32_t& skillpoint) const;

		CombatType_t elementType;
		int16_t elementDamage;
};

class WeaponDistance : public Weapon
{
	public:
		WeaponDistance(LuaInterface* _interface);
		virtual ~WeaponDistance() {}

		virtual bool configureWeapon(const ItemType& it);

		virtual int32_t playerWeaponCheck(Player* player, Creature* target) const;

		virtual bool useWeapon(Player* player, Item* item, Creature* target) const;
		virtual int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const;

	protected:
		virtual void onUsedAmmo(Player* player, Item* item, Tile* destTile) const;
		virtual bool getSkillType(const Player* player, const Item* item, skills_t& skill, uint32_t& skillpoint) const;

		int32_t hitChance, maxHitChance, breakChance, ammoAttackValue;
};

class WeaponWand : public Weapon
{
	public:
		WeaponWand(LuaInterface* _interface);
		virtual ~WeaponWand() {}

		virtual bool configureEvent(xmlNodePtr p);
		virtual bool configureWeapon(const ItemType& it);

		virtual int32_t getWeaponDamage(const Player* player, const Creature* target, const Item* item, bool maxDamage = false) const;

	protected:
		virtual bool getSkillType(const Player*, const Item*, skills_t&, uint32_t&) const {return false;}

		int32_t minChange, maxChange;
};
#endif

 

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...