Ir para conteúdo

[TFS 1.2] Flying Mount System


Posts Recomendados

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)

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

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.

Link para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...