Postado Março 2, 2015 10 anos Este é um post popular. Battle Arena System 8.60 com NPC Testado em OTX Server & TFS 0.4 @Atualizado : É super importante o uso de uma distro que possua a função "doPlayerOpenChannel". surgirá o seguinte erro caso a função não seja encontrada : [string "loadBuffer"]:8: attempt to call global 'doPlayerOpenChannel' (a nil value) se a sua não tem, basta você compilar suas sources ou usar qualquer outra que possua. Battle Arena é um sistema onde permite o ganho de notificações dentro de um canal chamado 'Battle Arena Channel' e experiências dentro de uma arena fechada, que pode ser acessada ao falar com um NPC chamado 'Battle Arena Manager'. As notificações são baseadas em jogos FPS como por exemplo Counter Strike 1.6, Gunz - The Duel e outros, que ao matar alguém, aparece uma mensagem escrito algo como: Você derrotou Neguin_Owna.ao morrer :Neguin_Owna derrotou você.para outras pessoas :Neguin_Owna derrotou Ladyazaleia. As experiências são calculadas automaticamente após derrotar alguém, segue abaixo uma pequena explicação : Neguin_Owna é level 100; a rateExperience do meu config.lua é 350; se eu matar o Neguin_Owna, o sistema irá multiplicar 350 vezes(*) 100 e eu ganharei 35000 de experiência. Você ganhou 35000 ponto(s) de experiência. Para ter acesso à arena, será necessário falar com o NPC 'Battle Arena Manager. Nada complicado, qualquer um conseguirá trocar uns papos com ele. Keywords : hi; participar; ok; cancelar; bye. Mas e o mapa? então pessoal, infelizmente eu não tive criatividade pra criar uma arena apropriada pra encaixar no sistema, então vocês terão que utilizar as suas arenas pvp's ou criar outra pro sistema, minhas dicas são : Como no sistema existem posições aleatórias para servirem de respawn quando um player morre, minha dica é que em cada posição configurada, você adicione uma pequena área quadrada com Protection Zone, como se fossem setores para que o jogador possa sair da arena quando quiser. Não precisa usar NO LOGOUT na arena toda, apenas PVP ZONE TOOL; Crie ou edite sua arena fechada, sem acesso à cidade a pé; Se tua arena for grandona, aumente o limite de jogadores. Agora vamos instalar o sistema.. 1 - Na pasta data/Lib, crie um arquivo battle-config.lua e dentro adicione isso : --[[ 'Battle Arena' desenvolvido por Ladyazaleia. WhatsApp : (83) 9629-6394 Facebook : https://www.facebook.com/wustehs ]] FPS_EVENTNAME = "Battle Arena" -- Nome do evento. FPS_FINISHTIME = 5 -- Dentro do evento, jogadores não poderão atacar uns aos outros enquanto esse tempo não esgotar após o comando /fps close ser executado. FPS_LIMITEPLAYERS = 26 -- Limite de jogadores. FPS_SHOWGODNAMEAFTERBAN = false -- true = Mostra o nome do GM na mensagem do banido; false = Mostra o nome 'Admininstrador'. FPS_ENABLEEXPERIENCE = true -- true = Habilita a experiência; false = Desabilita. FPS_BLOCKIP = false -- true = Jogadores que tentarem usar MC pra ganhar exp fácil, não conseguirão atacar seus próprios chars; false = permite isso. FPS_CHANNEL = 15 -- ID do Battle Arena Channel. FPS_SPAWNPLAYER = { {x = 261, y = 619, z = 7}, {x = 275, y = 619, z = 7}, {x = 261, y = 630, z = 7}, {x = 275, y = 630, z = 7} } 2 - Na pasta data/XML, abra o arquivo channels.xml e adicione isso antes do </channels> : <channel id="15" name="Battle Arena Channel"/> 3 - Na pasta data/Npc, crie um arquivo Battle Arena Manager.xml e dentro adicione isso: <?xml version="1.0"?> <npc name="Battle Arena Manager" floorchange="0" walkinterval="2000"> <health now="150" max="150"/> <look type="266"/> <interaction range="3" idletime="30" idleinterval="1500" defaultpublic="0"> <interact keywords="hi" focus="1"> <action name="script" value="hello"/> <response><action name="script"><![CDATA[ local str = "Olá "..getCreatureName(cid).."" if (getGlobalStorageValue(5600) ~= 1) then selfSay(""..str..", infelizmente estamos indisponível. {bye}!", cid) else selfSay("Tem "..getGlobalStorageValue(5602).." player(s) lá dentro, deseja {Participar}?", cid) return true end ]]></action> <interact keywords="participar"> <action name="script" value="join"/> <response><action name="script"><![CDATA[ if (getGlobalStorageValue(5600) ~= 1) then return true end if (getPlayerStorageValue(cid, 5604) == 1) then selfSay("Sinto muito, você está temporariamente bloqueado(a).", cid) return true end doPlayerOpenChannel(cid, FPS_CHANNEL) selfSay("Confirme : {Ok} ou {Cancelar}?", cid) ]]></action> <interact keywords="ok"> <action name="script" value="ok"/> <response><action name="script"><![CDATA[ if (getGlobalStorageValue(5600) ~= 1) then return true end if (getGlobalStorageValue(5601) == 1) then selfSay("Já iremos fechar, volte outro dia!", cid) return true end if (getGlobalStorageValue(5602) >= FPS_LIMITEPLAYERS and getPlayerAccess(cid) < 3) then selfSay("Limite de jogadores alcançado, aguarde até que alguém saia.", cid) return true end selfSay("Boa sorte!", cid) if (getPlayerStorageValue(cid, 5602) ~= 1) then domodlib('battle-config') doPlayerSendChannelMessage(cid,"", "Você participou do jogo.", MSG_WHITE, FPS_CHANNEL) if (getPlayerAccess(cid) < 3) then setGlobalStorageValue(5602, getGlobalStorageValue(5602)+1) msgForOthers(""..getCreatureName(cid).." participou do jogo.") end setPlayerStorageValue(cid, 5602, 1) end doSendMagicEffect(getThingPos(cid), CONST_ME_POFF) doTeleportThing(cid, FPS_SPAWNPLAYER[math.random(1, #FPS_SPAWNPLAYER)]) doSendMagicEffect(getThingPos(cid), CONST_ME_TELEPORT) doPlayerOpenChannel(cid, FPS_CHANNEL) ]]></action></response> </interact> <interact keywords="cancelar" focus="0"> <response text="Okay {|NAME|}, volte quando puder!"/> </interact> </response> </interact> <interact keywords="bye" focus="0"> <response text="Tchau, até breve!"/> </interact> </response> </interact> <interact event="onPlayerLeave" focus="0"> <response text="How rude!" public="1"/> </interact> </interaction> </npc> 4 - E por último e mais importante, na pasta Mods, crie um arquivo battle-mod.xml e adicione isso: <?xml version="1.0" encoding="UTF-8"?> <mod name="Battle Arena System" version="1.0" author="Ladyazaleia" contact="https://www.facebook.com/wustehs"enabled="yes"> <config name="battle-config"><![CDATA[ function msgForOthers(mensagem, classe) if (not classe) then classe = MSG_WHITE end for _, pid in ipairs(getPlayersOnline()) do if (getPlayerStorageValue(pid, 5602) == 1) then doPlayerSendChannelMessage(pid, "", mensagem, classe, FPS_CHANNEL) end end return true end function doPlayerRemoveLethalConditions(cid) -- function by Rush Event. local tmp = {1, 2, 4, 16, 32, 65, 128, 256, 512, 1024, 2048, 4096, 8192, 32768, 65536} for i = 1, #tmp do if (hasCondition(cid, tmp[i])) then doRemoveCondition(cid, tmp[i]) end end return true end function closeEvent(cid) setGlobalStorageValue(5600, -1) setGlobalStorageValue(5601, -1) for _, pid in ipairs(getPlayersOnline()) do doPlayerSendChannelMessage(pid, "", ""..FPS_EVENTNAME.." foi fechado.", MSG_WHITE, FPS_CHANNEL) if (getPlayerStorageValue(pid, 5602) == 1) then doSendMagicEffect(getThingPos(pid), CONST_ME_POFF) doTeleportThing(pid, getTownTemplePosition(getPlayerTown(cid))) doSendMagicEffect(getThingPos(pid), CONST_ME_TELEPORT) doCreatureAddHealth(pid, getCreatureMaxHealth(pid), false) doCreatureAddMana(pid, getCreatureMaxMana(pid), false) setPlayerStorageValue(pid, 5601, 0) setPlayerStorageValue(pid, 5602, 0) setPlayerStorageValue(pid, 5603, 0) doPlayerSave(pid) end end setGlobalStorageValue(5602, -1) return true end MSG_WHITE = TALKTYPE_CHANNEL_MANAGEMENT or TALKTYPE_CHANNEL_W MSG_RED = TALKTYPE_GAMEMASTER_CHANNEL or TALKTYPE_CHANNEL_RN MSG_ORANGE = TALKTYPE_CHANNEL_ORANGE or TALKTYPE_CHANNEL_O ]]></config> <talkaction log="yes" words="/fps" event="script"><![CDATA[ domodlib('battle-config') function onSay(cid, words, param, channel) if (param == "") then return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Error, comando inválido.") end if (getPlayerAccess(cid) >= 3) then if (string.lower(param) == "open") then if (getGlobalStorageValue(5600) ~= 1) then setGlobalStorageValue(5600, 1) if (getGlobalStorageValue(5600) == 1) then setGlobalStorageValue(5602, 0) doBroadcastMessage(""..FPS_EVENTNAME.." foi aberto, fale com o NPC 'Battle Arena Manager'.", 22) end else return true end return true end if (string.lower(param) == "close") then if (getGlobalStorageValue(5600) ~= -1 and getGlobalStorageValue(5601) ~= 1) then setGlobalStorageValue(5601, 1) setPlayerStorageValue(cid, 5605, 1) msgForOthers(""..FPS_FINISHTIME.." segundos restantes.") addEvent(setPlayerStorageValue, FPS_FINISHTIME * 1000, cid, 5605, -1) addEvent(closeEvent, FPS_FINISHTIME * 1000, cid) else doPlayerPopupFYI(cid, "AVISO :\n"..getCreatureName(cid)..", o portal encontra-se fechado atualmente.\nimpossivel fecha-lo duas vezes.") return true end return true end local t = string.explode(param, ",") local pid = getPlayerByName(t[2]) if (string.lower(t[1]) == "ban") then if (not t[2] or tonumber(t[2])) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Desculpe, digite o nome do jogador.") return true end if (not isPlayer(pid)) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, ""..t[2].." não existe ou encontra-se off-line.") return true end if (getPlayerStorageValue(pid, 5604) ~= 1) then if (getPlayerStorageValue(pid, 5602) == 1) then doTeleportThing(pid, getTownTemplePosition(getPlayerTown(pid))) doSendMagicEffect(getThingPos(pid), CONST_ME_TELEPORT) setGlobalStorageValue(5602, getGlobalStorageValue(5602)-1) end setPlayerStorageValue(pid, 5601, 0) setPlayerStorageValue(pid, 5602, 0) setPlayerStorageValue(pid, 5604, 1) -- blocked. msgForOthers(""..t[2].." foi bloqueado(a).") local ba_banr = "Admininstrador" if (FPS_REVEALEDAFTERBANPLAYER) then ba_banr = ""..getCreatureName(cid).."" end doPlayerPopupFYI(pid, "AVISO :\n O "..ba_banr.." bloqueou você.\nvocê está temporariamente bloqueado(a) de participar.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você bloqueou "..t[2]..".") else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, ""..t[2].." já foi bloqueado(a).") return true end return true end if (string.lower(t[1]) == "unban") then if (not t[2] or tonumber(t[2])) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Desculpe, digite o nome do jogador.") return true end if (not isPlayer(pid)) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, ""..t[2].." não existe ou encontra-se off-line.") return true end if (getPlayerStorageValue(pid, 5604) == 1) then setPlayerStorageValue(pid, 5604, 0) -- unblocked. msgForOthers(""..t[2].." foi desbloqueado(a).") doPlayerPopupFYI(pid, "AVISO :\nVocê foi desbloqueado(a).\nparticipe do "..FPS_EVENTNAME.." quando o mesmo estiver disponível.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você desbloqueou "..t[2]..".") else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, ""..t[2].." já foi desbloqueado(a).") return true end return true end end local ba_players = "Indisponível" if (getGlobalStorageValue(5602) ~= -1) then ba_players = tostring(getGlobalStorageValue(5602)) end local limiteplayers = ""..ba_players.."/"..FPS_LIMITEPLAYERS.."" if (getGlobalStorageValue(5602) >= FPS_LIMITEPLAYERS) then limiteplayers = "FULL/"..FPS_LIMITEPLAYERS.."" end if (string.lower(param) == "status") then local status = ""..FPS_EVENTNAME.." Status :\nOla "..getCreatureName(cid)..",\nveja algumas informações sobre o(a) "..FPS_EVENTNAME.."." doShowTextDialog(cid, 2395, ""..status.."\n\nPontos : ("..getPlayerStorageValue(cid, 5601)..")\nJogadores : ["..limiteplayers.."]") return true end return true end ]]></talkaction> <event type="preparedeath" name="FPSprepare" event="script"><![CDATA[ domodlib('battle-config') function onPrepareDeath(cid, deathList) local target = deathList[1] if (getGlobalStorageValue(5600) == 1 and getPlayerStorageValue(cid, 5602) == 1) then local i = 10 doPlayerOpenChannel(cid, FPS_CHANNEL) doCreatureAddHealth(cid, getCreatureMaxHealth(cid), MAGIC_EFFECT_UNKNOWN, COLOR_UNKNOWN, true) doCreatureAddMana(cid, getCreatureMaxMana(cid)) doTeleportThing(cid, FPS_SPAWNPLAYER[math.random(1, #FPS_SPAWNPLAYER)]) doSendMagicEffect(getThingPos(cid), CONST_ME_TELEPORT) doPlayerRemoveLethalConditions(cid) if (isMonster(target)) then addEvent(doPlayerSendChannelMessage, i, cid, "", ""..getCreatureName(target).." matou você.", MSG_RED, FPS_CHANNEL) setPlayerStorageValue(cid, 5602, 0) msgForOthers(""..getCreatureName(target).." matou "..getCreatureName(cid)..".") setPlayerStorageValue(cid, 5602, 1) setPlayerStorageValue(cid, 5601, 0) return false end if (not isCreature(target)) then addEvent(doPlayerSendChannelMessage, i, cid, "", "Voce cometeu suicídio.", MSG_RED, FPS_CHANNEL) setPlayerStorageValue(cid, 5602, 0) msgForOthers(""..getCreatureName(cid).." cometeu suicídio.") setPlayerStorageValue(cid, 5602, 1) setPlayerStorageValue(cid, 5601, 0) return false end doPlayerOpenChannel(target, FPS_CHANNEL) setPlayerStorageValue(target, 5601, getPlayerStorageValue(target, 5601)+1) setPlayerStorageValue(cid, 5602, 0) setPlayerStorageValue(target, 5602, 0) msgForOthers(""..getCreatureName(target).." derrotou "..getCreatureName(cid)..".") setPlayerStorageValue(target, 5602, 1) setPlayerStorageValue(cid, 5602, 1) addEvent(doPlayerSendChannelMessage, i, cid, "", ""..getCreatureName(target).." derrotou você.", MSG_RED, FPS_CHANNEL) addEvent(doPlayerSendChannelMessage, i, target, "", "Você derrotou "..getCreatureName(cid)..".", MSG_ORANGE, FPS_CHANNEL) dofile("config.lua") local EXP = 0 if (FPS_ENABLEEXPERIENCE) then EXP = rateExperience * getPlayerLevel(cid) doPlayerAddExperience(target, EXP) end doSendAnimatedText(getThingPos(target), tostring(EXP), gainExperienceColor) doPlayerSendTextMessage(target, MESSAGE_STATUS_DEFAULT, "Você ganhou "..EXP.." ponto(s) de experiência.") setPlayerStorageValue(cid, 5601, 0) return false end return true end ]]></event> <event type="logout" name="FPSlogout" event="script"><![CDATA[ domodlib('battle-config') function onLogout(cid) if (getGlobalStorageValue(5601) == 1 and getPlayerStorageValue(cid, 5602) == 1 or getPlayerStorageValue(cid, 5605) == 1) then doPlayerSendCancel(cid, "Aguarde "..FPS_FINISHTIME.." segundo(s).") return false end if(getPlayerStorageValue(cid, 5602) == 1) then setPlayerStorageValue(cid, 5601, 0) setPlayerStorageValue(cid, 5602, 0) doSendMagicEffect(getThingPos(cid), CONST_ME_POFF) doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid))) doSendMagicEffect(getThingPos(cid), CONST_ME_TELEPORT) doPlayerSendChannelMessage(cid, "", "Você saiu do jogo.", MSG_WHITE, FPS_CHANNEL) doPlayerRemoveLethalConditions(cid) doPlayerSave(cid) if (getPlayerAccess(cid) < 3) then setGlobalStorageValue(5602, getGlobalStorageValue(5602)-1) msgForOthers(""..getCreatureName(cid).." saiu do jogo.") end return false end return true end ]]></event> <event type="combat" name="FPScombat" event="script"><![CDATA[ function onCombat(cid, target) if(FPS_BLOCKIP) then if (getPlayerIp(cid) == getPlayerIp(target)) then return false end end for _, pid in ipairs(getPlayersOnline()) do if (getGlobalStorageValue(5600) == 1 and getGlobalStorageValue(5601) == 1 and getPlayerStorageValue(pid, 5602) == 1) then return false end end return true end ]]></event> <event type="attack" name="FPSattack" event="script"><![CDATA[ function onAttack(cid, target) if(FPS_BLOCKIP) then if (getPlayerIp(cid) == getPlayerIp(target)) then return false end end for _, pid in ipairs(getPlayersOnline()) do if (getGlobalStorageValue(5600) == 1 and getGlobalStorageValue(5601) == 1 and getPlayerStorageValue(pid, 5602) == 1) then return false end end return true end ]]></event> <event type="login" name="FPSlogin" event="buffer"><![CDATA[ if (getPlayerStorageValue(cid, 5601) == -1) then setPlayerStorageValue(cid, 5601, 0) end registerCreatureEvent(cid, "FPSprepare") registerCreatureEvent(cid, "FPSlogout") registerCreatureEvent(cid, "FPScombat") registerCreatureEvent(cid, "PFSattack") registerCreatureEvent(cid, "PFScast") ]]></event> <globalevent name="FPS tips" interval="600000" event="script"><![CDATA[ domodlib('battle-config') function onThink(interval) local FPS_tips = { "Atualmente existem "..getGlobalStorageValue(5602).." player(s) lutando, não deixe de participar.", "Com o canal fechado, você não recebe informações dentro do jogo. deixe-o sempre aberto.", "Cuidado ao ofender um jogador, você corre o risco de ser bloqueado(a).", "Aperte 'CTRL + Q' caso você queira sair do jogo, você precisa está em protection zone.", "Chame seus amigos e venha jogar, porquê aqui a diversão nunca acaba.", "Dica : configure o comando '/fps status' como hotkey. Assim você poderá checar suas informações com facilidade." } if (getGlobalStorageValue(5600) == 1) then msgForOthers(FPS_tips[math.random(1, #FPS_tips)]) end return true end ]]></globalevent> </mod> As configurações são modificadas apenas no arquivo battle-config.lua, vou explicar :FPS_EVENTNAME : Nome do evento;FPS_FINISHTIME : Dentro do evento, jogadores não poderão atacar uns aos outros enquanto esse tempo não esgotar após o comando /fps close ser executado. Configure algum numero a cima de 2 para uma melhor segurança;FPS_LIMITEPLAYERS : Limite de jogadores;FPS_SHOWGODNAMEAFTERBAN : true = Mostra o nome do GM na mensagem do banido; false = Mostra o nome 'Admininstrador';FPS_ENABLEEXPERIENCE : true = Habilita a experiência; false = Desabilita;FPS_BLOCKIP : true = Jogadores que tentarem usar MC pra ganhar exp fácil, não conseguirão atacar seus próprios chars; false = permite isso;FPS_CHANNEL : ID do Battle Arena Channel. não mude essa ID, apenas se a mesma estiver em uso;FPS_SPAWNPLAYER : Posições que servirão de respawn para os jogadores que morrerem. Se você quiser remover as posições aleatórias e deixar só uma, edite o FPS_SPAWNPLAYER deixando apenas uma posição, assim : FPS_SPAWNPLAYER = { {x = 261, y = 619, z = 7} } mas eu prefiro com posições aleatórias, fica bem mais legal.Fiz alguns comandos :Player(s) :/fps status - Mostra informações sobre a arena, quantos jogadores estão lá, o limite, e outros.Gamemaster(s) :/fps status/fps open - Abre a arena;/fps close - Fecha a arena;/fps ban, nomedojogador - Bloquear um jogador;/fps unban, nomedojogador - Desbloquear um jogador;Para um jogador sair da arena, ele precisa ir até um lugar com protection Zone(Setores) e pressionarCTRL + Q, não vai deslogar! ele vai se retirar da arena indo diretamente pro templo;Créditos : Halls Santos (eu). Editado Março 18, 2015 10 anos por Danihcv Correção de bug de formatação. Tópico totalmente refeito! ^^ (veja o histórico de edições)
Postado Março 2, 2015 10 anos Tópico aprovado, obrigado por compartilhar. Não testei, a ideia em si é ótima, parabéns! Este tópico foi movido: Para: "OTServ → Scripting → Sistemas e MODs"
Postado Março 2, 2015 10 anos Parabéns pelo script, Fim de semana irei testá-lo. Parece estar muito bom! Abraço.
Postado Março 2, 2015 10 anos Autor Obrigado Luan; jaé Bruno, testa mesmo rs, é bem dahora para a arena ficar mais movimentada.
Postado Março 3, 2015 10 anos Tá Dando esse erro aqui Editado Março 4, 2015 10 anos por nickissonlobo (veja o histórico de edições)
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.