Ir para conteúdo

Featured Replies

Postado

Olá, tenho alma de compartilhador de conhecimento, assim como peguei algumas coisas daqui, sinto que devo também.

 

Meu parceiro pediu-me que fizesse com que as quests dele tivessem seu funcionamento no TFS 1.0 assim como em um servidor que baixara a muito tempo. Eu olhei o script e era uma zona total, não entendi nada e resolvi escrever um do jeito que eu entendo por programação.

 

O que ele gostaria é que tivesse o poder de criar quests, do modo antigo do tibia, apenas você e o baú, pelo próprio editor. Com essa maneira, ele simplesmente coloca qualquer container no mapa, mas pera aí, o que é um container para um código de OT? É qualquer coisa que possa carregar em dentro de si, uma ou mais de uma outra coisa. Corpos mortos, baús, etc.

 

Note que caso o container, por exemplo um baú, seja para beneficar o jogador com mais de um item, é necessário criar um outro container dentro deste e adicionar os itens dentro desse último container criado. Um exemplo: para uma quest que dê 10 cerejas e 10 pães crie um baú com uma bag dentro, dentro da bag adicione as 10 cerejas e os 10 pães.

 

Mãos a obra.

 

Copie o código abaixo para um arquivo com qualquer nome desejável, eu o nomeei de "editor.lua"

function onUse(cid, item, fromPosition, itemEx, toPosition)
	local container = Container(item.uid)
	local player = Player(cid)

	if player:getStorageValue(item.uid) == -1 then

		local questReward = container:getItem(0)
		local questRewardName = questReward:getType():getName()

		local weight = 0;

		if questReward:isContainer() then
			weight = questReward:getWeight()
		else
			weight = questReward:getType():getWeight(questReward:getCount())
		end
		
		local freecap = player:getFreeCapacity()

		if freecap >= weight then
			local reward = questReward:clone()
			local result = player:addItemEx(reward)
			
			if result ~= RETURNVALUE_NOERROR then
				player:sendTextMessage(MESSAGE_INFO_DESCR, 'You have not enough room.')
			else
				player:sendTextMessage(MESSAGE_INFO_DESCR, 'You have found a ' .. questRewardName .. '.')
				player:setStorageValue(item.uid, 1)
			end
		else
			player:sendTextMessage(MESSAGE_INFO_DESCR, 'You have found a ' .. questRewardName .. ' weighing ' .. string.format("%.2f", weight) .. ' oz. It\'s too heavy.')
		end

	else

		player:sendTextMessage(MESSAGE_INFO_DESCR, "It is empty.")

	end

	return true
end 

Neste outro passo tu podes seguir dois caminhos, o primeiro e o mais correto é uma alteração no código fonte do forgottenserver. Então, desta forma, se for a preferia por ti. Faça:

 

No arquivo luascript.h, logo após a linha de número 744, ou procure algo parecido com:

static int32_t luaContainerGetSize(lua_State* L);
static int32_t luaContainerGetCapacity(lua_State* L);
static int32_t luaContainerGetEmptySlots(lua_State* L); 

adicione uma nova linha com o seguinte:

static int32_t luaContainerGetWeight(lua_State* L);

No arquivo luascript.cpp, logo após a linha de número 2100, ou procure algo parecido com:

registerMethod("Container", "getSize", LuaScriptInterface::luaContainerGetSize);
registerMethod("Container", "getCapacity", LuaScriptInterface::luaContainerGetCapacity);
registerMethod("Container", "getEmptySlots", LuaScriptInterface::luaContainerGetEmptySlots);

adicione uma nova linha com o seguinte:

registerMethod("Container", "getWeight", LuaScriptInterface::luaContainerGetWeight);

Ainda em luascript.cpp, logo após a linha de número 6895, ou procure algo parecido com:

int32_t LuaScriptInterface::luaContainerGetEmptySlots(lua_State* L)

Logo após essa função (não a linha), insira o código abaixo:

int32_t LuaScriptInterface::luaContainerGetWeight(lua_State* L)
{
	// container:getWeight()
	Container* container = getUserdata<Container>(L, 1);
	if (!container) {
		lua_pushnil(L);
		return 1;
	}

	double weight = container->getWeight();
	lua_pushnumber(L, weight);

	return 1;
}

E qual o motivo de eu preferir ter este código no lado do servidor compilado? Desempenho. O peso do container é guardado em memória e acessado diretamente, não há qualquer conta com inúmeras multiplicações ou funções recursivas.

 

Mas caso esteja de mal humor e não queira compilar um servidor, terá que construir uma função da qual eu particularmente não gosto:

function getWeight(item)
	local totalWeight = 0;
	
	if item:isContainer() then
		local size = item:getSize()
		for i = 0, size - 1 do
			totalWeight = totalWeight + getWeight(item:getItem(i))
		end
	else
		totalWeight = totalWeight + item:getType():getWeight(item:getCount())
	end
	
	return totalWeight;
end

Coloque este código, essa função, antes da função onUse dentro de editor.lua

 

E troque aonde diz 

questReward:getWeight()

por

getWeight(questReward) 

Para terminar e fechar logo, não esqueça de adicionar o action id , eu normalmente uso 2000 pra esta actionId. É importante também lembrar que o UniqueId do baú deve ser ÚNICO em todo seu servidor, apenas dessa forma poderemos saber quais baús o jogador já abriu e conseguiu a recompensa.

 

Agora, vá aos testes meu querido! Salve todos os scripts, se tiver que compilar o servidor, vá e faça isso. Coloque um baú no seu mapa com um item apenas dentro, se tu colocares mais do que um item, apenas o primeiro será considerado, assim como pode ser visto na linha:

local questReward = container:getItem(0)

Dessa forma, caso seja necessário vários itens, lembre-se, uma bag, backpack, qualquer container com os itens dentro.

 

Agora seja criativo, crie corpos de dragões, humanos, esqueletos, coloque chaves dentro de caixas, livros importantes na biblioteca, entre várias oportunidades.

 

E então, o que acharam?

Participe da conversa

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

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.7k

Informação Importante

Confirmação de Termo