Ir para conteúdo
  • Cadastre-se

NPC NPC que dá um item e passa uma mensagem.


Posts Recomendados

Olá pessoal do Tibia King tudo bem?

Bom estou aqui para fazer um pedido bem básico,

Alguém poderia me ajudar?

Queria um NPC, que fala-se com o player tipo assim:

 

                                   23:54 HaxYu: hi
                                   23:54 Rey: Eai! Você já conhece nosso servidor? Curta-nos no Facebook! Leia a placa! e ganhe uma 'BP'. 
 
E quando o player disser 'BP', ele entrega o seguinte item para o Player (ID: 12991)
 
1507188_546562012123088_5539421655723959
 
 
                                                                                     
 

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Me diga uma coisa, o player precisará clicar na placa para somente após isto dizer "BP" e ser recompensado?

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Se der seria ótimo, se não só ele dizendo 'BP' mesmo,

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Boa noite.

 

@@ EDITADO - POST INUTILIZADO.

O tópico será atualizado no outro post com o SCRIPT.

rey.xml:

<?xml version="1.0"?>
<npc name="Rey" script="recompensa.lua" walkinterval="50000" floorchange="0">
<health now="100" max="100"/>
<look type="153" head="58" body="58" legs="58" feet="50" addons="2"/>
<parameters>
<parameter key="message_greet" value="E ai |PLAYERNAME|! Você já conhece nosso servidor? Curta-nos no Facebook! Leia a placa e ganhe uma {BP}." />
</parameters>
</npc>

recompensa.lua:

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end
function creatureSayCallback(cid, type, msg)
if(not npcHandler:isFocused(cid)) then
return false
end
 
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
local recompensa = 12991 -- ID do item recompensa
local strg = divulgue -- Não precisa mexer aqui

    if msgcontains(msg, 'BP') then
        if getPlayerStorageValue(cid, strg) == 1 then
            selfSay("Aí está sua recompensa!", cid)
            doPlayerAddItem(cid, recompensa, 1)
           setPlayerStorageValue(cid, strg, 2)
            talkState[talkUser] = 0
            return true
        else
            selfSay("Calma apressado, primeiro você precisa curtir nossa página e clicar na placa de divulgação do server que se encontra aqui abaixo.", cid)
            selfSay("Quando fizer isso, volte e lhe darei sua recompensa.", cid)
            talkState[talkUser] = 0
            return true
        end
    end                
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

 

E lembre-se, é muito importante adicionar a actionID "50010" na placa pelo MapEditor com o seguinte script:

Em actions.xml adicione:

<action actionid="50010" script="divulgue.lua"/>

Agora em divulgue.lua adicione o script abaixo:

local strg = divulgue
local texto = Curta nossa página no Facebook

            function onUse(cid, item, frompos, item2, topos)
        if getPlayerStorageValue(cid, strg) == 0 then
            setPlayerStorageValue(cid, strg, 1)
            doPlayerSendTextMessage(cid, 23, " ".. texto ..".")
        else
            doPlayerSendCancel(cid, "Voce ja clicou, agora va pegar sua recompensa no NPC Rey.")
        end
        elseif getPlayerStorageValue(cid, strg) == 2 then
            doPlayerSendCancel(cid, "Voce ja pegou sua recompensa por ajudar na divulgacao.")
    return true
end

 

Não testei, então teste e me diga o que deu.

Caso dê erro, poste e tentaremos corrigi-los.

 

Abraços e boa sorte.

Editado por Adriano SwaTT (veja o histórico de edições)

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Boa noite Adriano Swatt, infelizmente deram os seguintes erros:

 

[10/04/2014 01:39:18] [Error - LuaScriptInterface::loadFile] data/actions/scripts/divulgue.lua:2: '=' expected near 'p'

[10/04/2014 01:39:18] [Warning - Event::loadScript] Cannot load script (data/actions/scripts/divulgue.lua)
[10/04/2014 01:39:18] data/actions/scripts/divulgue.lua:2: '=' expected near 'p'
 
 
Esse listado á cima é o erro!
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
[10/04/2014 01:39:34] [Warning - Npc::loadFromXml] Cannot load npc file (data/npc/Rey.xml).
[10/04/2014 01:39:34] Line: 6, Info: Input is not proper UTF-8, indicate encoding !
[10/04/2014 01:39:34] Bytes: 0xEA 0x20 0x6A 0xE1
 
 
[10/04/2014 01:39:35] [Warning - Npc::loadFromXml] Cannot load npc file (data/npc/Rey.xml).
[10/04/2014 01:39:35] Line: 6, Info: Input is not proper UTF-8, indicate encoding !
[10/04/2014 01:39:35] Bytes: 0xEA 0x20 0x6A 0xE1
 
 
[10/04/2014 01:39:35] [Warning - Npc::loadFromXml] Cannot load npc file (data/npc/Rey.xml).
[10/04/2014 01:39:35] Line: 6, Info: Input is not proper UTF-8, indicate encoding !
[10/04/2014 01:39:35] Bytes: 0xEA 0x20 0x6A 0xE1
 
 
 
10168221_546598202119469_808076625399275
Obrigado mesmo!

Caso, esse jeito não dê certo, já estaria bem feliz com o esquema de dizer "BP" e ele entregar o item.

Editado por Shinob (veja o histórico de edições)

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

E ele deu um erro nessa parte também:

Com esse código o NPC Rey, desaparece.

<?xml version="1.0"?>
<npc name="Rey" script="recompensa.lua" walkinterval="50000" floorchange="0">
<health now="100" max="100"/>
<look type="153" head="58" body="58" legs="58" feet="50" addons="2"/>
<parameters>
<parameter key="message_greet" value="E ai |PLAYERNAME|! Você já conhece nosso servidor? Curta-nos no Facebook! Leia a placa e ganhe uma {BP}." />
</parameters>
</npc>

Mas se eu voltar para o de antes:

Com esse ele até aparece mas só fala "E ai"

<?xml version="1.0"?>
<npc name="Rey" script="recompensa.lua" walkinterval="50000" floorchange="0">
<health now="100" max="100"/>
<look type="153" head="58" body="58" legs="58" feet="50" addons="2"/>
<parameters>
<parameter key="message_greet" value="E ai" />
</parameters>
</npc>

10256493_546605418785414_109439838368974

 

1533817_546605425452080_4536319213432722

 

 

Obrigado desde já!

Editado por Shinob (veja o histórico de edições)

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

agora ta certo

local strg = divulgue
local texto = "Curta nossa pagina no Facebook."

            function onUse(cid, item, frompos, item2, topos)
        if getPlayerStorageValue(cid, strg) == 0 then
            setPlayerStorageValue(cid, strg, 1)
            doPlayerSendTextMessage(cid, 23, texto)
        else
            doPlayerSendCancel(cid, "Voce ja clicou, agora va pegar sua recompensa no NPC Rey.")
        end
        elseif getPlayerStorageValue(cid, strg) == 2 then
            doPlayerSendCancel(cid, "Voce ja pegou sua recompensa por ajudar na divulgacao.")
    return true
end

Todos os meus trabalhos importantes estão na seção "Sobre mim" no meu perfil; Dá uma passada lá!

"Há três caminhos para o fracasso: não ensinar o que se sabe, não praticar o que se ensina, e não perguntar o que se ignora." - São Beda

I7Pm6ih.png

(obg ao @Beeny por fazer essa linda sign <3)

Link para o post
Compartilhar em outros sites
Deu erro no ELSE IF
 
[10/04/2014 03:51:05] [Error - LuaScriptInterface::loadFile] data/actions/scripts/divulgue.lua:11: 'end' expected (to close 'function' at line 4) near 'elseif'
[10/04/2014 03:51:05] [Warning - Event::loadScript] Cannot load script (data/actions/scripts/divulgue.lua)
[10/04/2014 03:51:05] data/actions/scripts/divulgue.lua:11: 'end' expected (to close 'function' at line 4) near 'elseif'
[10/04/2014 03:51:05] [Error - LuaScriptInterface::loadFile] data/actions/scripts/divulgue.lua:11: 'end' expected (to close 'function' at line 4) near 'elseif'
[10/04/2014 03:51:05] [Warning - Event::loadScript] Cannot load script (data/actions/scripts/divulgue.lua)
[10/04/2014 03:51:05] data/actions/scripts/divulgue.lua:11: 'end' expected (to close 'function' at line 4) near 'elseif'

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Todos scripts corrigidos e testados.

Caso dê algum erro, poste para resolvermos.

 

Obs: Quando precisar postar mais de uma vez em seguida, edite seu post anterior para não ficar 2 posts consecutivos, isso é chamado de Double-Post e o fórum tem Políticas que proíbem isso.

 

Ao script:

rey.xml:

<?xml version="1.0"?>
<npc name="Rey" script="rey.lua" walkinterval="50000" floorchange="0">
<health now="100" max="100"/>
<look type="153" head="58" body="58" legs="58" feet="50" addons="2"/>
<parameters>
<parameter key="message_greet" value="Voce ja conhece nosso servidor? Leia a placa abaixo e Curta-nos no Facebook para ganhar uma {BP}." />
</parameters>
</npc>

rey.lua:

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end
function creatureSayCallback(cid, type, msg)
if(not npcHandler:isFocused(cid)) then
return false
end
 
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
local item = 12991 -- ID do item recompensa
local strg = divulgue -- Não precisa mexer aqui

    if msgcontains(msg, 'BP') and getPlayerStorageValue(cid, strg) == 1 then
            selfSay("Ai estah sua recompensa!", cid)
            doPlayerAddItem(cid, item, 1)
            setPlayerStorageValue(cid, strg, 2)
            talkState[talkUser] = 0
        else
            selfSay("Calma apressado, primeiro voce precisa curtir nossa pagina e clicar na placa de divulgacao do server que se encontra aqui abaixo.", cid)
            selfSay("Quando fizer isso, volte e lhe darei sua recompensa.", cid)
            talkState[talkUser] = 0
        end
    end                
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

 

Agora vamos adicionar a tag ao actions.xml:

<action actionid="50010" event="script" value="divulgue.lua" />

Agora criamos o script divulgue.lua:

local strg = divulgue
local texto = "Curta nossa pagina no Facebook."

            function onUse(cid, item, frompos, item2, topos)
local check = getPlayerStorageValue(cid, strg)
        if check == 0 then
            setPlayerStorageValue(cid, strg, 1)
            doPlayerSendTextMessage(cid, 23, texto)
        elseif check == 2 then
            doPlayerSendCancel(cid, "Voce ja pegou sua recompensa por ajudar na divulgacao.")
        elseif check == 1 then
            doPlayerSendCancel(cid, "Voce ja clicou, agora va pegar sua recompensa no NPC Rey.")
        end
    return true
end

 

Well done!

Caso dê algum erro, favor postá-lo para corrigirmos².

 

Boa sorte.

Editado por Adriano SwaTT (veja o histórico de edições)

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Agora deu o seguinte erro:

 
 
[10/04/2014 12:37:19] [Warning - Npc::loadFromXml] Cannot load npc file (data/npc/Rey.xml).
[10/04/2014 12:37:19] Line: 6, Info: Input is not proper UTF-8, indicate encoding !
[10/04/2014 12:37:19] Bytes: 0xEA 0x20 0x6A 0xE1

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Atualizei a parte do NPC.XML, teste e poste o resultado.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Deu tudo certo, porém, ele clica na placa, volta á falar com o NPC, mas o NPC manda ele voltar e clicar na placa novamente..

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Você editou a placa pelo MapEditor?

Adicionou o ActionID: 50010 na placa?

 

Quando clica na placa, exibe alguma mensagem?

Editado por Adriano SwaTT (veja o histórico de edições)

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Sim, Editei o Action ID,  e aparece a mensagem dizendo que ele já clicou, e deve ir falar com o NPC, mas quando o player fala com o NPC ele manda você ir novamente na placa..

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Atualizei o script do post.

Atualize seu divulgue.lua do ActionID, o arquivo rey.lua do NPC com o novo script postado e teste novamente.

 

Boa sorte.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

local strg = divulgue tem que ser o mesmo storage que o npc usa pra checar, caso contrario não vai funcionar

 Whatsapp: +55 (48) 98815-0709 Discord: Qwizer#5713

 

Global 100% 7.40 com Website

TFS 1.2 10.97-11.00 + GlobalFull OtherWorld ...

 

Link para o post
Compartilhar em outros sites

Sim, sei disso.

E no script está certo, está assim, tanto que testei várias vezes e funcionou perfeitamente comigo.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Bom, agora eu dou use na placa e não acontece nada..

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Me diz, no MapEditor você adicionou ActionID ou UniqueID à placa?

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

ActionID = 50010

Gregorio, HaxYu

Corporation Of Technology

Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

  • Conteúdo Similar

    • Por Arkanjo39
      CUIDA, CUIDA E VEM CONHECER NOSSO SERVER. KING BAIAK ACABOU DE SER LANÇADO!!! VEM SER O TOP 1 Site com Otclient: https://kingbaiak.com/ PARA NOVOS JOGARES ADM TA DANDO AQUELA FORCINHA! SERVIDOR 8.60 COM RESETS, MONTARIAS E GOLDEN OUTFIT! INFORMAÇÕES BÁSICAS DO SERVIDOR: [+] MAPA BAIAK [+] HIGH EXP [+] RESETS COM + DAMAGE [+] AUTOLOOT AUTOMÁTICO [+] CITY DONATE [+] ROSHAMUUL, ORAMOND E NETHER [+] MONTARIAS E GOLDEN OUTFIT [+] INVASÃO DE MONSTROS AUTOMÁTICAS [+] DAILY MONSTER QUE APARECE AO LOGAR [+] MONTARIAS COM COMANDO !MOUNT [+] SISTEMA DE ROLETA ATUAL [+] CAST WATCH [+] FAST ATTACK [+] CAST ARROWS [+] PUSH CRUZADO [+] REWARD CHEST [+] WARSQUARE [+] COMBO EXP DE POTIONS [+] MINERAÇÃO COM LOJA [+] SISTEMA DE BOSS [+] CRITICAL/DODGE [500/500] [+] LIFE E MANA EM PORCENTAGEM* [+] VARIAS QUESTS [+] EVENTO DTT (AUTOMÁTICO) [+] EVENTO BATLEFIELD (AUTOMÁTICO) [+] EVENTO SNOWBALLWAR (AUTOMÁTICO) [+] EVENTO DESERT WAR (AUTOMÁTICO) [+] EVENTO ZOMBIE (AUTOMÁTICO) [+] EVENTO CAMPO MINADO (AUTOMÁTICO) [+] EVENTO TEAM BATLE (AUTOMÁTICO) [+] EVENTO CAPTURE THE FLAG (AUTOMÁTICO)
    • Por BTitan
      Baiak Titan: Uma Experiência Incomparável no Universo Baiak
       
      O Baiak Titan combina a nostalgia dos antigos tempos de OTServ com a inovação e modernidade atuais. Oferecemos um mapa vasto, com mais de 100 áreas de caça para explorar, além de vocações equilibradas para um PvP justo e emocionante. Diversos eventos automáticos ocorrem diariamente, garantindo diversão constante para os jogadores. O servidor conta com vários sistemas, como por exemplo, montarias para quem utiliza o cliente exclusivo, monstros do Tibia 9.6+, sistema de mineração, entre outros!
       
      Por Que Escolher o Baiak Titan?
       
      PvP de Alta Qualidade: Embora seja um servidor Baiak, nosso mapa é cuidadosamente projetado para proporcionar ganho de experiência sem perder a seriedade do jogo, oferecendo desafios instigantes e um equilíbrio perfeito para combates épicos.
      Jogabilidade Customizada: O mapa Baiak foi exclusivamente adaptado para promover intensas batalhas de PvP, com recursos inovadores que mantêm a jogabilidade sempre fresca e emocionante.

      Detalhes do Servidor:
       
      IP: baiaktitan.com Website: https://baiaktitan.com Account Manager: 1/1
        Principais Características:
       
      Uptime 24/7, Sem Lag: Jogue a qualquer hora com a estabilidade de servidores dedicados e de alta performance. Velocidade de Ataque Equilibrada: Ajustada perfeitamente para garantir combates dinâmicos e justos. Sistema de Cast: Transmita suas jogadas ao vivo e assista aos seus amigos em ação. Cliente Exclusivo: Software personalizado com novos outfits, montarias e criaturas, enriquecendo ainda mais sua experiência no jogo. Runas, Poções e Flechas Não Infinitas: Valorizamos uma jogabilidade mais estratégica e desafiadora, onde os recursos precisam ser geridos com sabedoria.
      Eventos Automáticos:
       
      Zombie Team Battle Monster Hunter Castle (War of Emperium) Capture The Flag DOTA Corrida Arena War (O último sobrevivente ganha) Fire Storm
        Taxas do Servidor:
       
      EXP: 200x (com stages)
      Skill: 100x
      Magic: 30x
      Loot: 3x
       
      Junte-se à nossa comunidade e viva essa aventura única. O Baiak Titan espera por você!
    • Por campospkks
      Servidor muito bem otimizado, com amplo map para uma diversão imperdível. 
       
      *  Quest System
      * bugs corrigidos 90,0%
      * Client Específico (V8)
      * Mobile Adaptavel e Otimizado
      * database.sql já com (Modulo Pix) 
      * site 95,9% atualizado (Troque, pois a marca já possuí proprietário)
      * Franquia Tibia Custom baseado em armas.
       
      Site Original: soulgun.com.br
      discord.gg/cCWcaMwjuB
      Relançamento Servidor 20-09-2024
      Horario 17:00
      whatsap Grupo
      https://chat.whatsapp.com/JsAyLAmwJQyGEWgHTI4096
      Video Do Game
      https://youtu.be/N8asxdnzmGw


    • Por chateadoagr
      Bem-vindo ao Genesis Online Tibia (GOT), um mundo onde a civilização foi devastada por um apocalipse zumbi. Inspirado em referências como The Walking Dead e Resident Evil, o GOT desafia você a sobreviver em meio ao caos, enfrentando hordas de mortos-vivos, explorando ruínas perigosas e formando alianças estratégicas. Embarque nesta jornada épica de sobrevivência e descoberta, onde cada escolha molda seu destino em um cenário hostil repleto de desafios e perigos iminentes.
       
       
      Adentre o universo de Genesis Online Tibia (GOT), um jogo repleto de sistemas inovadores e emocionantes. Equipe-se com um vasto arsenal de armas para enfrentar as ameaças do apocalipse zumbi, enquanto o sistema autoloot simplifica suas conquistas. Desenvolva seu personagem através de um sistema de upgrade único, aprimorando habilidades e atributos para enfrentar desafios cada vez mais formidáveis.
       
      Explore um mundo imersivo onde o som desempenha um papel crucial, criando uma atmosfera envolvente e realista. Vasculhe cada canto em busca de recursos vitais, desvendando segredos e tesouros ocultos. Siga uma cativante história através de missões que expandem o enredo, revelando os mistérios por trás do apocalipse e oferecendo recompensas valiosas.
       
      Em Genesis Online Tibia, a jornada pela sobrevivência é repleta de ação, estratégia e emoção, convidando você a se aventurar em um mundo onde cada decisão molda seu destino e determina sua capacidade de enfrentar os desafios que aguardam.

      Em breve imagens do servidor!
       
       
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo