Ir para conteúdo

El Rusher

Cavaleiro
  • Total de itens

    156
  • Registro em

  • Última visita

  • Dias Ganhos

    19

Tudo que El Rusher postou

  1. El Rusher

    Depot House

    Olá! Isso acontece porque cada depot no Tibia é vinculado a uma determinada "town" (cidade). Quando você coloca um depot em uma house, ele é tratado como um novo depot separado do depot original localizado no CP (temple) da cidade. Para resolver esse problema, você precisará garantir que ambos os depots (o da house e o do CP) estejam vinculados à mesma "town ID" e que eles compartilhem a mesma "depot ID" Verifique a Town ID: Certifique-se de que a "town ID" do depot na house seja a mesma do depot original no CP. Essa informação geralmente está definida no arquivo map ou no código da script que cria o depot. Vincule o Depot ID: Verifique o depotid do depot da house e do depot no CP. Ambos precisam compartilhar o mesmo depotid para que os itens sejam acessíveis de qualquer um dos depots. Scripts e Configurações: Em alguns casos, pode ser necessário ajustar o código do servidor para garantir que os depots compartilhem o mesmo inventário. Dependendo do código do servidor, você pode precisar revisar as funções que lidam com a criação e gestão de depots para garantir que eles estejam corretamente sincronizados. Outra opção é criar ou modificar um script LUA que faz a checagem e sincronização entre os depots. Isso pode ser feito no evento de abertura do depot, onde você sincroniza os itens entre os depots do CP e da casa do jogador. Um exemplo básico de script: local function syncDepots(player) local mainDepot = player:getDepot(1) -- CP depot ID local houseDepot = player:getDepot(2) -- House depot ID (ajuste conforme o ID do depot na casa) -- Sincroniza itens do depot da casa com o CP for i = 0, houseDepot:getCapacity() - 1 do local item = houseDepot:getItem(i) if item then mainDepot:addItemEx(item) end end end function onUse(player, item, fromPosition, target, toPosition, isHotkey) syncDepots(player) -- Continuar a lógica normal de abrir o depot... end
  2. <?xml version="1.0" encoding="ISO-8859-1"?> <mod name="Characters Market System" version="1.0" author="LuckOake" contact="none" enabled="yes"> ------------------------------------------------------------------------------------ <config name="market"><![CDATA[ price = 27112 owner = 27113 level = 717217 -- Level min of character.-- min_price = 1 -- Price min of character (in currency 6535)-- max_price = 1000000000 -- Price maximum of character (in currency 6535)-- function doTransferCharacter(cid, accId) local playerGuid = getPlayerGUIDByName(cid) if not playerGuid then return false, "Player GUID not found." end return db.executeQuery("UPDATE `players` SET `account_id` = "..accId.." WHERE `id` = "..playerGuid.."") end function doOfflinePlayerAddMoney(guid, money, itemID) local playerGuid = getPlayerGUIDByName(guid) if not playerGuid then return false, "Player GUID not found." end return db.executeQuery("UPDATE `players` SET `balance` = `balance` + '"..money.."' WHERE `id` = '"..playerGuid.."';") end function setOfflinePlayerStorageValue(name, key, value) local playerGuid = getPlayerGUIDByName(name) if not playerGuid then return false, "Player GUID not found." end local result = db.getResult("SELECT * FROM `player_storage` WHERE `player_id` = ".. playerGuid .." AND `key` = ".. key ..";") if result:getID() == -1 then return db.executeQuery("INSERT INTO `player_storage` (`player_id`, `key`, `value`) VALUES (".. playerGuid ..", ".. key ..", ".. value ..");") else result:free() return db.executeQuery("UPDATE `player_storage` SET `value` = ".. value .." WHERE `player_id` = ".. playerGuid .." AND `key` = ".. key ..";") end end function getOfflinePlayerStorageValue(name, key) local playerGuid = getPlayerGUIDByName(name) if not playerGuid then return nil end local result = db.getResult("SELECT `value` FROM `player_storage` WHERE `player_id` = '".. playerGuid .."' AND `key` = ".. key ..";") if result:getID() == -1 then return nil end local ret = result:getDataInt("value") result:free() return ret end function getOfflinePlayerValue(name, value) local playerGuid = getPlayerGUIDByName(name) if not playerGuid then return nil end local result = db.getResult("SELECT `"..value.."` FROM `players` WHERE `id` = "..playerGuid..";") if result:getID() == -1 then return nil end local ret = result:getDataInt(value) result:free() return ret end function isCharacterForSale(name) local charPrice = getOfflinePlayerStorageValue(name, price) if not charPrice or charPrice < 1 then return false else return true end end ]]></config> ------------------------------------------------------------------------------------ <talkaction words="!character" event="buffer"><![CDATA[ domodlib('market') local t = string.explode(param, ",") if t[1] == "sell" then if not t[3] or not tonumber(t[3]) or t[4] or tonumber(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Incorrect Params. Specify the character name and the price.") return true elseif getPlayerAccountId(cid) ~= getAccountIdByName(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This is not your character.") return true elseif isCharacterForSale(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This character is already for sale.") return true elseif getPlayerGUIDByName(t[2]) == getPlayerGUID(cid) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You cannot sell yourself.") return true elseif getPlayerByName(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "The character must be offline to be sold.") return true elseif getOfflinePlayerValue(t[2], "level") < level then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Your character can't be sold until it has level "..level..".") return true elseif tonumber(t[3]) < min_price then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Sorry, but the minimum price for selling a character is "..min_price.." currency units.") return true elseif tonumber(t[3]) > max_price then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Sorry, but the maximum price for selling a character is "..max_price.." currency units.") return true end setOfflinePlayerStorageValue(t[2], price, t[3]) setOfflinePlayerStorageValue(t[2], owner, getPlayerGUID(cid)) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, 'Your character "'..t[2]..'" is now for sale for the price of "'..t[3]..'" currency units.') elseif t[1] == "buy" then if not t[2] then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Incorrect Params. Specify the character name.") return true elseif not playerExists(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This character doesn't exist.") return true elseif getPlayerAccountId(cid) == getAccountIdByName(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You can't buy your own character.") return true elseif not isCharacterForSale(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This character is not for sale.") return true elseif not doPlayerRemoveItem(cid, 6535, getOfflinePlayerStorageValue(t[2], price)) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Not enough currency. This character's price is "..getOfflinePlayerStorageValue(t[2], price).." currency units.") return true end if not getPlayerByGUID(getOfflinePlayerStorageValue(t[2], owner)) then doOfflinePlayerAddItem(getPlayerNameByGUID(getOfflinePlayerStorageValue(t[2], owner)), getOfflinePlayerStorageValue(t[2], price), 6535) setOfflinePlayerStorageValue(getPlayerNameByGUID(getOfflinePlayerStorageValue(t[2], owner)), 41792, getPlayerGUIDByName(t[2])) else doPlayerAddItem(getPlayerByGUID(getOfflinePlayerStorageValue(t[2], owner)), 6535, getOfflinePlayerStorageValue(t[2], price)) doPlayerSendTextMessage(getPlayerByGUID(getOfflinePlayerStorageValue(t[2], owner)), MESSAGE_STATUS_CONSOLE_BLUE, 'Your character "'..t[2]..'" has been sold for the price of '..getOfflinePlayerStorageValue(t[2], price)..' currency units.') end doTransferCharacter(t[2], getPlayerAccountId(cid)) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, 'You bought the character "'..t[2]..'" for the price of '..getOfflinePlayerStorageValue(t[2], price)..' currency units.') setOfflinePlayerStorageValue(t[2], owner, -1) setOfflinePlayerStorageValue(t[2], price, -1) return true elseif t[1] == "remove" then if not t[2] then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Incorrect Params. Specify the character name.") return true elseif getPlayerAccountId(cid) ~= getAccountIdByName(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This is not your character.") return true elseif not isCharacterForSale(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This character is not for sale.") return true end setOfflinePlayerStorageValue(t[2], price, -1) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, 'You removed the character "'..t[2]..'" from the Characters Market.') return true elseif t[1] == "list" then local result = db.getResult("SELECT `name` FROM `players`") if result:getID() == -1 then return true end local msg = "Characters For Sale:\n\n" while true do local name = result:getDataString("name") if isCharacterForSale(name) then local sex = getOfflinePlayerValue(name, "sex") == 1 and "Male" or "Female" msg = ""..msg.." - ".. name .." (Level: "..getOfflinePlayerValue(name, "level").." / Vocation: "..getVocationInfo(getOfflinePlayerValue(name, "vocation")).name.." / Sex: "..sex.." / Owner: "..getPlayerNameByGUID(getOfflinePlayerStorageValue(name, owner))..") [Price: "..getOfflinePlayerStorageValue(name, price).."] \n" end if not result:next() then break end end doPlayerPopupFYI(cid, msg) return true elseif not t[1] or t[1] ~= "buy" or t[1] ~= "sell" or t[1] ~= "remove" or t[1] ~= "list" then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Incorrect params. You can only 'buy' or 'sell' a character, 'remove' it from the Characters Market or see the 'list' of characters for sale.") return true end return true ]]></talkaction> ------------------------------------------------------------------------------------ <event type="login" name="MarketLogin" event="script"><![CDATA[ function onLogin(cid) domodlib('market') if getPlayerStorageValue(cid, price) > 0 then return false elseif getPlayerStorageValue(cid, 41792) ~= -1 then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You sold the character "..getPlayerNameByGUID(getPlayerStorageValue(cid, 41792))..". The money is in your bank account.") setPlayerStorageValue(cid, 41792, -1) end return true end ]]></event> </mod> Mudanças Realizadas Modificação para usar a moeda com ID 6535: No código doPlayerRemoveItem e doPlayerAddItem ao invés de doPlayerRemoveMoney e doPlayerAddMoney para a transação. Verificação de parâmetros: Ajuste na verificação e mensagem de erro para refletir a moeda correta. Configurações mínimas e máximas de preço: Atualização das variáveis min_price e max_price para refletir os valores corretos na nova moeda. Com essas alterações, o script agora utiliza a moeda com ID 6535 para a compra e permite que os jogadores definam a quantidade desejada ao vender um personagem.
  3. 1. Verifique o Código JavaScript O botão de seleção de vocação e o valor do campo pdt_id são definidos pelo JavaScript. Certifique-se de que o JavaScript está funcionando corretamente e que o valor está sendo corretamente atribuído ao campo pdt_id. Aqui está um exemplo de função JavaScript que deve estar presente para selecionar a vocação: function selectpdt(id) { document.getElementById('pdt_id').value = id; var buttons = document.getElementsByClassName('pdt_blc'); for (var i = 0; i < buttons.length; i++) { buttons[i].style.border = 'none'; } document.getElementById('b' + id).style.border = '2px solid #f00'; // Ajuste a borda para indicar seleção } 2. Verifique o HTML do Formulário Assegure-se de que o formulário HTML está configurado corretamente para enviar os dados: O campo oculto para vocação (pdt_id) deve estar presente e ser atualizado pelo JavaScript quando uma vocação é selecionada. O botão de submit (Criar Personagem) deve estar habilitado quando todos os campos forem preenchidos. No seu código, o botão de submit está desabilitado (disabled), o que pode ser a causa do problema. Verifique se o JavaScript está habilitando o botão após a seleção da vocação e o preenchimento dos campos obrigatórios. 3. Verifique a Função selectpdt Verifique se a função JavaScript selectpdt está sendo chamada corretamente ao clicar em uma vocação. Você pode adicionar um console.log para depuração: function selectpdt(id) { console.log('Vocation selected:', id); // Adicione isso para verificar se a função é chamada document.getElementById('pdt_id').value = id; // Resto do código } 4. Verifique o Código PHP para Processamento de Dados Certifique-se de que o valor de $_POST['pdt_id'] está sendo corretamente verificado e validado no código PHP. Aqui está uma parte relevante do seu código: // Validate vocation id if (!in_array((int)$_POST['pdt_id'], $config['available_vocations'])) { $errors[] = 'Permissão negada. Vocação errada.'; } Certifique-se de que o $_POST['pdt_id'] está sendo enviado corretamente e contém um ID válido. atualizando seu código deve ficar mais ou menos assim: <?php require_once 'engine/init.php'; protect_page(); include 'layout/overall/header.php'; $imagem = 'http://' . $_SERVER['HTTP_HOST'] . '/layout/images/vocstatus'; $statusid = 1; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $required_fields = array('name', 'selected_town', 'pdt_id'); $errors = array(); foreach ($required_fields as $field) { if (empty($_POST[$field])) { $errors[] = 'You need to fill in all fields.'; break; } } if (empty($errors)) { if (!Token::isValid($_POST['token'])) { $errors[] = 'O token é inválido.'; } $_POST['name'] = validate_name($_POST['name']); if ($_POST['name'] === false) { $errors[] = 'Seu nome não pode conter mais de 2 palavras.'; } else { if (user_character_exist($_POST['name']) !== false) { $errors[] = 'Desculpe, esse nome de personagem já existe.'; } if (!preg_match("/^[a-zA-Z_ ]+$/", $_POST['name'])) { $errors[] = 'Seu nome pode conter apenas a-z, A-Z e espaços.'; } if (strlen($_POST['name']) < $config['minL'] || strlen($_POST['name']) > $config['maxL']) { $errors[] = 'O nome do seu personagem deve estar entre ' . $config['minL'] . ' - ' . $config['maxL'] . ' caracteres longos.'; } if (in_array(strtolower($_POST['name']), $config['invalidNames'])) { $errors[] = 'Este nome de usuario esta bloqueado.'; } $resname = explode(" ", $_POST['name']); foreach ($resname as $res) { if (in_array(strtolower($res), $config['invalidNameTags'])) { $errors[] = 'Seu nome de usuário contém uma palavra restrita.'; } else if (strlen($res) == 1) { $errors[] = 'Palavras muito curtas em seu nome.'; } } if (!in_array((int)$_POST['pdt_id'], $config['available_vocations'])) { $errors[] = 'Permissão negada. Vocação errada.'; } $char_count = user_character_list_count($session_user_id); if ($char_count >= $config['max_characters']) { $errors[] = 'Sua conta não tem permissão para ter mais de ' . $config['max_characters'] . ' personagens.'; } if (validate_ip(getIP()) === false && $config['validate_IP'] === true) { $errors[] = 'Falha ao reconhecer o seu endereço IP. (Não é um endereço IPv4 válido).'; } } } } ?> <div id="title"> <div class="name">Criar novo personagem</div> </div> <br> <?php if (isset($_GET['success']) && empty($_GET['success'])) { echo 'Parabéns! Seu personagem foi criado. Te vejo no jogo!'; } else { if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($errors)) { if ($config['log_ip']) { znote_visitor_insert_detailed_data(2); } // Register $character_data = array( 'name' => format_character_name($_POST['name']), 'elo_points' => 0, 'account_id' => $session_user_id, 'vocation' => $_POST['pdt_id'], 'lastip' => getIPLong(), 'created' => time() ); user_create_character($character_data); header('Location: createcharacter.php?success'); exit(); } else if (!empty($errors)) { echo '<font color="red"><b>'; echo output_errors($errors); echo '</b></font>'; } ?> <br> <link rel="stylesheet" type="text/css" href="layout/css/style.css"> <script type="text/javascript" src="/layout/js/selection.js"></script> <center> <div class="Text"> <br>Selecione o personagem desejado:</div> <div class="caixa" style="width: 600px;height: 300px;overflow: auto;"> <table border="0" cellspacing="10" cellpadding="0"> <?php $y = 0; $i = 0; foreach ($config['available_vocations'] as $id) { if ($i == 0) { echo '<tr>'; } $i++; $y++; ?> <td> <table style="width:115px;" border="0" cellspacing="0" cellpadding="0"> <tr style="height:75px;"> <td> <div id="i<?php echo $id; ?>" class="pdt_cls" style="background-image:url('<?php echo $config['images']['selectVocation']; ?>/<?php echo $id; ?>.png'), url(/layout/images/donate/back.png);"> <div id="b<?php echo $id; ?>" class="pdt_blc" value="<?php echo $id; ?>" onclick="selectpdt(<?php echo $id; ?>);"></div> </div> </td> </tr> <tr> <td> <center> <div class="pdt_nme"><?php echo vocation_id_to_name($id); ?></div> </center> </td> </tr> </table> </td> <td> <div style="width:20px;"></div> </td> <?php if ($i == 3) { echo '</tr>'; $i = 0; } } ?> </table> </div> <br> <form action="" method="post"> <li> <font color="white">Digite o nome para seu personagem:</font> <br> <input type="text" name="name"> </li> <input id="pdt_id" name="pdt_id" type="hidden" value="0" /> <table> <tr> <td> <input id="ckb_obs" name="ckb_obs" onclick="chkbox();" type="checkbox" /> </td> <td> <label class="Text" style="width:100%;" for="ckb_obs"> <center>Estou ciente das <a href="/termos.php" style="font-family:monospace; font-size:13px; font-weight:bold;">observações referentes a criação do personagem.</a></center> </label> </td> </tr> </table> <input type="hidden" name="token" value="<?php echo Token::generate(); ?>" /> <div style="height:20px;"></div> <input id="Button" type="submit" value="Criar Personagem" /> </form> </center> <?php } include 'layout/overall/footer.php'; ?>
  4. Parece que há dois problemas distintos com sua configuração: 1. Erro ao Abrir o Arquivo de Configuração O erro indica que o arquivo config.lua não pôde ser encontrado no caminho especificado. Verifique o seguinte: Caminho do Arquivo: Certifique-se de que o caminho D:/OTServ8.60/config.lua está correto e que o arquivo config.lua realmente existe nesse diretório. Permissões de Arquivo: Verifique se o servidor web (por exemplo, Apache no XAMPP) tem permissões suficientes para ler o arquivo config.lua. Extensão do Arquivo: Confirme se o arquivo realmente tem a extensão .lua e não .txt ou outra extensão. 2. Erro de Tipo de Banco de Dados O segundo erro indica que o tipo de banco de dados não está sendo reconhecido corretamente. Pode ser que o problema esteja na forma como o arquivo config.lua está sendo lido e interpretado. A configuração que você forneceu parece correta, mas vamos verificar algumas possíveis soluções: Passos para Resolver o Problema Verifique a Leitura do Arquivo config.lua Certifique-se de que o PHP está configurado corretamente para ler arquivos .lua. Muitas vezes, o PHP pode ter problemas com formatos de arquivo que não são padrão. Em vez de parse_ini_file, você pode usar outra abordagem para carregar e interpretar o arquivo Lua. Valide a Sintaxe do Arquivo config.lua Embora o conteúdo pareça correto, o formato do arquivo Lua deve ser adequado. Aqui está um exemplo básico de como o config.lua pode estar estruturado: sqlType = "mysql" sqlHost = "localhost" sqlPort = 3306 sqlUser = "root" sqlPass = "" sqlDatabase = "hogwarts" sqliteDatabase = "orion.s3db" sqlKeepAlive = 0 mysqlReadTimeout = 10 mysqlWriteTimeout = 10 encryptionType = "sha1" Certifique-se de que não há caracteres extras ou formatação incorreta. Verifique a Configuração do PHP Se o PHP está tentando abrir o arquivo .lua como se fosse um arquivo INI, você pode ter que ajustar o código PHP. Em vez de parse_ini_file, você pode precisar usar uma biblioteca Lua específica ou ler o arquivo Lua manualmente e processá-lo. Por exemplo: // Exemplo de leitura manual $config = file_get_contents('D:/OTServ8.60/config.lua'); // Faça o parsing necessário aqui Verifique a Configuração do Banco de Dados Certifique-se de que seu banco de dados está configurado corretamente e que o nome do banco de dados (hogwarts) existe. Além disso, o tipo de banco de dados deve ser mysql conforme definido em sqlType.
  5. Abra o arquivo config.lua: Este arquivo geralmente está localizado na pasta de configuração do seu servidor, como data/ ou config/. Procure por definições relacionadas a canais de NPC: O ID do canal NPC pode estar definido diretamente no arquivo ou pode haver uma referência para a tabela de canais. Você pode procurar por algo semelhante a: -- Definições de canais channels = { [1] = {name = "Default", description = "Canal padrão"}, [2] = {name = "NPC", description = "Canal dos NPCs"}, -- Outros canais } Verifique o Código-Fonte do Servidor Localize o arquivo de definição de canais: Isso pode estar em um arquivo relacionado a canais ou mensagens. Pode ser algo como channels.cpp ou um arquivo similar. Procure pela definição do canal NPC: Procure por IDs ou definições que correspondam ao canal de NPCs.
  6. Encontre o arquivo de configuração do cliente: Normalmente, isso pode ser um arquivo .cfg, .ini ou um arquivo XML/JSON, dependendo do cliente que você está usando. Abra o arquivo de configuração: Use um editor de texto para abrir o arquivo. Procure por configurações relacionadas à barra de saúde: Algo como healthinfo ou statusbar. Se o seu cliente usa XML para configurações, você pode encontrar algo assim: <interface> <healthinfo visible="false" /> </interface> Você precisaria alterar visible="false" para visible="true": <interface> <healthinfo visible="true" /> </interface> 2. Modificação no Código-Fonte Se a configuração não estiver diretamente disponível em um arquivo de configuração, você pode precisar modificar o código-fonte do cliente. Aqui está um exemplo de como você pode fazer isso em C++: Exemplo em C++ Encontre a função de inicialização da interface do cliente: Esta função geralmente é responsável por configurar e renderizar os elementos da interface do usuário quando o cliente é iniciado. Adicione o código para tornar a barra de saúde visível: Isso pode ser algo assim: void Interface::initialize() { // Outras inicializações // Certifique-se de que a barra de saúde esteja visível healthInfoBar->setVisible(true); }
  7. Para ajustar o código e garantir que um jogador não possa atravessar outro jogador no depósito, você pode modificar a função canWalkthrough para retornar false quando os jogadores estiverem no depósito. Aqui está uma versão atualizada da função que adiciona esta verificação: bool Player::canWalkthrough(const Creature* creature) const { if (creature == this || hasCustomFlag(PlayerCustomFlag_CanWalkthrough) || creature->isWalkable() || (creature->getMaster() && creature->getMaster() != this && canWalkthrough(creature->getMaster()))) return true; const Player* player = creature->getPlayer(); if (!player) return false; // Verifica se os jogadores estão no depósito if (player->getTile()->hasFlag(TILESTATE_DEPOT) || this->getTile()->hasFlag(TILESTATE_DEPOT)) { return false; } if ((((g_game.getWorldType() == WORLD_TYPE_NO_PVP && player->getVocation()->isAttackable()) || player->getTile()->hasFlag(TILESTATE_PROTECTIONZONE) || (player->getVocation()->isAttackable() && player->getLevel() < (uint32_t)g_config.getNumber(ConfigManager::PROTECTION_LEVEL))) && player->getTile()->ground) && (!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges) || player->getAccess() <= getAccess())) return true; return (player->isGhost() && getGhostAccess() < player->getGhostAccess()) || (isGhost() && getGhostAccess() > player->getGhostAccess()); } Aqui, adicionamos a verificação: if (player->getTile()->hasFlag(TILESTATE_DEPOT) || this->getTile()->hasFlag(TILESTATE_DEPOT)) { return false; }
  8. Os erros indicam que a função getPlayerGUIDByName está retornando nil para os nomes de personagens fornecidos. Isso pode ocorrer devido a vários motivos, como o personagem não existir na base de dados, erros de sintaxe nos nomes dos personagens, ou problemas de conexão com o banco de dados. Vamos ajustar o script para lidar melhor com esses casos e garantir que a função getPlayerGUIDByName esteja retornando valores corretos ou tratando os erros adequadamente. Vou também adicionar mais debug prints para ajudar a identificar a causa exata dos problemas. <?xml version="1.0" encoding="ISO-8859-1"?> <mod name="Characters Market System" version="1.0" author="LuckOake" contact="none" enabled="yes"> <config name="market"><![CDATA[ price = 27112 owner = 27113 level = 717217 -- Level min of character. -- min_price = 10000000000000 -- Price min of character -- max_price = 10000000000000 -- Price maximum of character -- function doTransferCharacter(cid, accId) local playerGUID = getPlayerGUIDByName(cid) print("doTransferCharacter - Player GUID for", cid, "is", playerGUID) if playerGUID then return db.executeQuery("UPDATE `players` SET `account_id` = " .. accId .. " WHERE `id` = " .. playerGUID) else print("Error: Player GUID for " .. cid .. " is nil.") return false end end function doOfflinePlayerAddMoney(guid, money) local playerGUID = getPlayerGUIDByName(guid) print("doOfflinePlayerAddMoney - Player GUID for", guid, "is", playerGUID) if playerGUID then return db.executeQuery("UPDATE `players` SET `balance` = `balance` + " .. money .. " WHERE `id` = " .. playerGUID .. ";") else print("Error: Player GUID for " .. guid .. " is nil.") return false end end function setOfflinePlayerStorageValue(name, key, value) local playerGUID = getPlayerGUIDByName(name) print("setOfflinePlayerStorageValue - Player GUID for", name, "is", playerGUID) if playerGUID then local result = db.getResult("SELECT * FROM `player_storage` WHERE `player_id` = " .. playerGUID .. " AND `key` = " .. key .. ";") if result:getID() == -1 then print("setOfflinePlayerStorageValue - No existing storage value found, inserting new value") return db.executeQuery("INSERT INTO `player_storage` (`player_id`, `key`, `value`) VALUES (" .. playerGUID .. ", " .. key .. ", " .. value .. ");") else result:free() print("setOfflinePlayerStorageValue - Existing storage value found, updating value") return db.executeQuery("UPDATE `player_storage` SET `value` = " .. value .. " WHERE `player_id` = " .. playerGUID .. " AND `key` = " .. key .. ";") end else print("Error: Player GUID for " .. name .. " is nil.") return false end end function getOfflinePlayerStorageValue(name, key) local playerGUID = getPlayerGUIDByName(name) print("getOfflinePlayerStorageValue - Player GUID for", name, "is", playerGUID) if playerGUID then local result = db.getResult("SELECT `value` FROM `player_storage` WHERE `player_id` = " .. playerGUID .. " AND `key` = " .. key .. ";") if result:getID() == -1 then print("getOfflinePlayerStorageValue - No storage value found for", name, "with key", key) return nil end local ret = result:getDataInt("value") print("getOfflinePlayerStorageValue - Retrieved storage value for", name, "with key", key, "is", ret) result:free() return ret else print("Error: Player GUID for " .. name .. " is nil.") return nil end end function getOfflinePlayerValue(name, value) local playerGUID = getPlayerGUIDByName(name) print("getOfflinePlayerValue - Player GUID for", name, "is", playerGUID) if playerGUID then local result = db.getResult("SELECT `" .. value .. "` FROM `players` WHERE `id` = " .. playerGUID .. ";") if result:getID() == -1 then print("getOfflinePlayerValue - No value found for", name, "with field", value) return nil end local ret = result:getDataInt(value) print("getOfflinePlayerValue - Retrieved value for", name, "with field", value, "is", ret) result:free() return ret else print("Error: Player GUID for " .. name .. " is nil.") return nil end end function isCharacterForSale(name) local playerGUID = getPlayerGUIDByName(name) print("isCharacterForSale - Player GUID for", name, "is", playerGUID) if playerGUID and getOfflinePlayerStorageValue(name, price) and getOfflinePlayerStorageValue(name, price) > 0 then return true else return false end end ]]></config> <talkaction words="!character" event="buffer"><![CDATA[ domodlib('market') local t = string.explode(param, ",") if t[1] == "sell" then if not t[3] or not tonumber(t[3]) or t[4] or tonumber(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Incorrect Params. Specify the character name and the price.") return true elseif getPlayerAccountId(cid) ~= getAccountIdByName(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This is not your character.") return true elseif isCharacterForSale(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This character is already for sale.") return true elseif getPlayerGUIDByName(t[2]) == getPlayerGUID(cid) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You cannot sell yourself.") return true elseif getPlayerByName(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "The character must be offline to be sold.") return true elseif getOfflinePlayerValue(t[2], "level") < level then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Your character can't be sold until it has level "..level..".") return true elseif tonumber(t[3]) < min_price then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Sorry, but the minimum price for selling a character is "..min_price..".") return true elseif tonumber(t[3]) > max_price then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Sorry, but the maximum price for selling a character is "..max_price..".") return true end setOfflinePlayerStorageValue(t[2], price, t[3]) setOfflinePlayerStorageValue(t[2], owner, getPlayerGUID(cid)) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, 'Your character "'..t[2]..'" is now for sale for the price of "'..t[3]..'" gold coins.') elseif t[1] == "buy" then if not t[2] then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Incorrect Params. Specify the character name.") return true elseif not playerExists(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This character doesn't exist.") return true elseif getPlayerAccountId(cid) == getAccountIdByName(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You can't buy your own character.") return true elseif not isCharacterForSale(t[2]) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "This character is not for sale.") return true elseif not doPlayerRemoveMoney(cid, getOfflinePlayerStorageValue(t[2], price)) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Not enough money. This character's price is "..getOfflinePlayerStorageValue(t[2], price).." gold coins.") return true end if not getPlayerByGUID(getOfflinePlayerStorageValue(t[2], owner)) then doOfflinePlayerAddMoney(getPlayerNameByGUID(getOfflinePlayerStorageValue(t[2], owner)), getOfflinePlayerStorageValue(t[2], price)) setOfflinePlayerStorageValue(getPlayerNameByGUID(getOfflinePlayerStorageValue(t[2], owner)), 41792, getPlayerGUIDByName(t[2])) else doPlayerAddMoney(getPlayerByGUID(getOfflinePlayerStorageValue(t[2], owner)), getOfflinePlayerStorageValue(t[2], price)) end doTransferCharacter(t[2], getPlayerAccountId(cid)) setOfflinePlayerStorageValue(t[2], price, 0) setOfflinePlayerStorageValue(t[2], owner, 0) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, 'You have bought the character "'..t[2]..'" for "'..getOfflinePlayerStorageValue(t[2], price)..'" gold coins.') elseif t[1] == "list" then doPlayerPopupFYI(cid, "Houses for sale") end return true ]]></talkaction> </mod>
  9. A variável talkUser foi ajustada para garantir que a conversa seja atribuída corretamente ao jogador. substitua: local talkUser = cid por: local talkUser = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid A lógica para verificar e atualizar a vocação e o nível do jogador foi revisada para garantir que esteja funcionando corretamente. if isInArray({"promotion", "promot", "promo"}, msg) then selfSay('Você precisa ter 100 [VIP COINS] e estar no level 717217!', cid) talkState[talkUser] = 1 elseif msg == "yes" and talkState[talkUser] == 1 then local playerVocation = getPlayerVocation(cid) if vocation[playerVocation] then if getPlayerLevel(cid) >= level then if getPlayerItemCount(cid, 11192) >= 100 then doPlayerRemoveItem(cid, 11192, 100) local newVocationId = vocation[playerVocation] doPlayerSetVocation(cid, newVocationId) doSendMagicEffect(getPlayerPosition(cid), 12) selfSay("Parabéns, você foi promovido!", cid) else selfSay("Você não tem 100 [VIP COINS] suficientes para ser promovido.", cid) end else selfSay("Desculpe, você precisa estar no level " .. level .. " ou acima para ser promovido!", cid) end else selfSay("Desculpe, você não pode receber promoção.", cid) end talkState[talkUser] = 0 end script completo corrigido: local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) local talkState = {} local vocation = { [2] = 6, [3] = 7, [4] = 8 } 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 msg = string.lower(msg) local level = 717217 if isInArray({"promotion", "promot", "promo"}, msg) then selfSay('Você precisa ter 100 [VIP COINS] e estar no level 717217!', cid) talkState[talkUser] = 1 elseif msg == "yes" and talkState[talkUser] == 1 then local playerVocation = getPlayerVocation(cid) if vocation[playerVocation] then if getPlayerLevel(cid) >= level then if getPlayerItemCount(cid, 11192) >= 100 then doPlayerRemoveItem(cid, 11192, 100) local newVocationId = vocation[playerVocation] doPlayerSetVocation(cid, newVocationId) doSendMagicEffect(getPlayerPosition(cid), 12) selfSay("Parabéns, você foi promovido!", cid) else selfSay("Você não tem 100 [VIP COINS] suficientes para ser promovido.", cid) end else selfSay("Desculpe, você precisa estar no level " .. level .. " ou acima para ser promovido!", cid) end else selfSay("Desculpe, você não pode receber promoção.", cid) end talkState[talkUser] = 0 end return true end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new())
  10. El Rusher

    Device System (Compro)

    descreva o sistema que eu faço pra tu meu nobre
  11. function onSay(cid, words, param) local guilds = {} local guild_rank = {} -- Seleciona o level e a guild de cada jogador com guild e com level maior que 10, ordenados pelo level local query = db.getResult("SELECT level, guild_id FROM players WHERE guild_id > 0 AND level > 10 ORDER BY level DESC") -- Caso nenhum jogador seja selecionado, retorna verdadeiro if query:getID() == -1 then return true end repeat local level = query:getDataInt("level") local guild_id = query:getDataInt("guild_id") -- Cria uma tabela dentro da tabela guilds para cada guilda if not guilds[guild_id] then guilds[guild_id] = {level = level, members = 1} -- Se a tabela já existir e o número de membros for menor que 10, soma o level e +1 ao número de membros elseif guilds[guild_id].members < 10 then guilds[guild_id].level = guilds[guild_id].level + level guilds[guild_id].members = guilds[guild_id].members + 1 end -- Termina se não existirem mais resultados until not query:next() query:free() -- Passa os resultados obtidos para a tabela guild_rank, para ordená-la com table.sort for i, k in pairs(guilds) do table.insert(guild_rank, {id = i, level = k.level}) end -- Ordena a tabela guild_rank de acordo com a soma dos levels table.sort(guild_rank, function(a, b) return a.level > b.level end) local i = 0 local str = ' Guild Rank\n' -- Crie uma string com o nome das guildas em um ranking for _, info in pairs(guild_rank) do i = i + 1 str = str .. i .. ' - '.. getGuildNameById(info.id) .. ' - ' .. info.level .. '\n' if i == 10 then break end end -- Se algum erro ocorrer e o ranking não tiver informações, manda a mensagem "No Guild Information..." local ret = str ~= ' Guild Rank\n' and str or "No guild information to be displayed." doPlayerPopupFYI(cid, ret) return true end O erro que você está encontrando, SQLITE ERROR: no such column: guild_id, indica que a coluna guild_id não existe na tabela players. adicione no seu banco de dados: ALTER TABLE players ADD COLUMN guild_id INTEGER DEFAULT 0;
  12. boa noite Script de Ação para "DANGER!" local config = { effectonuse = 65, -- Efeito visual ao usar o item levelscrit = 100, -- Nível máximo do crítico lvlcritDanger = 48913 -- Storage para crítico "DANGER!" } function onUse(cid, item, frompos, item2, topos) local currentLevel = getPlayerStorageValue(cid, config.lvlcritDanger) or 0 if currentLevel < config.levelscrit then doRemoveItem(item.uid, 1) doSendMagicEffect(topos, config.effectonuse) doPlayerSendTextMessage(cid, 22, "You've Leveled your Critical Skill to [" .. (currentLevel + 1) .. "/" .. config.levelscrit .. "].") setPlayerStorageValue(cid, config.lvlcritDanger, currentLevel + 1) else doPlayerSendTextMessage(cid, 22, "You've already reached the MAX level of Critical Skill.\nCongratulations!!!!") return 0 end return 1 end Script de Combate local lvlcrit = 48904 local lvlcritDanger = 48913 function onCombat(cid, target) if isPlayer(cid) and isCreature(target) then local criticalChance = getPlayerStorageValue(cid, lvlcrit) or 0 local criticalDangerChance = getPlayerStorageValue(cid, lvlcritDanger) or 0 local chance = math.random(1, 1000) -- Mantém um intervalo razoável -- Verifica primeiro o crítico perigoso if chance <= (criticalDangerChance * 3) then local damage = 100 -- Valor do dano crítico "DANGER!" (ajuste conforme necessário) doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -damage, -damage, 255) doSendAnimatedText(getCreaturePos(target), "DANGER!", 190) doSendMagicEffect(getCreaturePosition(cid), 52) elseif chance <= (criticalChance * 3) then local damage = 100 -- Valor do dano crítico "BOOSTER" (ajuste conforme necessário) doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -damage, -damage, 255) doSendAnimatedText(getCreaturePos(target), "+BOOSTER!", 31) doSendMagicEffect(getCreaturePosition(cid), 54) end end return true end
  13. local MONEY_AMOUNT = 1000000 -- Quantidade de dinheiro (em gold coins) que o player necessitará para reviver local MAGIC_EFFECT_TELEPORT = 65 -- Efeito que aparecerá quando o player for teleportado local PLAYER_REBORN_POSITION_X = 66541 local PLAYER_REBORN_POSITION_Y = 66542 local PLAYER_REBORN_POSITION_Z = 66543 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 if msgcontains(msg, 'reviver') or msgcontains(msg, 'revive') then selfSay('Você precisa de ' .. MONEY_AMOUNT .. ' gold(s) para ressuscitar no local onde você morreu recentemente', cid) talkState[talkUser] = 1 elseif msgcontains(msg, 'yes') and talkState[talkUser] == 1 then if getPlayerMoney(cid) >= MONEY_AMOUNT then doPlayerRemoveMoney(cid, MONEY_AMOUNT) if teleportPlayerToPositionReborn(cid) then doTeleportThing(cid, {x = PLAYER_REBORN_POSITION_X, y = PLAYER_REBORN_POSITION_Y, z = PLAYER_REBORN_POSITION_Z}) doSendMagicEffect(getCreaturePosition(cid), MAGIC_EFFECT_TELEPORT) selfSay('Ok, você foi ressuscitado', cid) end else selfSay('Desculpe, mas você não possui dinheiro suficiente.', cid) end talkState[talkUser] = 0 elseif msgcontains(msg, 'no') and talkState[talkUser] == 1 then talkState[talkUser] = 0 selfSay('Ok, até mais.', cid) end return true end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new()) function teleportPlayerToPositionReborn(cid) local playerRebornPositionX = getPlayerStorageValue(cid, PLAYER_REBORN_POSITION_X) local playerRebornPositionY = getPlayerStorageValue(cid, PLAYER_REBORN_POSITION_Y) local playerRebornPositionZ = getPlayerStorageValue(cid, PLAYER_REBORN_POSITION_Z) if playerRebornPositionX == -1 or playerRebornPositionY == -1 or playerRebornPositionZ == -1 then selfSay('Você não morreu nenhuma vez ainda.', cid) return false end doTeleportThing(cid, {x = playerRebornPositionX, y = playerRebornPositionY, z = playerRebornPositionZ}) return true end Correção na Função teleportPlayerToPositionReborn: Os valores PLAYER_REBORN_POSITION_X, PLAYER_REBORN_POSITION_Y e PLAYER_REBORN_POSITION_Z devem ser usados corretamente para obter a posição armazenada do jogador. Correção na Lógica de Teleporte: A função doTeleportThing é chamada uma vez no teleportPlayerToPositionReborn e não precisa ser chamada novamente na função principal. Adição de Mensage
  14. boa noite local lvlcrit = 48913 -- armazenamento para críticos normais local lvlcritDanger = 48904 -- armazenamento para críticos perigosos local multiplier = 1.5 -- multiplicador de dano function onCombat(cid, target) print("onCombat chamado com cid: " .. tostring(cid) .. " target: " .. tostring(target)) if isPlayer(cid) and isCreature(target) then local criticalChance = getPlayerStorageValue(cid, lvlcrit) or 0 local criticalDangerChance = getPlayerStorageValue(cid, lvlcritDanger) or 0 local chance = math.random(1, 1000) -- Mantém um intervalo razoável print("Chances de crítico: normal=" .. criticalChance .. " perigo=" .. criticalDangerChance .. " sorteio=" .. chance) -- Verifica se a chance de crítico BOOSTER é atingida if chance <= (criticalChance * 3) then print("Crítico BOOSTER atingido!") local damage = 100 -- Valor do dano crítico BOOSTER (ajuste conforme necessário) doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -damage, -damage, 255) doSendAnimatedText(getCreaturePosition(target), "+BOOSTER!", 31) doSendMagicEffect(getCreaturePosition(cid), 54) return true end -- Verifica se a chance de crítico DANGER é atingida if chance <= (criticalDangerChance * 3) then print("Crítico DANGER atingido!") local damage = 100 -- Valor do dano crítico DANGER (ajuste conforme necessário) doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -damage, -damage, 255) doSendAnimatedText(getCreaturePosition(target), "DANGER!", 190) doSendMagicEffect(getCreaturePosition(cid), 52) return true end end return true end
  15. local config = AscendingFerumbrasConfig local crystals = { [1] = { fromPosition = Position(33389, 31467, 14), toPosition = Position(33391, 31469, 14), crystalPosition = Position(33390, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal1 }, [2] = { fromPosition = Position(33393, 31467, 14), toPosition = Position(33395, 31469, 14), crystalPosition = Position(33394, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal2 }, [3] = { fromPosition = Position(33396, 31470, 14), toPosition = Position(33398, 31472, 14), crystalPosition = Position(33397, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal3 }, [4] = { fromPosition = Position(33396, 31474, 14), toPosition = Position(33398, 31476, 14), crystalPosition = Position(33397, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal4 }, [5] = { fromPosition = Position(33393, 31477, 14), toPosition = Position(33395, 31479, 14), crystalPosition = Position(33394, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal5 }, [6] = { fromPosition = Position(33389, 31477, 14), toPosition = Position(33391, 31479, 14), crystalPosition = Position(33390, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal6 }, [7] = { fromPosition = Position(33386, 31474, 14), toPosition = Position(33388, 31476, 14), crystalPosition = Position(33387, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal7 }, [8] = { fromPosition = Position(33386, 31470, 14), toPosition = Position(33388, 31472, 14), crystalPosition = Position(33387, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal8 }, } local function createDestabilizedFerumbrasIfNeeded() local essenceCount = Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence) if essenceCount == 8 then Game.createMonster("Destabilized Ferumbras", config.bossPos, true, true) for i = 1, config.maxSummon do local summonPos = Position(math.random(33381, 33403), math.random(31462, 31483), 14) if not Game.createMonster("Rift Fragment", summonPos, true, true) then print(string.format("Error: Could not create Rift Fragment at position %s", summonPos)) end end end end local riftInvaderDeath = CreatureEvent("RiftInvaderDeath") function riftInvaderDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) local name = creature:getName():lower() if name == "rift invader" then for i = 1, #crystals do local crystal = crystals[i] if creature:getPosition():isInRange(crystal.fromPosition, crystal.toPosition) then if Game.getStorageValue(crystal.globalStorage) > 6 then local item = Tile(crystal.crystalPosition):getItemById(14955) if item then item:transform(14961) Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals) + 1) lasthitkiller:say("The negative energy of the rift creature is absorbed by the crystal!", TALKTYPE_MONSTER_SAY, nil, nil, crystal.crystalPosition) lasthitkiller:say("ARGH!", TALKTYPE_MONSTER_SAY, nil, nil, Position(33392, 31473, 14)) end end Game.setStorageValue(crystal.globalStorage, Game.getStorageValue(crystal.globalStorage) + 1) end end local pool = Tile(creature:getPosition()):getItemById(2886) if pool then pool:remove() end local vortex = Game.createItem(config.vortex, 1, creature:getPosition()) if vortex then addEvent(function(creaturePos) local tile = Tile(creaturePos) if tile then local vortexItem = tile:getItemById(config.vortex) if vortexItem then vortexItem:remove(1) end end end, 10 * 1000, creature:getPosition()) end createDestabilizedFerumbrasIfNeeded() end return true end riftInvaderDeath:register() local vortex = Action() function vortex.onStepIn(creature, item, position, fromPosition) local monster = creature:getMonster() if monster and monster:getName():lower() == "ferumbras essence" then monster:remove() position:sendMagicEffect(CONST_ME_POFF) local essenceCount = Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence) if essenceCount < 0 then essenceCount = 0 end essenceCount = essenceCount + 1 Game.setStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence, essenceCount) if essenceCount >= 8 then createDestabilizedFerumbrasIfNeeded() end end return true end vortex:uid(1022) vortex:register() Neste código revisado, eu movi a criação do "Destabilized Ferumbras" para uma função separada chamada createDestabilizedFerumbrasIfNeeded. Esta função é chamada tanto na função riftInvaderDeath.onDeath quanto na função vortex.onStepIn, sempre que uma essência é transformada em cristal ou quando uma essência entra no vortex.
  16. vamos alterar a lógica entao: function vortex.onStepIn(creature, item, position, fromPosition) local monster = creature:getMonster() if not monster or monster:getName():lower() ~= "ferumbras essence" then return true end print("Ferumbras Essence entrou no vortex") monster:remove() position:sendMagicEffect(CONST_ME_POFF) local essenceCount = Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence) if essenceCount < 0 then essenceCount = 0 end essenceCount = essenceCount + 1 Game.setStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence, essenceCount) print("Número atual de essências:", essenceCount) if essenceCount >= 8 then print("Todas as essências transformadas, criando Destabilized Ferumbras") Game.createMonster("Destabilized Ferumbras", config.bossPos, true, true) for i = 1, config.maxSummon do local summonPos = Position(math.random(33381, 33403), math.random(31462, 31483), 14) if not Game.createMonster("Rift Fragment", summonPos, true, true) then print(string.format("Error: Could not create Rift Fragment at position %s", summonPos)) end end end return true end
  17. Bom dia, teste assim: ferumbras_lever local config = AscendingFerumbrasConfig local function clearFerumbrasRoom() local spectators = Game.getSpectators(config.bossPos, false, false, 20, 20, 20, 20) for i = 1, #spectators do local spectator = spectators[i] if spectator:isPlayer() then spectator:teleportTo(config.exitPosition) spectator:getPosition():sendMagicEffect(CONST_ME_TELEPORT) spectator:say("Time out! You were teleported out by strange forces.", TALKTYPE_MONSTER_SAY) elseif spectator:isMonster() then spectator:remove() end end end local ferumbrasAscendantLever = Action() function ferumbrasAscendantLever.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 8911 then if player:getPosition() ~= config.leverPos then return true end for x = 33269, 33271 do for y = 31477, 31481 do local playerTile = Tile(Position(x, y, 14)):getTopCreature() if playerTile and playerTile:isPlayer() then if not playerTile:canFightBoss("Ferumbras Mortal Shell") then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You or a member in your team have to wait %d days to face Ferumbras again!", config.days)) item:transform(8912) return true end end end end local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15) for i = 1, #specs do spec = specs[i] if spec:isPlayer() then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "There's someone fighting with Ferumbras.") return true end end local spectators = Game.getSpectators(config.bossPos, false, false, 15, 15, 15, 15) for i = 1, #spectators do local spectator = spectators[i] if spectator:isMonster() then spectator:remove() end end for x = 33269, 33271 do for y = 31477, 31481 do local playerTile = Tile(Position(x, y, 14)):getTopCreature() if playerTile and playerTile:isPlayer() then playerTile:getPosition():sendMagicEffect(CONST_ME_POFF) playerTile:teleportTo(config.newPos) playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT) playerTile:setBossCooldown("Ferumbras Mortal Shell", os.time() + config.days * 24 * 3600) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have %d minutes to kill and loot this boss. Otherwise you will lose that chance and will be kicked out.", config.time)) addEvent(clearFerumbrasRoom, config.time * 60 * 1000, player:getId(), config.centerRoom, config.range, config.range, config.exitPosition) for b = 1, config.maxSummon do local xrand = math.random(-4, 4) local yrand = math.random(-4, 4) local position = Position(33392 + xrand, 31473 + yrand, 14) if not Game.createMonster(config.summonName, position) then logger.error("[ferumbrasAscendantLever.onUse] can't create monster {}, on position {}", config.summonName, position:toString()) end end Game.createMonster(config.bossName, config.bossPos, true, true) item:transform(8912) end end end elseif item.itemid == 8912 then item:transform(8911) return true end end ferumbrasAscendantLever:uid(1021) ferumbrasAscendantLever:register() rift_invader_death local crystals = { [1] = { fromPosition = Position(33389, 31467, 14), toPosition = Position(33391, 31469, 14), crystalPosition = Position(33390, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal1 }, [2] = { fromPosition = Position(33393, 31467, 14), toPosition = Position(33395, 31469, 14), crystalPosition = Position(33394, 31468, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal2 }, [3] = { fromPosition = Position(33396, 31470, 14), toPosition = Position(33398, 31472, 14), crystalPosition = Position(33397, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal3 }, [4] = { fromPosition = Position(33396, 31474, 14), toPosition = Position(33398, 31476, 14), crystalPosition = Position(33397, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal4 }, [5] = { fromPosition = Position(33393, 31477, 14), toPosition = Position(33395, 31479, 14), crystalPosition = Position(33394, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal5 }, [6] = { fromPosition = Position(33389, 31477, 14), toPosition = Position(33391, 31479, 14), crystalPosition = Position(33390, 31478, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal6 }, [7] = { fromPosition = Position(33386, 31474, 14), toPosition = Position(33388, 31476, 14), crystalPosition = Position(33387, 31475, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal7 }, [8] = { fromPosition = Position(33386, 31470, 14), toPosition = Position(33388, 31472, 14), crystalPosition = Position(33387, 31471, 14), globalStorage = GlobalStorage.FerumbrasAscendant.Crystals.Crystal8 }, } local config = AscendingFerumbrasConfig local riftInvaderDeath = CreatureEvent("RiftInvaderDeath") function riftInvaderDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) local pos = Position(33392 + math.random(-4, 4), 31473 + math.random(-4, 4), 14) local name = creature:getName():lower() if name ~= "rift invader" then return true end Game.createMonster(name, pos) for i = 1, #crystals do local crystal = crystals[i] if creature:getPosition():isInRange(crystal.fromPosition, crystal.toPosition) then if Game.getStorageValue(crystal.globalStorage) > 6 then local item = Tile(crystal.crystalPosition):getItemById(14955) if not item then return true end item:transform(14961) Game.setStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals, Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals) + 1) end if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Crystals.AllCrystals) == 8 then local creature = Tile(config.bossPos):getTopCreature() if creature then creature:say("NOOOOOOOOOOO!", TALKTYPE_MONSTER_YELL) creature:say("FERUMBRAS BURSTS INTO SOUL SPLINTERS!", TALKTYPE_MONSTER_YELL, nil, nil, Position(33392, 31475, 14)) creature:remove() end for a = 1, #crystals do local crystalEffect = crystals[a] crystalEffect.crystalPosition:sendMagicEffect(CONST_ME_FERUMBRAS) Game.createMonster("Ferumbras Soul Splinter", Position(33392, 31473, 14), false, true) end end Game.setStorageValue(crystal.globalStorage, Game.getStorageValue(crystal.globalStorage) + 1) lasthitkiller:say("The negative energy of the rift creature is absorbed by the crystal!", TALKTYPE_MONSTER_SAY, nil, nil, crystal.crystalPosition) lasthitkiller:say("ARGH!", TALKTYPE_MONSTER_SAY, nil, nil, Position(33392, 31473, 14)) end end local pool = Tile(creature:getPosition()):getItemById(2886) if pool then pool:remove() end local vortex = Game.createItem(config.vortex, 1, creature:getPosition()) if vortex then addEvent(function(creaturePos) local tile = Tile(creaturePos) if tile then local vortexItem = tile:getItemById(config.vortex) if vortexItem then vortexItem:remove(1) end end end, 10 * 1000, creature:getPosition()) end return true end riftInvaderDeath:register() Vortex: local vortex = MoveEvent() local config = AscendingFerumbrasConfig function vortex.onStepIn(creature, item, position, fromPosition) local monster = creature:getMonster() if not monster or monster:getName():lower() ~= "ferumbras essence" then return true end monster:remove() position:sendMagicEffect(CONST_ME_POFF) local essenceCount = Game.getStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence) if essenceCount < 0 then essenceCount = 0 end Game.setStorageValue(GlobalStorage.FerumbrasAscendant.FerumbrasEssence, essenceCount + 1) if essenceCount + 1 >= 8 then Game.createMonster("Destabilized Ferumbras", config.bossPos, true, true) for i = 1, config.maxSummon do local summonPos = Position(math.random(33381, 33403), math.random(31462, 31483), 14) if not Game.createMonster("Rift Fragment", summonPos, true, true) then print(string.format("Error: Could not create Rift Fragment at position %s", summonPos)) end end end return true end vortex:type("stepin") vortex:id(config.vortex) vortex:register()
  18. preciso dos scripts pra poder alterar meu nobre,a Store que tu menciona fica em um NPC, MOD ou Site?
  19. testa assim: local lvlcrit = 48904 local lvlcritDanger = 48913 local multiplier = 1.5 function onCombat(cid, target) if isPlayer(cid) and isCreature(target) then local criticalChance = getPlayerStorageValue(cid, lvlcrit) or 0 local criticalDangerChance = getPlayerStorageValue(cid, lvlcritDanger) or 0 local chance = math.random(1, 1000) -- Mantém um intervalo razoável if chance <= (criticalChance * 3) then local damage = 100 -- Valor do dano crítico BOOSTER (ajuste conforme necessário) doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -damage, -damage, 255) doSendAnimatedText(getCreaturePos(target), "+BOOSTER!", 31) doSendMagicEffect(getCreaturePosition(cid), 54) elseif chance <= (criticalDangerChance * 3) then local damage = 100 -- Valor do dano crítico DANGER (ajuste conforme necessário) doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -damage, -damage, 255) doSendAnimatedText(getCreaturePos(target), "DANGER!", 190) doSendMagicEffect(getCreaturePosition(cid), 52) end end return true end
  20. se existe uma função no TFS pra alterar tamanho de fontes eu desconheço, entao vou usar a funçao doSendAnimatedText(position, text, color) e TEXTCOLOR_WHITE pra deixar o mais semelhante ao que parece, eu nao tenho mais computador hoje em dia devido a problemas economicos, mas por logica deve ficar +- assim: local colorMsg = "orange" local tableBoss = { ["[EXP] Statue"] = {seconds = 3600, newBoss = "[EXP] Statue"} } local function countdown(position) for i = 5, 0, -1 do addEvent(function() doSendAnimatedText(position, tostring(i), TEXTCOLOR_WHITE) end, (5 - i) * 1000) end end local function timer(position, duration) countdown(position) addEvent(function() for i = 0, (duration - 1) do addEvent(function() doSendAnimatedText(position, tostring(duration - i), TEXTCOLOR_WHITE) end, (i + 6) * 1000) end end, 6000) end local lastTarget = nil function onKill(cid, target, damage, flags) if lastTarget and lastTarget == target then return true end lastTarget = target if isPlayer(target) then return true end local boss = tableBoss[getCreatureName(target)] if not boss then return true end local position = getThingPos(target) doPlayerSendTextMessage(cid, MESSAGE_TYPES[colorMsg], "The boss will be born in " .. boss.seconds .. " seconds.") timer(position, boss.seconds) addEvent(doCreateMonster, (boss.seconds + 5) * 1000, boss.newBoss, position) return true end
  21. local colorMsg = "orange" local tableBoss = { ["[EXP] Statue"] = {seconds = 3600, newBoss = "[EXP] Statue", event = nil} } local function timer(position, duration, color) for i = 0, (duration - 1) do addEvent(function() doSendAnimatedText(position, tostring(duration - i), color) end, i * 1000) end end function onKill(cid, target, damage, flags) if isPlayer(target) then return true end local bossName = getCreatureName(target) local boss = tableBoss[bossName] if not boss then return true end local position = getThingPos(target) -- Cancelar evento anterior se existir if boss.event then stopEvent(boss.event) end doPlayerSendTextMessage(cid, MESSAGE_TYPES[colorMsg], "The boss will be born in " .. boss.seconds .. " seconds.") timer(position, boss.seconds, COLOR_WHITE) boss.event = addEvent(function() boss.event = nil -- resetar evento doCreateMonster(boss.newBoss, position) end, boss.seconds * 1000) return true end 1.Cancelamento do evento anterior: Antes de criar um novo evento de nascimento do monstro, o script cancela o evento anterior usando stopEvent(boss.event) se ele ainda estiver ativo. 2.Reset do evento: Quando o monstro é criado, o evento é resetado para nil, permitindo que novos eventos sejam criados sem problema na próxima vez que o monstro for morto. Essa modificação deve evitar a criação de múltiplos monstros quando o jogador está em cima do contador de tempo.
  22. Isso ta acontecendo pq a conexão com o banco de dados não ta sendo iniciada corretamente, no seu caso mais precisamente na linha 23 onde você está chamando db.executeQuery... db não está definido como uma conexão com o banco de dados ou que a função executeQuery não está disponível no contexto atual.
  23. local colorMsg = "orange" local tableBoss = { ["[EXP] Statue"] = {seconds = 3600, newBoss = "[EXP] Statue", event = nil} } local function timer(position, duration, color) for i = 0, (duration - 1) do addEvent(function() doSendAnimatedText(position, tostring(duration - i), color) end, i * 1000) end end function onKill(cid, target, damage, flags) if isPlayer(target) then return true end local boss = tableBoss[getCreatureName(target)] if not boss then return true end local position = getThingPos(target) if boss.event == nil then doPlayerSendTextMessage(cid, MESSAGE_TYPES[colorMsg], "The boss will be born in " .. boss.seconds .. " seconds.") timer(position, boss.seconds, COLOR_WHITE) boss.event = addEvent(doCreateMonster, boss.seconds * 1000, boss.newBoss, position) end return true end
  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...