Ir para conteúdo
  • 0
Epic Tibia

Scripting Prey system

Pergunta

Epic Tibia    0
Epic Tibia

Antes de fazer a sua pergunta, tenha certeza de ter lido as regras da seção e o guia abaixo:

https://forums.otserv.com.br/index.php?/forums/topic/168583-regras-da-seção/

https://forums.otserv.com.br/index.php?/forums/topic/165121-como-fazer-uma-pergunta-ou-o-grande-guia-do-usuário-com-dúvidas/

Descreva em algumas palavras a base utilizada. (Nome do servidor / Nome do cliente / Nome do website / etc.).

 

Base:

The Forgotten Server 1.0, Versão: 12.00.

Qual é a sua pergunta?

Como desabilito a 3° prey nas contas criadas?

Elas estão vindos com a 3° prey aberta, queria por pra desabilitar somenta na store.

Gostaria de deixar igual essa imagem

 

Você tem o código disponível? Se tiver poste-o na caixa de código que está dentro do spoiler abaixo:

Spoiler


 

 

Você tem alguma imagem que possa auxiliar no problema? Se sim, anexe-a dentro do spoiler abaixo:

Spoiler

2.png.5e14e2d2763e741e3c085051a2c2903b.png.597e4d3431e673b02e71c6bff74b83b5.png

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

4 respostass a esta questão

Recommended Posts

  • 0
Defused    6
Defused

Também estou com essa necessidade.

 

No otserver que estou usando como base (OTServBR - Global do Majesty) os chares são criados com o terceiro slot de prey habilitado, e eu gostaria de deixar esse slot bloqueado por padrão, e liberá-lo apenas via compra na gamestore.

 

Reparei que no arquivo "src/iologindata.cpp" há um trecho onde são feitas as inserções dos registros referente aos slots na tabela "prey_slots" do banco de dados quando o player loga pela primeira vez e/ou não há nenhum registro nessa tabela referente aos slots dele, no seguinte trecho de código:

Spoiler

// New Prey
bool IOLoginData::loadPlayerPreyData(Player* player) 
{
	Database& db = Database::getInstance();
	DBResult_ptr result;
	std::ostringstream query;
	query << "SELECT `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade` FROM `prey_slots` WHERE `player_id` = " << player->getGUID();
	if ((result = db.storeQuery(query.str()))) {
		do {
			uint16_t slotNum = result->getNumber<uint16_t>("num");
			player->preySlotState[slotNum] = result->getNumber<uint16_t>("state");
			player->preySlotUnlocked[slotNum] = result->getNumber<uint16_t>("unlocked");
			player->preySlotCurrentMonster[slotNum] = result->getString("current");
			player->preySlotMonsterList[slotNum] = result->getString("monster_list");
			player->preySlotFreeRerollIn[slotNum] = result->getNumber<uint16_t>("free_reroll_in");
			player->preySlotTimeLeft[slotNum] = result->getNumber<uint16_t>("time_left");
			player->preySlotNextUse[slotNum] = result->getNumber<uint32_t>("next_use");
			player->preySlotBonusType[slotNum] = result->getNumber<uint16_t>("bonus_type");
			player->preySlotBonusValue[slotNum] = result->getNumber<uint16_t>("bonus_value");
			player->preySlotBonusGrade[slotNum] = result->getNumber<uint16_t>("bonus_grade");
		} while (result->next());
	}
	else {
		query.str(std::string());
		DBInsert preyDataQuery("INSERT INTO `prey_slots` (`player_id`, `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade`) VALUES ");
		for (size_t num = 0; num < PREY_SLOTNUM_THIRD + 1; num++) {
			query << player->getGUID() << ',' << num << ',' << 3 << ',' << 1 << ',' << db.escapeString("") << ',' << db.escapeString("") << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0;
			if (!preyDataQuery.addRow(query)) {
				return false;
			}
		}
		if (!preyDataQuery.execute()) {
			return false;
		}
		// Reload player data
		return loadPlayerPreyData(player);
	}

	return true;
}

 

 

Eu fiz a seguinte alteração:

 

De:

DBInsert preyDataQuery("INSERT INTO `prey_slots` (`player_id`, `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade`) VALUES ");
		for (size_t num = 0; num < PREY_SLOTNUM_THIRD + 1; num++) {
			query << player->getGUID() << ',' << num << ',' << 3 << ',' << 1 << ',' << db.escapeString("") << ',' << db.escapeString("") << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0;

 

Para:

DBInsert preyDataQuery("INSERT INTO `prey_slots` (`player_id`, `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade`) VALUES ");
		for (size_t num = 0; num < PREY_SLOTNUM_THIRD + 1; num++) {
			query << player->getGUID() << ',' << num << ',' << "CASE WHEN `num` = 2 THEN 1 ELSE 3 END" << ',' << "CASE WHEN `num` = 2 THEN 0 ELSE 1 END" << ',' << db.escapeString("") << ',' << db.escapeString("") << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0;

 

A informação desses slots fica guardada na tabela "prey_slots", onde temos as colunas "player_id, num, state e unlocked". A coluna "num" identifica qual slot é (0, 1 ou 2). A coluna "state" identifica se o slot está sem nenhum bixo selecionado, se há algum bixo selecionado ou se está inativa. A coluna "unlocked" identifica se o slot está liberado ou desativado (0 ou 1).

 

Por padrão, quando você loga pela primeira vez no char, é registrado na tabela "prey_slots" os seguites registros:

Cabeçalho: player_id, num, state, unlocked.

x, 0, 3, 1

x, 1, 3, 1

x, 2, 3, 1

 

Onde "x" é o id do player, state = 3 para todos indicando que o slot está disponível para selecionar alguma criatura, e unlocked = 1 para todos indicando que o player "x" possui permissão de utilizar o slot.

 

Fazendo essa alteração, consegui - de modo bem precário eu sei - fazer com que os players que não possuem registros nessa tabela, sejam registrados com a terceira slot bloqueada, porém a partir disso não consigo fazer com que a compra do slot na gamestore libere o slot novamente. Quando a compra é feita, o player recebe o storage id "63253" com o valor "1" e nada mais. Tentei botar para atribuir o storage e então logo em seguida rodar o update na tabela "prey_slots" atualizando os valores de "state" para 3 e "unlocked" para 1 onde "num" for 2, e quando isso acontece, ele até atualiza no banco de dados porém o slot não é liberado instantaneamente para o player, teoricamente ele deveria deslogar e logar para que sejam lidos os novos valores dessa tabela, mas quando ele reloga, os valores de "state" e "unlocked" voltam para 1 e 0 respectivamente.

 

Já tentei colocar esse mesmo update no arquivo "data/creaturescript/scripts/others/logout.lua", verificando se o player possui a storage e se o valor de "unlocked" for 0, mas não funcionou.

 

Não vou conseguir postar as minhas tentativas além desse de/para que postei acima do arquivo iologindata.cpp porque esmurrei tanto os arquivos que acabei fazendo muita merda e tive que retornar para o ponto onde estava quando apenas deixei o terceiro slot bloqueado.

 

Me falta muito conhecimento a respeito da sintaxe C++ e também LUA, por isso estou me ferrando tanto, e por isso também que optei por bloquear o terceiro slot pela query ao invés de ir por um caminho mais descente.

 

Se alguém puder me ajudar, ficarei muito grato e com certeza darei rep++ para todos que pelo menos tentarem me ajudar.

 

Caso faltei com alguma informação essencial, por gentileza me questione abaixo que forneço o que for preciso.

 

Perdoem-me pelo textão, eu sei, TLDR mas tentei ser o mais claro o possível e agora já são 14h  e estou trabalhando em implementações e correções desde ontem de tarde, então já estou bem lesado de sono kkk.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
ticardoo    2
ticardoo
Em 16/02/2020 em 13:56, Defused disse:

Também estou com essa necessidade.

 

No otserver que estou usando como base (OTServBR - Global do Majesty) os chares são criados com o terceiro slot de prey habilitado, e eu gostaria de deixar esse slot bloqueado por padrão, e liberá-lo apenas via compra na gamestore.

 

Reparei que no arquivo "src/iologindata.cpp" há um trecho onde são feitas as inserções dos registros referente aos slots na tabela "prey_slots" do banco de dados quando o player loga pela primeira vez e/ou não há nenhum registro nessa tabela referente aos slots dele, no seguinte trecho de código:

  Mostrar conteúdo oculto


// New Prey
bool IOLoginData::loadPlayerPreyData(Player* player) 
{
	Database& db = Database::getInstance();
	DBResult_ptr result;
	std::ostringstream query;
	query << "SELECT `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade` FROM `prey_slots` WHERE `player_id` = " << player->getGUID();
	if ((result = db.storeQuery(query.str()))) {
		do {
			uint16_t slotNum = result->getNumber<uint16_t>("num");
			player->preySlotState[slotNum] = result->getNumber<uint16_t>("state");
			player->preySlotUnlocked[slotNum] = result->getNumber<uint16_t>("unlocked");
			player->preySlotCurrentMonster[slotNum] = result->getString("current");
			player->preySlotMonsterList[slotNum] = result->getString("monster_list");
			player->preySlotFreeRerollIn[slotNum] = result->getNumber<uint16_t>("free_reroll_in");
			player->preySlotTimeLeft[slotNum] = result->getNumber<uint16_t>("time_left");
			player->preySlotNextUse[slotNum] = result->getNumber<uint32_t>("next_use");
			player->preySlotBonusType[slotNum] = result->getNumber<uint16_t>("bonus_type");
			player->preySlotBonusValue[slotNum] = result->getNumber<uint16_t>("bonus_value");
			player->preySlotBonusGrade[slotNum] = result->getNumber<uint16_t>("bonus_grade");
		} while (result->next());
	}
	else {
		query.str(std::string());
		DBInsert preyDataQuery("INSERT INTO `prey_slots` (`player_id`, `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade`) VALUES ");
		for (size_t num = 0; num < PREY_SLOTNUM_THIRD + 1; num++) {
			query << player->getGUID() << ',' << num << ',' << 3 << ',' << 1 << ',' << db.escapeString("") << ',' << db.escapeString("") << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0;
			if (!preyDataQuery.addRow(query)) {
				return false;
			}
		}
		if (!preyDataQuery.execute()) {
			return false;
		}
		// Reload player data
		return loadPlayerPreyData(player);
	}

	return true;
}

 

 

Eu fiz a seguinte alteração:

 

De:


DBInsert preyDataQuery("INSERT INTO `prey_slots` (`player_id`, `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade`) VALUES ");
		for (size_t num = 0; num < PREY_SLOTNUM_THIRD + 1; num++) {
			query << player->getGUID() << ',' << num << ',' << 3 << ',' << 1 << ',' << db.escapeString("") << ',' << db.escapeString("") << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0;

 

Para:


DBInsert preyDataQuery("INSERT INTO `prey_slots` (`player_id`, `num`, `state`, `unlocked`, `current`, `monster_list`, `free_reroll_in`, `time_left`, `next_use`, `bonus_type`, `bonus_value`, `bonus_grade`) VALUES ");
		for (size_t num = 0; num < PREY_SLOTNUM_THIRD + 1; num++) {
			query << player->getGUID() << ',' << num << ',' << "CASE WHEN `num` = 2 THEN 1 ELSE 3 END" << ',' << "CASE WHEN `num` = 2 THEN 0 ELSE 1 END" << ',' << db.escapeString("") << ',' << db.escapeString("") << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0 << ',' << 0;

 

A informação desses slots fica guardada na tabela "prey_slots", onde temos as colunas "player_id, num, state e unlocked". A coluna "num" identifica qual slot é (0, 1 ou 2). A coluna "state" identifica se o slot está sem nenhum bixo selecionado, se há algum bixo selecionado ou se está inativa. A coluna "unlocked" identifica se o slot está liberado ou desativado (0 ou 1).

 

Por padrão, quando você loga pela primeira vez no char, é registrado na tabela "prey_slots" os seguites registros:

Cabeçalho: player_id, num, state, unlocked.

x, 0, 3, 1

x, 1, 3, 1

x, 2, 3, 1

 

Onde "x" é o id do player, state = 3 para todos indicando que o slot está disponível para selecionar alguma criatura, e unlocked = 1 para todos indicando que o player "x" possui permissão de utilizar o slot.

 

Fazendo essa alteração, consegui - de modo bem precário eu sei - fazer com que os players que não possuem registros nessa tabela, sejam registrados com a terceira slot bloqueada, porém a partir disso não consigo fazer com que a compra do slot na gamestore libere o slot novamente. Quando a compra é feita, o player recebe o storage id "63253" com o valor "1" e nada mais. Tentei botar para atribuir o storage e então logo em seguida rodar o update na tabela "prey_slots" atualizando os valores de "state" para 3 e "unlocked" para 1 onde "num" for 2, e quando isso acontece, ele até atualiza no banco de dados porém o slot não é liberado instantaneamente para o player, teoricamente ele deveria deslogar e logar para que sejam lidos os novos valores dessa tabela, mas quando ele reloga, os valores de "state" e "unlocked" voltam para 1 e 0 respectivamente.

 

Já tentei colocar esse mesmo update no arquivo "data/creaturescript/scripts/others/logout.lua", verificando se o player possui a storage e se o valor de "unlocked" for 0, mas não funcionou.

 

Não vou conseguir postar as minhas tentativas além desse de/para que postei acima do arquivo iologindata.cpp porque esmurrei tanto os arquivos que acabei fazendo muita merda e tive que retornar para o ponto onde estava quando apenas deixei o terceiro slot bloqueado.

 

Me falta muito conhecimento a respeito da sintaxe C++ e também LUA, por isso estou me ferrando tanto, e por isso também que optei por bloquear o terceiro slot pela query ao invés de ir por um caminho mais descente.

 

Se alguém puder me ajudar, ficarei muito grato e com certeza darei rep++ para todos que pelo menos tentarem me ajudar.

 

Caso faltei com alguma informação essencial, por gentileza me questione abaixo que forneço o que for preciso.

 

Perdoem-me pelo textão, eu sei, TLDR mas tentei ser o mais claro o possível e agora já são 14h  e estou trabalhando em implementações e correções desde ontem de tarde, então já estou bem lesado de sono kkk.

Você precisa setar um valor padrão no caso 0 pra todos os slots no iologindata.
Depois manipular esse 0 com seus respectivos estados pelo preydata em prey.lua.
Não é necessário forçar uma atualização crua da database ao comprar o slot,  caso a base seja otbr basta utilizar player:setPreyState ou player:setPreyUnlock

Dê uma olhada como feito no link citado acima. Enjoy

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
Defused    6
Defused

Cara, obrigado pela ajuda, de verdade.

 

Eu consegui deixar do jeito que eu queria, porém vou tentar sim utilizar as funções que você me passou porque com certeza vai ficar bem melhor hahah

 

Vou tentar aqui quando eu tiver um tempo e eu posto o resultado aqui

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante
Este tópico está impedido de receber novos posts.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×