Ir para conteúdo
  • 0

Lua:dostarttrade(Player, Tradepartner, Transferitem)


bepokemon

Pergunta

Seria bem legal se alguem tomasse a iniciativa de postar o code da funcão doStartTrade(), que já existe em alguns OTs porém nao está aberta para todos. Em geral pode-se usar como base a funcão interna utilizada no comando !sellhouse, que utiliza deste mecanismo.

Aqui está os fragmentos do !sellhouse:

 

 

commands.cpp:

bool Commands::sellHouse(Creature* creature, const std::string& cmd, const std::string& param)
{
Player* player = creature->getPlayer();
if(player){
	House* house = Houses::getInstance().getHouseByPlayerId(player->getGUID());
	if(!house){
		player->sendCancel("You do not own any house.");
		return false;
	}

	Player* tradePartner = game->getPlayerByName(param);
	if(!(tradePartner && tradePartner != player)){
		player->sendCancel("Trade player not found.");
		return false;
	}

	if(tradePartner->getPlayerInfo(PLAYERINFO_LEVEL) < 1){
		player->sendCancel("Trade player level is too low.");
		return false;
	}

	if(Houses::getInstance().getHouseByPlayerId(tradePartner->getGUID())){
		player->sendCancel("Trade player already owns a house.");
		return false;
	}

	if(!Position::areInRange<2,2,0>(tradePartner->getPosition(), player->getPosition())){
		player->sendCancel("Trade player is too far away.");
		return false;
	}

	Item* transferItem = house->getTransferItem();
	if(!transferItem){
		player->sendCancel("You can not trade this house.");
		return false;
	}

	transferItem->getParent()->setParent(player);
	if(game->internalStartTrade(player, tradePartner, transferItem)){
		return true;
	}
	else{
		house->resetTransferItem();
	}
}
return false;
}

talkactions.cpp:

bool TalkAction::houseSell(Creature* creature, const std::string& cmd, const std::string& param)
{
Player* player = creature->getPlayer();
if(!player || !g_config.getBool(ConfigManager::HOUSE_BUY_AND_SELL))
	return false;

House* house = Houses::getInstance()->getHouseByPlayerId(player->getGUID());
if(!house && (!player->getGuildId() || !(house = Houses::getInstance()->getHouseByGuildId(player->getGuildId()))))
{
	player->sendCancel("You do not rent any flat.");
	g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
	return false;
}

if(house->isGuild() && player->getGuildLevel() != GUILDLEVEL_LEADER)
{
	player->sendCancel("You have to be at least a guild leader to sell this hall.");
	g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
	return false;
}

Player* tradePartner = NULL;
ReturnValue ret = g_game.getPlayerByNameWildcard(param, tradePartner);
if(ret != RET_NOERROR)
{
	player->sendCancelMessage(ret);
	g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
	return false;
}

if(tradePartner == player)
{
	player->sendCancel("You cannot trade with yourself.");
	g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
	return false;
}

if(!house->isGuild())
{
	if(Houses::getInstance()->getHouseByPlayerId(tradePartner->getGUID()))
	{
		player->sendCancel("Trade player already rents another house.");
		g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
		return false;
	}

	uint16_t housesPerAccount = g_config.getNumber(ConfigManager::HOUSES_PER_ACCOUNT);
	if(housesPerAccount > 0 && Houses::getInstance()->getHousesCount(tradePartner->getAccount()) >= housesPerAccount)
	{
		char buffer[100];
		sprintf(buffer, "Trade player has reached limit of %d house%s per account.", housesPerAccount, (housesPerAccount != 1 ? "s" : ""));

		player->sendCancel(buffer);
		g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
		return false;
	}

	if(!tradePartner->isPremium() && !g_config.getBool(ConfigManager::HOUSE_NEED_PREMIUM))
	{
		player->sendCancel("Trade player does not have a premium account.");
		g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
		return false;
	}

	uint32_t levelToBuyHouse = g_config.getNumber(ConfigManager::LEVEL_TO_BUY_HOUSE);
	if(tradePartner->getLevel() < levelToBuyHouse)
	{
		char buffer[100];
		sprintf(buffer, "Trade player has to be at least Level %d to buy house.", levelToBuyHouse);

		player->sendCancel(buffer);
		g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
		return false;
	}
}
else
{
	if(!tradePartner->getGuildId() || tradePartner->getGuildLevel() != GUILDLEVEL_LEADER)
	{
		player->sendCancel("Trade player has to be at least a guild leader to buy a hall.");
		g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
		return false;
	}

	if(Houses::getInstance()->getHouseByGuildId(tradePartner->getGuildId()))
	{
		player->sendCancel("Trade player's guild already rents another hall.");
		g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
		return false;
	}
}

if(!Position::areInRange<3,3,0>(tradePartner->getPosition(), player->getPosition()))
{
	player->sendCancel("Trade player is too far away.");
	g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
	return false;
}

if(!Houses::getInstance()->payRent(player, house, 0))
{
	player->sendCancel("You have to pay a pre-rent first.");
	g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
	return false;
}

Item* transferItem = TransferItem::createTransferItem(house);
player->transferContainer.__addThing(NULL, transferItem);

player->transferContainer.setParent(player);
if(!g_game.internalStartTrade(player, tradePartner, transferItem))
	transferItem->onTradeEvent(ON_TRADE_CANCEL, player, NULL);

g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE);
return false;
}

 

 

 

OBS: Seria legal algo que funcionasse assim:

local item = doCreateItemEx(itemid)
doItemSetAttribute(item.uid, attr, value)
local pid = getPlayerByName(name)
if not pid then return true end
doStartTrade(cid, pid, item)

 

A comunidade inteira agradece desde já.

Editado por Byerne
Link para o comentário
Compartilhar em outros sites

10 respostass a esta questão

Posts Recomendados

  • 0

To meio lerdo mas você poderia me dizer o que essa função iria fazer (cada parâmetro)?

Um exemplo dum script iria ajudar tbm e.e

 

Iniciaria uma troca em o param #1 e o param #2.

(Mandaria a mensagem de trade para o segundo "Param#1 wants to trade with you...")

 

Assim como no !sellhouse atual o player 2 então poderia trocar qualquer item ou container pelo item trocado, seria util apenas se fosse possível setar um aid/uid para este item, assim complementando com a funcão onTradeAccept e onTradeRequest para criar sistemas úteis que não existem para o público atualmente.

Link para o comentário
Compartilhar em outros sites

  • 0

Vou tentar fazer ela aqui, apesar de que to bem enferrujado em lua e c++ '-'

 

@offtopic

 

Você acha que seria possível fazer um war system PURO LUA ? dai em c++ teria apenas as funções de emblemas...

O servidor que eu uso é quase impossivel de adicionar o war system do elf (TFS 0.2.7), dai eu queria fazer um sisteminha em lua ^^

 

Bom, impossivel eu não sei, pois eu consegui adicionar o sistema dele inteiro no TFS 0.3.6pl1 =D

Editado por fireelement
Link para o comentário
Compartilhar em outros sites

  • 0

Ah ja consegui resolver aqui, o Talaturen lançou um war system que resolveu meu problema... no 8.54 até da para colocar mas teria que modificar o client.

Eu queria colocar no 8.60 mesmo mas era no TFS 0.2.

Link para o comentário
Compartilhar em outros sites

  • 0

  • Qual a versão usada? Se eu fizer baseado no repositório SVN vai funcionar para você?
  • A função precisa verificar se o item pode ser "tradeable"?
  • Os players precisam estar no range/distância normal do trade pro trade dar certo?
  • Se tiver limite de distância normal do trade, precisa dar autoWalk?
  • Precisa verificar se os items não estão recebendo trade? *meio óbvio, mas perguntando*
  • Precisa verificar o limite max de itens que podem ser trocados por vez?
  • O item precisa estar no inventário do player?

 

[...] seria util apenas se fosse possível setar um aid/uid para este item [...]

Estou longe dos otserv há um tempo, mas aparentemente não é possível fazer trocas de item que possui um uid...

Bom, ao menos com o trade do SVN revisão 6261, em game.cpp, função playerRequestTrade, linhas 2732 a 2735:

if(!tradeItem || tradeItem->getClientID() != spriteId || !tradeItem->isPickupable() || tradeItem->getUniqueId() != 0)

{

player->sendCancelMessage(RET_NOTPOSSIBLE);

return false;

}

 

Abraços

~Niohundranittionio

Editado por niohundranittionio
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novos posts.
×
×
  • Criar Novo...