Jump to content
×
×
  • Create New...

[TFS 1.2] Flying Mount System


Recommended Posts

Para dar uma força na sessão de programação vo lotar de código isso aqui, bom la vamos nós hoje é um fly system para tfs 1.2, sem gambiarras.

 

Vá no arquivo creaturevent.cpp procure por:

} else if (tmpStr == "extendedopcode") {
 		type = CREATURE_EVENT_EXTENDED_OPCODE;

Coloque isso abaixo:

} else if (tmpStr == "move") {
		type = CREATURE_EVENT_MOVE;

Depois procure por:

case CREATURE_EVENT_EXTENDED_OPCODE:
 			return "onExtendedOpcode";

Coloque isso abaixo:

case CREATURE_EVENT_MOVE:
			return "onMove";

Depois procure por:

void CreatureEvent::executeExtendedOpcode(Player* player, uint8_t opcode, const std::string& buffer)

No Final dessa função coloque isso abaixo:

bool CreatureEvent::executeOnMove(Player* player, const Position& fromPosition, const Position& toPosition)
{
    //onMove(player, frompos, topos)
	if (!scriptInterface->reserveScriptEnv()) {
		std::cout << "[Error - CreatureEvent::executeOnMove] Call stack overflow" << std::endl;
		return false;
	}

	ScriptEnvironment* env = scriptInterface->getScriptEnv();
	env->setScriptId(scriptId, scriptInterface);

	lua_State* L = scriptInterface->getLuaState();
	scriptInterface->pushFunction(scriptId);

	LuaScriptInterface::pushUserdata(L, player);
	LuaScriptInterface::setMetatable(L, -1, "Player");
	LuaScriptInterface::pushPosition(L, fromPosition);
	LuaScriptInterface::pushPosition(L, toPosition);

	return scriptInterface->callFunction(3);
}

Vá no arquivo creatureevent.h procure por:

CREATURE_EVENT_EXTENDED_OPCODE, // otclient additional network opcodes

Coloque isso abaixo:

CREATURE_EVENT_MOVE,

Ainda no arquivo creatureevent.h procure por:

void executeExtendedOpcode(Player* player, uint8_t opcode, const std::string& buffer);

Coloque isso abaixo:

bool executeOnMove(Player* player, const Position& fromPosition, const Position& toPosition);

Vá no arquivo events.cpp procure por:

playerOnGainSkillTries = -1;

Coloque isso abaixo:

playerOnToggleMount = -1;

Ainda no arquivo events.cpp procure por:

} else if (methodName == "onGainSkillTries") {
 				playerOnGainSkillTries = event;

Coloque isso abaixo:

} else if (methodName == "onToggleMount") {
				playerOnToggleMount = event;

Ainda no arquivo events.cpp procure por:

void Events::eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_t& tries)

No Final dessa função coloque isso abaixo:

bool Events::eventPlayerOnToggleMount(Player* player, uint8_t mountid, bool mounting)
{
	// Player:onToggleMount(mountid, mounting)
	if (playerOnToggleMount == -1) {
		return true;
	}

	if (!scriptInterface.reserveScriptEnv()) {
		std::cout << "[Error - Events::eventPlayerOnToggleMount] Call stack overflow" << std::endl;
		return false;
	}

	ScriptEnvironment* env = scriptInterface.getScriptEnv();
	env->setScriptId(playerOnToggleMount, &scriptInterface);

	lua_State* L = scriptInterface.getLuaState();
	scriptInterface.pushFunction(playerOnToggleMount);

	LuaScriptInterface::pushUserdata<Player>(L, player);
	LuaScriptInterface::setMetatable(L, -1, "Player");
	lua_pushnumber(L, mountid);
	LuaScriptInterface::pushBoolean(L, mounting);

	return scriptInterface.callFunction(3);
}

Vá no arquivo events.h procure por:

void eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_t& tries);

Coloque isso abaixo:

bool eventPlayerOnToggleMount(Player* player, uint8_t mountid, bool mounting);

Ainda no arquivo events.h procure por:

int32_t playerOnGainSkillTries;

Coloque isso abaixo:

int32_t playerOnToggleMount;

Vá no arquivo game.cpp procure por:

player->resetIdleTime();

Embaixo de uma quebra de linha e coloque isso abaixo:

const Position& currentPos = player->getPosition();
	Position destPos = getNextPosition(direction, currentPos);
	const CreatureEventList& moveEvents = player->getCreatureEvents(CREATURE_EVENT_MOVE);
	for (CreatureEvent* moveEvent : moveEvents) {
		if (!moveEvent->executeOnMove(player, currentPos, destPos)) {
			player->sendCancelWalk();
			return;
		}
	}

Vá no arquivo player.cpp procure por:

bool Player::toggleMount(bool mount)
 			return false;
 		}

Coloque isso abaixo:

if (!g_events->eventPlayerOnToggleMount(this, currentMountId, mount)) {
			return false;
		}

Ainda no arquivo player.cpp procure por:

bool Player::toggleMount(bool mount)
 			return false;
 		}

Coloque isso abaixo:

uint8_t currentMountId = getCurrentMount();
		if (!g_events->eventPlayerOnToggleMount(this, currentMountId, mount)) {
			return false;
		}

Bom aqui acabamos o sistema na source vamos para á parte de programação lua no datapack.

 

Instale essa Lib no seu servidor:

FlyingMounts = {65} -- Mounts in this table are going to force fly when mounting/dismounting.
PvpRestrictions = "high" -- You can set 3 different types of pvp restrictions
-- None:
---- Nothing will be done, the players can attack each other anytime while flying.
 
-- Medium:
-- The players can attack each other while flying, but they cant start flying if they already have pz and they will have a huge interval (configurable) to go up and down. The interval is only applied to the people with PZ locked.
 
-- High:
---- Players can't attack each other while flying at all and they cant start flying as in medium. This could be abused to escape from pks as you can't be attacked by them while flying.
 
ChangeFloorInterval = 2 -- seconds
ChangeFloorIntervalPZ = 10 -- seconds, only in medium restriction.
 
function Position:createFlyFloor()
    local toTile = Tile(self)
    if not toTile or not toTile:getItems() or not toTile:getGround() then
        doAreaCombatHealth(0, 0, self, 0, 0, 0, CONST_ME_NONE)
        Game.createItem(460, 1, self)
    end
end
 
function Tile:hasValidGround()
    local ground = self:getGround()
    local nilitem = self:getItemById(460)
    if ground and not nilitem  then
        return true
    end
 
    return false
end
 
function Player:activateFly()
    self:setStorageValue(16400, 1)
    self:registerEvent("FlyEvent")
    return true
end
 
function Player:deactivateFly()
    local can, floor = self:canDeactivateFly()
    local pos = self:getPosition()
    if can then
        local curtile = Tile(pos)
        local itemfloor = curtile:getItemById(460)
        if itemfloor then
            itemfloor:remove()
        end
        self:setStorageValue(16400, -1)
        self:unregisterEvent("FlyEvent")
        if pos.z ~= floor then
            pos.z = floor
            self:teleportTo(pos)
            pos:sendMagicEffect(CONST_ME_TELEPORT)
        end
    end
 
    return can
end
 
function Player:isFlying()
    return self:getStorageValue(16400) == 1
end
 
function Player:canDeactivateFly()
    local pos = self:getPosition()
    for z = pos.z, 15 do
        local tmp = Tile(pos.x, pos.y, z)
        if tmp and tmp:hasValidGround() then
            if self:canFlyDown(z) then
                return true, z
            else
                return false
            end
        end
    end
 
    return false
end
 
function Player:canFlyUp()
    local pos = self:getPosition()
    local tmp = Tile(pos.x, pos.y, pos.z-1)
    if tmp and tmp:hasValidGround() then
        return false
    end
 
    return true
end
 
function Player:canFlyDown(floor)
    local pos = self:getPosition()
    local tmp = Tile(pos)
    if floor and floor == pos.z then
        return true
    end
 
    if tmp:hasValidGround() then
        return false
    end
 
    tmp = Tile(pos.x, pos.y, floor or pos.z+1)
    if tmp and (tmp:getHouse() or tmp:hasFlag(TILESTATE_PROTECTIONZONE) or tmp:hasFlag(TILESTATE_FLOORCHANGE) or tmp:hasFlag(TILESTATE_BLOCKSOLID)) then
        return false
    end
 
    return true
end
 
function Player:flyUp()
    if self:isFlying() then
        if self:canFlyUp() then
            local pos = self:getPosition()
            local tile = Tile(pos)
            local itemfloor = tile:getItemById(460)
            if itemfloor then
                itemfloor:remove()
            end
 
            pos.z = pos.z-1
            pos:createFlyFloor()
            self:teleportTo(pos)
            pos:sendMagicEffect(CONST_ME_TELEPORT)
 
            return true
        end
 
        return false
    else
        self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You are not flying.")
    end
end
 
function Player:flyDown()
    if self:isFlying() then
        if self:canFlyDown() then
            local pos = self:getPosition()
            local tile = Tile(pos)
            local itemfloor = tile:getItemById(460)
            if itemfloor then
                itemfloor:remove()
            end
 
            pos.z = pos.z+1
            pos:createFlyFloor()
            self:teleportTo(pos)
            pos:sendMagicEffect(CONST_ME_TELEPORT)
            return true
        end
 
        return false
    else
        self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You are not flying.")
    end
end

Agora em creaturescripts instale:

--     <event type="move" name="FlyEvent" script="flyevent.lua" />
function onMove(player, fromPosition, toPosition)
    if PvpRestrictions:lower() == "high" and player:isPzLocked() then
        return true
    end
 
    if player:isFlying() then
        local fromTile = Tile(fromPosition)
        local fromItem = fromTile:getItemById(460)
        if fromItem then
            fromItem:remove()
        end
        toPosition:createFlyFloor()
    end
    return true
end

Agora em talkactions instale:

--    <talkaction words="!down" script="fly.lua" />
--    <talkaction words="!up" script="fly.lua" />
 
local exhauststorage = 16500
function onSay(player, words)
    if not player:isFlying() then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You are not flying.")
        return false
    end
 
    if player:isPzLocked() and PvpRestrictions:lower() == "high" then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You cannot use this command in fight.")
        return false
    end
 
    local last = player:getStorageValue(exhauststorage)
    local interval = ChangeFloorInterval
    if PvpRestrictions:lower() == "medium" and player:isPzLocked() then
        interval = ChangeFloorIntervalPZ
    end
 
    if last+interval > os.time() then
        player:sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED)
        return false
    end
 
    if words == "!up" then
        local ret = player:flyUp()
        if ret == false then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You cannot fly up.")
        else
            player:setStorageValue(exhauststorage, os.time())
        end
    elseif words == "!down" then
        local ret = player:flyDown()
        if ret == false then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You cannot fly down.")
        else
            player:setStorageValue(exhauststorage, os.time())
        end
    end
    return false
end

Agora em data/events/events.xml troque:

 <event class="Creature" method="onTargetCombat" enabled="0" />

Por:

 <event class="Player" method="onToggleMount" enabled="1" />

Agora em events/scripts/creature.lua troque á função onTargetCombat por:

function Creature:onTargetCombat(target)
    if self and target then
        if PvpRestrictions:lower() == "high" then
            if self:isPlayer() and self:isFlying() then
                local pos = self:getPosition()
                local tile = Tile(pos)
                if tile:getItemById(460) then
                    return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER
                end
            end
 
            if target:isPlayer() and target:isFlying() then
                local pos = target:getPosition()
                local tile = Tile(pos)
                if tile:getItemById(460) then
                    return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER
                end
            end
        end
    end
    return true
end

Agora em events/scripts/player.lua adicione á função:

function Player:onToggleMount(mountid, mount)
    if mount then
        if isInArray(FlyingMounts, mountid) then
            if isInArray({"high", "medium"}, PvpRestrictions:lower()) and self:isPzLocked() then
                self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You cannot start flying now.")
                return false
            end
            self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You are now flying.")
            self:activateFly()
        end
    elseif self:isFlying() then
        local ret = self:deactivateFly()
        if ret then
            self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You are no longer flying.")
        else
            self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You can't deactivate fly now.")
        end
        return ret
    end
    return true
end

Agora coloque em logout.lua encima da função onLogout(player) :

if player:isFlying() then
	player:sendCancelMessage("You cannot logout while flying.")
	return false
end

Pronto só Compilar á source e utilizar o sistema.

 

Créditos

DarkWore (5% Por trazer ao Xtibia)

Mkalo (95% Por Desenvolver)

Edited by DarkWore
Link to post
Share on other sites
36 minutos atrás, nociam disse:

Eu utilizei por um tempinho no meu servidor ela, mais ai apareceu algo melhor e mudei mas muito bom trazer pro fórum e em português.

Obrigado, Abração.

Link to post
Share on other sites
  • 1 month later...

Alguém pode ajudar a criar tile 460 em uma area ao redor do player 4x4, porque não trava no momento de andar com o player, alguém pode ajudar? Acredito que seja na função abaixo.

 

function Position:createFlyFloor()    local toTile = Tile(self)    if not toTile or not toTile:getItems() or not toTile:getGround() then        doAreaCombatHealth(0, 0, self, 0, 0, 0, CONST_ME_NONE)        Game.createItem(460, 1, self)    endend
Link to post
Share on other sites
1 hora atrás, deglorio disse:

Alguém pode ajudar a criar tile 460 em uma area ao redor do player 4x4, porque não trava no momento de andar com o player, alguém pode ajudar? Acredito que seja na função abaixo.

 

function Position:createFlyFloor()    local toTile = Tile(self)    if not toTile or not toTile:getItems() or not toTile:getGround() then        doAreaCombatHealth(0, 0, self, 0, 0, 0, CONST_ME_NONE)        Game.createItem(460, 1, self)    endend

Eae Deglorio quanto tempo parceiro, chama no privado ae tenho um convite.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.


    Administrador |  Diretor |  Coordenador |  Moderador |  Suporter |  Estagiário |  Herói
  • Similar Content

    • By Haka
      Versão do Servidor: TFS - 0.3.5 Tipo de Script: Código: Quando eu tento compilar o fts aparece essse erro
       
        In constructor 'ODBCResult::ODBCResult(void*)': 
      351 databaseodbc.cpp 'res' was not declared in this scope
      351 databaseodbc.cpp *** [Obj/databaseodbc.o] Error 1  
       
      se alguem puder me ajudar, agradeceria muito
       
    • By Yan Liima
      Limite máximo de players em guild in-game 😜

      Bom galera estou postando esse conteúdo como complemento do limite em WEBSITE
      Ao utilizar !joinguild esse code verifica se a guilda já atingiu o limite máximo de membros(configurado)
      Eu estarei disponibilizando de duas maneiras:
      1º Será um valor configurado no proprio config.lua, onde determinará o limite máximo de todas as guild.(já incluido na 0.4 rev3996)
      2º A verificação será feita por DB, onde terá um valor padrão para cada guilda criada, podendo ser alterado o valor de membros maximo.
      Ou seja, a guilda número UM pode ter máximo de 50 players, e a guilda número DOIS pode ter o máximo de 100.
      Vocês pode ser criativos e vender items que aumenta o limite ou fazer eventos/sorteios para aumentar...

      Enfim, vamos lá...
      Primeira maneira:

       
      Segunda maneira:

       
      Prontinho galera, espero que ajude algumas pessoas xD
    • By Yan Oliveira
      Olá pessoal!
       
      Esse é um tutorial bem simples para o player(master) não poder atacar seus summons e o summon do player(master) não atacar outros players.
       
      Esse tutorial é muito útil principalmente para quem está desenvolvendo derivados.
       
      *OBS: Esse tutorial só funciona para TFS 1.X (1.0+)
       
      Vamos ao tutorial!!!
       
      Siga os passos à seguir:
       
      1-  Abra sua source e procure o arquivo combat.cpp
      2- Procure pela função: 
      ReturnValue Combat::canTargetCreature(Player* attacker, Creature* target) 3- Insira o código à seguir dentro da função encontrada no passo anterior:
      // BLOCO QUE O PLAYER (MASTER) NÃO PODE ATACAR O SUMMON // if (target->isSummon()) { return RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE; } // BLOCO QUE O SUMMON DO PLAYER (MASTER) NÃO PODE ATACAR OUTRO JOGADOR // if (attacker->isSummon() && target->getPlayer()) { return RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER; }  
      4- Compile a source
       
      Pronto! Agora está terminado e você pode jogar!
       
      Um recurso simples, mas bem útil.
    • By StrikersBR12
      Alguem me ajuda com esse erro?

    • By Senju uchira
      oiee tou com esses pobleminhas ao compila uns codigo ,alguém consegue me ajuda ou solucionar rsrsrs dou REP+++++++++


      up