Ir para conteúdo
  • Cadastre-se

Posts Recomendados

Eae galera, estava vendo alguns tópicos aqui do fórum e vi muita gente procurando issoe eu também procurei e não achei, então resolvi procurar,e  achei na OTLand e estou trazendo para cá, EU APENAS TRADUZI, NÃO TENHO NENHUM CRÉDITO POR ISSO.
 
Se eu não poder fazer isso por favor me avisem aqui no tópico que eu retiro.
 
Créditos SOMENTE do: cbrm (OTLand)
 
Tested on TFS 1.2, 10.77/78
Based on
 http://www.tibia.com/news/?subtopic=newsarchive&id=2486
219xauf.png
 
20p537s.gifOque tem?
Spoiler

*Custom depot como reward chest para armazenar o loot que não foi pego dos bosses.
*Recompensa individual para cada jogador que da hit no boss.
*Chance de loot determinado por % do dano causado ao boss.
*O player pode "pegar" seu reward container diretamente do corpo do boss.
*Recompensas não reclamadas são enviadas para os reward chests dos players online e offline quando o corpo apodrecer.
*Loot que não for pego sera apagados após sete dias de ser armazenado
*Os items apenas podem ser retirados do reward chest, e não pode colocar items lá dentro.
*Reward chests dos players são armazenados codificados, serialized tables on database
*Limite de exhaustion para abrir o reward chest, a fim de evitar o spam em sql queries.

 

 

20p537s.gifTo-do

Spoiler

*Dano recebido pelo boss leva a uma queda de % do loot.
*Quantidade de healers dada a boss slayers leva a uma queda de % do loot.
*Abrir reward chest com um inner depot.
*Definir os corpos dos bosses como um depot para torná-los mais realistar.

 

 
20p537s.gifChangelog
Spoiler

(0.1) lançamento inicial
(0.2) base64 coding para recompensas serializados
(0.3) correção com bosses com corpses infinitos
(0.4) correçao para os bosses com nomes minúsculos

 

 

20p537s.gifComentários

Spoiler

Esse é um sistema que eu fui contratado a escrever um ano atrás, Agora foi lançado com o consentimento do cliente. É parecido com o Tibia's Boss Reward recurso que permite que todos os jogadores que participaram de matar o boss pegue parte do seu loot. Ele ainda está muito longe da criação original, mas pelo menos é algo que muitos donos de OTS desejam. Eu convido todos os desenvolvedores, programadores e criadores de scripts que desejam melhorar este código, para que isso possa ficar mais perto da perfeição.

 

 
 
20p537s.gifAgradecimentos especiais para
Spoiler

@Dalkon, por dicas em C++
@gugahoa, pelas funções do loot
@Colandus and @Cykotitan, pelo string.diff function
@Printer, por atualizar as exhaustion functions

 

20p537s.gifInstruções de instalação

Execute a query na database

 

CREATE TABLE IF NOT EXISTS `player_rewardchest` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `player_id` int(11) NOT NULL,
    `reward` text NOT NULL,
    `date` bigint(20) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  FOREIGN KEY (`player_id`) REFERENCES `players` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;

src/const.h
Abaixo...

ITEM_MARKET = 14405

...Adicione:

ITEM_REWARD_CHEST = 21584,
REWARD_CHEST_DEPOT = 99,

src/depotchest.h
Abaixo...

explicit DepotChest(uint16_t _type);

 

...Adicione:

uint32_t getDepotId() const {
    return depotId;
}

void setDepotId(uint32_t id) {
    depotId = id;
}

 

Abaixo...

uint32_t maxDepotItems;

...Adicione:

uint32_t depotId;

src/depotchest.cpp
Abaixo...

maxDepotItems = 1500;

...Adicione:

depotId = 0;

Acima...

return Container::queryAdd(index, thing, count, flags, actor);

...Adicione:

if (actor != nullptr && getDepotId() == REWARD_CHEST_DEPOT) {
    return RETURNVALUE_NOTPOSSIBLE;
}

src/depotlocker.h
Acima...

//cylinder implementations

...Adicione:

void setMaxLockerItems(uint32_t maxitems) {
    maxSize = maxitems;
}

src/luascript.h
Acima...

static int luaContainerGetSize(lua_State* L);

...Adicione:

static int luaContainerGetContentDescription(lua_State* L);

src/luascript.cpp
Acima...

registerMethod("Container", "getSize", LuaScriptInterface::luaContainerGetSize);

...Adicione:

registerMethod("Container", "getContentDescription", LuaScriptInterface::luaContainerGetContentDescription);

Acima...

int LuaScriptInterface::luaContainerGetSize(lua_State* L)

...Adicione:

int LuaScriptInterface::luaContainerGetContentDescription(lua_State* L)
{
    // container:getContentDescription()
    Container* container = getUserdata<Container>(L, 1);
    if (container) {
        std::ostringstream ss;
        ss << container->getContentDescription();
        pushString(L, ss.str());
    } else {
        lua_pushnil(L);
    }
    return 1;
}

src/actions.cpp
Troque:

//depot container
if (DepotLocker* depot = container->getDepotLocker()) {
    DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId());
    myDepotLocker->setParent(depot->getParent()->getTile());
    openContainer = myDepotLocker;
    player->setLastDepotId(depot->getDepotId());
} else {
    openContainer = container;
}

Por:

//reward chest and depot container
if (item->getID() == ITEM_REWARD_CHEST) {
    DepotLocker* myRewardChest = player->getRewardChest();
    myRewardChest->setParent(item->getTile());
    openContainer = myRewardChest;
    player->setLastDepotId(REWARD_CHEST_DEPOT);
} else if (DepotLocker* depot = container->getDepotLocker()) {
    DepotLocker* myDepotLocker = player->getDepotLocker(depot->getDepotId());
    myDepotLocker->setParent(depot->getParent()->getTile());
    openContainer = myDepotLocker;
    player->setLastDepotId(depot->getDepotId());
} else {
    openContainer = container;
}

src/player.h
Abaixo...

DepotLocker* getDepotLocker(uint32_t depotId);

...Adicione:

DepotLocker* getRewardChest();

src/player.cpp
Abaixo...

DepotChest* depotChest = new DepotChest(ITEM_DEPOT);

...Adicione:

depotChest->setDepotId(depotId);

Acima...

void Player::sendCancelMessage(ReturnValue message) const

...Adicione:

DepotLocker* Player::getRewardChest()
{
    auto it = depotLockerMap.find(REWARD_CHEST_DEPOT);
    if (it != depotLockerMap.end()) {
        inbox->setParent(it->second);
        return it->second;
    }

    DepotLocker* rewardChest = new DepotLocker(ITEM_LOCKER1);
    rewardChest->setDepotId(REWARD_CHEST_DEPOT);
    rewardChest->setMaxLockerItems(1);
    rewardChest->internalAddThing(getDepotChest(REWARD_CHEST_DEPOT, true));
    depotLockerMap[REWARD_CHEST_DEPOT] = rewardChest;
    return rewardChest;
}

On player.cpp, container.cpp, inbox.cpp

Change:

if (!item->isPickupable()) {

 Por:

if (item->getID() != 21518 && !item->isPickupable()) {

Adicione em @ data/actions/actions.xml

<!-- Reward Chest System -->
<action itemid="21584" script="reward_chest.lua"/>
<action actionid="21584" script="reward_chest.lua"/>

Crie @ data/actions/scripts/reward_chest.lua

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    --Reward Chest
    if item:getId() == 21584 then
        if player:getExhaustion(REWARD_CHEST.STORAGE) > 0 then
            return player:sendCancelMessage('You need to wait ' .. string.diff(player:getStorageValue(REWARD_CHEST.STORAGE)-os.time()) .. ' before using this chest again.')
        end
        player:updateRewardChest()
    --Boss Corpse
    elseif item:getActionId() == 21584 then
        local reward = REWARD_CHEST.LOOT[tonumber(item:getAttribute('text'))][player:getGuid()]
        if reward ~= nil then
            local rewardBag = Container(doCreateItemEx(REWARD_CHEST.CONTAINER, 1))
            addContainerItems(rewardBag, reward)
            if player:getCapacity() < rewardBag:getCapacity() then
                return player:sendCancelMessage(RETURNVALUE_NOTENOUGHCAPACITY)
            end
            if player:addItemEx(rewardBag, false) == RETURNVALUE_NOERROR then
                REWARD_CHEST.LOOT[tonumber(item:getAttribute('text'))][player:getGuid()] = nil
                player:sendCancelMessage('You have picked up a reward container.')
            else
                player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM)
                return true
            end
        end
    end
    return false
end

Adicione @ data/creaturescripts/creaturescripts.xml

<event type="kill" name="RewardChest" script="reward_chest.lua"/>

Registre em @data/creaturescripts/scripts/login.lua

player:registerEvent("RewardChest")

Adicione @ data/items/items.xml

<item id="21518" article="a" name="reward container">
    <attribute key="weight" value="1800" />
    <attribute key="containersize" value="24" />
    <attribute key="slotType" value="backpack" />
</item>
<item id="21584" article="a" name="reward chest">
    <attribute key="type" value="depot" />
    <attribute key="containerSize" value="1" />
    <attribute key="description" value="This chest contains your rewards earned in battles." />
</item>

Add @ data/lib/core/player.lua

function Player.setExhaustion(self, value, time)
    return self:setStorageValue(value, time + os.time())
end

function Player.getExhaustion(self, value)
    local storage = self:getStorageValue(value)
    if storage <= 0 then
        return 0
    end
    return storage - os.time()
end

Crie em @ data/creaturescripts/scripts/reward_chest.lua

(download anexado nesse post)

 

Download

 

RELEMBRANDO CRÉDITOS APENAS DO CBRM DA OTLAND

Editado por kk4444
*Adicionar Imagens e Link de Download (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
  • 1 month later...
  • 3 weeks later...
  • 2 weeks later...
  • 5 weeks later...

MMHUCMQ.png  Esta é uma mensagem automática, este tópico foi movido para a área correta.
  Regras do fórum: http://www.tibiaking.com/forum/topic/1281-regras-gerais/#comment-7680

Este tópico foi movido:
De: Scripting OTServ > OTServ > Geral
Para: Scripting OTServ > OTServ > Sistemas e MODs

Link para o post
Compartilhar em outros sites
  • 2 months later...
  • 5 months later...
  • 3 weeks later...
  • 1 year later...
Em 20/01/2016 em 08:18, robi123 disse:

em que lugar que fica o bau ?

 

Você vai no arquivo que ele deixo disponível para baixar, abra ele e la você vera os seguintes campos:

BOSSES = {"bibby bloodbath", "chizzoron the distorter", "ferumbras",
            "furyosa", "gaz'haragoth", "ghazbaran", "hirintror",
            "jaul", "mad mage", "mawhawk", "morgaroth", "obujos",
            "ocyakao", "omrafir", "orshabaal", "raging mage",
            "tanjis", "the mutated pumpkin", "the pale count",
            "the welter", "tyrn", "white pale", "zulazza the corruptor",
            "zushuka"},

    LOOT = {"Platinum Coins","Crystal Coins"},            
    DECAY = {},

 

Onde esta em Vermelho você configura quais os monstros que terão esse sistema ativado ao morrer!

Onde esta em Azul você configura qual o loot que ficara disponivel apos o monstro morrer! (Obs: Não sei se do modo que eu coloquei vai funcionar, pois ainda não testei mais fica ai a dica.)

 

Em 22/04/2016 em 20:27, YeiB disse:

é normal que o que deve ir na rewardchest vem no corpo da criatura?

a reward chest vai vazia

reward.jpg

 

 

Sim é normal pois como foi explicado no link que o cara deixou disponível, apos o monstro morrer você e quem te ajudou a mata-lo poderão abrir esse loot e cada um terá um loot referente a quanto você ajudou a matar o mesmo.

Para configurar o loot só fazer da forma que expliquei acima para o @robi123

 

@nortonsky faça da forma que eu expliquei acima ;)  Se ajudei REP+ !!!

Em 26/10/2016 em 18:51, Matheus Junior disse:

Boa noite galera, Alguem que fez este sistema, poderia me ajudar, em como fazer mais detalhado pois ja li e reli...
estou iniciando agora e isto e um objetivo que estou atras e so achei este... obg desde ja

 

Tente fazer da forma que eu expliquei ai acima, se funcionar avise aqui! 

Link para o post
Compartilhar em outros sites

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

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

  • Conteúdo Similar

    • Por Codex NG
      Sorry I don't speak spanish so you will have to bare with me.
       
      This is a new way for people to create npc's which use different types of currency, rather than a coming up with different items to trade with the npc or trying to edit the npc modules this method simplifies everything by providing the npc with a npc currency id.
       
      All this npc currency id is, is a storage value.. pretty simple eh?
      If the npc doesn't have a currency id then it will use the normal currency e.g. gold, plat, cc etc..
       
      I originally posted this on otland, but fuck them xD
       
      Using Lailene here you can see she has a currency attribute with id of 123456
      <?xml version="1.0" encoding="UTF-8"?> <npc name="Lailene" currency="123456" script="lailene.lua" walkinterval="2000" floorchange="0" speechbubble="2"> <health now="100" max="100"/> <look type="279" head="114" body="94" legs="113" feet="114" addons="0"/> </npc>  
      Now any player who has a storage value of 123456 can purchase things from her shop provided they have enough value stored within the storage, similar to having money in the bank.
      The money or in this case the storage value is added and removed from the player in real time.
       
      Lets get to the code
       
      game.cpp
      Find this
      bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) Replace the whole function with this.
      bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) { if (cylinder == nullptr) { return false; } if (money == 0) { return true; } uint32_t currencyId = 0; Player* player; if (Creature* creature = cylinder->getCreature()) { if (Player* p = creature->getPlayer()) { currencyId = p->getNpcCurrencyId(); player = p; } } if (!currencyId) { std::vector<Container*> containers; std::multimap<uint32_t, Item*> moneyMap; uint64_t moneyCount = 0; for (size_t i = cylinder->getFirstIndex(), j = cylinder->getLastIndex(); i < j; ++i) { Thing* thing = cylinder->getThing(i); if (!thing) { continue; } Item* item = thing->getItem(); if (!item) { continue; } Container* container = item->getContainer(); if (container) { containers.push_back(container); } else { const uint32_t worth = item->getWorth(); if (worth != 0) { moneyCount += worth; moneyMap.emplace(worth, item); } } } size_t i = 0; while (i < containers.size()) { Container* container = containers[i++]; for (Item* item : container->getItemList()) { Container* tmpContainer = item->getContainer(); if (tmpContainer) { containers.push_back(tmpContainer); } else { const uint32_t worth = item->getWorth(); if (worth != 0) { moneyCount += worth; moneyMap.emplace(worth, item); } } } } if (moneyCount < money) { return false; } for (const auto& moneyEntry : moneyMap) { Item* item = moneyEntry.second; if (moneyEntry.first < money) { internalRemoveItem(item); money -= moneyEntry.first; } else if (moneyEntry.first > money) { const uint32_t worth = moneyEntry.first / item->getItemCount(); const uint32_t removeCount = (money / worth) + 1; addMoney(cylinder, (worth * removeCount) - money, flags); internalRemoveItem(item, removeCount); break; } else { internalRemoveItem(item); break; } } } else { int32_t value; player->getStorageValue(currencyId, value); if (value < money) { return false; } player->addStorageValue(currencyId, value - money); } return true; } Next find this
      void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) Replace the whole function with this
      void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) { if (money == 0) { return; } if (Creature* creature = cylinder->getCreature()) { if (Player* player = creature->getPlayer()) { if(uint32_t currencyId = player->getNpcCurrencyId()){ int32_t value; player->getStorageValue(currencyId, value); player->addStorageValue(currencyId, value + money); return; } } } uint32_t crystalCoins = money / 10000; money -= crystalCoins * 10000; while (crystalCoins > 0) { const uint16_t count = std::min<uint32_t>(100, crystalCoins); Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, count); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT); } crystalCoins -= count; } uint16_t platinumCoins = money / 100; if (platinumCoins != 0) { Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT); } money -= platinumCoins * 100; } if (money != 0) { Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT); } } }  
      npc.cpp
      Look for this
      pugi::xml_attribute attr; if ((attr = npcNode.attribute("speed"))) { baseSpeed = pugi::cast<uint32_t>(attr.value()); } else { baseSpeed = 100; } Right underneath that you are going to place this.
      if ((attr = npcNode.attribute("currency"))) { currency = pugi::cast<uint32_t>(attr.value()); }  
      npc.h
      Look for this
      bool isPushable() const final { return walkTicks > 0; } Place this right underneath
      uint32_t getCurrencyId() const { return currency; } Look for this
      uint32_t walkTicks; Place this right underneath
      uint32_t currency;  
      player.cpp
      Find this
      void Player::openShopWindow(Npc* npc, const std::list<ShopInfo>& shop) Replace that function with this
      void Player::openShopWindow(Npc* npc, const std::list<ShopInfo>& shop) { shopItemList = shop; sendShop(npc); sendSaleItemList(npc); } Next find this
      bool Player::updateSaleShopList(const Item* item) Replace that function with this
      bool Player::updateSaleShopList(const Item* item) { uint16_t itemId = item->getID(); if (itemId != ITEM_GOLD_COIN && itemId != ITEM_PLATINUM_COIN && itemId != ITEM_CRYSTAL_COIN) { auto it = std::find_if(shopItemList.begin(), shopItemList.end(), [itemId](const ShopInfo& shopInfo) { return shopInfo.itemId == itemId && shopInfo.sellPrice != 0; }); if (it == shopItemList.end()) { const Container* container = item->getContainer(); if (!container) { return false; } const auto& items = container->getItemList(); return std::any_of(items.begin(), items.end(), [this](const Item* containerItem) { return updateSaleShopList(containerItem); }); } } if (client) { client->sendSaleItemList(shopOwner, shopItemList); } return true; } Next you are going to look for
      uint64_t Player::getMoney() const Now right underneath that function you are going to place these.
      uint64_t Player::getMoney(Npc* npc) const { uint64_t cash; setNpcCurrencyId(npc); uint32_t currencyId = getNpcCurrencyId(); if (currencyId) { int32_t value; getStorageValue(currencyId, value); cash = (uint64_t)value; } else { cash = getMoney(); } return cash; } void Player::setNpcCurrencyId(Npc* npc) const{ currencyId = npc->getCurrencyId(); } uint32_t Player::getNpcCurrencyId() const { return currencyId; }  
      player.h
      Look for this
      uint64_t getMoney() const; Place this right underneath
      uint64_t getMoney(Npc*) const; void setNpcCurrencyId(Npc*) const; uint32_t getNpcCurrencyId() const; Find this
      void sendShop(Npc* npc) const { if (client) { client->sendShop(npc, shopItemList); } } Place this right underneath
      void sendSaleItemList(Npc* npc) const { if (client) { client->sendSaleItemList(npc, shopItemList); } } Find this
      uint32_t manaMax; Place this right underneath
      mutable uint32_t currencyId;  
      protocolgame.cpp
      Now find this function
      void ProtocolGame::sendSaleItemList(const std::list<ShopInfo>& shop) Place this right underneath
      void ProtocolGame::sendSaleItemList(Npc* npc, const std::list<ShopInfo>& shop) { NetworkMessage msg; msg.addByte(0x7B); msg.add<uint64_t>(player->getMoney(npc)); std::map<uint16_t, uint32_t> saleMap; if (shop.size() <= 5) { // For very small shops it's not worth it to create the complete map for (const ShopInfo& shopInfo : shop) { if (shopInfo.sellPrice == 0) { continue; } int8_t subtype = -1; const ItemType& itemType = Item::items[shopInfo.itemId]; if (itemType.hasSubType() && !itemType.stackable) { subtype = (shopInfo.subType == 0 ? -1 : shopInfo.subType); } uint32_t count = player->getItemTypeCount(shopInfo.itemId, subtype); if (count > 0) { saleMap[shopInfo.itemId] = count; } } } else { // Large shop, it's better to get a cached map of all item counts and use it // We need a temporary map since the finished map should only contain items // available in the shop std::map<uint32_t, uint32_t> tempSaleMap; player->getAllItemTypeCount(tempSaleMap); // We must still check manually for the special items that require subtype matches // (That is, fluids such as potions etc., actually these items are very few since // health potions now use their own ID) for (const ShopInfo& shopInfo : shop) { if (shopInfo.sellPrice == 0) { continue; } int8_t subtype = -1; const ItemType& itemType = Item::items[shopInfo.itemId]; if (itemType.hasSubType() && !itemType.stackable) { subtype = (shopInfo.subType == 0 ? -1 : shopInfo.subType); } if (subtype != -1) { uint32_t count; if (!itemType.isFluidContainer() && !itemType.isSplash()) { count = player->getItemTypeCount(shopInfo.itemId, subtype); // This shop item requires extra checks } else { count = subtype; } if (count > 0) { saleMap[shopInfo.itemId] = count; } } else { std::map<uint32_t, uint32_t>::const_iterator findIt = tempSaleMap.find(shopInfo.itemId); if (findIt != tempSaleMap.end() && findIt->second > 0) { saleMap[shopInfo.itemId] = findIt->second; } } } } uint8_t itemsToSend = std::min<size_t>(saleMap.size(), std::numeric_limits<uint8_t>::max()); msg.addByte(itemsToSend); uint8_t i = 0; for (std::map<uint16_t, uint32_t>::const_iterator it = saleMap.begin(); i < itemsToSend; ++it, ++i) { msg.addItemId(it->first); msg.addByte(std::min<uint32_t>(it->second, std::numeric_limits<uint8_t>::max())); } writeToOutputBuffer(msg); }  
      protocolgame.h
      Find this
      void sendSaleItemList(const std::list<ShopInfo>& shop); Place this right underneath
      void sendSaleItemList(Npc* npc, const std::list<ShopInfo>& shop);  
      luascript.cpp
      Find
      int LuaScriptInterface::luaPlayerAddMoney(lua_State* L) Replace that whole function with this
      int LuaScriptInterface::luaPlayerAddMoney(lua_State* L) { // player:addMoney(money[, currencyId]) uint64_t money = getNumber<uint64_t>(L, 2); uint32_t currencyId = getNumber<uint32_t>(L, 3); Player* player = getUserdata<Player>(L, 1); if (player) { if (currencyId) { int32_t value; player->getStorageValue(currencyId, value); player->addStorageValue(currencyId, value + money); } else { g_game.addMoney(player, money); } pushBoolean(L, true); } else { lua_pushnil(L); } return 1; } Next find this function which should be right below it.
      int LuaScriptInterface::luaPlayerRemoveMoney(lua_State* L) Replace that whole function with this
      int LuaScriptInterface::luaPlayerRemoveMoney(lua_State* L) { // player:removeMoney(money[, currencyId]) Player* player = getUserdata<Player>(L, 1); if (player) { uint64_t money = getNumber<uint64_t>(L, 2); uint32_t currencyId = getNumber<uint32_t>(L, 3); if (currencyId) { int32_t value; player->getStorageValue(currencyId, value); if (value < money) { pushBoolean(L, false); return 1; } player->addStorageValue(currencyId, value - money); pushBoolean(L, true); } else { pushBoolean(L, g_game.removeMoney(player, money)); } } else { lua_pushnil(L); } return 1; }  
    • Por DeCarvalho
      Bem procurei aqui na comunidade um VIP System mais informativo e nada, além de ter tido problema com os que estão aqui e acabei achando em outro lugar um que funcionou perfeitamente para mim.
       
      Usando tfs disponibilizado neste tópico http://www.tibiaking.com/forum/topic/53099-1078-tfs-12-cast-system-novos-outfits-mounts/
       
      Só estou trazendo o conteúdo e por não conhecer bem não posso dar suporte mas do jeito que está é só 'instalar' e vai funcionar.
       
      Creditos.: Summ
       
      Sistema Vip
       



       
      Talkaction !checkvip para todos os players
       



       
      Talkaction /vip para membros da staff
      - /vip adddays, NomedoPlayer, 5 --> Adiciona 5 dias vip para o Player. - /vip removedays, NomedoPlayer, 5 --> Remove 5 dias vip do Player. - /vip remove, PlayerName --> Remove todos os dias vip do Player. - /vip check, NomedoPlayer --> Checa quantos dias vip o Player tem. - /vip addinfinite, NomedoPlayer --> Adiciona tempo vip infinito para o Player.


       
      Tiles VIP



       
      Portas VIP / Actions



       
      Items que adicionam dias VIP
      ItemId 10135 adiciona 10 dias vip. ItemId 10134 adiciona 30 dias vip. ItemId 10133 adiciona 90 dias vip.


       
      Imagens
       
      Comando !checkvip mas sem ter vip



       
      Comando /vip adddays, dracoknight, 5



       
      Comando !checkvip após adicionar 5 dias



       
      Comando /vip addinfinite, dracoknight



       
      Comando !checkvip após usar infinite 



       
      Comando /vip remove, dracoknight



    • Por Diego767
      Boa tarde, nao sei se estou no lugar certo para fazer a pergunta, mas vamos tentar...
      Meu ot esta rodando bem, porem os itens e monstros mais novos nao tem (cobra sword, terra helmet, e nem os monstros que dropam isso)
      O que eu poderia fazer para add eles, os itens e os monstros? 
    • Por .Smile
      Olá a todos, atualmente estou aprendendo programação e desenvolvendo um Servidor, uma das coisas chatas a se fazer era ficar alternando entre um Personagem PLAYER e outro GOD para testar algumas coisas, com esses 2 scripts eu resolvi esse problema.

      É um script simples que eu pretendo futuramente melhorá-lo.

      What does the command do?
      /adm - Transforma seu personagem em GOD e kika ele
      /player - Transforma seu personagem em PLAYER e kika ele
       
      LEMBRANDO QUE: Não é qualquer que consegue usar esse comando, você precisa ter dado a sua conta o acesso de god, assim podendo ter esse comando num Servidor Online com outros jogadores sem que os mesmos possam usar.

      \data\talkactions
      talkactions.xml
      Code: <talkaction words="/player" script="player.lua" /> <talkaction words="/adm" script="adm.lua" /> \data\talkactions\scripts 
      adm.lua
      Code: function onSay(player, words, param) if player:getAccountType() < ACCOUNT_TYPE_GOD then return false end local position = player:getPosition() player:setGroup(Group(3)) position:sendMagicEffect(14) player:remove() return false end \data\talkactions\scripts
      player.lua
      function onSay(player, words, param) if player:getAccountType() < ACCOUNT_TYPE_GOD then return false end local position = player:getPosition() player:setGroup(Group(1)) position:sendMagicEffect(13) player:remove() return false end  
    • Por EddyHavoc
      Resumo
      A maneira atual para implementar Modal Window é um pouco complicada. Atualmente precisamos cria-la em algum lugar, registrar o evento, adicionar os botões em uma ordem específica, definir o ID da janela, dos botões e da escolha. Isso não é o ideal, então esta biblioteca foi criada pelo Non Sequitur para ajudar nisso. E eu estou trazendo para a OtServBrasil.

      Exemplo/ Tutorial Usando Modal Window
       
      Instalando
      Adicionar em data/lib/lib.lua dofile('data/lib/modalwindow.lua') Crie o arquivo modalwindow.lua com o seguinte conteúdo em data/lib if not modalWindows then modalWindows = { modalWindowConstructor = ModalWindow, nextFreeId = 500, windows = {} } end local MT = {} MT.__index = MT function ModalWindow(...) local args = {...} if type(args[1]) == 'table' then local self = setmetatable(args[1], MT) local id = modalWindows.nextFreeId self.id = id self.buttons = {} self.choices = {} self.players = {} self.created = false modalWindows.nextFreeId = id + 1 table.insert(modalWindows.windows, self) return self end return modalWindows.modalWindowConstructor(...) end function MT:setDefaultCallback(callback) self.defaultCallback = callback end function MT:addButton(text, callback) local button = {text = tostring(text), callback = callback} table.insert(self.buttons, button) return button end function MT:addButtons(...) for _, text in ipairs({...}) do table.insert(self.buttons, {text = tostring(text)}) end end function MT:addChoice(text) local choice = {text = tostring(text)} table.insert(self.choices, choice) return choice end function MT:addChoices(...) for _, text in ipairs({...}) do table.insert(self.choices, {text = tostring(text)}) end end function MT:setDefaultEnterButton(text) self.defaultEnterButton = text end function MT:setDefaultEscapeButton(text) self.defaultEscapeButton = text end function MT:setTitle(title) self.title = tostring(title) end function MT:setMessage(message) self.message = tostring(message) end local buttonOrder = { [4] = {3, 4, 2, 1}, [3] = {2, 3, 1}, [2] = {1, 2}, [1] = {1} } function MT:create() local modalWindow = modalWindows.modalWindowConstructor(self.id, self.title, self.message) local order = buttonOrder[math.min(#self.buttons, 4)] if order then for _, i in ipairs(order) do local button = self.buttons[i] modalWindow:addButton(i, button.text) button.id = i if button.text == self.defaultEnterButton then modalWindow:setDefaultEnterButton(i) elseif button.text == self.defaultEscapeButton then modalWindow:setDefaultEscapeButton(i) end end end for _, choice in ipairs(self.choices) do modalWindow:addChoice(_, choice.text) choice.id = _ end self.modalWindow = modalWindow end function MT:sendToPlayer(player) if not self.modalWindow then self:create() end player:registerEvent('ModalWindowHelper') self.players[player:getId()] = true return self.modalWindow:sendToPlayer(player) end Adicionar em data/creaturescripts/craturescripts.xml <event type="modalwindow" name="ModalWindowHelper" script="modalwindowhelper.lua" /> Crie o arquivo modalwindowhelper.lua com o seguinte conteúdo em data/creaturescripts/scripts/ function onModalWindow(player, modalWindowId, buttonId, choiceId) local modalWindow for _, window in ipairs(modalWindows.windows) do if window.id == modalWindowId then modalWindow = window break end end if not modalWindow then return true end local playerId = player:getId() if not modalWindow.players[playerId] then return true end modalWindow.players[playerId] = nil local choice = modalWindow.choices[choiceId] for _, button in ipairs(modalWindow.buttons) do if button.id == buttonId then local callback = button.callback or modalWindow.defaultCallback if callback then callback(button, choice) break end end end return true end  
      Pronto!
       
      Espero que gostem. Posteriormente irei postar um tutorial de como usar/ aplicar e alguns scripts utilizando a Biblioteca.
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo